博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
GDB的两个技巧
阅读量:6412 次
发布时间:2019-06-23

本文共 1947 字,大约阅读时间需要 6 分钟。

分享两个GDB的小技巧:

1, GDB失效时手工得到stack;

2, GDB执行用户命令脚本;

调试内存型服务程序的有时会遇到core dump或死锁问题,且gdb或者pstack都无法显示调用栈(call stack)。这是因为线程的调用栈被破坏了,而调用栈存放了函数的返回地址,gdb解析函数返回地址(根据地址查找符号表)失败,gdb也没有进行容错处理,只要有一处地址解析失败就无法展开调用栈。然而幸运的是,调用栈往往只是部分被破坏,RSP堆栈寄存器中保存的值往往也是正确的,可以通过手工的方法恢复。具体做法如下:

(gdb) set logging onCopying output to gdb.txt.(gdb) x /2000a $rsp0x426cb890: 0x0 0x40x426cb8a0: 0x426cb8c0 0x1000x426cb8b0: 0x3e8 0x552f59 <_ZN5tbnet16EPollSocketEvent9getEventsEiPNS_7IOEventEi+41>0x426cb8c0: 0x1823c8a000000011 0x00x426cb8d0: 0x0 0x00x426cb8e0: 0x0 0x0...

如上图,类似”0x552f59 <_ZN5tbnet16EPollSocketEvent9getEventsEiPNS_7IOEventEi+41>”这样的代码符号看起来是有效的。通过所有看似有效的程序代码符号基本能够得出core dump时的调用栈。

当然,有可能出现core dump线程的调用栈被完全破坏的情况,通过上述方法恢复的信息仍然是无效的。由于每个线程堆栈地址空间的大小为10M,因此,线程之间互相破坏调用堆栈的可能性几乎是不存在的,此时,可以通过其它线程的调用栈分析其行为,往往也能找到线索。如果所有线程的调用栈都“看似被破坏”,那么,往往有两种可能:

a, 可执行程序和core文件对不上,被摆乌龙了,如发现core dump问题的时候可执行程序已经更新到最新版本,老版本没有保存;

b, 磁盘满了或者ulimit设置太小,导致core dump文件信息不全;

如果core文件对不上或者信息不全的问题,还可以通过dmesg命令找到程序core dump时的指令寄存器RIP的值,再通过addr2line获取程序最后执行的代码行。如:

[rizhao.ych@OceanBase036040 updateserver]$ dmesg | grep updateserverupdateserver[8099]: segfault at 0000000000000000 rip 0000000000500fbf rsp 000000004c296e30 error 4[rizhao.ych@OceanBase036040 updateserver]$ addr2line -e updateserver 0000000000500fbf/home/rizhao/dev/oceanbase/src/common/ob_base_server.cpp:222

另外一个用得比较多的功能是GDB执行用户命令脚本。我们组无施同学有一个例子:Oceanbase系统有一个ObGetParam的类,是一个数组,里面的每个元素是一个ObCellInfo,ObGetParam中可能包含成百上千个ObCellInfo,现在需要在GDB调试的时候输出数组中所有的ObCellInfo对象信息。脚本如下:

define dumpGetParamset $cell_list = ($arg0)set $cell_num = ($arg1)set $cell_idx = (0)while ($cell_idx < $cell_num)  printf "cell_idx:%d,table_id:%llu,column_id:%llu\n", $cell_idx,     $cell_list[$cell_idx].table_id_, $cell_list[$cell_idx].column_id  set $cell_idx = $cell_idx + 1endend

上面的代码定义了一个命令叫dumpGetParam,其第一个参数$arg0是cell数组的地址,第二个参数$arg1是数组大小,代码的功能就是打印所有cell的信息。

把上面的代码写入一个文本文件dump_get_param.txt,在gdb中执行source dump_get_param.txt,然后就可以使用dumpGetParam命令了。

转载地址:http://nwura.baihongyu.com/

你可能感兴趣的文章
js Uncaught TypeError: undefined is not a function
查看>>
数据库存储引擎
查看>>
[2019.2.13]BZOJ4318 OSU!
查看>>
版本号带两个小数点的,如何比较大小?( NSStringCompareOptions )
查看>>
QCustomplot使用分享(三) 图
查看>>
什么是java?
查看>>
WPF路径动画(动态逆向动画)
查看>>
Low Level Reader Protocol (LLRP) 简介
查看>>
[Micropython]TPYBoard v10x NRF24L01无线通讯模块使用教程
查看>>
mysql中show processlist过滤和杀死线程
查看>>
最新Sublime Text 2 激活 汉化
查看>>
基础数据类型之字典
查看>>
第七次作业
查看>>
Oracle中NVARCHAR2与VARCHAR2的区别
查看>>
php debug
查看>>
Ubuntu构建LVS+Keepalived高可用负载均衡集群【生产环境部署】
查看>>
lvm实现快速备份文件及数据库,lvm快照原理
查看>>
设计模式之Factory Method(工厂方法)
查看>>
10K入职linux运维岗位小伙伴感谢信及面试经历分享
查看>>
zookeeper入门之Curator的使用之几种监听器的使用
查看>>