原文地址:http://elennatuzi.spaces.live.com/blog/cns!1A9FD94426AD53B!359.entry
我想对于用NS来仿真的人来说,很重要的一个问题就是调试,因为并没有像VC那样方便的集成的调试环境。《NS与网络模拟》的书中介绍了tcl debug和KDevelop调试的方法,这里主要介绍gdb调试的方法。因为偶个人第一次写ns代码调试用的就是gdb,感觉安装使用都很方便,这里简单介绍一下:
1.重新运行cygwin的setup文件,选择gdb组件,下载安装。
2.修改Makefile,添加调试信息,即CCOPT = -g//(后面可能还有其他参数,保留),其实就是在ns编译的时候gcc后面添加-g选项。
3.重新编译NS2:make clean,make depend然后make
我make的时候indep-utils/webtrace-conv/dex/proxytrac2any.cc出了声明错误,在main函数前添加extern int IsLittleEndian(void);extern void ToOtherEndian(TEntry *e);
常用命令:
进入gdb调试状态:$gdb ns
运行脚本:<gdb>r file.tcl
设置断点:<gdb>b file.cc:行数
删除断点:<gdb>d b 断点编号(1,2,...)
显示变量或函数值:<gdb>display var
删除变量或函数值显示:<gdb>d d 变量编号
单步执行:<gdb>n
单步跳入:<gdb>s
循环执行:<gdb>c
列出运行栈的内容:<gdb>bt——主要针对遇到segment fault的情况
退出调试:<gdb>q
原文地址:http://hi.baidu.com/follow_my_dream_peteryzq/blog/item/0c49fa803fd878a80cf4d29e.html
NS2程序的入口点:main函数, (位于ns2.*目录的common子目录的TclAppInit.cc文件)
main函数中只有两句代码
Tcl_Main(argc, argv, Tcl_AppInit);
return 0;
这个函数可以说包装了整个NS2框架,因为紧接着它的下一句语句就是:return 0!
然而,此时,当我们想通过F5(单步跳入)查看TclMain函数的具体实现时,IDE的终端又直接跳至提示符。也就是说,我们仍然无法查看Tcl_Main函数的原型,也就无法查看NS2框架的大部分内容。
我们能查看到 main函数的实现却看不到Tcl_main函数的实现的原因在于: Tcl_Main函数所在的文件并非位于ns2.*目录下,而是位于另一个目录下(后面将看到是tcl8.4.*目录的unix子目录)。而且Tcl_Main函数是被编译到一个静态链接库文件中去了(后面我们将知道是libtcl8.*.a)。 我们此时,只是在ns2.*目录下,用./configure --enable-debug 添加了调试信息,但却没有在 Tcl_Main 函数所在有 tcl8.4.*目录下 添加调试信息(具体来说是在tcl8.4.*的unix目录下的Makefile文件中添加 -g选项)
为了能够跟踪到Tcl_Main函数中去,我们作如下操作:
切换到 tcl8.4.*目录的unix子目录,然后 我们会发现 里面有一个libtcl8.*.a 和另一个libtclstub.*.a 文件,前一个大小为700多K(这其实是未添加调试信息前的大小)。 再次用make clean命令清除所有目标、库文件后,我们不能再次用sudo ./configure --enable-debug 命令来添加 调试信息(其原因在于此处的 Makefile.in 文件有些特殊)。 我们所要做的是 将 Makefile文件中的 下面内容(102-106行)
# To change the compiler switches, for example to change from optimization to
# debugging symbols, change the following line:
#CFLAGS = $(CFLAGS_DEBUG)
#CFLAGS = $(CFLAGS_OPTIMIZE)
#CFLAGS = $(CFLAGS_DEBUG) $(CFLAGS_OPTIMIZE)
CFLAGS = $(CFLAGS_OPTIMIZE) -DTCL_DBGX=$(TCL_DBGX)
换成
# To change the compiler switches, for example to change from optimization to
# debugging symbols, change the following line:
#CFLAGS = $(CFLAGS_DEBUG)
#CFLAGS = $(CFLAGS_OPTIMIZE)
CFLAGS = $(CFLAGS_DEBUG) $(CFLAGS_OPTIMIZE)
#CFLAGS = $(CFLAGS_OPTIMIZE) -DTCL_DBGX=$(TCL_DBGX)
其意思是 将编译械从原来的 优化模式 切换 到 DEBUg+ OPTIMIZE模式。相当于 前面所讲 的 在CCOPT 后添加 -g 选项
然后 ,再次 make ,生成两个新的.a 文件.
注意:在unix目录生成新的.a文件后,须将这两个文件拷贝至 ns-allinone-2.3*的lib目录下(因为,在生成NS2时,指定的libtcl8.*.a 的库路径为lib)
其实,我们在用make 命令生成NS时,从终端的输出便可以知道NS引用了哪些静态库。为了能够全程调试,这些静态库都应该如libtcl8.*.a库一样,添加调试信息后重新编译生成。
添加调试信息无非就是更改对应的Makefile 中的gcc 编译选项(不同库的Makefile不相同,有的库用 ./configure --enable-debug命令不能添加 调试信息,必须手动修改Makefile)
另外,还需要注意的是:NS所依赖的这些静态库实际上是有相互依赖关系的,因此,重新编译它们,也需要按照一定的顺序。这也是为什么 NS的allinone包在安装各个包时,其顺序都是固定的原因。