免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 20634 | 回复: 9
打印 上一主题 下一主题

求大牛真解:关于 gdb 调试 bt 之后 如何分析出问题所在 .(有例子) [复制链接]

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-03-28 17:53 |只看该作者 |倒序浏览
当GDB提示符出现的时候,表明GDB已经做好准备进行调试了,现在可以通过run命令让程序开始在GDB的监控下运行:

(gdb) run
Starting program: /home/xiaowp/thesis/gcc/code/crash
Input an integer:10

Program received signal SIGSEGV, Segmentation fault.
0×4008576b in _IO_vfscanf_internal () from /lib/libc.so.6



仔细分析一下GDB给出的输出结果不难看出,程序是由于段错误而导致异常中止的,说明内存操作出了问题,具体发生问题的地方是在调用_IO_vfscanf_internal ( )的时候。为了得到更加有价值的信息,可以使用GDB提供的回溯跟踪命令backtrace,执行结果如下:



(gdb) backtrace
#0 0×4008576b in _IO_vfscanf_internal () from /lib/libc.so.6
#1 0xbffff0c0 in ?? ()
#2 0×4008e0ba in scanf () from /lib/libc.so.6
#3 0×08048393 in main () at crash.c:11
#4 0×40042917 in __libc_start_main () from /lib/libc.so.6



跳过输出结果中的前面三行,从输出结果的第四行中不难看出,GDB已经将错误定位到crash.c中的第11行了。现在仔细检查一下:  // 这是如何分析得出的  求大牛真解

(gdb) frame 3
#3 0×08048393 in main () at crash.c:11
11 scanf("%d", input);

论坛徽章:
1
双鱼座
日期:2013-08-28 13:47:26
2 [报告]
发表于 2011-03-28 18:19 |只看该作者
11行"scanf("%d", input);"中的"input"是个整形指针还是个整形变量?
要是整形变量,改成"scanf("%d", &input);"试试.
要是整形指针,看看是否已为其分配空间.

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
3 [报告]
发表于 2011-03-28 18:29 |只看该作者
回复 2# firkraag


     这个是别人的帖子    我想问的是

这一共 5个打印:

(gdb) backtrace
#0 0×4008576b in _IO_vfscanf_internal () from /lib/libc.so.6
#1 0xbffff0c0 in ?? ()
#2 0×4008e0ba in scanf () from /lib/libc.so.6
#3 0×08048393 in main () at crash.c:11
#4 0×40042917 in __libc_start_main () from /lib/libc.so.6

他怎么知道是 第#3的问题  就因为 其他都是/lib?

论坛徽章:
1
双鱼座
日期:2013-08-28 13:47:26
4 [报告]
发表于 2011-03-28 18:34 |只看该作者
看backtrace输出的函数调用栈.

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
5 [报告]
发表于 2011-03-28 18:38 |只看该作者
回复 4# firkraag


    这5行 打印 就是 bt命令 敲出来的

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
6 [报告]
发表于 2011-03-28 18:38 |只看该作者
回复 4# firkraag


    这5行 打印 就是 bt命令 敲出来的

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
7 [报告]
发表于 2011-03-29 08:44 |只看该作者
再顶一下

论坛徽章:
1
双鱼座
日期:2013-08-28 13:47:26
8 [报告]
发表于 2011-03-29 10:33 |只看该作者
默认情况下,GCC在编译时不会将调试符号插入到生成的二进制代码中,因为这样会增加可执行文件的大小。如果需要在编译时生成调试符号信息,可以使用GCC的-g或者-ggdb选项。GCC在产生调试符号时,同样采用了分级的思路,开发人员可以通过在-g选项后附加数字1、2或3来指定在代码中加入调试信息的多少。默认的级别是2(-g2),此时产生的调试信息包括扩展的符号表、行号、局部或外部变量信息。级别3(-g3)包含级别2中的所有调试信息,以及源代码中定义的宏。级别1(-g1)不包含局部变量和与行号有关的调试信息,因此只能够用于回溯跟踪和堆栈转储之用。回溯跟踪指的是监视程序在运行过程中的函数调用历史,堆栈转储则是一种以原始的十六进制格式保存程序执行环境的方法,两者都是经常用到的调试手段。

论坛徽章:
0
9 [报告]
发表于 2012-10-09 13:55 |只看该作者
还是想要请教各位大神如何查看打印出来的堆栈信息。通过这些内容去分析
多谢先

论坛徽章:
0
10 [报告]
发表于 2014-10-10 12:45 |只看该作者
第四行是main()函数的代码,而前几行都是系统代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP