当GDB提示符出现的时候,表明GDB已经做好准备进行调试了,现在可以通过run命令让程序开始在GDB的监控下运行:
(gdb) runStarting program: /home/xiaowp/thesis/gcc/code/crashInput an integer:10Program received signal SIGSEGV, Segmentation fault.0x4008576b in _IO_vfscanf_internal () from /lib/libc.so.6
仔细分析一下GDB给出的输出结果不难看出,程序是由于段错误而导致异常中止的,说明内存操作出了问题,具体发生问题的地方是在调用_IO_vfscanf_internal ( )的时候 。为了得到更加有价值的信息,可以使用GDB提供的回溯跟踪命令backtrace,执行结果如下:
(gdb) backtrace#00x4008576b in _IO_vfscanf_internal () from /lib/libc.so.6#10xbffff0c0 in ?? ()#20x4008e0ba in scanf () from /lib/libc.so.6#30x08048393 in main () at crash.c:11#40x40042917 in __libc_start_main () from /lib/libc.so.6
跳过输出结果中的前面三行,从输出结果的第四行中不难看出,GDB已经将错误定位到crash.c中的第11行了 。现在仔细检查一下:
(gdb) frame 3#30x08048393 in main () at crash.c:1111scanf("%d", input);
使用GDB提供的frame命令可以定位到发生错误的代码段,该命令后面跟着的数值可以在backtrace命令输出结果中的行首找到 。现在已经发现错误所在了,应该将
scanf("%d", input);改为scanf("%d", &input);
完成后就可以退出GDB了,命令如下:
(gdb) quit
GDB的功能远远不止如此,它还可以单步跟踪程序、检查内存变量和设置断点等 。
调试时可能会需要用到编译器产生的中间结果,这时可以使用-save-temps选项,让GCC将预处理代码、汇编代码和目标代码都作为文件保存起来 。如果想检查生成的代码是否能够通过手工调整的办法来提高执行性能,在编译过程中生成的中间文件将会很有帮助,具体情况如下:
# gcc -save-temps foo.c -o foo# ls foo*foofoo.cfoo.ifoo.s
GCC支持的其它调试选项还包括-p和-pg,它们会将剖析(Profiling)信息加入到最终生成的二进制代码中 。剖析信息对于找出程序的性能瓶颈很有帮助,是协助Linux程序员开发出高性能程序的有力工具 。在编译时加入-p选项会在生成的代码中加入通用剖析工具(Prof)能够识别的统计信息,而-pg选项则生成只有GNU剖析工具(Gprof)才能识别的统计信息 。
最后提醒一点,虽然GCC允许在优化的同时加入调试符号信息,但优化后的代码对于调试本身而言将是一个很大的挑战 。代码在经过优化之后,在源程序中声明和使用的变量很可能不再使用,控制流也可能会突然跳转到意外的地方,循环语句有可能因为循环展开而变得到处都有,所有这些对调试来讲都将是一场噩梦 。建议在调试的时候最好不使用任何优化选项,只有当程序在最终发行的时候才考虑对其进行优化 。
上次的培训园地中介绍了GCC的编译过程、警告提示功能、库依赖、代码优化和程序调试六个方面的内容 。这期是最后的一部分内容 。
加速
在将源代码变成可执行文件的过程中,需要经过许多中间步骤,包含预处理、编译、汇编和连接 。这些过程实际上是由不同的程序负责完成的 。大多数情况下GCC可以为Linux程序员完成所有的后台工作,自动调用相应程序进行处理 。
这样做有一个很明显的缺点,就是GCC在处理每一个源文件时,最终都需要生成好几个临时文件才能完成相应的工作,从而无形中导致处理速度变慢 。例如,GCC在处理一个源文件时,可能需要一个临时文件来保存预处理的输出、一个临时文件来保存编译器的输出、一个临时文件来保存汇编器的输出,而读写这些临时文件显然需要耗费一定的时间 。当软件项目变得非常庞大的时候,花费在这上面的代价可能会变得很沉重 。
推荐阅读
- Linux上安装GCC编译器过程
- Linux精彩桌面 GNOME桌面主题安装实例
- 【体验精彩】诺基亚6681最新详细评测之初印象
- 低端也精彩
- 逼真立体声的精彩 酷机康佳M929评测手记
- 父母在儿子婚礼上的精彩讲话稿
- 海尔V280,绝色纤薄,百万精彩
- 关于Linux操作系统下GCC的使用方法说明
- Linux系统平台下关于GCC编译及使用的方法
- S文手记:移动互联 精彩体验--海尔 V8800