<rss version="2.0">
<channel>
<title><![CDATA[☆★ ☜^_^☞ yhustc的储藏箱★☆]]></title>
<description><![CDATA[yhustc的博客，爱技术，爱生活]]></description>
<link>http://www.yhustc.com</link>
<language>zh_CN</language>
<pubDate>2010-09-03 19:31:02</pubDate>
<lastBuildDate>2010-09-03 19:31:02</lastBuildDate>
<generator>YBlog RSS Generator</generator>
<ttl>5</ttl>
<item>
<title><![CDATA[适用GDB调试NS2程序]]></title>
<link>http://www.yhustc.com/Blog/239.html</link>
<description><![CDATA[<p>&nbsp;非常详细的一篇文章，特转载收藏</p>
<p><span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', Times, serif; line-height: 18px; font-size: 12px; color: rgb(153, 153, 153); ">
<p>gdb调试工具类似于vc中的debug工具。目前有命令行的和窗口界面的。窗口界面是DDD。我只用了命令行的。</p>
<p>用gdb调试ns2，要注意几点：<br />
1，安装gdb，下载gdb包，安装了就是了。<br />
2，改写Makefile，使之称为debug版本，具体做法：<br />
在代码里面添加调试信息：修改Makefile(没有任何后缀的)将里面<br />
<font color="#ff0000"><font color="#ff00ff">CCOPT&nbsp;=&nbsp;&nbsp;&nbsp;&nbsp; #如果是ns-allinone-2.28,这里是CCOPT = -O2</font><br />
</font>STATIC&nbsp;=&nbsp;<br />
LDFLAGS&nbsp;= $(STATIC)<br />
LDOUT&nbsp;= -o $(BLANK)<br />
改变为：<br />
<font color="#ff00ff">CCOPT&nbsp;= -g&nbsp;&nbsp; #如果是ns-allinone-2.28,这里修改为 CCOPT = -O2 -g<br />
</font>STATIC&nbsp;=&nbsp;<br />
LDFLAGS&nbsp;= $(STATIC)<br />
LDOUT&nbsp;= -o $(BLANK)<br />
修改的东西是粉红色字体所示<br />
然后重新编译&nbsp;<br />
注意：以下步骤一个都不能少<br />
<font color="#ff00ff">Make clean&nbsp;<br />
Make depend<br />
Make</font></p>
<p><font color="#ff00ff"><font color="#000000">3，调试：<br />
建议把我们的测试脚本写在ns-allinone-2.**/ns-2.XX/mytclscript/下面<br />
当调试时，首先进入ns-2.XX文件夹&nbsp;&nbsp; [tengda@localhost ~]$ cd ns-allinone-2.31/ns-2.31/<br />
然后 [tengda@localhost ns-2.31]$ gdb ns<br />
之后会出现<br />
Copyright (C) 2006 Free Software Foundation, Inc.<br />
GDB is free software, covered by the GNU General Public License, and you are<br />
welcome to change it and/or distribute copies of it under certain conditions.<br />
Type &quot;show copying&quot; to see the conditions.<br />
There is absolutely no warranty for GDB.&nbsp; Type &quot;show warranty&quot; for details.<br />
This GDB was configured as &quot;i386-redhat-linux-gnu&quot;...Using host libthread_db library &quot;/lib/libthread_db.so.1&quot;.<br />
&nbsp;<br />
(gdb)&nbsp;<br />
然后在该平台上运行我们的脚本，可以用cd 命令进入我们脚本所在文件夹。运行我们的脚本：<br />
(gdb) run mbs.tcl</font></font></p>
<p>这样就可以进行调试了。具体调试过程与命令，我转载如下：</p>
<p>＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝</p>
<font color="#ff00ff">
<p>GDB（GNU 项目调试器）可以让您了解程序在执行时&ldquo;内部&rdquo; 究竟在干些什么，以及在程序发生崩溃的瞬间正在做什么。</p>
<p>GDB 做以下 4 件主要的事情来帮助您捕获程序中的 bug：</p>
<ul>
    <li>在程序启动之前指定一些可以影响程序行为的变量或条件</li>
    <li>在某个指定的地方或条件下暂停程序</li>
    <li>在程序停止时检查已经发生了什么</li>
    <li>在程序执行过程中修改程序中的变量或条件，这样就可以体验修复一个 bug 的成果，并继续了解其他 bug</li>
</ul>
<p>&nbsp;</p>
<p>要调试的程序可以是使用 C、C++、Pascal、Objective-C 以及其他很多语言编写的。GDB 的二进制文件名是 gdb。</p>
<p>gdb 中有很多命令。使用&nbsp;<code><font face="Courier New">help</font></code>&nbsp;命令可以列出所有的命令，以及关于如何使用这些命令的介绍。下表给出了最常用的 GDB 命令。</p>
<p><br />
<a name="table1"></a><strong>表 1. gdb 中最常用的命令</strong></p>
<table border="1">
    <tbody>
        <tr>
            <th style="font-family: Georgia, 'Times New Roman', Times, serif; font-size: 11px; color: rgb(153, 153, 153); line-height: 18px; ">命令</th>
            <th style="font-family: Georgia, 'Times New Roman', Times, serif; font-size: 11px; color: rgb(153, 153, 153); line-height: 18px; ">说明</th>
            <th style="font-family: Georgia, 'Times New Roman', Times, serif; font-size: 11px; color: rgb(153, 153, 153); line-height: 18px; ">例子</th>
        </tr>
        <tr>
            <td style="font-family: Georgia, 'Times New Roman', Times, serif; font-size: 11px; color: rgb(153, 153, 153); line-height: 18px; "><code><font face="Courier New">help</font></code></td>
            <td style="font-family: Georgia, 'Times New Roman', Times, serif; font-size: 11px; color: rgb(153, 153, 153); line-height: 18px; ">显示命令类别</td>
            <td style="font-family: Georgia, 'Times New Roman', Times, serif; font-size: 11px; color: rgb(153, 153, 153); line-height: 18px; "><code><font face="Courier New">help</font></code>&nbsp;- 显示命令类别<br />
            <code><font face="Courier New">help breakpoints&nbsp;</font></code>- 显示属于 breakpoints 类别的命令<br />
            <code><font face="Courier New">help break</font></code>&nbsp;- 显示 break 命令的解释</td>
        </tr>
        <tr>
            <td style="font-family: Georgia, 'Times New Roman', Times, serif; font-size: 11px; color: rgb(153, 153, 153); line-height: 18px; "><code><font face="Courier New">run</font></code></td>
            <td style="font-family: Georgia, 'Times New Roman', Times, serif; font-size: 11px; color: rgb(153, 153, 153); line-height: 18px; ">启动所调试的程序</td>
            <td style="font-family: Georgia, 'Times New Roman', Times, serif; font-size: 11px; color: rgb(153, 153, 153); line-height: 18px; ">?</td>
        </tr>
        <tr>
            <td style="font-family: Georgia, 'Times New Roman', Times, serif; font-size: 11px; color: rgb(153, 153, 153); line-height: 18px; "><code><font face="Courier New">kill</font></code></td>
            <td style="font-family: Georgia, 'Times New Roman', Times, serif; font-size: 11px; color: rgb(153, 153, 153); line-height: 18px; ">终止正在调试的程序的执行</td>
            <td style="font-family: Georgia, 'Times New Roman', Times, serif; font-size: 11px; color: rgb(153, 153, 153); line-height: 18px; ">通常这会在要执行的代码行已经超过了您想要调试的代码时使用。执行&nbsp;<code><font face="Courier New">kill</font></code>&nbsp;会重置断点，并从头再次运行这个程序</td>
        </tr>
        <tr>
            <td style="font-family: Georgia, 'Times New Roman', Times, serif; font-size: 11px; color: rgb(153, 153, 153); line-height: 18px; ">&nbsp;</td>
            <td style="font-family: Georgia, 'Times New Roman', Times, serif; font-size: 11px; color: rgb(153, 153, 153); line-height: 18px; ">&nbsp;</td>
            <td style="font-family: Georgia, 'Times New Roman', Times, serif; font-size: 11px; color: rgb(153, 153, 153); line-height: 18px; ">&nbsp;</td>
        </tr>
        <tr>
            <td style="font-family: Georgia, 'Times New Roman', Times, serif; font-size: 11px; color: rgb(153, 153, 153); line-height: 18px; "><code><font face="Courier New">cont</font></code></td>
            <td style="font-family: Georgia, 'Times New Roman', Times, serif; font-size: 11px; color: rgb(153, 153, 153); line-height: 18px; ">所调试的程序运行到一个断点、异常或单步之后，继续执行</td>
            <td style="font-family: Georgia, 'Times New Roman', Times, serif; font-size: 11px; color: rgb(153, 153, 153); line-height: 18px; ">?</td>
        </tr>
        <tr>
            <td style="font-family: Georgia, 'Times New Roman', Times, serif; font-size: 11px; color: rgb(153, 153, 153); line-height: 18px; "><code><font face="Courier New">info break</font></code></td>
            <td style="font-family: Georgia, 'Times New Roman', Times, serif; font-size: 11px; color: rgb(153, 153, 153); line-height: 18px; ">显示当前的断点或观察点</td>
            <td style="font-family: Georgia, 'Times New Roman', Times, serif; font-size: 11px; color: rgb(153, 153, 153); line-height: 18px; ">?</td>
        </tr>
        <tr>
            <td style="font-family: Georgia, 'Times New Roman', Times, serif; font-size: 11px; color: rgb(153, 153, 153); line-height: 18px; "><code><font face="Courier New">break</font></code></td>
            <td style="font-family: Georgia, 'Times New Roman', Times, serif; font-size: 11px; color: rgb(153, 153, 153); line-height: 18px; ">在指定的行或函数处设置断点</td>
            <td style="font-family: Georgia, 'Times New Roman', Times, serif; font-size: 11px; color: rgb(153, 153, 153); line-height: 18px; "><code><font face="Courier New">break 93 if i=8</font></code>&nbsp;- 当变量 i 等于 8 时，在第 93 行停止程序执行</td>
        </tr>
        <tr>
            <td style="font-family: Georgia, 'Times New Roman', Times, serif; font-size: 11px; color: rgb(153, 153, 153); line-height: 18px; "><code><font face="Courier New">Step</font></code></td>
            <td style="font-family: Georgia, 'Times New Roman', Times, serif; font-size: 11px; color: rgb(153, 153, 153); line-height: 18px; ">单步执行程序，直到它到达一个不同的源代码行。您可以使用&nbsp;<code><font face="Courier New">s</font></code>&nbsp;来代表 step 命令</td>
            <td style="font-family: Georgia, 'Times New Roman', Times, serif; font-size: 11px; color: rgb(153, 153, 153); line-height: 18px; ">?</td>
        </tr>
        <tr>
            <td style="font-family: Georgia, 'Times New Roman', Times, serif; font-size: 11px; color: rgb(153, 153, 153); line-height: 18px; "><code><font face="Courier New">Next</font></code></td>
            <td style="font-family: Georgia, 'Times New Roman', Times, serif; font-size: 11px; color: rgb(153, 153, 153); line-height: 18px; ">与 step 命令类似，只是它不会&ldquo;单步跟踪到&rdquo;子例程中</td>
            <td style="font-family: Georgia, 'Times New Roman', Times, serif; font-size: 11px; color: rgb(153, 153, 153); line-height: 18px; ">?</td>
        </tr>
        <tr>
            <td style="font-family: Georgia, 'Times New Roman', Times, serif; font-size: 11px; color: rgb(153, 153, 153); line-height: 18px; "><code><font face="Courier New">print</font></code></td>
            <td style="font-family: Georgia, 'Times New Roman', Times, serif; font-size: 11px; color: rgb(153, 153, 153); line-height: 18px; ">打印一个变量或表达式的值</td>
            <td style="font-family: Georgia, 'Times New Roman', Times, serif; font-size: 11px; color: rgb(153, 153, 153); line-height: 18px; "><code><font face="Courier New">print pointer</font></code>&nbsp;- 打印变量指针的内容<br />
            <code><font face="Courier New">print *pointer</font></code>&nbsp;- 打印指针所指向的数据结构的内容</td>
        </tr>
        <tr>
            <td style="font-family: Georgia, 'Times New Roman', Times, serif; font-size: 11px; color: rgb(153, 153, 153); line-height: 18px; "><code><font face="Courier New">delete</font></code></td>
            <td style="font-family: Georgia, 'Times New Roman', Times, serif; font-size: 11px; color: rgb(153, 153, 153); line-height: 18px; ">删除某些断点或自动显示表达式</td>
            <td style="font-family: Georgia, 'Times New Roman', Times, serif; font-size: 11px; color: rgb(153, 153, 153); line-height: 18px; "><code><font face="Courier New">delete 1</font></code>&nbsp;- 删除断点 1。断点可以通过&nbsp;<code><font face="Courier New">info break</font></code>&nbsp;来显示</td>
        </tr>
        <tr>
            <td style="font-family: Georgia, 'Times New Roman', Times, serif; font-size: 11px; color: rgb(153, 153, 153); line-height: 18px; "><code><font face="Courier New">watch</font></code></td>
            <td style="font-family: Georgia, 'Times New Roman', Times, serif; font-size: 11px; color: rgb(153, 153, 153); line-height: 18px; ">为一个表达式设置一个观察点。当表达式的值发生变化时，这个观察点就会暂停程序的执行</td>
            <td style="font-family: Georgia, 'Times New Roman', Times, serif; font-size: 11px; color: rgb(153, 153, 153); line-height: 18px; ">?</td>
        </tr>
        <tr>
            <td style="font-family: Georgia, 'Times New Roman', Times, serif; font-size: 11px; color: rgb(153, 153, 153); line-height: 18px; "><code><font face="Courier New">where</font></code></td>
            <td style="font-family: Georgia, 'Times New Roman', Times, serif; font-size: 11px; color: rgb(153, 153, 153); line-height: 18px; ">打印所有堆栈帧的栈信息</td>
            <td style="font-family: Georgia, 'Times New Roman', Times, serif; font-size: 11px; color: rgb(153, 153, 153); line-height: 18px; "><code><font face="Courier New">where</font></code>&nbsp;- 不使用参数，输出当前线程的堆栈信息<br />
            <code><font face="Courier New">where all</font></code>&nbsp;- 输出当前线程组中所有线程的堆栈信息<br />
            <code><font face="Courier New">where threadindex&nbsp;</font></code>- 输出指定线程的堆栈信息</td>
        </tr>
        <tr>
            <td style="font-family: Georgia, 'Times New Roman', Times, serif; font-size: 11px; color: rgb(153, 153, 153); line-height: 18px; "><code><font face="Courier New">attach</font></code></td>
            <td style="font-family: Georgia, 'Times New Roman', Times, serif; font-size: 11px; color: rgb(153, 153, 153); line-height: 18px; ">开始查看一个已经运行的进程</td>
            <td style="font-family: Georgia, 'Times New Roman', Times, serif; font-size: 11px; color: rgb(153, 153, 153); line-height: 18px; ">attach &lt;process_id&gt; - 附加到进程 process_id 上。process_id 可以使用 ps 命令找到</td>
        </tr>
        <tr>
            <td style="font-family: Georgia, 'Times New Roman', Times, serif; font-size: 11px; color: rgb(153, 153, 153); line-height: 18px; "><code><font face="Courier New">info thread</font></code></td>
            <td style="font-family: Georgia, 'Times New Roman', Times, serif; font-size: 11px; color: rgb(153, 153, 153); line-height: 18px; ">显示当前正在运行的线程</td>
            <td style="font-family: Georgia, 'Times New Roman', Times, serif; font-size: 11px; color: rgb(153, 153, 153); line-height: 18px; ">?</td>
        </tr>
        <tr>
            <td style="font-family: Georgia, 'Times New Roman', Times, serif; font-size: 11px; color: rgb(153, 153, 153); line-height: 18px; "><code><font face="Courier New">thread apply threadno command</font></code></td>
            <td style="font-family: Georgia, 'Times New Roman', Times, serif; font-size: 11px; color: rgb(153, 153, 153); line-height: 18px; ">对一个线程运行 gdb 命令</td>
            <td style="font-family: Georgia, 'Times New Roman', Times, serif; font-size: 11px; color: rgb(153, 153, 153); line-height: 18px; "><code><font face="Courier New">thread apply 3 where</font></code>&nbsp;- 对线程 3 运行&nbsp;<code><font face="Courier New">where</font></code>&nbsp;命令</td>
        </tr>
        <tr>
            <td style="font-family: Georgia, 'Times New Roman', Times, serif; font-size: 11px; color: rgb(153, 153, 153); line-height: 18px; "><code><font face="Courier New">Thread threadno</font></code></td>
            <td style="font-family: Georgia, 'Times New Roman', Times, serif; font-size: 11px; color: rgb(153, 153, 153); line-height: 18px; ">选择一个线程作为当前线程</td>
            <td style="font-family: Georgia, 'Times New Roman', Times, serif; font-size: 11px; color: rgb(153, 153, 153); line-height: 18px; ">?</td>
        </tr>
    </tbody>
</table>
<p>&nbsp;</p>
<p>如果一个程序崩溃了，并生成了一个 core 文件，您可以查看 core 文件来判断进程结束时的状态。使用下面的命令启动 gdb：</p>
<p>&nbsp;</p>
<table border="0" cellspacing="0" cellpadding="0" width="600">
    <tbody>
        <tr>
            <td class="code-outline" style="font-family: Georgia, 'Times New Roman', Times, serif; font-size: 11px; color: rgb(153, 153, 153); line-height: 18px; ">
            <pre class="displaycode">
# gdb programname corefilename </pre>
            </td>
        </tr>
    </tbody>
</table>
<p>&nbsp;</p>
<p>要调试一个 core 文件，您需要可执行程序、源代码文件以及 core 文件。要对一个 core 文件启动 gdb，请使用 -c 选项：</p>
<p>&nbsp;</p>
<table border="0" cellspacing="0" cellpadding="0" width="600">
    <tbody>
        <tr>
            <td class="code-outline" style="font-family: Georgia, 'Times New Roman', Times, serif; font-size: 11px; color: rgb(153, 153, 153); line-height: 18px; ">
            <pre class="displaycode">
# gdb -c core programname </pre>
            </td>
        </tr>
    </tbody>
</table>
<p>&nbsp;</p>
<p>gdb 会显示是哪行代码导致这个程序产生了核心转储。</p>
<p>默认情况下，核心转储在 Novell 的 SUSE LINUX Enterprise Server 9（SLES 9）和 Red Hat? Enterprise Linux Advanced Server（RHEL AS 4）上都是禁用的。要启用核心转储，请以 root 用户的身份在命令行中执行&nbsp;<code><font face="Courier New">ulimit &ndash;c unlimited</font></code>。</p>
<p><a href="http://www.ibm.com/developerworks/cn/linux/l-pow-debug/sidefile1.html" style="color: rgb(0, 51, 51); text-decoration: none; "><font color="#5c81a7">清单 8</font></a>&nbsp;中的例子阐述了如何使用 gdb 来定位程序中的 bug。<a name="listing8"></a>清单 8 是一段包含 bug 的 C++ 代码。</p>
<p><a href="http://www.ibm.com/developerworks/cn/linux/l-pow-debug/sidefile1.html" style="color: rgb(0, 51, 51); text-decoration: none; "><font color="#5c81a7">清单 8</font></a>&nbsp;中的 C++ 程序试图构建 10 个链接在一起的数字框（number box），例如：</p>
<p><br />
<a name="N10326"></a><strong>图 1. 一个包含 10 个链接在一起的数字框的列表</strong><br />
<img src="http://www.ibm.com/developerworks/cn/linux/l-pow-debug/linkednumberboxes1.gif" alt="" width="572" height="30" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; " /></p>
<p>然后试图从这个列表中逐个删除数字框。</p>
<p>编译并运行这个程序，如下所示：</p>
<p><br />
<a name="N1033C"></a><strong>清单 9. 编译并运行这个程序</strong></p>
<table border="0" cellspacing="0" cellpadding="0" width="600">
    <tbody>
        <tr>
            <td class="code-outline" style="font-family: Georgia, 'Times New Roman', Times, serif; font-size: 11px; color: rgb(153, 153, 153); line-height: 18px; ">
            <pre class="displaycode">
                
# g++ -g -o gdbtest1 gdbtest1.cpp
# ./gdbtest1
Number Box &quot;0&quot; created
Number Box &quot;1&quot; created
Number Box &quot;2&quot; created
Number Box &quot;3&quot; created
Number Box &quot;4&quot; created
Number Box &quot;5&quot; created
Number Box &quot;6&quot; created
Number Box &quot;7&quot; created
Number Box &quot;8&quot; created
Number Box &quot;9&quot; created
list created
Number Box &quot;9&quot; deleted
Segmentation fault
</pre>
            </td>
        </tr>
    </tbody>
</table>
<p>&nbsp;</p>
<p>正如您可以看到的一样，这个程序会导致段错误。调用 gdb 来看一下这个问题，如下所示：</p>
<p><br />
<a name="N10349"></a><strong>清单 10. 调用 gdb</strong></p>
<table border="0" cellspacing="0" cellpadding="0" width="600">
    <tbody>
        <tr>
            <td class="code-outline" style="font-family: Georgia, 'Times New Roman', Times, serif; font-size: 11px; color: rgb(153, 153, 153); line-height: 18px; ">
            <pre class="displaycode">
                
# gdb ./gdbtest1
GNU gdb 6.2.1
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you 
are welcome to change it and/or distribute copies of it under certain 
conditions.
Type &quot;show copying&quot; to see the conditions.
There is absolutely no warranty for GDB.  Type &quot;show warranty&quot; for 
details.
This GDB was configured as &quot;ppc-suse-linux&quot;...Using host libthread_db 
library &quot;/lib/tls/libthread_db.so.1&quot;.
(gdb)
</pre>
            </td>
        </tr>
    </tbody>
</table>
<p>&nbsp;</p>
<p>您知道段错误是在数字框 &quot;9&quot; 被删除之后发生的。执行&nbsp;<code><font face="Courier New">run</font></code>&nbsp;和&nbsp;<code><font face="Courier New">where</font></code>&nbsp;命令来精确定位段错误发生在程序中的什么位置。</p>
<p><br />
<a name="N1035E"></a><strong>清单 11. 执行 run 和 where 命令</strong></p>
<table border="0" cellspacing="0" cellpadding="0" width="600">
    <tbody>
        <tr>
            <td class="code-outline" style="font-family: Georgia, 'Times New Roman', Times, serif; font-size: 11px; color: rgb(153, 153, 153); line-height: 18px; ">
            <pre class="displaycode">
                
(gdb) run
Starting program: /root/test/gdbtest1 
Number Box &quot;0&quot; created
Number Box &quot;1&quot; created
Number Box &quot;2&quot; created
Number Box &quot;3&quot; created
Number Box &quot;4&quot; created
Number Box &quot;5&quot; created
Number Box &quot;6&quot; created
Number Box &quot;7&quot; created
Number Box &quot;8&quot; created
Number Box &quot;9&quot; created
list created
Number Box &quot;9&quot; deleted
Program received signal SIGSEGV, Segmentation fault.
0x10000f74 in NumBox&lt;int&gt;::GetNext (this=0x0) at gdbtest1.cpp:14
14              NumBox&lt;T&gt;*GetNext() const { return Next; }
(gdb) where
#0  0x10000f74 in NumBox&lt;int&gt;::GetNext (this=0x0) at gdbtest1.cpp:14
#1  0x10000d10 in NumChain&lt;int&gt;::RemoveBox (this=0x10012008, 
<br />item_to_remove=@0xffffe200) at gdbtest1.cpp:63
#2  0x10000978 in main (argc=1, argv=0xffffe554) at gdbtest1.cpp:94
(gdb)
</pre>
            </td>
        </tr>
    </tbody>
</table>
<p>&nbsp;</p>
<p>跟踪信息显示这个程序在第 14 行&nbsp;<code><font face="Courier New">NumBox&lt;int&gt;::GetNext (this=0x0)</font></code>&nbsp;接收到一个段错误。这个数字框上 Next 指针的地址是 0x0，这对于一个数字框来说是一个无效的地址。从上面的跟踪信息可以看出，<code><font face="Courier New">GetNext</font></code>&nbsp;函数是由 63 行调用的。看一下在 gdbtest1.cpp 的 63 行附近发生了什么：</p>
<p><br />
<a name="N10375"></a><strong>清单 12. gdbtest1.cpp</strong></p>
<table border="0" cellspacing="0" cellpadding="0" width="600">
    <tbody>
        <tr>
            <td class="code-outline" style="font-family: Georgia, 'Times New Roman', Times, serif; font-size: 11px; color: rgb(153, 153, 153); line-height: 18px; ">
            <pre class="displaycode">
                
     54                       } else {
     55                               temp-&gt;SetNext (current-&gt;GetNext());
     56                               delete temp;
     57                               temp = 0;
     58                               return 0;
     59                       }
     60               }
     61               current = 0;
     62               temp = current;
     63               current = current-&gt;GetNext();
     64       }
     65 
     66       return -1;
</pre>
            </td>
        </tr>
    </tbody>
</table>
<p>&nbsp;</p>
<p>第 61 行&nbsp;<code><font face="Courier New">current=0</font></code>&nbsp;将这个指针设置为一个无效的地址，这正是产生段错误的根源。注释掉第 61 行，将其保存为 gdbtest2.cpp，然后编译并重新运行。</p>
<p><br />
<a name="N10386"></a><strong>清单 13. 再次运行程序（gdbtest2.cpp）</strong></p>
<table border="0" cellspacing="0" cellpadding="0" width="600">
    <tbody>
        <tr>
            <td class="code-outline" style="font-family: Georgia, 'Times New Roman', Times, serif; font-size: 11px; color: rgb(153, 153, 153); line-height: 18px; ">
            <pre class="displaycode">
                
# g++ -g -o gdbtest2 gdbtest2.cpp
# ./gdbtest2
Number Box &quot;0&quot; created
Number Box &quot;1&quot; created
Number Box &quot;2&quot; created
Number Box &quot;3&quot; created
Number Box &quot;4&quot; created
Number Box &quot;5&quot; created
Number Box &quot;6&quot; created
Number Box &quot;7&quot; created
Number Box &quot;8&quot; created
Number Box &quot;9&quot; created
list created
Number Box &quot;9&quot; deleted
Number Box &quot;0&quot; deleted
</pre>
            </td>
        </tr>
    </tbody>
</table>
<p>&nbsp;</p>
<p>这个程序现在可以成功完成而不会出现段错误了。然而，结果并不像我们预期的一样：程序在删除 Number Box &quot;9&quot;之后删除了 Number Box &quot;0&quot;，而不像我们期望的一样删除 Number Box &quot;8,&quot;。使用 gdb 再次来看一下。</p>
<p><br />
<a name="N10393"></a><strong>清单 14. 再次使用 gdb 进行查看</strong></p>
<table border="0" cellspacing="0" cellpadding="0" width="600">
    <tbody>
        <tr>
            <td class="code-outline" style="font-family: Georgia, 'Times New Roman', Times, serif; font-size: 11px; color: rgb(153, 153, 153); line-height: 18px; ">
            <pre class="displaycode">
                
# gdb ./gdbtest2
GNU gdb 6.2.1
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you 
are welcome to change it and/or distribute copies of it under certain 
conditions.
Type &quot;show copying&quot; to see the conditions.
There is absolutely no warranty for GDB.  Type &quot;show warranty&quot; for 
details.
This GDB was configured as &quot;ppc-suse-linux&quot;...Using host libthread_db 
library &quot;/lib/tls/libthread_db.so.1&quot;.
(gdb) break 94 if i==8
Breakpoint 1 at 0x10000968: file gdbtest2.cpp, line 94.
(gdb) run
Starting program: /root/test/gdbtest2 
Number Box &quot;0&quot; created
Number Box &quot;1&quot; created
Number Box &quot;2&quot; created
Number Box &quot;3&quot; created
Number Box &quot;4&quot; created
Number Box &quot;5&quot; created
Number Box &quot;6&quot; created
Number Box &quot;7&quot; created
Number Box &quot;8&quot; created
Number Box &quot;9&quot; created
list created
Number Box &quot;9&quot; deleted
Breakpoint 1, main (argc=1, argv=0xffffe554) at gdbtest2.cpp:94
94                      list -&gt;RemoveBox(i);
</pre>
            </td>
        </tr>
    </tbody>
</table>
<p>&nbsp;</p>
<p>您可能希望找出为什么这个程序删除的是 Number Box 0，而不是 Number Box 8，因此需要在您认为程序会删除 Number Box 8 的地方停止程序。设置这个断点：<code><font face="Courier New">break 94 if i==8</font></code>，可以在 i 等于 8 时在第 94 行处停止程序。然后<code><font face="Courier New">单步跟踪</font></code>到&nbsp;<code><font face="Courier New">RemoveBox()</font></code>&nbsp;函数中。</p>
<p><br />
<a name="N103AC"></a><strong>清单 15. 单步跟踪到 RemoveBox() 函数中</strong></p>
<table border="0" cellspacing="0" cellpadding="0" width="600">
    <tbody>
        <tr>
            <td class="code-outline" style="font-family: Georgia, 'Times New Roman', Times, serif; font-size: 11px; color: rgb(153, 153, 153); line-height: 18px; ">
            <pre class="displaycode">
                
(gdb) s
38                      NumBox&lt;T&gt; *temp = 0;  
(gdb) s
40                      while (current != 0) {
(gdb) print pointer
$1 = (NumBox&lt;int&gt; *) 0x100120a8
 (gdb) print *pointer
$2 = {Num = 0, Next = 0x0}
(gdb)
</pre>
            </td>
        </tr>
    </tbody>
</table>
<p>&nbsp;</p>
<p>指针早已指向了 Number Box &quot;0&quot;，因此这个 bug 可能就存在于程序删除 Number Box &quot;9&quot; 的地方。要在 gdb 中重新启动这个程序，请使用&nbsp;<code><font face="Courier New">kill</font></code>&nbsp;删除原来的断点，然后添加一个 i 等于 9 时的新断点，然后再次运行这个程序。</p>
<p><br />
<a name="N103BD"></a><strong>清单 16. 在 gdb 中重新启动程序</strong></p>
<table border="0" cellspacing="0" cellpadding="0" width="600">
    <tbody>
        <tr>
            <td class="code-outline" style="font-family: Georgia, 'Times New Roman', Times, serif; font-size: 11px; color: rgb(153, 153, 153); line-height: 18px; ">
            <pre class="displaycode">
                
(gdb) kill
Kill the program being debugged? (y or n) y
(gdb) info break
Num Type           Disp Enb Address    What
1   breakpoint     keep y   0x10000968 in main at gdbtest2.cpp:94
        stop only if i == 8
        breakpoint already hit 1 time
(gdb) delete 1
(gdb) break 94 if i==9
Breakpoint 2 at 0x10000968: file gdbtest2.cpp, line 94.
(gdb) run
Starting program: /root/test/gdbtest2 
Number Box &quot;0&quot; created
Number Box &quot;1&quot; created
Number Box &quot;2&quot; created
Number Box &quot;3&quot; created
Number Box &quot;4&quot; created
Number Box &quot;5&quot; created
Number Box &quot;6&quot; created
Number Box &quot;7&quot; created
Number Box &quot;8&quot; created
Number Box &quot;9&quot; created
list created
Breakpoint 2, main (argc=1, argv=0xffffe554) at gdbtest2.cpp:94
94                      list -&gt;RemoveBox(i);
(gdb)
</pre>
            </td>
        </tr>
    </tbody>
</table>
<p>&nbsp;</p>
<p>当这一次单步跟踪&nbsp;<code><font face="Courier New">RemoveBox()</font></code>&nbsp;函数时，要特别注意&nbsp;<code><font face="Courier New">list-&gt;pointer</font></code>&nbsp;正在指向哪一个数字框，因为 bug 可能就在于&nbsp;<code><font face="Courier New">list-&gt;pointer</font></code>&nbsp;开始指向 Number Box &quot;0&quot; 的地方。请使用&nbsp;<code><font face="Courier New">display *pointer</font></code>命令来查看，这会自动显示这个函数。</p>
<p><br />
<a name="N103DA"></a><strong>清单 17. 使用 display *pointer 命令进行监视</strong></p>
<table border="0" cellspacing="0" cellpadding="0" width="600">
    <tbody>
        <tr>
            <td class="code-outline" style="font-family: Georgia, 'Times New Roman', Times, serif; font-size: 11px; color: rgb(153, 153, 153); line-height: 18px; ">
            <pre class="displaycode">
                
Breakpoint 2, main (argc=1, argv=0xffffe554) at gdbtest2.cpp:94
94            list -&gt;RemoveBox(i);
(gdb) s
NumChain&lt;int&gt;::RemoveBox (this=0x10012008, item_to_remove=@0xffffe200) <br />
at gdbtest2.cpp:37
37            NumBox&lt;T&gt; *current = pointer;
(gdb) display *pointer
1: *this-&gt;pointer = {Num = 9, Next = 0x10012098}
(gdb) s
38            NumBox&lt;T&gt; *temp = 0;  
1: *this-&gt;pointer = {Num = 9, Next = 0x10012098}
(gdb) s
40            while (current != 0) {
1: *this-&gt;pointer = {Num = 9, Next = 0x10012098}
(gdb) s
41                    if (current-&gt;GetValue() == item_to_remove) {
1: *this-&gt;pointer = {Num = 9, Next = 0x10012098}
(gdb) s
NumBox&lt;int&gt;::GetValue (this=0x100120a8) at gdbtest2.cpp:16
16            const T&amp; GetValue () const { return Num; }
(gdb) s
NumChain&lt;int&gt;::RemoveBox (this=0x10012008, item_to_remove=@0xffffe200) <br /> 
at gdbtest2.cpp:42
42                       if (temp == 0) { 
1: *this-&gt;pointer = {Num = 9, Next = 0x10012098}
(gdb) s
44                               if (current-&gt;GetNext() == 0) {
1: *this-&gt;pointer = {Num = 9, Next = 0x10012098}
(gdb) s
NumBox&lt;int&gt;::GetNext (this=0x100120a8) at gdbtest2.cpp:14
14            NumBox&lt;T&gt;*GetNext() const { return Next; }
(gdb) s
NumChain&lt;int&gt;::RemoveBox (this=0x10012008, item_to_remove=@0xffffe200) <br />
at gdbtest2.cpp:50
50                                            delete current;
1: *this-&gt;pointer = {Num = 9, Next = 0x10012098}
(gdb) s
~NumBox (this=0x100120a8) at gdbtest2.cpp:10
10            std::cout &lt;&lt; &quot;Number Box &quot; &lt;&lt;&quot;\&quot;&quot;  &lt;&lt; GetValue() <br /> 
&lt;&lt;&quot;\&quot;&quot;  &lt;&lt;&quot; deleted&quot; &lt;&lt; std::endl;
(gdb) s
NumBox&lt;int&gt;::GetValue (this=0x100120a8) at gdbtest2.cpp:16
16            const T&amp; GetValue () const { return Num; }
(gdb) s
Number Box &quot;9&quot; deleted
~NumBox (this=0x100120a8) at gdbtest2.cpp:11
11            Next = 0;
(gdb) s
NumChain&lt;int&gt;::RemoveBox (this=0x10012008, item_to_remove=@0xffffe200) <br />
at gdbtest2.cpp:51
51                                           current = 0;
1: *this-&gt;pointer = {Num = 0, Next = 0x0}
(gdb) s
53                                    return 0;
1: *this-&gt;pointer = {Num = 0, Next = 0x0}
(gdb) s
0x10000d1c      66                      return -1;
1: *this-&gt;pointer = {Num = 0, Next = 0x0}
</pre>
            </td>
        </tr>
    </tbody>
</table>
<p>&nbsp;</p>
<p>从上面的跟踪过程中，您可以看到&nbsp;<code><font face="Courier New">list-&gt;pointer</font></code>&nbsp;在删除 Number Box &quot;9&quot; 之后指向了 Number Box &quot;0&quot;。这个逻辑并不正确，因为在删除 Number Box &quot;9&quot; 之后，<code><font face="Courier New">list-&gt;pointer</font></code>&nbsp;应该指向的是 Number Box &quot;8&quot;。现在非常显然我们应该在第 50 行之前添加一条语句&nbsp;<code><font face="Courier New">pointer = pointer-&gt;GetNext();</font></code>，如下所示：</p>
<p><br />
<a name="N103FD"></a><strong>清单 18. 在第 50 行之前添加一条 pointer = pointer-&gt;GetNext(); 语句</strong></p>
<table border="0" cellspacing="0" cellpadding="0" width="600">
    <tbody>
        <tr>
            <td class="code-outline" style="font-family: Georgia, 'Times New Roman', Times, serif; font-size: 11px; color: rgb(153, 153, 153); line-height: 18px; ">
            <pre class="displaycode">
                
     49                     } else {
     50                             pointer = pointer-&gt;GetNext();
     51                             delete current;
     52                             current = 0;
     53                      }
     54                      return 0;
</pre>
            </td>
        </tr>
    </tbody>
</table>
<p>&nbsp;</p>
<p>将新修改之后的程序保存为 gdbtest3.cpp，然后编译并再次运行。</p>
<p><br />
<a name="listing19"></a><strong>清单 19. 再次运行程序（gdbtest3.cpp）</strong></p>
<table border="0" cellspacing="0" cellpadding="0" width="600">
    <tbody>
        <tr>
            <td class="code-outline" style="font-family: Georgia, 'Times New Roman', Times, serif; font-size: 11px; color: rgb(153, 153, 153); line-height: 18px; ">
            <pre class="displaycode">
                
# g++ -g -o gdbtest3 gdbtest3.cpp
# ./gdbtest3
Number Box &quot;0&quot; created
Number Box &quot;1&quot; created
Number Box &quot;2&quot; created
Number Box &quot;3&quot; created
Number Box &quot;4&quot; created
Number Box &quot;5&quot; created
Number Box &quot;6&quot; created
Number Box &quot;7&quot; created
Number Box &quot;8&quot; created
Number Box &quot;9&quot; created
list created
Number Box &quot;9&quot; deleted
Number Box &quot;8&quot; deleted
Number Box &quot;7&quot; deleted
Number Box &quot;6&quot; deleted
Number Box &quot;5&quot; deleted
Number Box &quot;4&quot; deleted
Number Box &quot;3&quot; deleted
Number Box &quot;2&quot; deleted
Number Box &quot;1&quot; deleted
Number Box &quot;0&quot; deleted
</pre>
            </td>
        </tr>
    </tbody>
</table>
<p>&nbsp;</p>
<p>这才是我们期望的结果。</p>
<p><a name="N10413"></a><span class="smalltitle"><strong><font face="Arial" size="3">多线程环境</font></strong></span></p>
<p>在 GDB 中有一些特殊的命令可以用于多线程应用程序的调试。下面这个例子给出了一个死锁情况，并介绍了如何使用这些命令来检查多线程应用程序中的问题：</p>
<p><br />
<a name="N1041F"></a><strong>清单 20. 多线程的例子</strong></p>
<table border="0" cellspacing="0" cellpadding="0" width="600">
    <tbody>
        <tr>
            <td class="code-outline" style="font-family: Georgia, 'Times New Roman', Times, serif; font-size: 11px; color: rgb(153, 153, 153); line-height: 18px; ">
            <pre class="displaycode">
                
#include &lt;stdio.h&gt;
#include &quot;pthread.h&gt;
pthread_mutex_t AccountA_mutex;
pthread_mutex_t AccountB_mutex;
struct BankAccount {
     char account_name[1];
     int balance;
};
struct BankAccount  accountA = {&quot;A&quot;, 10000 };
struct BankAccount  accountB = {&quot;B&quot;, 20000 };
void * transferAB (void* amount_ptr) {
     int amount = *((int*)amount_ptr);
     pthread_mutex_lock(&amp;AccountA_mutex);
     if (accountA.balance &lt; amount)   {
             printf(&quot;There is not enough memory in Account A!\n&quot;);
             pthread_mutex_unlock(&amp;AccountA_mutex);
             pthread_exit((void *)1);
     }
     accountA.balance -=amount;
     sleep(1);
     pthread_mutex_lock(&amp;AccountB_mutex);
     accountB.balance +=amount;
     pthread_mutex_unlock(&amp;AccountA_mutex); 
     pthread_mutex_unlock(&amp;AccountB_mutex);
}
void * transferBA (void* amount_ptr) {
     int amount = *((int*)amount_ptr);
     pthread_mutex_lock(&amp;AccountB_mutex);
     if (accountB.balance &lt; amount)   {
             printf(&quot;There is not enough memory in Account B!\n&quot;);
             pthread_mutex_unlock(&amp;AccountB_mutex);
             pthread_exit((void *)1);
     }
     accountB.balance -=amount;
     sleep(1);
     pthread_mutex_lock(&amp;AccountA_mutex);
     accountA.balance +=amount;
     pthread_mutex_unlock(&amp;AccountB_mutex);
     pthread_mutex_unlock(&amp;AccountA_mutex);
}
int main(int argc, char* argv[]) {
     int             threadid[4];
     pthread_t       pthread[4];
     int             transfer_amount[4] = {100, 200, 300, 400};
     int             final_balanceA, final_balanceB;
     final_balanceA=accountA.balance-transfer_amount[0]-<br />
transfer_amount[1]+transfer_amount[2]+transfer_amount[3];
     final_balanceB=accountB.balance+transfer_amount[0]<br />
+transfer_amount[1]-transfer_amount[2]-transfer_amount[3];
     if (threadid[0] = pthread_create(&amp;pthread[0], NULL, transferAB, <br />(void*)&amp;transfer_amount[0]) &quot; 0) {
             perror(&quot;Thread #0 creation failed.&quot;);
             exit (1);
        }
     if (threadid[1] = pthread_create(&amp;pthread[1], NULL, transferAB, <br />(void*)&amp;transfer_amount[1]) &quot; 0) {
             perror(&quot;Thread #1 creation failed.&quot;);
             exit (1);
     }
     if (threadid[2] = pthread_create(&amp;pthread[2], NULL, transferBA, <br />(void*)&amp;transfer_amount[2]) &lt; 0) {
             perror(&quot;Thread #2 creation failed.&quot;);
             exit (1);
     }
     if (threadid[3] = pthread_create(&amp;pthread[3], NULL, transferBA, <br />(void*)&amp;transfer_amount[3]) &lt; 0) {
             perror(&quot;Thread #3 creation failed.&quot;);
             exit (1);
     }
     printf(&quot;Transitions are in progress..&quot;);
     while ((accountA.balance != final_balanceA) &amp;&amp; (accountB.balance <br />!= final_balanceB)) {
             printf(&quot;..&quot;);
     }
     printf(&quot;\nAll the  money is transferred !!\n&quot;);
}
</pre>
            </td>
        </tr>
    </tbody>
</table>
<p>&nbsp;</p>
<p>使用 gcc 来编译这个程序，如下所示：</p>
<table border="0" cellspacing="0" cellpadding="0" width="600">
    <tbody>
        <tr>
            <td class="code-outline" style="font-family: Georgia, 'Times New Roman', Times, serif; font-size: 11px; color: rgb(153, 153, 153); line-height: 18px; ">
            <pre class="displaycode">
# gcc -g -o gdbtest2 gdbtest2.c -L/lib/tls -lpthread
</pre>
            </td>
        </tr>
    </tbody>
</table>
<p>&nbsp;</p>
<p>程序 gdbtest2 会挂起，不会返回一条&nbsp;<code><font face="Courier New">All the money is transferred !!</font></code>&nbsp;消息。</p>
<p>将 gdb 附加到正在运行的进程上，从而了解这个进程内部正在发生什么。</p>
<p><br />
<a name="N10449"></a><strong>清单 21. 将 gdb 附加到正在运行的进程上</strong></p>
<table border="0" cellspacing="0" cellpadding="0" width="600">
    <tbody>
        <tr>
            <td class="code-outline" style="font-family: Georgia, 'Times New Roman', Times, serif; font-size: 11px; color: rgb(153, 153, 153); line-height: 18px; ">
            <pre class="displaycode">
                
# ps -ef |grep gdbtest2
root      9510  8065  1 06:30 pts/1    00:00:00 ./gdbtest2
root      9516  9400  0 06:30 pts/4    00:00:00 grep gdbtest2
# gdb -pid 9510
GNU gdb 6.2.1
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you 
are welcome to change it and/or distribute copies of it under certain 
conditions.
Type &quot;show copying&quot; to see the conditions.
There is absolutely no warranty for GDB.  Type &quot;show warranty&quot; for 
details.
This GDB was configured as &quot;ppc-suse-linux&quot;.
Attaching to process 9510
Reading symbols from /root/test/gdbtest2...done.
Using host libthread_db library &quot;/lib/tls/libthread_db.so.1&quot;.
Reading symbols from /lib/tls/libpthread.so.0...done.
[Thread debugging using libthread_db enabled]
[New Thread 1073991712 (LWP 9510)]
[New Thread 1090771744 (LWP 9514)]
[New Thread 1086577440 (LWP 9513)]
[New Thread 1082383136 (LWP 9512)]
[New Thread 1078188832 (LWP 9511)]
Loaded symbols for /lib/tls/libpthread.so.0
Reading symbols from /lib/tls/libc.so.6...done.
Loaded symbols for /lib/tls/libc.so.6
Reading symbols from /lib/ld.so.1...done.
Loaded symbols for /lib/ld.so.1
0x0ff4ac40 in __write_nocancel () from /lib/tls/libc.so.6
(gdb) info thread
  5 Thread 1078188832 (LWP 9511)  0x0ffe94ec in __lll_lock_wait () <br />from /lib/tls/libpthread.so.0
  4 Thread 1082383136 (LWP 9512)  0x0ffe94ec in __lll_lock_wait () <br />from /lib/tls/libpthread.so.0
  3 Thread 1086577440 (LWP 9513)  0x0ffe94ec in __lll_lock_wait () <br />from /lib/tls/libpthread.so.0
  2 Thread 1090771744 (LWP 9514)  0x0ffe94ec in __lll_lock_wait () <br />from /lib/tls/libpthread.so.0
  1 Thread 1073991712 (LWP 9510)  0x0ff4ac40 in __write_nocancel () <br />from /lib/tls/libc.so.6
(gdb)
</pre>
            </td>
        </tr>
    </tbody>
</table>
<p>&nbsp;</p>
<p>从&nbsp;<code><font face="Courier New">info thread</font></code>&nbsp;命令中，我们可以了解到除了主线程（thread #1）之外的所有线程都在等待函数&nbsp;<code><font face="Courier New">__lll_lock_wait ()</font></code>&nbsp;完成。</p>
<p>使用&nbsp;<code><font face="Courier New">thread apply threadno where</font></code>&nbsp;命令来查看每个线程到底运行到了什么地方：</p>
<p><br />
<a name="N1046F"></a><strong>清单 22. 查看每个线程运行到了什么地方</strong></p>
<table border="0" cellspacing="0" cellpadding="0" width="600">
    <tbody>
        <tr>
            <td class="code-outline" style="font-family: Georgia, 'Times New Roman', Times, serif; font-size: 11px; color: rgb(153, 153, 153); line-height: 18px; ">
            <pre class="displaycode">
                
(gdb) thread apply 1 where
Thread 1 (Thread 1073991712 (LWP 9510)):
#0  0x0ff4ac40 in __write_nocancel () from /lib/tls/libc.so.6
#1  0x0ff4ac28 in __write_nocancel () from /lib/tls/libc.so.6
Previous frame identical to this frame (corrupt stack?)
#0  0x0ff4ac40 in __write_nocancel () from /lib/tls/libc.so.6
(gdb) thread apply 2 where
Thread 2 (Thread 1090771744 (LWP 9514)):
#0  0x0ffe94ec in __lll_lock_wait () from /lib/tls/libpthread.so.0
#1  0x0ffe466c in pthread_mutex_lock () from /lib/tls/libpthread.so.0
#2  0x0ffe466c in pthread_mutex_lock () from /lib/tls/libpthread.so.0
#3  0x0ffe466c in pthread_mutex_lock () from /lib/tls/libpthread.so.0
#4  0x0ffe466c in pthread_mutex_lock () from /lib/tls/libpthread.so.0
Previous frame inner to this frame (corrupt stack?)
#0  0x0ff4ac40 in __write_nocancel () from /lib/tls/libc.so.6
(gdb) thread apply 3 where
Thread 3 (Thread 1086577440 (LWP 9513)):
#0  0x0ffe94ec in __lll_lock_wait () from /lib/tls/libpthread.so.0
#1  0x0ffe466c in pthread_mutex_lock () from /lib/tls/libpthread.so.0
#2  0x0ffe466c in pthread_mutex_lock () from /lib/tls/libpthread.so.0
#3  0x0ffe466c in pthread_mutex_lock () from /lib/tls/libpthread.so.0
#4  0x0ffe466c in pthread_mutex_lock () from /lib/tls/libpthread.so.0
Previous frame inner to this frame (corrupt stack?)
#0  0x0ff4ac40 in __write_nocancel () from /lib/tls/libc.so.6
(gdb) thread apply 4 where
Thread 4 (Thread 1082383136 (LWP 9512)):
#0  0x0ffe94ec in __lll_lock_wait () from /lib/tls/libpthread.so.0
#1  0x0ffe466c in pthread_mutex_lock () from /lib/tls/libpthread.so.0
#2  0x0ffe466c in pthread_mutex_lock () from /lib/tls/libpthread.so.0
#3  0x0ffe466c in pthread_mutex_lock () from /lib/tls/libpthread.so.0
#4  0x0ffe466c in pthread_mutex_lock () from /lib/tls/libpthread.so.0
Previous frame inner to this frame (corrupt stack?)
#0  0x0ff4ac40 in __write_nocancel () from /lib/tls/libc.so.6
 (gdb) thread apply 5 where
Thread 5 (Thread 1078188832 (LWP 9511)):
#0  0x0ffe94ec in __lll_lock_wait () from /lib/tls/libpthread.so.0
#1  0x0ffe466c in pthread_mutex_lock () from /lib/tls/libpthread.so.0
#2  0x0ffe466c in pthread_mutex_lock () from /lib/tls/libpthread.so.0
#3  0x0ffe466c in pthread_mutex_lock () from /lib/tls/libpthread.so.0
#4  0x0ffe466c in pthread_mutex_lock () from /lib/tls/libpthread.so.0
Previous frame inner to this frame (corrupt stack?)
#0  0x0ff4ac40 in __write_nocancel () from /lib/tls/libc.so.6
</pre>
            </td>
        </tr>
    </tbody>
</table>
<p>&nbsp;</p>
<p>每个线程都试图对一个互斥体进行加锁，但是这个互斥体却是不可用的，可能是因为有另外一个线程已经对其进行加锁了。从上面的证据我们可以判断程序中一定存在死锁。您还可以看到哪个线程现在拥有这个互斥体。</p>
<p><br />
<a name="N1047C"></a><strong>清单 23. 查看哪个线程拥有互斥体</strong></p>
<table border="0" cellspacing="0" cellpadding="0" width="600">
    <tbody>
        <tr>
            <td class="code-outline" style="font-family: Georgia, 'Times New Roman', Times, serif; font-size: 11px; color: rgb(153, 153, 153); line-height: 18px; ">
            <pre class="displaycode">
                
(gdb) print AccountA_mutex
$1 = {__m_reserved = 2, __m_count = 0, __m_owner = 0x2527, <br />
__m_kind = 0, __m_lock  = {__status = 1, __spinlock = 0}}
(gdb) print 0x2527
$2 = 9511
(gdb) print AccountB_mutex
$3 = {__m_reserved = 2, __m_count = 0, __m_owner = 0x2529, <br />
__m_kind = 0, __m_lock = {__status = 1, __spinlock = 0}}
(gdb) print 0x2529
$4 = 9513
(gdb)  
</pre>
            </td>
        </tr>
    </tbody>
</table>
<p>&nbsp;</p>
<p>从上面的命令中，我们可以看出&nbsp;<code><font face="Courier New">AccontA_mutex</font></code>&nbsp;是被线程 5（LWP 9511）加锁（拥有）的，而&nbsp;<code><font face="Courier New">AccontB_mutex</font></code>&nbsp;是被线程 3（LWP 9513）加锁（拥有）的。</p>
<p>为了解决上面的死锁情况，可以按照相同的顺序对互斥体进行加锁，如下所示：&nbsp;<br />
<a name="N10497"></a><strong>清单 24. 按照相同的顺序对互斥体进行加锁</strong></p>
<table border="0" cellspacing="0" cellpadding="0" width="600">
    <tbody>
        <tr>
            <td class="code-outline" style="font-family: Georgia, 'Times New Roman', Times, serif; font-size: 11px; color: rgb(153, 153, 153); line-height: 18px; ">
            <pre class="displaycode">
                    
.
.
void * transferAB (void* amount_ptr) {
        int amount = *((int*)amount_ptr);
        pthread_mutex_lock(&amp;AccountA_mutex);
        pthread_mutex_lock(&amp;AccountB_mutex);
        if (accountA.balance &lt; amount)   {
                printf(&quot;There is not enough memory in Account A!\n&quot;);
                pthread_mutex_unlock(&amp;AccountA_mutex);
                pthread_exit((void *)1);
        }
        accountA.balance -=amount;
        sleep(1);
        accountB.balance +=amount;
        pthread_mutex_unlock(&amp;AccountA_mutex);
        pthread_mutex_unlock(&amp;AccountB_mutex);
}
void * transferBA (void* amount_ptr) {
        int amount = *((int*)amount_ptr);
        pthread_mutex_lock(&amp;AccountA_mutex);
        pthread_mutex_lock(&amp;AccountB_mutex);
        if (accountB.balance &lt; amount)   {
                printf(&quot;There is not enough memory in Account B!\n&quot;);
                pthread_mutex_unlock(&amp;AccountB_mutex);
                pthread_exit((void *)1);
        }
        accountB.balance -=amount;
        sleep(1);
        accountA.balance +=amount;
        pthread_mutex_unlock(&amp;AccountA_mutex);
        pthread_mutex_unlock(&amp;AccountB_mutex);
}
.
.
</pre>
            </td>
        </tr>
    </tbody>
</table>
<p>&nbsp;</p>
<p>或者对每个帐号单独进行加锁，如下所示：&nbsp;<br />
<a name="N104A4"></a><strong>清单 25. 对每个帐号单独进行加锁</strong></p>
<table border="0" cellspacing="0" cellpadding="0" width="600">
    <tbody>
        <tr>
            <td class="code-outline" style="font-family: Georgia, 'Times New Roman', Times, serif; font-size: 11px; color: rgb(153, 153, 153); line-height: 18px; ">
            <pre class="displaycode">
                    
.
.
void * transferAB (void* amount_ptr) {
        int amount = *((int*)amount_ptr);
        pthread_mutex_lock(&amp;AccountA_mutex);
        if (accountA.balance &lt; amount)   {
                printf(&quot;There is not enough memory in Account A!\n&quot;);
                pthread_mutex_unlock(&amp;AccountA_mutex);
                pthread_exit((void *)1);
        }
        accountA.balance -=amount;
        sleep(1);
        pthread_mutex_unlock(&amp;AccountA_mutex);
        pthread_mutex_lock(&amp;AccountB_mutex); 
        accountB.balance +=amount;
        pthread_mutex_unlock(&amp;AccountB_mutex);
}
void * transferBA (void* amount_ptr) {
        int amount = *((int*)amount_ptr);
        pthread_mutex_lock(&amp;AccountB_mutex);
        if (accountB.balance &lt; amount)   {
                printf(&quot;There is not enough memory in Account B!\n&quot;);
                pthread_mutex_unlock(&amp;AccountB_mutex);
                pthread_exit((void *)1);
        }
        accountB.balance -=amount;
        sleep(1);
        pthread_mutex_unlock(&amp;AccountB_mutex);
        pthread_mutex_lock(&amp;AccountA_mutex); 
        accountA.balance +=amount;
        pthread_mutex_unlock(&amp;AccountA_mutex);
}.
</pre>
            </td>
        </tr>
    </tbody>
</table>
<p>&nbsp;</p>
<p><font color="#000000">＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝</font></p>
</font></span></p>]]></description>
<pubDate>2010-09-02 16:24:16</pubDate>
</item>
<item>
<title><![CDATA[C/C++中宏的使用]]></title>
<link>http://www.yhustc.com/Blog/238.html</link>
<description><![CDATA[<p>C/C++中使用宏非常的方便，比如下面这一行实现两个元素的交换</p>
<div class="codeText">
<div class="codeHead">cpp代码</div>
<ol class="dp-cpp">
    <li class="alt"><span><span class="preprocessor">#define&nbsp;exch(A,B)&nbsp;{&nbsp;Item&nbsp;t&nbsp;=&nbsp;A;&nbsp;A&nbsp;=&nbsp;B;&nbsp;B&nbsp;=&nbsp;t;}</span><span>&nbsp;</span></span></li>
</ol>
</div>
<p>但是宏有一个潜在的问题，详见《C++编程思想》关于内联函数一章的具体内容。</p>
<p>问题是什么列？就是宏只是简单的代码替换，并没有内联函数那样的生成临时变量的功能。今天我着实被这个问题坑的很惨。三路划分的快速排序算法结果总是不正确，搞了半个多小时，才发现问题。</p>
<p>如果使用上面的exch的宏，下面的代码就会出现问题</p>
<div class="codeText">
<div class="codeHead">cpp代码</div>
<ol class="dp-cpp">
    <li class="alt"><span><span>exch(a[++p],a[i]); &nbsp;</span></span></li>
    <li><span>exch(a[--q],a[j]);&nbsp;</span></li>
</ol>
</div>
<p>你会发现，被交换的元素的索引是不正确的，总是位于期望元素的后面一个。最终导致结果出错。</p>
<p>问题就出在宏上面。这里不用把++p、--q这样的放到下标中，必须在事前计算好，直接放变量，如a[p]、a[q]。因为宏是实现的整字替换，那么结果就是</p>
<div class="codeText">
<div class="codeHead">cpp代码</div>
<ol class="dp-cpp">
    <li class="alt"><span><span>Item&nbsp;t&nbsp;=&nbsp;a[++p];&nbsp;a[++p]&nbsp;=&nbsp;a[i];&nbsp;a[i]&nbsp;=&nbsp;t;&nbsp;</span></span></li>
</ol>
</div>
<p>然后就悲剧了。</p>
<p>看书必须敲代码，不敲代码，犯一些错误，印象不深刻啊。你要是问我C++的内联函数有什么好处，以及关于内联函数的地址分配等问题，我肯定能背出书上的内容。但是背书没用啊，轮到自己敲代码的时候就傻&times;了。</p>]]></description>
<pubDate>2010-08-03 17:17:33</pubDate>
</item>
<item>
<title><![CDATA[一个国外的广告网站readbud]]></title>
<link>http://www.yhustc.com/Blog/237.html</link>
<description><![CDATA[<p><a target="_blank" href="http://www.readbud.com/?ref=4738120">readbud</a>这个网站，晚上膘叔推荐的，说是看文章有钱拿。</p>
<p>看了一下，基本上就是根据你勾选的个人兴趣，推荐软文，里面做了个把连接，定向投放广告。</p>
<p>省去了需要搜索引擎分析页面内容，完了从广告商的佣金里面提出一部分吸引流量。</p>
<p>那个打分，我估计是统计软文质量用的，打分高的软文就多展示一下下。</p>
<p>阅读文章并打分有很少量的钱，好在是美金，paypal结算，有兴趣的可以试试。</p>
<p><a target="_blank" href="http://www.readbud.com/?ref=4738120">readbud</a>，不厚道的说，大家点击连接进入吧，就别自己输入网址了，不解释，好人一生平安，o(&cap;_&cap;)o 哈哈</p>]]></description>
<pubDate>2010-08-02 22:56:24</pubDate>
</item>
<item>
<title><![CDATA[zz如何在UBUNTU下制作ISO镜像]]></title>
<link>http://www.yhustc.com/Blog/236.html</link>
<description><![CDATA[<p>&nbsp;&nbsp; &nbsp; &nbsp;&nbsp;<span class="Apple-style-span" style="font-family: 'courier new', courier, monospace; line-height: 21px; color: rgb(17, 17, 17); ">在Windows下有很多大型破解软件可以完成，但是在linux下就轻便多了。而且不用承受非法使用软件带来的不安（如果你感觉不安的话）。步骤如下 </span></p>
<p style="text-indent: 2em; text-align: justify; ">1 如果你是直接从cd压制iso文件的，执行</p>
<p style="text-indent: 2em; text-align: justify; ">sudo umount /dev/cdrom<br />
dd if=/dev/cdrom of=file.iso bs=1024</p>
<p style="text-indent: 2em; text-align: justify; ">2 如果你要把某个文件或者目录压到iso文件中，需要使用mkisofs这个工具。这个工具非常强大，还可以压缩DVD格式的iso。你想改的参数都可以修改，而且还有-gui这个参数，用脚趾头猜猜是干什么的？使用linux一定要学会看帮助哦。最简单的用法如下：</p>
<p style="text-indent: 2em; text-align: justify; ">mkisofs -r -o file.iso your_folder_name/</p>
<p style="text-indent: 2em; text-align: justify; ">3 如果你想装酷生成一个MD5文件，执行</p>
<p style="text-indent: 2em; text-align: justify; ">md5sum file.iso &gt; file.iso.md5</p>
<p style="text-indent: 2em; text-align: justify; ">4 如果你想把一个iso文件烧制出来更简单了。右键点这个文件，然后看到了没有？有烧录的选项。我的刻录机可能不行了，每次在windiows下刻录很容易刻坏。所以我总是到ubuntu下来刻录，又快又好。</p>
<p>&nbsp;</p>]]></description>
<pubDate>2010-07-24 12:22:47</pubDate>
</item>
<item>
<title><![CDATA[NS2无线网络仿真trace文件mac地址不正确的问题]]></title>
<link>http://www.yhustc.com/Blog/235.html</link>
<description><![CDATA[<p>使用<a target="_blank" href="http://ndsl.csie.cgu.edu.tw/wimax_ns2.php">长庚大学的NS2的WIMAX模块</a>做仿真，结果trace文件的mac地址总是很奇怪，而且nam的动画显示仿真过程中有问题。</p>
<p>一步步的查啊查，最后发现问题在cmutrace类（trace/cmu-trace.cc）中。一下分析全部是针对老版本的trace格式，请自行修改变通。</p>
<p>hdr_mac802_11（mac/mac-802_11.h）与hdr_mac（mac/mac.h）使用的是同一块内存空间，而我所使用的802.16的头部，是在hdr_mac的基础上再加了一个hdr_mac802_16，也就是说，如果要取mac地址相关信息，应该是从hdr_mac中间取。</p>
<p>看cmutrace的format_mac函数，第一行：struct hdr_mac802_11 *mh = HDR_MAC802_11(p); 也就是说默认无线仿真是802.11的，那么用hdr_mac802_11结构体，当然取不到正确的源和目的MAC地址啦。继续往上看，format_mac_common函数的最后一个分支是对老版本的trace格式进行处理的，有下面几行：</p>
<div class="codeText">
<div class="codeHead">cpp代码</div>
<ol class="dp-cpp">
    <li class="alt"><span><span class="keyword">if</span><span>&nbsp;(strcmp&nbsp;(mactype,&nbsp;</span><span class="string">&quot;Mac/SMAC&quot;</span><span>)&nbsp;==&nbsp;0)&nbsp;{ &nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;format_smac(p,&nbsp;offset); &nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;}&nbsp;</span><span class="keyword">else</span><span>&nbsp;{ &nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;format_mac(p,&nbsp;offset); &nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;}&nbsp;</span></li>
</ol>
</div>
<p>那么，我们自己添加一个 else if (strcmp (mactype, &quot;Mac/802_16&quot;) == 0)的分支就可以了，再自己实现一个类似format_mac的函数，从hdr_mac中取地址，并生成trace，trace文件中MAC地址不对的问题就解决了。</p>
<p>我估计生成nam的类中也有相似问题，不过懒得修改了，直接看trace分析得了。</p>]]></description>
<pubDate>2010-07-23 16:08:31</pubDate>
</item>
<item>
<title><![CDATA[WiMAX MAC管理消息]]></title>
<link>http://www.yhustc.com/Blog/234.html</link>
<description><![CDATA[<p>Type&nbsp;&nbsp;&nbsp;&nbsp; Message name&nbsp;&nbsp;&nbsp;&nbsp; Message description&nbsp;&nbsp;&nbsp;&nbsp; Connection <br />
0&nbsp;&nbsp;&nbsp;&nbsp; UCD&nbsp;&nbsp;&nbsp;&nbsp; Uplink Channel Descriptor&nbsp;&nbsp;&nbsp;&nbsp; Broadcast Fragmentable Broadcast <br />
1&nbsp;&nbsp;&nbsp;&nbsp; DCD&nbsp;&nbsp;&nbsp;&nbsp; Downlink Channel Descriptor&nbsp;&nbsp;&nbsp;&nbsp; Broadcast Fragmentable Broadcast <br />
2&nbsp;&nbsp;&nbsp;&nbsp; DL-MAP&nbsp;&nbsp;&nbsp;&nbsp; Downlink Access Definition&nbsp;&nbsp;&nbsp;&nbsp; Broadcast <br />
3&nbsp;&nbsp;&nbsp;&nbsp; UL-MAP&nbsp;&nbsp;&nbsp;&nbsp; Uplink Access Definition&nbsp;&nbsp;&nbsp;&nbsp; Broadcast <br />
4&nbsp;&nbsp;&nbsp;&nbsp; RNG-REQ&nbsp;&nbsp;&nbsp;&nbsp; Ranging Request&nbsp;&nbsp;&nbsp;&nbsp; Initial Ranging or Basic <br />
5&nbsp;&nbsp;&nbsp;&nbsp; RNG-RSP&nbsp;&nbsp;&nbsp;&nbsp; Ranging Response&nbsp;&nbsp;&nbsp;&nbsp; Initial Ranging or Basic <br />
6&nbsp;&nbsp;&nbsp;&nbsp; REG-REQ&nbsp;&nbsp;&nbsp;&nbsp; Registration Request&nbsp;&nbsp;&nbsp;&nbsp; Primary Management <br />
7&nbsp;&nbsp;&nbsp;&nbsp; REG-RSP&nbsp;&nbsp;&nbsp;&nbsp; Registration Response&nbsp;&nbsp;&nbsp;&nbsp; Primary Management <br />
8&nbsp;&nbsp;&nbsp;&nbsp; &mdash;&nbsp;&nbsp;&nbsp;&nbsp; Reserved&nbsp;&nbsp;&nbsp;&nbsp; &mdash; <br />
9&nbsp;&nbsp;&nbsp;&nbsp; PKM-REQ&nbsp;&nbsp;&nbsp;&nbsp; Privacy Key Management Request&nbsp;&nbsp;&nbsp;&nbsp; Primary Management <br />
10&nbsp;&nbsp;&nbsp;&nbsp; PKM-RSP&nbsp;&nbsp;&nbsp;&nbsp; Privacy Key Management Response&nbsp;&nbsp;&nbsp;&nbsp; Primary Management or Broadcast a <br />
11&nbsp;&nbsp;&nbsp;&nbsp; DSA-REQ&nbsp;&nbsp;&nbsp;&nbsp; Dynamic Service Addition Request&nbsp;&nbsp;&nbsp;&nbsp; Primary Management <br />
12&nbsp;&nbsp;&nbsp;&nbsp; DSA-RSP&nbsp;&nbsp;&nbsp;&nbsp; Dynamic Service Addition Response&nbsp;&nbsp;&nbsp;&nbsp; Primary Management <br />
13&nbsp;&nbsp;&nbsp;&nbsp; DSA-ACK&nbsp;&nbsp;&nbsp;&nbsp; Dynamic Service Addition Acknowledge&nbsp;&nbsp;&nbsp;&nbsp; Primary Management <br />
14&nbsp;&nbsp;&nbsp;&nbsp; DSC-REQ&nbsp;&nbsp;&nbsp;&nbsp; Dynamic Service Change Request&nbsp;&nbsp;&nbsp;&nbsp; Primary Management <br />
15&nbsp;&nbsp;&nbsp;&nbsp; DSC-RSP&nbsp;&nbsp;&nbsp;&nbsp; Dynamic Service Change Response&nbsp;&nbsp;&nbsp;&nbsp; Primary Management <br />
16&nbsp;&nbsp;&nbsp;&nbsp; DSC-ACK&nbsp;&nbsp;&nbsp;&nbsp; Dynamic Service Change Acknowledge&nbsp;&nbsp;&nbsp;&nbsp; Primary Management <br />
17&nbsp;&nbsp;&nbsp;&nbsp; DSD-REQ&nbsp;&nbsp;&nbsp;&nbsp; Dynamic Service Deletion Request&nbsp;&nbsp;&nbsp;&nbsp; Primary Management <br />
18&nbsp;&nbsp;&nbsp;&nbsp; DSD-RSP&nbsp;&nbsp;&nbsp;&nbsp; Dynamic Service Deletion Response&nbsp;&nbsp;&nbsp;&nbsp; Primary Management <br />
19&nbsp;&nbsp;&nbsp;&nbsp; &mdash;&nbsp;&nbsp;&nbsp;&nbsp; Reserved&nbsp;&nbsp;&nbsp;&nbsp; &mdash; <br />
20&nbsp;&nbsp;&nbsp;&nbsp; &mdash;&nbsp;&nbsp;&nbsp;&nbsp; Reserved&nbsp;&nbsp;&nbsp;&nbsp; &mdash; <br />
21&nbsp;&nbsp;&nbsp;&nbsp; MCA-REQ&nbsp;&nbsp;&nbsp;&nbsp; Multicast Assignment Request&nbsp;&nbsp;&nbsp;&nbsp; Primary Management <br />
22&nbsp;&nbsp;&nbsp;&nbsp; MCA-RSP&nbsp;&nbsp;&nbsp;&nbsp; Multicast Assignment Response&nbsp;&nbsp;&nbsp;&nbsp; Primary Management <br />
23&nbsp;&nbsp;&nbsp;&nbsp; DBPC-REQ&nbsp;&nbsp;&nbsp;&nbsp; Downlink Burst Profile Change Request&nbsp;&nbsp;&nbsp;&nbsp; Basic <br />
24&nbsp;&nbsp;&nbsp;&nbsp; DBPC-RSP&nbsp;&nbsp;&nbsp;&nbsp; Downlink Burst Profile Change Response&nbsp;&nbsp;&nbsp;&nbsp; Basic <br />
25&nbsp;&nbsp;&nbsp;&nbsp; RES-CMD&nbsp;&nbsp;&nbsp;&nbsp; Reset Command&nbsp;&nbsp;&nbsp;&nbsp; Basic <br />
26&nbsp;&nbsp;&nbsp;&nbsp; SBC-REQ&nbsp;&nbsp;&nbsp;&nbsp; SS Basic Capability Request&nbsp;&nbsp;&nbsp;&nbsp; Basic <br />
27&nbsp;&nbsp;&nbsp;&nbsp; SBC-RSP&nbsp;&nbsp;&nbsp;&nbsp; SS Basic Capability Response&nbsp;&nbsp;&nbsp;&nbsp; Basic <br />
28&nbsp;&nbsp;&nbsp;&nbsp; CLK-CMP&nbsp;&nbsp;&nbsp;&nbsp; SS network clock comparison&nbsp;&nbsp;&nbsp;&nbsp; Broadcast <br />
29&nbsp;&nbsp;&nbsp;&nbsp; DREG-CMD&nbsp;&nbsp;&nbsp;&nbsp; De/Re-register Command&nbsp;&nbsp;&nbsp;&nbsp; Basic <br />
30&nbsp;&nbsp;&nbsp;&nbsp; DSX-RVD&nbsp;&nbsp;&nbsp;&nbsp; DSx Received Message&nbsp;&nbsp;&nbsp;&nbsp; Primary Management <br />
31&nbsp;&nbsp;&nbsp;&nbsp; TFTP-CPLT&nbsp;&nbsp;&nbsp;&nbsp; Config File TFTP Complete Message&nbsp;&nbsp;&nbsp;&nbsp; Primary Management <br />
32&nbsp;&nbsp;&nbsp;&nbsp; TFTP-RSP&nbsp;&nbsp;&nbsp;&nbsp; Config File TFTP Complete Response&nbsp;&nbsp;&nbsp;&nbsp; Primary Management <br />
33&nbsp;&nbsp;&nbsp;&nbsp; ARQ-Feedback&nbsp;&nbsp;&nbsp;&nbsp; Standalone ARQ Feedback&nbsp;&nbsp;&nbsp;&nbsp; Basic <br />
34&nbsp;&nbsp;&nbsp;&nbsp; ARQ-Discard&nbsp;&nbsp;&nbsp;&nbsp; ARQ Discard message&nbsp;&nbsp;&nbsp;&nbsp; Basic <br />
35&nbsp;&nbsp;&nbsp;&nbsp; ARQ-Reset&nbsp;&nbsp;&nbsp;&nbsp; ARQ Reset message&nbsp;&nbsp;&nbsp;&nbsp; Basic <br />
36&nbsp;&nbsp;&nbsp;&nbsp; REP-REQ&nbsp;&nbsp;&nbsp;&nbsp; Channel measurement Report Request&nbsp;&nbsp;&nbsp;&nbsp; Basic <br />
37&nbsp;&nbsp;&nbsp;&nbsp; REP-RSP&nbsp;&nbsp;&nbsp;&nbsp; Channel measurement Report Response&nbsp;&nbsp;&nbsp;&nbsp; Basic <br />
38&nbsp;&nbsp;&nbsp;&nbsp; FPC&nbsp;&nbsp;&nbsp;&nbsp; Fast Power Control&nbsp;&nbsp;&nbsp;&nbsp; Broadcast <br />
39&nbsp;&nbsp;&nbsp;&nbsp; MSH-NCFG&nbsp;&nbsp;&nbsp;&nbsp; Mesh Network Configuration&nbsp;&nbsp;&nbsp;&nbsp; Broadcast <br />
40&nbsp;&nbsp;&nbsp;&nbsp; MSH-NENT&nbsp;&nbsp;&nbsp;&nbsp; Mesh Network Entry&nbsp;&nbsp;&nbsp;&nbsp; Basic <br />
41&nbsp;&nbsp;&nbsp;&nbsp; MSH-DSCH&nbsp;&nbsp;&nbsp;&nbsp; Mesh Distributed Schedule&nbsp;&nbsp;&nbsp;&nbsp; Broadcast <br />
42&nbsp;&nbsp;&nbsp;&nbsp; MSH-CSCH&nbsp;&nbsp;&nbsp;&nbsp; Mesh Centralized Schedule&nbsp;&nbsp;&nbsp;&nbsp; Broadcast <br />
43&nbsp;&nbsp;&nbsp;&nbsp; MSH-CSCF&nbsp;&nbsp;&nbsp;&nbsp; Mesh Centralized Schedule Configuration&nbsp;&nbsp;&nbsp;&nbsp; Broadcast <br />
44&nbsp;&nbsp;&nbsp;&nbsp; AAS-FBCK-REQ&nbsp;&nbsp;&nbsp;&nbsp; AAS Feedback Request&nbsp;&nbsp;&nbsp;&nbsp; Basic <br />
45&nbsp;&nbsp;&nbsp;&nbsp; AAS-FBCK-RSP&nbsp;&nbsp;&nbsp;&nbsp; AAS Feedback Response&nbsp;&nbsp;&nbsp;&nbsp; Basic <br />
46&nbsp;&nbsp;&nbsp;&nbsp; AAS_Beam_Select&nbsp;&nbsp;&nbsp;&nbsp; AAS Beam Select message&nbsp;&nbsp;&nbsp;&nbsp; Basic <br />
47&nbsp;&nbsp;&nbsp;&nbsp; AAS_BEAM_REQ&nbsp;&nbsp;&nbsp;&nbsp; AAS Beam Request message&nbsp;&nbsp;&nbsp;&nbsp; Basic <br />
48&nbsp;&nbsp;&nbsp;&nbsp; AAS_BEAM_RSP&nbsp;&nbsp;&nbsp;&nbsp; AAS Beam Response message&nbsp;&nbsp;&nbsp;&nbsp; Basic <br />
49&nbsp;&nbsp;&nbsp;&nbsp; DREG-REQ&nbsp;&nbsp;&nbsp;&nbsp; SS De-registration message&nbsp;&nbsp;&nbsp;&nbsp; Basic <br />
50&nbsp;&nbsp;&nbsp;&nbsp; MOB_SLP-REQ&nbsp;&nbsp;&nbsp;&nbsp; sleep request message&nbsp;&nbsp;&nbsp;&nbsp; basic <br />
51&nbsp;&nbsp;&nbsp;&nbsp; MOB_SLP-RSP&nbsp;&nbsp;&nbsp;&nbsp; sleep response message&nbsp;&nbsp;&nbsp;&nbsp; basic <br />
52&nbsp;&nbsp;&nbsp;&nbsp; MOB_TRF-IND&nbsp;&nbsp;&nbsp;&nbsp; traffic indication message&nbsp;&nbsp;&nbsp;&nbsp; broadcast <br />
53&nbsp;&nbsp;&nbsp;&nbsp; MOB_NBR-ADV&nbsp;&nbsp;&nbsp;&nbsp; neighbor advertisement message&nbsp;&nbsp;&nbsp;&nbsp; broadcast, primary management <br />
54&nbsp;&nbsp;&nbsp;&nbsp; MOB_SCN-REQ&nbsp;&nbsp;&nbsp;&nbsp; scanning interval allocation request&nbsp;&nbsp;&nbsp;&nbsp; basic <br />
55&nbsp;&nbsp;&nbsp;&nbsp; MOB_SCN-RSP&nbsp;&nbsp;&nbsp;&nbsp; scanning interval allocation response&nbsp;&nbsp;&nbsp;&nbsp; basic <br />
56&nbsp;&nbsp;&nbsp;&nbsp; MOB_BSHO-REQ&nbsp;&nbsp;&nbsp;&nbsp; BS HO request message&nbsp;&nbsp;&nbsp;&nbsp; basic <br />
57&nbsp;&nbsp;&nbsp;&nbsp; MOB_MSHO-REQ&nbsp;&nbsp;&nbsp;&nbsp; MS HO request message&nbsp;&nbsp;&nbsp;&nbsp; basic <br />
58&nbsp;&nbsp;&nbsp;&nbsp; MOB_BSHO-RSP&nbsp;&nbsp;&nbsp;&nbsp; BS HO response message&nbsp;&nbsp;&nbsp;&nbsp; basic <br />
59&nbsp;&nbsp;&nbsp;&nbsp; MOB_HO-IND&nbsp;&nbsp;&nbsp;&nbsp; HO indication message&nbsp;&nbsp;&nbsp;&nbsp; basic <br />
60&nbsp;&nbsp;&nbsp;&nbsp; MOB_SCN-REP&nbsp;&nbsp;&nbsp;&nbsp; Scanning result report message&nbsp;&nbsp;&nbsp;&nbsp; primary management <br />
61&nbsp;&nbsp;&nbsp;&nbsp; MOB_PAG-ADV&nbsp;&nbsp;&nbsp;&nbsp; BS broadcast paging message&nbsp;&nbsp;&nbsp;&nbsp; broadcast <br />
62&nbsp;&nbsp;&nbsp;&nbsp; MBS_MAP&nbsp;&nbsp;&nbsp;&nbsp; MBS MAP message&nbsp;&nbsp;&nbsp;&nbsp; &mdash; <br />
63&nbsp;&nbsp;&nbsp;&nbsp; PMC_REQ&nbsp;&nbsp;&nbsp;&nbsp; Power control mode change request message&nbsp;&nbsp;&nbsp;&nbsp; Basic <br />
64&nbsp;&nbsp;&nbsp;&nbsp; PMC_RSP&nbsp;&nbsp;&nbsp;&nbsp; Power control mode change response message&nbsp;&nbsp;&nbsp;&nbsp; Basic <br />
65&nbsp;&nbsp;&nbsp;&nbsp; PRC-LT-CTRL&nbsp;&nbsp;&nbsp;&nbsp; Setup/Tear-down of long-term MIMO precoding&nbsp;&nbsp;&nbsp;&nbsp; Basic <br />
66&nbsp;&nbsp;&nbsp;&nbsp; MOB_ASC-REP&nbsp;&nbsp;&nbsp;&nbsp; Association result report message&nbsp;&nbsp;&nbsp;&nbsp; primary management <br />
67&ndash;255&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Reserved&nbsp;&nbsp;&nbsp;&nbsp; &mdash;</p>]]></description>
<pubDate>2010-07-23 10:02:23</pubDate>
</item>
<item>
<title><![CDATA[cygwin无法安装gcc和XFree86的问题]]></title>
<link>http://www.yhustc.com/Blog/233.html</link>
<description><![CDATA[<p>一直用debian的VPS运行NS2的，因为我都是看trace。</p>
<p>今天修改了一个支持WIMAX的NS 2.33，想用nam看看动画，所以装了一个cygwin，准备编译NS2。</p>
<p>cygwin的安装镜像可以使用这个，速度很快 <a href="http://www.cygwin.cn/pub/">http://www.cygwin.cn/pub/</a></p>
<p>安装所需的一些包：XFree86/xorg, autoconf, make, patch, perl, gcc, gcc-g++, gawk, gnuplot, tar, gzip</p>
<p>然后就开始install了，结果cygcheck -c gcc的时候显示没有安装gcc。仔细查了一下，发现安装的时候选软件包，有gcc，但是体积更大的，是那个gcc-core。看了一下gcc的说明，只是一个update helper，估计实际用还是用gcc-core。</p>
<p>于是到install脚本里面搜索gcc，把&ldquo;packages_base=&quot;<span style="color: #ff0000">gcc</span> gcc-g++ gawk tar gzip make patch perl w32api&quot;&rdquo;修改成&ldquo;packages_base=&quot;<span style="color: #ff0000">gcc-core </span>gcc-g++ gawk tar gzip make patch perl w32api&quot;&rdquo;即可。</p>
<p>继续运行install，这会显示没有X，也就是说XFree86和xorg都没有安装。install脚本里面搜对X的检测，发现是先检测xorg，如果没有再检查XFree86。重新运行cygwin的setup，发现XFree86只能搜到一个字体文件，其他的开发包什么的在这个版本里面都去掉了。没法只好装xorg。</p>
<p>搜xorg，发现没有什么东西，因为下面的那个&ldquo;hide obsolete packages&rdquo;勾选要去掉，现在可以看到一堆软件列表了吧。根据install脚本里面的检测说明，勾选&ldquo;xorg-x11-base xorg-x11-bin xorg-x11-bin-dlls xorg-x11-devel xorg-x11-libs-data xorg-x11-etc&rdquo;，鉴于7.0版本那个体积到太小，怕有问题，选低版本的6.9，几M一个，放心一点。</p>
<p>安装完成后，就可以正式开始install ns2了。</p>]]></description>
<pubDate>2010-07-16 13:31:58</pubDate>
</item>
<item>
<title><![CDATA[NS2中从应用层访问UM-OLSR的路由表]]></title>
<link>http://www.yhustc.com/Blog/232.html</link>
<description><![CDATA[<p>　　做一个跨层优化的仿真，在应用层Application里面要访问OLSR的路由表项，结合底层路由信息做P2P的传输策略优化。OLSR使用的是UM-OLSR。</p>
<p>　　根据UM-OLSR的说明，如果要对单个节点上的agent进行设置，可以使用如下代码</p>
<div class="codeText">
<div class="codeHead">TCL代码</div>
<ol class="dp-rb">
    <li class="alt"><span><span>set&nbsp;ra&nbsp;[</span><span class="variable">$mobilenode</span><span>&nbsp;agent&nbsp;255] &nbsp;</span></span></li>
    <li><span class="variable">$ra</span><span>&nbsp;set&nbsp;use_mac_&nbsp;</span><span class="keyword">true</span><span>&nbsp;</span></li>
    <li class="alt"><span class="variable">$ra</span><span>&nbsp;set&nbsp;tc_ival_&nbsp;6&nbsp;</span></li>
</ol>
</div>
<p><font face="Courier New">这说明，ra取到的是对应agent的引用，可以直接操作这个路由agent了。</font></p>
<p><font face="Courier New"><font face="Arial">　　</font>那么自己的application要怎么做就简单多了，把上面的mobilenode换成自己的node对象，然后运行上面的第一句TCL即可。如下所示：</font></p>
<div class="codeText">
<div class="codeHead">cpp代码</div>
<ol class="dp-cpp">
    <li class="alt"><span><span>nsaddr_t&nbsp;node_addr_&nbsp;=&nbsp;agent_-&gt;addr(); &nbsp;</span></span></li>
    <li><span class="datatypes">int</span><span>&nbsp;node_id_&nbsp;=&nbsp;OLSR::node_id(node_addr_); &nbsp;</span></li>
    <li class="alt"><span class="datatypes">char</span><span>&nbsp;command[256]; &nbsp;</span></li>
    <li><span>sprintf(command,&nbsp;</span><span class="string">&quot;set&nbsp;ra&nbsp;[$node_(%d)&nbsp;agent&nbsp;255]&quot;</span><span>,&nbsp;node_id_);&nbsp;</span><span class="comment">//id与node_数组是对应的 </span><span>&nbsp;</span></li>
    <li class="alt"><span>tcl.eval(command); &nbsp;</span></li>
    <li><span class="keyword">const</span><span>&nbsp;</span><span class="datatypes">char</span><span>*&nbsp;ref&nbsp;=&nbsp;tcl.result(); &nbsp;</span></li>
    <li class="alt"><span>OLSR*&nbsp;olsr_agent_&nbsp;=&nbsp;(OLSR*)tcl.lookup(ref);&nbsp;</span></li>
</ol>
</div>
<p><font face="Courier New"><font face="Arial">　　</font>取到application所在node的OLSR Agent了，剩下的就是访问OLSR_rtable以及其中的OLSR_rt_entry了，自己改造一下OLSR_rtable吧，o(&cap;_&cap;)o </font></p>]]></description>
<pubDate>2010-07-07 17:28:23</pubDate>
</item>
<item>
<title><![CDATA[10个腾讯微博的邀请]]></title>
<link>http://www.yhustc.com/Blog/231.html</link>
<description><![CDATA[<p>之前的终于被人注册完了，继续放10个，不知道QQ还会不会继续给生成邀请码</p>
<p>6.28 还有两个可用</p>
<p><a href="http://t.qq.com/invite/8b385f68a82a77649701">http://t.qq.com/invite/8b385f68a82a77649701</a><br />
<a href="http://t.qq.com/invite/d83aad50ac4052d01583">http://t.qq.com/invite/d83aad50ac4052d01583</a><br />
<a href="http://t.qq.com/invite/ed5fa31e0c191fa550a3">http://t.qq.com/invite/ed5fa31e0c191fa550a3</a><br />
<a href="http://t.qq.com/invite/6f707e17e4faffd6469d">http://t.qq.com/invite/6f707e17e4faffd6469d</a>&nbsp; 可用<br />
<a href="http://t.qq.com/invite/a813bb007d77f77b22cd">http://t.qq.com/invite/a813bb007d77f77b22cd</a>&nbsp; 可用<br />
<a href="http://t.qq.com/invite/0d588b2c5144c56c496b">http://t.qq.com/invite/0d588b2c5144c56c496b</a><br />
<a href="http://t.qq.com/invite/0ff0c62d2dcd023f667d">http://t.qq.com/invite/0ff0c62d2dcd023f667d</a><br />
<a href="http://t.qq.com/invite/34e4e3f6ea2340036e7d">http://t.qq.com/invite/34e4e3f6ea2340036e7d</a><br />
<a href="http://t.qq.com/invite/2f22607d07e8eda3a863">http://t.qq.com/invite/2f22607d07e8eda3a863</a><br />
<a href="http://t.qq.com/invite/68fc1cf69791e89cc179">http://t.qq.com/invite/68fc1cf69791e89cc179</a></p>]]></description>
<pubDate>2010-06-16 19:42:21</pubDate>
</item>
<item>
<title><![CDATA[罗老号历史重演啊]]></title>
<link>http://www.yhustc.com/Blog/230.html</link>
<description><![CDATA[<p>除了火箭的结局重演，更喜气的是去年棒子说的&ldquo;部分成功&rdquo;态度也重演了。</p>
<p>o(︶︿︶)o&nbsp; 新闻引用：</p>
<p>中新网6月10日电 据韩联社报道，韩国&ldquo;罗老&rdquo;号运载火箭在当地时间10日下午5点01分发射升空后，在第55秒时突破音速，但在第137秒后于70Km上空失去了通信联 络。 据报道，韩国航空宇宙研究院负责人李柱镇在当天的记者会上，作出了上述表示。他说：&ldquo;在通信断绝之前，一切数据都正常。我们会致力于找到这一人 造卫星。&rdquo;</p>]]></description>
<pubDate>2010-06-10 17:20:09</pubDate>
</item>
</channel>
</rss>