??xml version="1.0" encoding="utf-8" standalone="yes"?>久久国产精品亚洲综合,亚洲邪恶天堂影院在线观看,国产亚洲情侣久久精品http://m.tkk7.com/zellux/category/21898.htmlq的大二:M 思?{待zh-cnSat, 24 May 2008 05:40:20 GMTSat, 24 May 2008 05:40:20 GMT60原来GCC是支持尾递归的递推优化?/title><link>http://m.tkk7.com/zellux/archive/2008/05/24/202528.html</link><dc:creator>ZelluX</dc:creator><author>ZelluX</author><pubDate>Fri, 23 May 2008 18:05:00 GMT</pubDate><guid>http://m.tkk7.com/zellux/archive/2008/05/24/202528.html</guid><wfw:comment>http://m.tkk7.com/zellux/comments/202528.html</wfw:comment><comments>http://m.tkk7.com/zellux/archive/2008/05/24/202528.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/zellux/comments/commentRss/202528.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/zellux/services/trackbacks/202528.html</trackback:ping><description><![CDATA[ <p>水木上有了个有趣的程?/p> <div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"> <img src="http://m.tkk7.com/images/OutliningIndicators/None.gif" align="top" /> <span style="COLOR: #000000">#include </span> <span style="COLOR: #000000"><</span> <span style="COLOR: #000000">stdlib.h</span> <span style="COLOR: #000000">></span> <span style="COLOR: #000000"> <br /> <img src="http://m.tkk7.com/images/OutliningIndicators/None.gif" align="top" />#include </span> <span style="COLOR: #000000"><</span> <span style="COLOR: #000000">stdio.h</span> <span style="COLOR: #000000">></span> <span style="COLOR: #000000"> <br /> <img src="http://m.tkk7.com/images/OutliningIndicators/None.gif" align="top" /> <br /> <img src="http://m.tkk7.com/images/OutliningIndicators/None.gif" align="top" /> </span> <span style="COLOR: #0000ff">void</span> <span style="COLOR: #000000"> print_forever(</span> <span style="COLOR: #0000ff">int</span> <span style="COLOR: #000000"> n)<br /><img id="Codehighlighter1_66_118_Open_Image" onclick="this.style.display='none'; Codehighlighter1_66_118_Open_Text.style.display='none'; Codehighlighter1_66_118_Closed_Image.style.display='inline'; Codehighlighter1_66_118_Closed_Text.style.display='inline';" src="http://m.tkk7.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_66_118_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_66_118_Closed_Text.style.display='none'; Codehighlighter1_66_118_Open_Image.style.display='inline'; Codehighlighter1_66_118_Open_Text.style.display='inline';" src="http://m.tkk7.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span> <span id="Codehighlighter1_66_118_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"> <img src="http://m.tkk7.com/images/dot.gif" /> </span> <span id="Codehighlighter1_66_118_Open_Text"> <span style="COLOR: #000000">{<br /><img src="http://m.tkk7.com/images/OutliningIndicators/InBlock.gif" align="top" />    printf(</span> <span style="COLOR: #000000">"</span> <span style="COLOR: #000000">%d\n</span> <span style="COLOR: #000000">"</span> <span style="COLOR: #000000">, n);<br /><img src="http://m.tkk7.com/images/OutliningIndicators/InBlock.gif" align="top" />    print_forever(n </span> <span style="COLOR: #000000">+</span> <span style="COLOR: #000000"> </span> <span style="COLOR: #000000">1</span> <span style="COLOR: #000000">);<br /><img src="http://m.tkk7.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span> </span> <span style="COLOR: #000000"> <br /> <img src="http://m.tkk7.com/images/OutliningIndicators/None.gif" align="top" /> <br /> <img src="http://m.tkk7.com/images/OutliningIndicators/None.gif" align="top" /> </span> <span style="COLOR: #0000ff">int</span> <span style="COLOR: #000000"> main(</span> <span style="COLOR: #0000ff">int</span> <span style="COLOR: #000000"> argc, </span> <span style="COLOR: #0000ff">char</span> <span style="COLOR: #000000"> </span> <span style="COLOR: #000000">*</span> <span style="COLOR: #000000">argv[])<br /><img id="Codehighlighter1_154_192_Open_Image" onclick="this.style.display='none'; Codehighlighter1_154_192_Open_Text.style.display='none'; Codehighlighter1_154_192_Closed_Image.style.display='inline'; Codehighlighter1_154_192_Closed_Text.style.display='inline';" src="http://m.tkk7.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_154_192_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_154_192_Closed_Text.style.display='none'; Codehighlighter1_154_192_Open_Image.style.display='inline'; Codehighlighter1_154_192_Open_Text.style.display='inline';" src="http://m.tkk7.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span> <span id="Codehighlighter1_154_192_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"> <img src="http://m.tkk7.com/images/dot.gif" /> </span> <span id="Codehighlighter1_154_192_Open_Text"> <span style="COLOR: #000000">{<br /><img src="http://m.tkk7.com/images/OutliningIndicators/InBlock.gif" align="top" />    print_forever(</span> <span style="COLOR: #000000">0</span> <span style="COLOR: #000000">);<br /><img src="http://m.tkk7.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span> <span style="COLOR: #0000ff">return</span> <span style="COLOR: #000000"> </span> <span style="COLOR: #000000">0</span> <span style="COLOR: #000000">;<br /><img src="http://m.tkk7.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span> </span> <span style="COLOR: #000000"> <br /> <img src="http://m.tkk7.com/images/OutliningIndicators/None.gif" align="top" /> </span> </div> <br />用gcc -O2~译q行后会不停地打C0开始的自然敎ͼ注意如果~译器没有做优化的话Q打印到某个数的时候肯定会发生栈溢Z而程序终止的情况Q但q个E序却能一直运行下去,说明~译器做了尾递归优化?br /><br />用gcc -O2 -S生成q个E序的汇~代码后证实了这一炏V?br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://m.tkk7.com/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">.L6:<br /><img src="http://m.tkk7.com/images/OutliningIndicators/None.gif" align="top" />        movl    </span><span style="COLOR: #000000">%</span><span style="COLOR: #000000">ebx, </span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">(</span><span style="COLOR: #000000">%</span><span style="COLOR: #000000">esp)<br /><img src="http://m.tkk7.com/images/OutliningIndicators/None.gif" align="top" />        addl    $</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">%</span><span style="COLOR: #000000">ebx<br /><img src="http://m.tkk7.com/images/OutliningIndicators/None.gif" align="top" />        movl    $.LC0, (</span><span style="COLOR: #000000">%</span><span style="COLOR: #000000">esp)<br /><img src="http://m.tkk7.com/images/OutliningIndicators/None.gif" align="top" />        call    printf<br /><img src="http://m.tkk7.com/images/OutliningIndicators/None.gif" align="top" />        jmp     .L6<br /><img src="http://m.tkk7.com/images/OutliningIndicators/None.gif" align="top" /></span></div>print_forever的关键部分被优化成了一个n不断增加的死循环?br /><br />接下来是分析哪个优化选项处理了尾递归?br /><br />用O3 O2 O1三个优化强度~译E序Q查看汇~代码后Q发现尾递归优化是O2中新增的功能。于是查看O2新开启的优化开养I<br />gcc -c -Q -O1 --help=optimizers > /tmp/O1-opts<br />gcc -c -Q -O2 --help=optimizers > /tmp/O2-opts<br />diff /tmp/O2-opts /tmp/O1-opts | grep enabled<br />输出l果Q?br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img id="Code_Closed_Image_020417" onclick="this.style.display='none'; Code_Closed_Text_020417.style.display='none'; Code_Open_Image_020417.style.display='inline'; Code_Open_Text_020417.style.display='inline';" height="16" src="http://m.tkk7.com/images/OutliningIndicators/ContractedBlock.gif" width="11" align="top" /><img id="Code_Open_Image_020417" style="DISPLAY: none" onclick="this.style.display='none'; Code_Open_Text_020417.style.display='none'; Code_Closed_Image_020417.style.display='inline'; Code_Closed_Text_020417.style.display='inline';" height="16" src="http://m.tkk7.com/images/OutliningIndicators/ExpandedBlockStart.gif" width="11" align="top" /><span id="Code_Closed_Text_020417" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"></span><span id="Code_Open_Text_020417" style="DISPLAY: none"><br /><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><img src="http://m.tkk7.com/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000"><</span><span style="COLOR: #000000">   </span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">falign</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">loops                               [enabled]<br /><img src="http://m.tkk7.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000">></span><span style="COLOR: #000000">   </span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">falign</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">jumps                               [enabled]<br /><img src="http://m.tkk7.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000">></span><span style="COLOR: #000000">   </span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">falign</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">labels                              [enabled]<br /><img src="http://m.tkk7.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000">></span><span style="COLOR: #000000">   </span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">fcaller</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">saves                              [enabled]<br /><img src="http://m.tkk7.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000">></span><span style="COLOR: #000000">   </span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">fcrossjumping                              [enabled]<br /><img src="http://m.tkk7.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000">></span><span style="COLOR: #000000">   </span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">fcse</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">follow</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">jumps                          [enabled]<br /><img src="http://m.tkk7.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000">></span><span style="COLOR: #000000">   </span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">fdelete</span><span style="COLOR: #000000">-</span><span style="COLOR: #0000ff">null</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">pointer</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">checks                [enabled]<br /><img src="http://m.tkk7.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000">></span><span style="COLOR: #000000">   </span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">fexpensive</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">optimizations                   [enabled]<br /><img src="http://m.tkk7.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000">></span><span style="COLOR: #000000">   </span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">fforward</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">propagate                         [enabled]<br /><img src="http://m.tkk7.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000">></span><span style="COLOR: #000000">   </span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">fgcse                                      [enabled]<br /><img src="http://m.tkk7.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000">></span><span style="COLOR: #000000">   </span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">finline</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">small</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">functions                    [enabled]<br /><img src="http://m.tkk7.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000">></span><span style="COLOR: #000000">   </span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">foptimize</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">register</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">move                    [enabled]<br /><img src="http://m.tkk7.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000">></span><span style="COLOR: #000000">   </span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">foptimize</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">sibling</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">calls                    [enabled]<br /><img src="http://m.tkk7.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000">></span><span style="COLOR: #000000">   </span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">fpeephole2                                 [enabled]<br /><img src="http://m.tkk7.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000">></span><span style="COLOR: #000000">   </span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">fregmove                                   [enabled]<br /><img src="http://m.tkk7.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000">></span><span style="COLOR: #000000">   </span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">freorder</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">blocks                            [enabled]<br /><img src="http://m.tkk7.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000">></span><span style="COLOR: #000000">   </span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">freorder</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">functions                         [enabled]<br /><img src="http://m.tkk7.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000">></span><span style="COLOR: #000000">   </span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">fschedule</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">insns2                           [enabled]<br /><img src="http://m.tkk7.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000">></span><span style="COLOR: #000000">   </span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">fstrict</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">aliasing                           [enabled]<br /><img src="http://m.tkk7.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000">></span><span style="COLOR: #000000">   </span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">fthread</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">jumps                              [enabled]<br /><img src="http://m.tkk7.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000">></span><span style="COLOR: #000000">   </span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">ftree</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">pre                                  [enabled]<br /><img src="http://m.tkk7.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000">></span><span style="COLOR: #000000">   </span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">ftree</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">store</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">ccp                            [enabled]<br /><img src="http://m.tkk7.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000">></span><span style="COLOR: #000000">   </span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">ftree</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">vrp                                  [enabled]<br /><img src="http://m.tkk7.com/images/OutliningIndicators/None.gif" align="top" /></span></span></div><br />l证实是-foptimize-sibling-callsq个选项实现了尾递归的优化,具体内容可以参看<br /><a >http://gcc.gnu.org./ml/gcc-patches/2000-03/msg00867.html</a><img src ="http://m.tkk7.com/zellux/aggbug/202528.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/zellux/" target="_blank">ZelluX</a> 2008-05-24 02:05 <a href="http://m.tkk7.com/zellux/archive/2008/05/24/202528.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C/C++中的序列?/title><link>http://m.tkk7.com/zellux/archive/2008/05/16/200811.html</link><dc:creator>ZelluX</dc:creator><author>ZelluX</author><pubDate>Fri, 16 May 2008 02:42:00 GMT</pubDate><guid>http://m.tkk7.com/zellux/archive/2008/05/16/200811.html</guid><wfw:comment>http://m.tkk7.com/zellux/comments/200811.html</wfw:comment><comments>http://m.tkk7.com/zellux/archive/2008/05/16/200811.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/zellux/comments/commentRss/200811.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/zellux/services/trackbacks/200811.html</trackback:ping><description><![CDATA[     摘要: 发信? NetMD (C++), 信区: CPlusPlus <br>? ? [FAQ] C/C++中的序列?<br>发信? 水木C֌ (Wed Feb 7 01:13:41 2007), 站内  <a href='http://m.tkk7.com/zellux/archive/2008/05/16/200811.html'>阅读全文</a><img src ="http://m.tkk7.com/zellux/aggbug/200811.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/zellux/" target="_blank">ZelluX</a> 2008-05-16 10:42 <a href="http://m.tkk7.com/zellux/archive/2008/05/16/200811.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Lab2http://m.tkk7.com/zellux/archive/2007/11/20/161745.htmlZelluXZelluXMon, 19 Nov 2007 16:37:00 GMThttp://m.tkk7.com/zellux/archive/2007/11/20/161745.htmlhttp://m.tkk7.com/zellux/comments/161745.htmlhttp://m.tkk7.com/zellux/archive/2007/11/20/161745.html#Feedback0http://m.tkk7.com/zellux/comments/commentRss/161745.htmlhttp://m.tkk7.com/zellux/services/trackbacks/161745.htmlq个lab主要考察gdb的用和Ҏ~代码的理解。后者在qx的作业中涉及得较多,q里不再赘述Q主要介l一?/span>gdb
其实偶对q个也不是很熟,有错误请指正 @@

单的_gdb是一Ƒּ大的调试工具Q尽它只有文本界面Q需要图形界面可以?/span>dddQ不q区别不大)Q但是功能却?/span>eclipse{调试环境强很多?/span>

接下来看看怎样让它?/span>lab2拆炸Ҏ务,在命令行下运?/span>gdb bombp开始调试这个炸弹程序,提高警惕Q恩

首先最重要的,是如何L炸弹的引爆,gdb自然提供了一般调试工具都包括的断点功能—?/span>break命o

?/span>gdb中输?/span>help break能够看到相关的信?/span>

(gdb) help break

Set breakpoint at specified line or function.
Argument may be line number, function name, or "*" and an address.
If line number is specified, break at start of code for that line.
If function is specified, break at start of code for that function.
If an address is specified, break at that exact address.
With no arg, uses current execution address of selected stack frame.
This is useful for breaking on return to a stack frame.
Multiple breakpoints at one place are permitted, and useful if conditional.
Do "help breakpoints" for info on other commands dealing with breakpoints.

可以看到break允许我们使用行号、函数名或地址讄断点

?/span>ctrl+z暂时挂v当前?/span>gdbq程Q运?/span>objdump –d bomb | more 查看反编译后的炸ҎӞ可以看到里面有这么一行(开始的那个地址每个人都不同Q:

08049719 <explode_bomb>:

q个是万恶的引爆炸弹的函数了,q行fgq回gdb环境Q在q个函数讄断点Q?/span>

break explode_bomb Q可以?/span>tab键自动补齐)

Breakpoint 1 at 0x8049707

接下来你可以喘口气,一般情况下炸弹是不会引爆的?/span>

下面我们来拆W一个炸弹,首先同样是设|断点,bomb.c中给Z各个兛_的函数名Q第一兛_?/span>phase_1Q?/span>break phase_1在第一兌|断?/span>

接下来就开始运行吧Q输?/span>run

Welcome to my fiendish little bomb. You hava 6 phases with

which to blow yourself up. Hava a nice day!

我们已经讄了炸Ҏ点,q些恐吓可以直接无视?/span>

输入ABCl箋Q输入这个是Z方便在后面的试中找到自q输入串地址Q?/span>

提示Breakpoint 2, 0x08048c2e in phase_1 ()Q说明现在程序已l停在第一个关?/span>

接下来就是分析汇~代码,使用disassemble phase_1昄q个函数的汇~代?/span>

注意其中关键的几行:

8048c2e:68 b4 99 04 08          push   $0x80499b4

8048c33:ff 75 08              pushl 0x8(%ebp)

8048c36:e8 b1 03 00 00        call   8048fec <strings_not_equal>

q个lab很厚道的一点就是函数名很明地说明了函数的功能 ^_^

估计q三行代码的意思就是比较两个字W串相等Q不相等的话应该׃让炸弹爆怺

因ؓ字符串很大,所以传递给q个比较函数的肯定是他们的地址Q分别ؓ0x80499b4?/span>0x8(%ebp)

我们先来看后者,使用p/x *(int*)($ebp + 8)查看字符串所在的地址

$1 = 0x804a720Ql?/span>p/x *0x804a720查看内存中这个地址的内?/span>

$2 = 0x434241Q连l的三个敎ͼ是不是想起什么了Q把q三个数分别转换为十q制Q就?/span>67 66 65Q分别ؓCBA?/span>ASCII码,看来q里保存了我们输入的丌Ӏ?/span>

接下?/span>0x80499b4里肯定保存着q关的密?/span>

p/x *0x80499b4Q显C?/span>$3 = 0x62726556Q?/span>c中的字符串是?/span>0l尾的,看来q个字符串还不止q个长度Ql?/span>

p/x *0x80499b4@10查看q个地址及其后面36个字节的内容Q终于在W二行中出现了终l符”0x0”Q不一定是四个字节Q?/span>

$4 = {0x62726556, 0x7469736f, 0x656c2079, 0x20736461, 0x75206f74, 0x656c636e, 0x202c7261, 0x72616e69,

 0x75636974, 0x6574616c, 0x69687420, 0x2e73676e, 0x0, 0x21776f57, 0x756f5920, 0x20657627, 0x75666564,

 0x20646573, 0x20656874, 0x72636573}

把开头到0x0的所有信息字节下来,通过手算或者自己写E序得出最后的密码Ԍ注意little endian中字W的排列方式Q)

输入run重新q行Q输入刚才得出的密码Ԍ如果前面的计正的话,׃提示

Phase 1 defused. How about the next one?

关于q个lab的一些其他心得:

1.       VMware中开发很不舒服,屏幕、字体丑@@、需?/span>Ctrl+Alt切换?/span>windowsQ不怎么方便Q推荐在windows下?/span>piettyd虚拟Z?/span>linuxpȝQ?/span>RedHat 9默认安装?/span>sshdQ,个h觉得q样比较方便?/span>

2.       ASCII查询可以?/span>linuxl端中运?/span>man ascii?/span>

3.       退?/span>gdb后,再次q入时一定要注意使用breakl?/span>explode_bomb上断点,不可大意 ~.~

4.       后面的几x及递归{内容,也有和前面几ơ作业很怼的东东?/span>

5.    gdb中还有一个很好用的jump指oQ可以在q行时Q意蟩转?br /> 6.    看汇~代码时Q用objdump -d bomb > bomb.asm把汇~代码保存到bomb.asm中,然后使用sftp工具把这个文件下载到windows或者直接在vim中查看,q样比在gdb中看方便一些?br /> 7.    个h认ؓlab2和期中考试不冲H,q个lab2可以帮你理清很多汇编语言的概?

其他补充Q?br /> sfox: 
可以通过GDB中的x /s addr输出以\0l尾的字W串
ICSLab: 
Z防止每次拆的时候都不停的输入之前的stage的keyQ可以把key存入文本文gQ一行一个keyQ不要有多余字符
然后GDB run 的时候用gdb bomb 回R
(gdb) b .... ....
(gdb) r password.txt
q样bomb׃自动从password.txt中读入之前的密码
直到到达最后一个空行处Q如Lab2的说明文档中所q?br />

ZelluX 2007-11-20 00:37 发表评论
]]>
C++ 入门W记 (8) - Object-Oriented Programminghttp://m.tkk7.com/zellux/archive/2007/11/15/160659.htmlZelluXZelluXWed, 14 Nov 2007 16:44:00 GMThttp://m.tkk7.com/zellux/archive/2007/11/15/160659.htmlhttp://m.tkk7.com/zellux/comments/160659.htmlhttp://m.tkk7.com/zellux/archive/2007/11/15/160659.html#Feedback4http://m.tkk7.com/zellux/comments/commentRss/160659.htmlhttp://m.tkk7.com/zellux/services/trackbacks/160659.html virtual void gen_elems(int pos) = 0;

2. 通常情况下,定义了一个或多个虚函数的基类要定义一个虚析构函数Q因为在释放子类内存时具体析构函数需要在q行期才能确定?
作者也不徏议把析构函数定义为纯虚的Q即使没有Q何具体的实现?br />
恩,睡觉

ZelluX 2007-11-15 00:44 发表评论
]]>
memcpy函数代码分析http://m.tkk7.com/zellux/archive/2007/10/19/153822.htmlZelluXZelluXFri, 19 Oct 2007 15:56:00 GMThttp://m.tkk7.com/zellux/archive/2007/10/19/153822.htmlhttp://m.tkk7.com/zellux/comments/153822.htmlhttp://m.tkk7.com/zellux/archive/2007/10/19/153822.html#Feedback2http://m.tkk7.com/zellux/comments/commentRss/153822.htmlhttp://m.tkk7.com/zellux/services/trackbacks/153822.htmlmaillist上有人问关于q个函数的问题,回复中有人推荐去看它的源代码

memcpy调用了__memcpy函数执行内存的复Ӟ__memcpy3d先不管了)Q下面是q个q两个函数的代码

void *memcpy(void *to, const void *from, size_t n)
{
#ifdef CONFIG_X86_USE_3DNOW
 
return __memcpy3d(to, from, n);
#else
 
return __memcpy(to, from, n);
#endif
}


static __always_inline void * __memcpy(void * to, const void * from, size_t n)
{
int d0, d1, d2;
__asm__ __volatile__(
 
"rep ; movsl\n\t"
 
"movl %4,%%ecx\n\t"
 
"andl $3,%%ecx\n\t"
#if 1 /* want to pay 2 byte penalty for a chance to skip microcoded rep? */
 
"jz 1f\n\t"
#endif
 
"rep ; movsb\n\t"
 
"1:"
 : 
"=&c" (d0), "=&D" (d1), "=&S" (d2)
 : 
"0" (n/4), "g" (n), "1" ((long) to), "2" ((long) from)
 : 
"memory");
return (to);
}

看了一本内联汇~的书,ȝ把这D代码搞懂了?br /> 起始Ӟ把n/4保存?ecx寄存器中Qƈ把to和from的地址分别存入%edi?esi Q引用占位符Q?br /> 然后重复调用movsl n/4ơ,接下来应该还?n mod 4)个字节尚未复Ӟq里用了一个比较y妙的Ҏ
movl %4, %%ecx    把n的g存到%ecx
andl $3, %%ecx    n?做逻辑与,得到n mod 4
jz 1f             如果4 | nQ蟩q后面的复制
rep movsb         再复?n mod 4)个字?br />
׃是按四个字节复制的,因此效率上memcpy肯定比strcpy高不?/span>

ZelluX 2007-10-19 23:56 发表评论
]]>
在未安装qt的windowspȝ中运行qtE序http://m.tkk7.com/zellux/archive/2007/10/04/150451.htmlZelluXZelluXThu, 04 Oct 2007 15:31:00 GMThttp://m.tkk7.com/zellux/archive/2007/10/04/150451.htmlhttp://m.tkk7.com/zellux/comments/150451.htmlhttp://m.tkk7.com/zellux/archive/2007/10/04/150451.html#Feedback2http://m.tkk7.com/zellux/comments/commentRss/150451.htmlhttp://m.tkk7.com/zellux/services/trackbacks/150451.html同目录下包含q三个文件即?br />
mingwm10.dll
QtCore4.dll
QtGui4.dll



ZelluX 2007-10-04 23:31 发表评论
]]>
C++ 入门W记 (7)http://m.tkk7.com/zellux/archive/2007/10/01/150087.htmlZelluXZelluXMon, 01 Oct 2007 11:26:00 GMThttp://m.tkk7.com/zellux/archive/2007/10/01/150087.htmlhttp://m.tkk7.com/zellux/comments/150087.htmlhttp://m.tkk7.com/zellux/archive/2007/10/01/150087.html#Feedback0http://m.tkk7.com/zellux/comments/commentRss/150087.htmlhttp://m.tkk7.com/zellux/services/trackbacks/150087.html 1. 泛型Ҏpush(elemType &x)无法接受常数{constcdQ必d形参声明为const elemType &x

2. 在给泛型cSimpleList增加operator<<ҎӞ把实C码放在类的声明外部会报错Q直接放在里面就可以Q不知道是不是必L内联inline的才可以?br /> 水木问了下,{案?br />
除非在友元声明中昑ּ指定了模板参敎ͼ否则与函数模板同名的友元函数的声明不会引用该函数模板.如果未指定模板参敎ͼ则友元声明将声明一个非模板函数?br />
3. C++中可以throw很多东西Q比如String, int{。catch (...)表示把所有的异常都捕捉到?br />

ZelluX 2007-10-01 19:26 发表评论
]]>
char *s = "hello"和char s1[]="world"的区?/title><link>http://m.tkk7.com/zellux/archive/2007/10/01/150002.html</link><dc:creator>ZelluX</dc:creator><author>ZelluX</author><pubDate>Sun, 30 Sep 2007 17:40:00 GMT</pubDate><guid>http://m.tkk7.com/zellux/archive/2007/10/01/150002.html</guid><wfw:comment>http://m.tkk7.com/zellux/comments/150002.html</wfw:comment><comments>http://m.tkk7.com/zellux/archive/2007/10/01/150002.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/zellux/comments/commentRss/150002.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/zellux/services/trackbacks/150002.html</trackback:ping><description><![CDATA[水木上的帖子<br /> <br /> s 是全局数据区,<br /> s1 是函数的栈空间区域,函数执行完成Q这个空间就没了<br /> ------------------------------------------------------------------------------------------<br /> 7.2 可是我听?char a[ ] ?char *a 是一L?<br /> q如此?你所听说的应该跟函数的Ş式参数有养I参见问题  6.4) 数组不是指针?数组定义 char a[6] h预留 6 个字W的位置, q用名称 ``a" 表示。也是? 有一个称?``a" 的位|? 可以攑օ 6 个字W?而指针申?char *p, h一个位|放|一个指? 用名U?``p" 表示?q个指针几乎可以指向M位置: M字符和Q何连l的字符, 或者哪里也不指(参见问题 5.1 ? 1.10)?<br /> <br /> 一个图形胜q千a万语。声?<br /> <br />     char a[] = "hello";<br />     char *p = "world";<br /> <br /> 会初始化下图所C的数据l果: <br /> <span style="font-family: Courier">       +---+---+---+---+---+---+<br style="font-family: " />     a: | h | e | l | l | o |\0 |<br style="font-family: " />        +---+---+---+---+---+---+<br style="font-family: " />        +-----+     +---+---+---+---+---+---+<br style="font-family: " />     p: |  *======> | w | o | r | l | d |\0 |<br style="font-family: " />        +-----+     +---+---+---+---+---+---+</span><br /> <br /> Ҏ x 是数l还是指? cM x[3] q样的引用会生成不同的代码。认识到q一点大有裨益。以上面的声明ؓ? 当编译器看到表达? a[3] 的时? 它生成代码从 a 的位|开始蟩q?3 ? 然后取出那个字符. 如果它看?p[3], 它生成代码找?``p" 的位|? 取出其中的指针? 在指针上?3 然后取出指向的字W。换a? a[3] ?名ؓ a 的对?(的v始位|? 之后 3 个位|的? ?p[3] ? p 指向的对象的 3 个位|之后的? 在上例中, a[3] ? p[3] y都是 'l' , 但是~译器到N里的途径不尽相同。本质的区别在于cM a 的数l和cM p 的指针一旦在表达式中出现׃按照不同的方法计? 不论它们是否有下标。下一问题l箋深入解释?参见问题 1.13?<br /> <br /> 参考资料: [K&R2, Sec. 5.5 p. 104]; [CT&P, Sec. 4.5 pp. 64-5]?<br /> <br /> 7.3 那么, ?C 语言?``指针和数l等? 到底是什么意?Q?<br /> ?C 语言中对数组和指针的困惑多数都来自这句话。说数组和指?``{h"  不表C它们相? 甚至也不能互换。它的意思是说数l和指针的算法定义可以用指针方便的访问数l或者模拟数l?<br /> 特别? {h的基来自q个关键定义: <br /> <br /> 一?T 的数l类型的左值如果出现在表达式中会蜕变ؓ一个指向数l第一个成员的指针(除了三种例外情况); l果指针的类型是 T 的指针?<br /> q就是说, 一旦数l出现在表达式中, ~译器会隐式地生成一个指向数l第一个成员地指针, 像E序员写Z &a[0] 一栗例外的情况? 数组? sizeof ?& 操作W的操作? 或者ؓ字符数组的字W串初始倹{?<br /> <br /> 作ؓq个q个定义的后? ~译器ƈ那么不严格区分数l下标操作符和指针。在形如 a[i] 的表辑ּ? Ҏ上边的规? 数组蜕化为指针然后按照指针变量的方式?p[i] 那样d, 如问?6.2 所q? 管最l的内存讉Kq不一栗?如果你把数组地址赋给指针: <br /> <br />     p = a;<br /> <br /> 那么 p[3] ?a[3] 会讉K同样的成员?<br /> 参见问题 6.6 ?6.11?<br /> ------------------------------------------------------------------------------------------<br /> char *s1 = "hello";<br /> char s2[6] = "hello";<br /> <br /> cd指针与类型数l名在很多场合中可等价用。容易给人造成的印象是两者是{h?br /> q话不尽然。首先我们要明白q是两个不同的东ѝ?br /> <br /> s1的类型char *Q而s2的类型是array of char?br /> s1初始化ؓ一个指针|指向一个内存区域,该处?个字W的数据Q?br /> ?h', 'e', 'l', 'l', 'o', '\0'?在运行过E中Qs1的值可改变Q指向其他Q何允许的地址?br /> 但上面的数据("hello")不会在程序退Z前销毁[注:q是另外一个比较迷惑h的细节]Q?br /> 即s1变量生命周期l束?br /> <br /> s2初始化ؓ6个字W的数组Q也?h', 'e', 'l', 'l', 'o', '\0'。在q行q程中,s2的内容可改变Q?br /> 也就是存储在s2中的hello也就"消失"了?br /> <br /> 但ؓ什么容易给人造成cd指针与类型数l名可等L疑惑呢?虽然cd不同Q但C规定Qؓ?br /> q求z与灉|性,C假设使用者知道自׃码会有什么结果。)在很多场合下Q认为数l名<br /> 与类型指针类型兼宏V记忆中只有2中情况下Q数l名不可{同视ؓ数组指针Q?amp;与sizeof操作W?br /> <br />     void foo1(const char *str) {...}; <br />     void foo2(int size) {return size};<br />     ...<br />     char *s1 = "hello";<br />     char s2[6] = "hello";<br />     <br />     foo1(s1);   // ok<br />     foo1(s2);   // ok<br />     foo1(&s2);  // incompatible<br />     foo2(&s2[0]);  // ok<br />     <br />     s1[0] = 0;  // error<br />     s2[0] = 0;  // ok<br />     <br />     s1 = s2;   // ok<br />     s2 = s1;   // error<br />         <br />     // 下面假设在ia32q_上运?br />     foo2(sizeof(s1)); // return 4, pointer size<br />     foo2(sizeof(s2)); // return 6, array size<br />     <br /> 只记得上面的q些内容Q不知道寚wQ与大家共同提高?br /> <img src ="http://m.tkk7.com/zellux/aggbug/150002.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/zellux/" target="_blank">ZelluX</a> 2007-10-01 01:40 <a href="http://m.tkk7.com/zellux/archive/2007/10/01/150002.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++ 学习W记 (6)http://m.tkk7.com/zellux/archive/2007/10/01/150001.htmlZelluXZelluXSun, 30 Sep 2007 17:08:00 GMThttp://m.tkk7.com/zellux/archive/2007/10/01/150001.htmlhttp://m.tkk7.com/zellux/comments/150001.htmlhttp://m.tkk7.com/zellux/archive/2007/10/01/150001.html#Feedback0http://m.tkk7.com/zellux/comments/commentRss/150001.htmlhttp://m.tkk7.com/zellux/services/trackbacks/150001.htmlC++ 学习W记(6) 
1. cd明中定义的函数都被自动处理ؓinline函数?
 
2. Triangular t5(); q句话似乎声明了一个类的实例,但事实上QC++Z保持与C语法的一_该语句会被解释成一个返回Triangular对象的函敎ͼ正确的声明应该去?)?
 
3. 考虑下面一D代?
class Matrix {
public:
    Matrix( int row, int col )  // ...
    ~Matrix()  { delete [] _pmat; }
private:
    int _row, _col;
    double *_pmat;
};

 
{
    Matrix mat(4, 4);
    {
        Matrix mat2 = mat;
    }
}
    把mat复制lmat2后,mat2中的_pmat与mat的_pmat指向同一个数l,在mat2所在的域结束后Qmat2被释放,同时删除了_pmat指针指向的内宏V错误发生?
    解决办法是在Matrix::Matrix( const Matrix &rhs )中详l指出深层拷贝的ҎQ同时实现赋值操作符的重载?/p>

4. mutable ?const
constҎ无法修改cȝ成员Qmutable成员除外?/p>

ZelluX 2007-10-01 01:08 发表评论
]]>
C++ 入门W记 (5)http://m.tkk7.com/zellux/archive/2007/09/24/147004.htmlZelluXZelluXMon, 24 Sep 2007 12:45:00 GMThttp://m.tkk7.com/zellux/archive/2007/09/24/147004.htmlhttp://m.tkk7.com/zellux/comments/147004.htmlhttp://m.tkk7.com/zellux/archive/2007/09/24/147004.html#Feedback0http://m.tkk7.com/zellux/comments/commentRss/147004.htmlhttp://m.tkk7.com/zellux/services/trackbacks/147004.html #include <limits>
int max_int = numeric_limits<int>::max();
double min_dbl = numeric_limits<double>::max();

2. A struct is simply a class whose members are public by default.

3. cȝ似有成员的保护依赖于Ҏ员名使用的限Ӟ也就是说Q通过地址操作、强制类型{换等技术可以被讉KQC++可以防止意外的发生,但不能阻止这U故意的ƺ骗。只有硬件层面才有可能防止这U恶意访问,但通常在现实中也很隑ց到?br />
4. 使用cȝ初始化列表代替代码体中的赋D句可以节省很多时间。而且Q如果一个数据成员是const的,那么它只能在初始化列表中q行初始化;如果一个数据成员是不具有零参数的构造函数的cȝ型,那么它也必须在初始化列表中进行初始化?

ZelluX 2007-09-24 20:45 发表评论
]]>
A Note on TMinhttp://m.tkk7.com/zellux/archive/2007/09/19/146605.htmlZelluXZelluXWed, 19 Sep 2007 13:26:00 GMThttp://m.tkk7.com/zellux/archive/2007/09/19/146605.htmlhttp://m.tkk7.com/zellux/comments/146605.htmlhttp://m.tkk7.com/zellux/archive/2007/09/19/146605.html#Feedback1http://m.tkk7.com/zellux/comments/commentRss/146605.htmlhttp://m.tkk7.com/zellux/services/trackbacks/146605.html

Summary

Due to one of the rules for processing integer constants in ANSI C, the numeric constant -2147483648 is handled in a peculiar way on a 32-bit, two's complement machine.

The problem can be corrected by writing -2147483647-1, rather than -2147483648 in any C code.


Description of Problem

The ANSI C standard requires that an integer constant too large to be represented as a signed integer be ``promoted'' to an unsigned value. When GCC encounters the value 2147483648, it gives a warning message: ``warning: decimal constant is so large that it is unsigned.'' The result is the same as if the value had been written 2147483648U.
ANSI C标准中要求太大的整型帔R都表CZؓunsigned

The compiler processes an expression of the form -X by first reading the expression X and then negating it. Thus, when the C compiler encounters the constant -2147483648, it first processes 2147483648, yielding 2147483648U, and then negates it. The unsigned negation of this value is also 2147483648U. The bit pattern is correct, but the type is wrong!

书上的一个小错误

Writing TMin in Code

The ANSI C standard states that the maximum and minimum integers should be declared as constants INT_MAX and INT_MIN in the file limits.h. Looking at this file on an IA32 Linux machine (in the directory /usr/include), we find the following declarations:
/* Minimum and maximum values a `signed int' can hold.  */
#define INT_MAX 2147483647
#define INT_MIN (-INT_MAX - 1)

This method of declaring INT_MIN avoids accidental promotion and also avoids any warning messages by the C compiler about integer overflow.

The following are ways to write TMin_32 for a 32-bit machine that give the correct value and type, and don't cause any error messages:

  • -2147483647-1
  • (int) 2147483648U
  • 1<<31
The first method is preferred, since it indicates that the result will be a negative number.
表示-2147483648的几U方?br />

ZelluX 2007-09-19 21:26 发表评论
]]>
支持参数和后台运行的shellhttp://m.tkk7.com/zellux/archive/2007/08/28/140541.htmlZelluXZelluXTue, 28 Aug 2007 07:37:00 GMThttp://m.tkk7.com/zellux/archive/2007/08/28/140541.htmlhttp://m.tkk7.com/zellux/comments/140541.htmlhttp://m.tkk7.com/zellux/archive/2007/08/28/140541.html#Feedback0http://m.tkk7.com/zellux/comments/commentRss/140541.htmlhttp://m.tkk7.com/zellux/services/trackbacks/140541.html
#include "csapp.h"
#define MAXARGS 128

void eval(char *cmdline);
int parseline(char *buf, char **argv);
int buildin_command(char **argv);

int main()
{
    
char cmdline[MAXLINE];

    
while (1)
    {
        printf(
"");
        Fgets(cmdline, MAXLINE, stdin);
        
if (feof(stdin))
            exit(
0);

        eval(cmdline);
    }
}

void eval(char *cmdline)
{
    
char *argv[MAXARGS];
    
char buf[MAXLINE];
    
int bg;
    pid_t pid;

    strcpy(buf, cmdline);
    bg 
= parseline(buf, argv);
    
if (argv[0== NULL)
        
return;

    
if (!builtin_command(argv))
    {
        
if ((pid = Fork()) == 0)
        {
            
if (execve(argv[0], argv, environ) < 0)
            {
                printf(
"%s: Command not found.\n", argv[0]);
                exit(
0);
            }
        }
        
        
if (!bg)
        {
            
int status;
            
if (waitpid(pid, &status, 0< 0)
                unix_error(
"waitfg: waitpid error");
        }
        
else
            printf(
"%d %s", pid, cmdline);
    }
    
return;
}

int builtin_command(char **argv)
{
    
if (!strcmp(argv[0], "quit"))
        exit(
0);
    
if (!strcmp(argv[0], "&"))
        
return 1;
    
return 0;
}

int parseline(char *buf, char **argv)
{
    
char *delim;
    
int argc;
    
int bg;

    buf[strlen(buf) 
- 1= ' ';
    
while (*buf && (*buf == ' '))
        buf
++;

    argc 
= 0;
    
while ((delim = strchr(buf, ' ')))
    {
        argv[argc
++= buf;
        
*delim = '\0';
        buf 
= delim + 1;
        
while (*buf && (*buf == ' '))
            buf
++;
    }
    argv[argc] 
= NULL;

    
if (argc == 0)
        
return 1;

    
if ((bg = (*argv[argc - 1== '&')) != 0)
        argv[
--argc] = NULL;

    
return bg;
}




ZelluX 2007-08-28 15:37 发表评论
]]>
APUE - File I/O (5)http://m.tkk7.com/zellux/archive/2007/08/22/138633.htmlZelluXZelluXWed, 22 Aug 2007 07:46:00 GMThttp://m.tkk7.com/zellux/archive/2007/08/22/138633.htmlhttp://m.tkk7.com/zellux/comments/138633.htmlhttp://m.tkk7.com/zellux/archive/2007/08/22/138633.html#Feedback0http://m.tkk7.com/zellux/comments/commentRss/138633.htmlhttp://m.tkk7.com/zellux/services/trackbacks/138633.html#include <unistd.h>
int dup(int filedes);
int dup2(int filedes, int filedes2);
// Both return: new file descriptor if OK, -1 on error

dupq回的file descriptor(以下Ufd)为当前可用的最低号码,dup2则指定目的fdQ如果该fd已被打开Q则首先关闭q个fd?br>dup后两个fd指向相同的file table entryQ这意味着它们׃n同一个的file status flag, read, write, append, offset{?br>
事实上,dup{h?br> fcntl(filedes, F_DUPFD, 0);

dup2和也cM?br> close(filedes2);
fcntl(filedes, F_DUPFD, filedes2);
但这不是一个原子操作,而且errno也有一定的不同?img src ="http://m.tkk7.com/zellux/aggbug/138633.html" width = "1" height = "1" />

ZelluX 2007-08-22 15:46 发表评论
]]>
APUE - File I/O (4) - Atomic Operationshttp://m.tkk7.com/zellux/archive/2007/08/21/138379.htmlZelluXZelluXTue, 21 Aug 2007 06:45:00 GMThttp://m.tkk7.com/zellux/archive/2007/08/21/138379.htmlhttp://m.tkk7.com/zellux/comments/138379.htmlhttp://m.tkk7.com/zellux/archive/2007/08/21/138379.html#Feedback0http://m.tkk7.com/zellux/comments/commentRss/138379.htmlhttp://m.tkk7.com/zellux/services/trackbacks/138379.htmlAppending to a File
 考虑某个单一q程试图在文件追加写入的操作。由于早期的UNIXpȝ不支持O_APPEND选项Q因此得先用lseekoffset|于文gN?br>if (lseek(fd, 0L, 2) < 0)
    err_sys("lseek error");
if (write(fd, buf, 100) != 100)
    err_sys("write error");
注意q里的lseek函数的第三个参数2{于SEEK_END帔RQ但是早期UNIXq没有这个常量名QSystem V中才引进Q?br>
q样的处理在多进E试囑֜同一文gNq加写入时就有可能出现问题?br>假设两个独立U程A B要在某个文gNq加写入Q用了上述ҎQƈ没有使用O_APPEND开兟?br>? 先A指向了该文gNQ假设是offset=1500的地方)Q接着内核切换到Bq程QB也指向了该尾部,然后写入?00字节Q此时内核把v-node 中当前文件的大小改ؓ?600。内核再ơ切换进E,Al箋q行Q调用writeҎQ结果就在offset=1500的地方写入了Q覆盖了Bq程写入? 内容?br>
q个问题其实和Java中的多线E差不多Q指向文件尾部和写入应该作ؓ一个原子操作执行,像Java中用synchronized块保护原子操作。用O_APPEND选项是一U解x法?br>另一U解x法时使用XSI extension中的pread和pwrite函数?br>#include <unistd.h>

ssize_t pread(int filedes, void *buf, size_t nbytes, off_t offset);
// Returns: number of bytes read, 0 if end of file, -1 on error

ssize_t pwrite(int filedes, const void *buf, size_t nbytes, off_t offset);
// Returns: number of bytes read, 0 if end of file, -1 on error

调用pread与调用lseek后再调用read{hQ以下情况除外:
1. pread的两个步骤无法被中断?br>2. 文g指针未被更新时?br>
pwrite与lseek+write的差别也怼?br>
Creating a File
当用O_CREAT和O_EXCL开兌用open函数Ӟ如果文g已经存在Q则open函数q回p|倹{如果不使用q两个开养I可以q样写:
if ((fd = open(pathname, O_WRONLY)) < 0) {
    
if (errno == ENOENT) {
        
if ((fd = creat(pathname, mode)) < 0)
            err_sys(
"creat error");
    } 
else {
        err_sys(
"open error");
    }
}

当open函数执行后creat函数执行前另一个进E创Z同名文g的话Q该数据׃被擦除?

ZelluX 2007-08-21 14:45 发表评论
]]>
APUE - File I/O (3) - File Sharinghttp://m.tkk7.com/zellux/archive/2007/08/20/138233.htmlZelluXZelluXMon, 20 Aug 2007 14:39:00 GMThttp://m.tkk7.com/zellux/archive/2007/08/20/138233.htmlhttp://m.tkk7.com/zellux/comments/138233.htmlhttp://m.tkk7.com/zellux/archive/2007/08/20/138233.html#Feedback0http://m.tkk7.com/zellux/comments/commentRss/138233.htmlhttp://m.tkk7.com/zellux/services/trackbacks/138233.htmlEvery process has an entry in the process table. Within each process table entry is a table of open file descriptors, which we can think of as a vector, with one entry per descriptor. Associated with each file descriptor are
1) The file descriptor flags (close-on-exec; refer to Figure 3.6 and Section 3.14)
2) A pointer to a file table entry

The kernel maintains a file table for all open files. Each file table entry contains
1) The file status flags for the file, such as read, write, append, sync, and nonblocking
2) The current file offset
3) A pointer to the v-node table entry for the file

Each open file (or device) has a v-node structure that contains information about the type of file and pointers to functions that operate on the file. For most files, the v-node also contains the i-node for the file. This information is read from disk when the file is opened, so that all the pertinent information about the file is readily available. For example, the i-node contains the owner of the file, the size of the file, pointers to where the actual data blocks for the file are located on disk, and so on.


上图三种数据l构及其怺联系
其中v-node主要用于提供单个操作pȝ上的多文件系l支持,Sun把它UCؓVirtual File System
linux中没有v-nodeQ用了一个generic i-node代替Q尽用了不同的实现方式,v-node在概念上与generic i-node相同?br>
下面来讨Z个独立的q程打开同一文g的情?br>q种情况下两个进E拥有不同的file tableQ但其中的两个指针指向了同一个v-node?br>
知道了这些数据结构的情况以后Q我们可以更_的知道某些操作的l果
1) 每次write操作l束后,当前文g的offset增加Q如果这个操作导致当前的offset出了文仉度,则i-node表中记录的文件大会被修改ؓ改动后的大小?br>2) 使用O_APPEND方式打开文g后,每次调用write函数Ӟ当前文g的offset都会被设|ؓi-node表中的该文g大小Q从而write函数只能在文件尾部追加?br>3) lseek 函数只改变在file table中的当前文goffsetQƈ不会产生io操作

注意file descriptor flag和file status flag的作用域差别Q前者属于某个单独进E的单独的file descriptorQ后者则适用于Q意进E中指向l定file table entry的所有descriptor。fcntl函数可以修改q两Uflag



ZelluX 2007-08-20 22:39 发表评论
]]>
APUE - File I/O (2) http://m.tkk7.com/zellux/archive/2007/08/13/136516.htmlZelluXZelluXMon, 13 Aug 2007 14:14:00 GMThttp://m.tkk7.com/zellux/archive/2007/08/13/136516.htmlhttp://m.tkk7.com/zellux/comments/136516.htmlhttp://m.tkk7.com/zellux/archive/2007/08/13/136516.html#Feedback0http://m.tkk7.com/zellux/comments/commentRss/136516.htmlhttp://m.tkk7.com/zellux/services/trackbacks/136516.htmlThe file's offset can be greater than the file's current size, in which case the next write to the file will extend the file. This is referred to as creating a hole in a file and is allowed. Any bytes in a file that not been written are read back as 0.
A hole in a file isn't required to have storage backing it on disk. Depending on the file system implementation, when you write after seeking past the end of the file, new disk blocks might be allocated to store the data, but there's no need to allocate disk blocks for the data between the old end of file and t he location where you start writing.

2. read Function
#include <unistd.h>
ssize_t read(int filedes, void *buf, size_t nbytes);
// Returns: number of bytes read, 0 if end of file, -1 on error
readd的字节数于所要求的字节数的几U可能:
1) 从文件中dQ在所要求的字节数d完成前到达文件尾?br> 2) 从终端读取,q种情况下通常每次最多读取一行内宏V?br> 3) 通过|络dQ网l缓冲可能导致读取到于要求的字节数?br> 4) 从管道或者FIFO中读?br> 5) 从record-oriented讑֤中读取,如磁带,每次臛_q回一个记录。orz...
6) 在一定数量的数据d后被信号中断?br>
3. write Function
#include <unistd.h>
ssize_t write(int filedes, const void *buf, size_t nbytes);
// Returns: number of bytes written if OK, -1 on error
D错误的通常原因是磁盘已满,或者超Zl定q程的文件大限制?

ZelluX 2007-08-13 22:14 发表评论
]]>
C++ 入门W记 (4)http://m.tkk7.com/zellux/archive/2007/08/12/136172.htmlZelluXZelluXSun, 12 Aug 2007 08:08:00 GMThttp://m.tkk7.com/zellux/archive/2007/08/12/136172.htmlhttp://m.tkk7.com/zellux/comments/136172.htmlhttp://m.tkk7.com/zellux/archive/2007/08/12/136172.html#Feedback0http://m.tkk7.com/zellux/comments/commentRss/136172.htmlhttp://m.tkk7.com/zellux/services/trackbacks/136172.htmlPS: 看了IEF2007 ipx vs pj, ipx vs lx的四场ZvPQipx和他们的差距自然很大Q细节上lx比pjZ,包括狗q入矿区时农民的控制Q开局的计等。推荐ipx vs pj中Luna上的一场,局面一边倒,ipx充分展示了ZvP的关键——灵z,打得很妖?br>
1. M存储字符串size()Ҏq回的结果的变量必须为string::size_typecd。特别重要的是,不要把size的返回结果赋l一个int变量。string::size_type是一个unsigned型?br>同样Q在定义用作索引的变量时Q最好也用string::size_typecd?br>
2. vector::const_iterator() q回只读q代器?

3.
typedef string *pstring;
const pstring cstr;
{h于string *const cstr;
而不是const string *cstr;
也可以写成pstring const str;
但是大多Ch习惯把const写在cd的前面,管q种情况把const攑֜cd后面更容易理解?br>

 



ZelluX 2007-08-12 16:08 发表评论
]]>
APUE - File I/O (1) http://m.tkk7.com/zellux/archive/2007/08/09/135654.htmlZelluXZelluXThu, 09 Aug 2007 14:46:00 GMThttp://m.tkk7.com/zellux/archive/2007/08/09/135654.htmlhttp://m.tkk7.com/zellux/comments/135654.htmlhttp://m.tkk7.com/zellux/archive/2007/08/09/135654.html#Feedback0http://m.tkk7.com/zellux/comments/commentRss/135654.htmlhttp://m.tkk7.com/zellux/services/trackbacks/135654.html
2. File Descriptors
? 怸所有打开的文仉是通过File Descriptor指向的。file descriptor是一个非负的整数Q按照管理,UNIXpȝ?指定E的标准输入Q?E的标准输出Q?为标准错误输出。ؓ了程序的通用性? 虑,q些magic number应该?lt;unistd.h>中的STDIN_FILENO, STDOUT_FILENO, STRERR_FILENO代替?br>file descriptor的范围是从[0, OPEN_MAX]Q早期系l的上限?9Q现在许多已l到达了63QLinux 2.4.22把每个进E打开的文件数上限提升C2^20.

3. open 函数
#include <fcntl.h>
int open(const char *pathname, int oflag, ..., /* mode_t mode */ );
q回: 正常 - 最的未被使用的file descriptorQ出?- 0
oflag: O_RDONLY(0), O_WRONLY(1), O_RDWR(2) 括号内ؓ大多数情况下的|q三个参C必选一个,剩下的可选参数指定了是否q加、是否创建等信息Q具体参见man 2 open

4. File Name and Pathname Truncation
如果创徏的文件名长度大于NAME_MAX帔RQBSDpȝ会返回一个错误状态,q把errno设ؓENAMETOOLONG。如果只是把文g名截去部分就有可能导致与已存在的文g重名?br>POSIX.1中的帔R_POSIX_NO_TRUNC指定了长文g名和路径会被截断q是会引发错?br>
5.  创徏文g
#include <fcntl.h>
int creat(const char *pathname, mode_t mode);
事实上这个函数等价于
open (pathname, O_WRONLY | O_CREAT | O_TRUNC, mode);

6. 关闭文g
#include <fcntl.h>
int close(int filedes);
q回: 成功 -1Q出?0
当一个进E结束时Q系l会自动关闭该进E打开的所有文件?br>
7. lseek 函数
每个打开的文仉有一个current file offset属性,通常是一个非负的整数。默认情况下文g打开后该gؓ0,除非指定了O_APPEND选项?br>#include <unistd.h>
off_t lseek(int filedes, off_t offset, int whence);
// Returns: new file offset if OK, -1 on error

可以通过seek 0字节来得到当前的offset
off_t currpos;
currpos = lseek(fd, 0, SEEK_CUR);
q个Ҏ也可以用来判断当前文件是否可以被seekQ如果是指向道(pipe)QFIFOQ或者socket的file descriptorQlseek把errno讄为ESPIPEq返?1

某些讑֤可能允许负值的offset(如FreeBSD上的/dev/kmem)Q因此在查返回值时应判断是否等?1Q而不是是否小?

ZelluX 2007-08-09 22:46 发表评论
]]>
CSAPP - Linking - 动态链接库http://m.tkk7.com/zellux/archive/2007/08/07/135097.htmlZelluXZelluXTue, 07 Aug 2007 15:10:00 GMThttp://m.tkk7.com/zellux/archive/2007/08/07/135097.htmlhttp://m.tkk7.com/zellux/comments/135097.htmlhttp://m.tkk7.com/zellux/archive/2007/08/07/135097.html#Feedback2http://m.tkk7.com/zellux/comments/commentRss/135097.htmlhttp://m.tkk7.com/zellux/services/trackbacks/135097.html 1) 静态库通常需要维护和定期更新Q而这些库的用者就得注意这些变化,q且在库修改后重新将自己的程序和库链接v?br> 2) 以printf和scanfq两个函Cؓ例,它们的代码在每个q行的进E里都保留了一份,在一个典型的操作pȝ上运行着50-100个进E,q无疑是对系l资源的严重费。(内存的一个有的Ҏ是Q它永远是一个短~的资源Q无关一个系l里有多大的内存Q?br>
2. ׃n?shared library)弥补了静态库的这些缺陗所谓共享库Q就是指?strong>q行?/strong>可以被读入到L?/strong>内存地址Qƈ与程序链接的模块。这个过E也被称为动态链?dynamic linking)Q由动态链接器(dynamic linker)完成?br> Unixpȝ中共享对象通常后缀?soQ微软的操作pȝ中大量用了׃n库,通常被称为DLL(dynamic link libraries)

3. ׃n库的“׃n”表现在两个方面:
1) 在Q何一个给定的文gpȝ中,对于某个特定的库Q只有一?so文g
2) ׃n库单独的一?text域可以由多个不同的运行进E共享?br>
4. ~译一个共享库Qgcc -shared -fPIC -o libvector.so addvec.c multvec.c
-fPIC开兌~译器生位|独立的代码(PIC, position independent code)
-shared开关得编译器产生׃n对象的文?br>
5. 动态链接的几个应用Q?br> 1) 软g的分布式开?br> 2) 开发高效的Web服务?br> 早期的Web服务器通过fork和execve调用子进E来产生动态的内容Q被UCؓCGIQ而现代的Web服务器则通过Z动态链接库的一U高效的方式?br> 主要的方法是把生成动态内容的函数打包C个共享库中,当服务器端接收到一个请求后Q服务器动态地dq且链接到相应的函数Qƈ直接调用q个函数Q? fork和execve则是在子q程的环境中q行的。函数调用后l箋存在Q以后的cMh都只需要一个简单的调用可以了。另外,Ҏ也可以在不停止服? 器的情况下更斎ͼ也可以加入新的函数?br>
6. Unixpȝ中读入ƈ链接׃n库的Ҏ
#include <dlfcn.h>
void *dlopen(const char *filename, int flag);
// returns: ptr to handle if OK, NULL on error
需要通过-rdynamic~译Q具体见CSAPP P569

获得已经打开的库的句?handle)
#include <dlfcn.h>
void #dlsym(void *handle, char *symbol);
// returns: ptr to symbol if OK, NULL on error

关闭׃n?br> #include <dlfcn.h>
int dlclose(void *handle);
// returns: 0 if OK, -1 on error

获得错误信息
#include <dlfcn.h>
const char *dlerror(void);

ZelluX 2007-08-07 23:10 发表评论
]]>
模仿命o行shell的简单程?/title><link>http://m.tkk7.com/zellux/archive/2007/08/04/134358.html</link><dc:creator>ZelluX</dc:creator><author>ZelluX</author><pubDate>Fri, 03 Aug 2007 16:20:00 GMT</pubDate><guid>http://m.tkk7.com/zellux/archive/2007/08/04/134358.html</guid><wfw:comment>http://m.tkk7.com/zellux/comments/134358.html</wfw:comment><comments>http://m.tkk7.com/zellux/archive/2007/08/04/134358.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/zellux/comments/commentRss/134358.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/zellux/services/trackbacks/134358.html</trackback:ping><description><![CDATA[APUE上的例程Q稍微改了下Q在q程开始和l束的时候会分别昄当前的PID和退出状态?br>不支持参?br>1. fgets命o从标准输入读入命令,当键入文件结束字W(通常是Ctrl+DQ时q程l束<br>2. 以\0替换输入命o的最后一个字W,卛_掉换行符Q得execlp能够处理<br>3. fork函数创徏一个新q程Q对父进E返回新的子q程的非负PIDQ对子进E返?<br>4. 在子q程中,调用execlp以执行从标准输入d的命令。fork和exec的组合生了一个新q程<br>5. 新的子进E开始执行后Q父q程{待子进E的l止Q这一要求由waitpid实现<br>6. 执行q个E序后还可以在这个简易shell中创建新的自w的q程<br><br> <div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000;">#include </span><span style="color: #000000;"><</span><span style="color: #000000;">sys</span><span style="color: #000000;">/</span><span style="color: #000000;">types.h</span><span style="color: #000000;">></span><span style="color: #000000;"><br>#include </span><span style="color: #000000;"><</span><span style="color: #000000;">sys</span><span style="color: #000000;">/</span><span style="color: #000000;">wait.h</span><span style="color: #000000;">></span><span style="color: #000000;"><br>#include </span><span style="color: #000000;">"</span><span style="color: #000000;">ourhdr.h</span><span style="color: #000000;">"</span><span style="color: #000000;"><br><br></span><span style="color: #0000ff;">int</span><span style="color: #000000;"> main(</span><span style="color: #0000ff;">void</span><span style="color: #000000;">)<br>{<br>    </span><span style="color: #0000ff;">char</span><span style="color: #000000;">    buf[MAXLINE];<br>    pid_t   pid;<br>    </span><span style="color: #0000ff;">int</span><span style="color: #000000;">     status;<br><br>    printf(</span><span style="color: #000000;">"</span><span style="color: #000000;">%% </span><span style="color: #000000;">"</span><span style="color: #000000;">);<br>    </span><span style="color: #0000ff;">while</span><span style="color: #000000;"> (fgets(buf, MAXLINE, stdin) </span><span style="color: #000000;">!=</span><span style="color: #000000;"> NULL)<br>    {<br>        buf [strlen(buf) </span><span style="color: #000000;">-</span><span style="color: #000000;"> </span><span style="color: #000000;">1</span><span style="color: #000000;">] </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #000000;">0</span><span style="color: #000000;">;<br><br>        </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> ( (pid </span><span style="color: #000000;">=</span><span style="color: #000000;"> fork()) </span><span style="color: #000000;"><</span><span style="color: #000000;"> </span><span style="color: #000000;">0</span><span style="color: #000000;">)<br>            err_sys(</span><span style="color: #000000;">"</span><span style="color: #000000;">fork error</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br>        </span><span style="color: #0000ff;">else</span><span style="color: #000000;"> </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> (pid </span><span style="color: #000000;">==</span><span style="color: #000000;"> </span><span style="color: #000000;">0</span><span style="color: #000000;">)<br>        {<br>            execlp(buf, buf, (</span><span style="color: #0000ff;">char</span><span style="color: #000000;"> </span><span style="color: #000000;">*</span><span style="color: #000000;">) </span><span style="color: #000000;">0</span><span style="color: #000000;">);<br>            err_ret(</span><span style="color: #000000;">"</span><span style="color: #000000;">couldn't execute: %s</span><span style="color: #000000;">"</span><span style="color: #000000;">, buf);<br>            exit(</span><span style="color: #000000;">127</span><span style="color: #000000;">);<br>        }<br><br>        printf(</span><span style="color: #000000;">"</span><span style="color: #000000;">*** %d ***\n</span><span style="color: #000000;">"</span><span style="color: #000000;">, status);<br><br>        </span><span style="color: #008000;">/*</span><span style="color: #008000;"> parent </span><span style="color: #008000;">*/</span><span style="color: #000000;"><br>        </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> ( (pid </span><span style="color: #000000;">=</span><span style="color: #000000;"> waitpid(pid, </span><span style="color: #000000;">&</span><span style="color: #000000;">status, </span><span style="color: #000000;">0</span><span style="color: #000000;">)) </span><span style="color: #000000;"><</span><span style="color: #000000;"> </span><span style="color: #000000;">0</span><span style="color: #000000;">)<br>            err_sys(</span><span style="color: #000000;">"</span><span style="color: #000000;">waitpid error</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br><br>        printf(</span><span style="color: #000000;">"</span><span style="color: #000000;">*** %d ***\n</span><span style="color: #000000;">"</span><span style="color: #000000;">, pid);<br>        printf(</span><span style="color: #000000;">"</span><span style="color: #000000;">%% </span><span style="color: #000000;">"</span><span style="color: #000000;">);<br>    }<br>    exit(</span><span style="color: #000000;">0</span><span style="color: #000000;">);<br>}<br></span></div> <br><img src ="http://m.tkk7.com/zellux/aggbug/134358.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/zellux/" target="_blank">ZelluX</a> 2007-08-04 00:20 <a href="http://m.tkk7.com/zellux/archive/2007/08/04/134358.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>~译《UNIX环境高~程》中的第一个程?/title><link>http://m.tkk7.com/zellux/archive/2007/08/03/134139.html</link><dc:creator>ZelluX</dc:creator><author>ZelluX</author><pubDate>Thu, 02 Aug 2007 17:13:00 GMT</pubDate><guid>http://m.tkk7.com/zellux/archive/2007/08/03/134139.html</guid><wfw:comment>http://m.tkk7.com/zellux/comments/134139.html</wfw:comment><comments>http://m.tkk7.com/zellux/archive/2007/08/03/134139.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://m.tkk7.com/zellux/comments/commentRss/134139.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/zellux/services/trackbacks/134139.html</trackback:ping><description><![CDATA[如果直接~译myls.cQ会报错<br>/tmp/cceQcwN0.o: In function `main':<br>myls.c:(.text+0x24): undefined reference to `err_quit'<br>myls.c:(.text+0x5b): undefined reference to `err_sys'<br>collect2: ld q回 1<br><br>需要下载随书附带的源代码ƈ~译所需的库文g<br>源代码下载:http://m.tkk7.com/Files/zellux/apue.linux3.tar.Z.zip<br>Q下载后L.zip后缀Q?br><br>apue/README 文g中有具体的编译方法,对于Linuxpȝ比较单,q入lib.rhlin目录Q然后运行makeQ就会在apue目录下生成libmisc.aQ以后编译的时候连接这个库p了?br><br>以书中的W一个程序myls.cZ <div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000;">#include </span><span style="color: #000000;"><</span><span style="color: #000000;">sys</span><span style="color: #000000;">/</span><span style="color: #000000;">types.h</span><span style="color: #000000;">></span><span style="color: #000000;"><br>#include </span><span style="color: #000000;"><</span><span style="color: #000000;">dirent.h</span><span style="color: #000000;">></span><span style="color: #000000;"><br><br>#include </span><span style="color: #000000;">"</span><span style="color: #000000;">ourhdr.h</span><span style="color: #000000;">"</span><span style="color: #000000;"><br><br></span><span style="color: #0000ff;">int</span><span style="color: #000000;"> main(</span><span style="color: #0000ff;">int</span><span style="color: #000000;"> argc, </span><span style="color: #0000ff;">char</span><span style="color: #000000;">*</span><span style="color: #000000;"> argv[])<br>{<br>    DIR             </span><span style="color: #000000;">*</span><span style="color: #000000;">dp;<br>    </span><span style="color: #0000ff;">struct</span><span style="color: #000000;"> dirent   </span><span style="color: #000000;">*</span><span style="color: #000000;">dirp;<br><br>    </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> (argc </span><span style="color: #000000;">!=</span><span style="color: #000000;"> </span><span style="color: #000000;">2</span><span style="color: #000000;">)<br>        err_quit(</span><span style="color: #000000;">"</span><span style="color: #000000;">a single argument (the directory name) is required</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br><br>    </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> ( (dp </span><span style="color: #000000;">=</span><span style="color: #000000;"> opendir(argv[</span><span style="color: #000000;">1</span><span style="color: #000000;">])) </span><span style="color: #000000;">==</span><span style="color: #000000;"> NULL)<br>        err_sys(</span><span style="color: #000000;">"</span><span style="color: #000000;">can't open %s</span><span style="color: #000000;">"</span><span style="color: #000000;">, argv[</span><span style="color: #000000;">1</span><span style="color: #000000;">]);<br><br>    </span><span style="color: #0000ff;">while</span><span style="color: #000000;"> ( (dirp </span><span style="color: #000000;">=</span><span style="color: #000000;"> readdir(dp)) </span><span style="color: #000000;">!=</span><span style="color: #000000;"> NULL)<br>        printf(</span><span style="color: #000000;">"</span><span style="color: #000000;">%s\n</span><span style="color: #000000;">"</span><span style="color: #000000;">, dirp</span><span style="color: #000000;">-></span><span style="color: #000000;">d_name);<br><br>    closedir(dp);<br>    exit(</span><span style="color: #000000;">0</span><span style="color: #000000;">);<br>}<br></span></div> <br>$ gcc myls.c libmisc.a<br>出现几个WarningQ?br>libmisc.a(strerror.o): In function `strerror':<br>strerror.c:(.text+0x18): warning: `sys_errlist' is deprecated; use `strerror' or `strerror_r' instead<br>strerror.c:(.text+0xf): warning: `sys_nerr' is deprecated; use `strerror' or `strerror_r' instead<br>看来q本书的太老了<img src="http://m.tkk7.com/CuteSoft_Client/CuteEditor/images/face7.gif" align="absmiddle" border="0"><br>$ ./a.out .<br>׃列出当前目录下的所有文?br><br><img src ="http://m.tkk7.com/zellux/aggbug/134139.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/zellux/" target="_blank">ZelluX</a> 2007-08-03 01:13 <a href="http://m.tkk7.com/zellux/archive/2007/08/03/134139.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>CSAPP - Linking - Strong and weak symbolshttp://m.tkk7.com/zellux/archive/2007/08/02/134126.htmlZelluXZelluXThu, 02 Aug 2007 15:45:00 GMThttp://m.tkk7.com/zellux/archive/2007/08/02/134126.htmlhttp://m.tkk7.com/zellux/comments/134126.htmlhttp://m.tkk7.com/zellux/archive/2007/08/02/134126.html#Feedback0http://m.tkk7.com/zellux/comments/commentRss/134126.htmlhttp://m.tkk7.com/zellux/services/trackbacks/134126.html《窃听风暴》的男主角乌里?#183;I埃(Ulrich Mühe) 病逝了。。?/span>
好片子,好演员,可惜了。。?/span>

CSAPP W七章Linking太枯燥了  啃了半天ȝ看到一点实际经历中遇到q的?br>
在编译阶D,~译器把全局变量标记为strong或者weakQƈ导出到汇~程序中Q由汇编E序把这些信息隐式地d到relocatable object file的符可(symbol table)中?br>函数和被初始化的全局变量被标CؓstrongQ未初始化的全局变量被标Cؓweak?br>Unixq接?linker)使用下面的规则来处理多个W号的情况:
1. 不允许多个strong symbol的存?br>2. 如果有一个strong symbol和若q个weak symbolQ用strong symbol
3. 只有若干个weak symbolQ则使用其中L一?br>
几个例子Q未Ҏ说明的情况,变量定义均在全局范围Q:
1. foo1.c和bar1.c中都有int main()ҎQ即存在了两个strong symbolQ连接器׃产生一条错误信息?br>2.
/* foo3.c */
#include 
<stdio.h>
void f(void);

int x = 15213;

int main()
{
    f();
    printf(
"x = %d\n", x);
    
return 0;
}

/* bar3.c */
int x;

void f()
{
    x 
= 15212;
}
main()Ҏ调用f()后,x变ؓ15212q被输出?br>注意q可能不是main()Ҏ的作者原来的意图?/span>
cM的情况也可能发生在两个weak symbol同名的时候?br>
3. 全局变量cd不同的情况:
/* foo5.c */
#include 
<stdio.h>
void f(void);

int x = 15213;
int y = 15212;

int main()
{
    f();
    printf(
"x = 0x%x  y = 0x%x \n", x, y);
    
return 0;
}

/* bar4.c */
double x;

void f()
{
    x 
= -0.0;
}
Ҏ书上的内容,
linux> gcc -o foobar5 foo5.c bar5.c
linux> ./foobar5
l果应该?br>x = 0x0  y = 0x80000000

但是在自己机器上~译时报错了Q可能连接器版本较高Q会自动扑ևq种错误
/usr/bin/ld: Warning: alignment 4 of symbol `x' in /tmp/ccupQXSG.o is smaller than 8 in /tmp/ccNNG9XZ.o
是double和int大小不义D的对齐问?br>

q些问题都比较细难以被查觉Q通常在程序执行了一D|间后才出现较严重的问题,因此很难被修复,其当许多程序员不清楚连接器的工作方式的时候?br>另外可以使用GCC?warn-common标记(flag)Q得它在解析多个同名的全局变量时发告?br>试了下没成功@@
gcc --warn-common提示无法识别的命令行选项Qgcc -Wall则不会发告?br>

ZelluX 2007-08-02 23:45 发表评论
]]>
推荐一本好书:高质量C++/C~程指南http://m.tkk7.com/zellux/archive/2007/08/01/133847.htmlZelluXZelluXWed, 01 Aug 2007 10:16:00 GMThttp://m.tkk7.com/zellux/archive/2007/08/01/133847.htmlhttp://m.tkk7.com/zellux/comments/133847.htmlhttp://m.tkk7.com/zellux/archive/2007/08/01/133847.html#Feedback0http://m.tkk7.com/zellux/comments/commentRss/133847.htmlhttp://m.tkk7.com/zellux/services/trackbacks/133847.html软g质量是被大多数程序员挂在嘴上而不是放在心上的东西Q?br>除了完全外行和真正的~程高手外,初读本书Q你最先的感受是惊慌Q?#8220;哇!我以前捏造的C++/C E序怎么会有那么多的毛病Q?#8221;
别难q,作者只不过比你早几q、多几次惊慌而已?br>误一两个时认真阅读q本Nl书Q你会L匪浅Q这是前面N-1 个读者的?
http://m.tkk7.com/Files/zellux/c.zip


ZelluX 2007-08-01 18:16 发表评论
]]>
C 学习W记 (2)http://m.tkk7.com/zellux/archive/2007/07/12/129904.htmlZelluXZelluXThu, 12 Jul 2007 11:33:00 GMThttp://m.tkk7.com/zellux/archive/2007/07/12/129904.htmlhttp://m.tkk7.com/zellux/comments/129904.htmlhttp://m.tkk7.com/zellux/archive/2007/07/12/129904.html#Feedback0http://m.tkk7.com/zellux/comments/commentRss/129904.htmlhttp://m.tkk7.com/zellux/services/trackbacks/129904.htmlAlgorithm in C上的ҎQ这U方法好处在于t[i]是指向各行首的指针,cM于Java的数l;而如果直接用malloc分配m*n*sizeof(int)大小的空_则没有这U效果,cM于C#中的[,]数组
int **malloc2d(int r, int c)
{
    int i;
    int **t = malloc(r * sizeof(int *));
    for (i = 0; i < r; i++)
        t[i] = malloc(c * sizeof(int));
    return t;
}


ZelluX 2007-07-12 19:33 发表评论
]]>
C 学习W记 (1)http://m.tkk7.com/zellux/archive/2007/07/10/129381.htmlZelluXZelluXTue, 10 Jul 2007 08:33:00 GMThttp://m.tkk7.com/zellux/archive/2007/07/10/129381.htmlhttp://m.tkk7.com/zellux/comments/129381.htmlhttp://m.tkk7.com/zellux/archive/2007/07/10/129381.html#Feedback0http://m.tkk7.com/zellux/comments/commentRss/129381.htmlhttp://m.tkk7.com/zellux/services/trackbacks/129381.html1. 函数接收一l数l的形参声明
func1(str)
char str[10];
{
}
表示有界数组Q数l的下标只能于或等于传递数l的大小?0可省略,表示无界数组?/p>

但事实上两者区别很,~译器只是让函数接收一个指针?/p>

二维数组cM

char str[][10];

2. ?/p>

#define MIN(a, b) (a<b) ? a : b

使用该宏时表辑ּ被直接替换,增加了代码的速度Q但因此增加了程序的长度?/p>

ZelluX 2007-07-10 16:33 发表评论
]]>
几个C的字W串操作代码http://m.tkk7.com/zellux/archive/2007/07/08/128923.htmlZelluXZelluXSun, 08 Jul 2007 13:05:00 GMThttp://m.tkk7.com/zellux/archive/2007/07/08/128923.htmlhttp://m.tkk7.com/zellux/comments/128923.htmlhttp://m.tkk7.com/zellux/archive/2007/07/08/128923.html#Feedback2http://m.tkk7.com/zellux/comments/commentRss/128923.htmlhttp://m.tkk7.com/zellux/services/trackbacks/128923.html1. 计算串长?strlen(a)
for (i = 0; a[i] != 0; i++); return i;

2. 复制 strcpy(a, b)
for (i = 0; (a[i] = b[i]) != 0; i++);

3. 比较 strcmp(a, b)
for (i = 0; a[i] == b[i]; i++)
    if (a[i] == 0) return 0;
return a[i] - b[i];
注意适用于不同长度的字符?br>
指针版本
1. strlen(a)
b = a; while (*b++); return b - a - 1;

2. strcpy(a, b)
while (*a++ = *b++);

3. strcmp(a, b)
while (*a++ = *b++)
    if (*(a-1) == 0) return 0;
return *(a-1) - *(b-1);





ZelluX 2007-07-08 21:05 发表评论
]]>
关于char*的内存分?/title><link>http://m.tkk7.com/zellux/archive/2007/06/17/124831.html</link><dc:creator>ZelluX</dc:creator><author>ZelluX</author><pubDate>Sun, 17 Jun 2007 12:22:00 GMT</pubDate><guid>http://m.tkk7.com/zellux/archive/2007/06/17/124831.html</guid><wfw:comment>http://m.tkk7.com/zellux/comments/124831.html</wfw:comment><comments>http://m.tkk7.com/zellux/archive/2007/06/17/124831.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://m.tkk7.com/zellux/comments/commentRss/124831.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/zellux/services/trackbacks/124831.html</trackback:ping><description><![CDATA[ <p>BBS上peter大牛的问题:</p> <p><em>char *s = "string1";<br/>strcpy(s, "string2");<br/>q样Z么会segmentation fault?</em><br/></p> <p>后面的解{:</p> <p><em>char *s="string1" //此时"string1"在常量区 s是指向常量区的一个指?你不能对<br/>帔R区的内容q行修改<br/><br/>char s[]="string2" //此时"string2" 在栈?此时可以寚w面的内容q行修改<br/><br/>所以你可以写成<br/><br/>char s[]="string1";<br/>strcpy(s,"string2");</em></p> <img src ="http://m.tkk7.com/zellux/aggbug/124831.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/zellux/" target="_blank">ZelluX</a> 2007-06-17 20:22 <a href="http://m.tkk7.com/zellux/archive/2007/06/17/124831.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++ 入门W记(3)http://m.tkk7.com/zellux/archive/2007/06/03/121672.htmlZelluXZelluXSun, 03 Jun 2007 10:58:00 GMThttp://m.tkk7.com/zellux/archive/2007/06/03/121672.htmlhttp://m.tkk7.com/zellux/comments/121672.htmlhttp://m.tkk7.com/zellux/archive/2007/06/03/121672.html#Feedback0http://m.tkk7.com/zellux/comments/commentRss/121672.htmlhttp://m.tkk7.com/zellux/services/trackbacks/121672.html1. 关于函数指针
The C++ Programming Language上的一D늤例代码:
map<string, int> histogram;

void record(const string& s)
{
histogram[s]++;
}

void print(const pair<const string, int>& r)
{
cout << r.first << ' ' << r.second << '\n\;
}

int main()
{
istream_iterator<string> ii(cin);
istream_iterator<string> eos;

for_each(ii, eos, record);
for_each(histogram.begin(), histogram.end(), print);
}

其中record和print是以函数指针的Ş式传递给for_each的。感觉这U方法最清晰、直接?br/>Javag更多的是用接口来辑ֈcM的效果的Q比如Collections.sort(Comparable)Q通常通过匿名内部cLq行自定义元素的比较Q从而排序。但是这在语义上已经不是函数了,而是被排序对象解释为实CComparable接口的对象?br/>另外Java反射机制中也有MehodҎQ觉得也可以通过传递Methodc,然后在sortҎ中调用这个Method的invokeҎQ这应该更接q函数指针的语义。但没看到过q样的实例?br/>C#则引入了委托的概念,通过delegate关键字声明该Ҏ。多一个关键字感觉是啰唆了点?-,-
现在开始对W一ơ在Thinking in Java中看到的Callback回调机制有了一Ҏ觉。当时看的时候很隄解?br/>看来在学习某一门语a的时候有一定其他语a的背景进行比较,很容易加q解?/p>

2. 使用地址传递结构,减少开销
学C++最不适应的就是指针的应用Q因为没有C的基Q尽高中竞赛用的是PascalQ也用指针实Ctrie、图的链式表C等比较复杂的数据结构,但是也没有像C++q样指针I插在整个程序中的,当然C更多?br/>C++传递结构时默认是先复制一份拷贝,然后函数操作的是该拷贝,而不是Java中的传递引用(当然Java没有l构q一cdQ?br/>C++ Primer Plus中指
1) 调用函数时传递地址&myStruct
2) 形参声明为指针MyStruct *
3) 讉K成员使用操作W?->

3. 引用用于结?br/>同样Qؓ了节省时I开销Q在函数q回值时量使用引用?br/>const MyStruct & use(MyStruct & mystruct)
注意最好将q回的引用声明ؓconstQ否则可以用这L代码Q?br/>use(myStruct).used = 10;
Ҏ产生语义混ؕ?br/>但在某些时候必d掉const关键字?/p>

ZelluX 2007-06-03 18:58 发表评论
]]>
C++ 入门W记(2)http://m.tkk7.com/zellux/archive/2007/05/30/120978.htmlZelluXZelluXWed, 30 May 2007 12:14:00 GMThttp://m.tkk7.com/zellux/archive/2007/05/30/120978.htmlhttp://m.tkk7.com/zellux/comments/120978.htmlhttp://m.tkk7.com/zellux/archive/2007/05/30/120978.html#Feedback0http://m.tkk7.com/zellux/comments/commentRss/120978.htmlhttp://m.tkk7.com/zellux/services/trackbacks/120978.html1. 最q用Dev C++写的几个E序中,最Ҏ出错的就是忘记初始化和数l越界。C++Q至在Dev C++~译器中Qƈ没有像Java那样严格的纠错功能,因此要格外小心?br>
2. C++ Programming Language上的一个样例程序,能看懂,但不能吃透?/p>

 

#include <iostream>
#include 
<vector>
#include 
<string>
#include 
<fstream>
#include 
<iterator>

using namespace std;

int main() {
    ifstream fin(
"p61.in");
    istream_iterator
<string> ii(fin);
    istream_iterator
<string> eos;
 
    vector
<string> b(ii, eos);
 
    ostream_iterator
<string> oo(cout, "\n");
 
    unique_copy(b.begin(), b.end(), oo);
 
    system(
"PAUSE");
}


3. 向函C递二l指?br>void f(int a[][4]) 或?void f(int (*a2)[4])



ZelluX 2007-05-30 20:14 发表评论
]]>
C++入门W记(1)http://m.tkk7.com/zellux/archive/2007/05/27/120221.htmlZelluXZelluXSun, 27 May 2007 11:56:00 GMThttp://m.tkk7.com/zellux/archive/2007/05/27/120221.htmlhttp://m.tkk7.com/zellux/comments/120221.htmlhttp://m.tkk7.com/zellux/archive/2007/05/27/120221.html#Feedback0http://m.tkk7.com/zellux/comments/commentRss/120221.htmlhttp://m.tkk7.com/zellux/services/trackbacks/120221.html1. string转int, double
atoi(str.c_str())
atod(str.c_str())

2. std库里已经有swapҎ了,难怪我写了以后反应ambiguous method




ZelluX 2007-05-27 19:56 发表评论
]]>
վ֩ģ壺 gavѲƵ| ѹۿavëƬվ| ŷ պ ۺ| aɫëƬ| ŷa߹ۿ| 츾avvrӰ| ĻþþƷˮ| 99þ޾ƷѶ| Ůѹۿվ| þþƷAV鶹| СƵ| 88xxѹۿ| ũѸһëƬѿƵ| 91޵ҹ| ҹƬ߹ۿӰԺ | ޴Ů߹ۿ| ޾ƷMV߹ۿ| ɫwwwƵ| þùƷƵ| ˳߹ۿa| һƵ| ˳վɫwww| ձÿӰѿ| aëƬѹۿ | ۺС˵| 91Դվ| þþøձѹۿ| ܲƵ| ˾Ʒձר6| Avۺɫרɫ| AVɫ | ޾Ʒ͵벻av| Ļa| aػƵƬƵ| ٸ̫߳ˬ߹ۿ| 9ᆱƷƵ| ǵӰȫ| һһ60Ƶ| ޹ƷҺ| ҹƬ߹ۿ| vavaó|