GDB调试总结

Linux下GDB调试命令

GDB 调试主要有三种方式:
1. gdb filename 直接调试目标程序 (gdb ./目标程序文件名)
2. gdb attach pid 附加进程
3. gdb filename corename 调试 core 文件


>gcc file.c -g -o app 编译命令
>gdb app 运行调试命令
>start 单步执行;>run全速执行;>list查看代码;>b+ line_num某行下断点;
>d + breakpoint_num 删除断点;
>info breakpoint 查看所有断点;
>disable/enable+breakpoint_num 禁用/启用断点;
>bt 栈帧;
>frame+ bt_number 临时切换栈帧。

GDB调试多线程命令:
info threads 显示当前可调试的所有线程,每个线程会有一个GDB为其分配的ID,后面操作线程的时候会用到这个ID。 前面有*的是当前调试的线程
thread ID(1,2,3…) 切换当前调试的线程为指定ID的线程;切换当前调试的线程为指定ID号,ID是gdb分配的序号,不是线程TID
break thread_test.c:123 thread all(例:在相应函数的位置设置断点break pthread_run1) 在所有线程中相应的行上设置断点
thread apply ID1 ID2 command 让一个或者多个线程执行GDB命令command
thread apply all command 让所有被调试线程执行GDB命令command
set scheduler-locking 选项 command 设置线程是以什么方式来执行命令
set scheduler-locking [on/off] on锁定其他线程,只有当前选择调试的线程执行,off表示不锁定任何线程,当运行到断点处,将所有的线程都暂停下来,直到指定某个线程继续执行,如果在当前线程下使用continue的话会启动所有线程(GDB默认)。
set scheduler-locking off 不锁定任何线程,也就是所有线程都执行,这是默认值
set scheduler-locking on 只有当前被调试程序会执行
set scheduler-locking on step 在单步的时候,除了next过一个函数的情况(熟悉情况的人可能知道,这其实是一个设置断点然后continue的行为)以外,只有当前线程会执行。

Linux下多线程查看工具(pstree、ps、pstack)
pstree

>pstree  主线程id
ps

>ps aux | grep ‘线程名‘
pstack


多线程调试的问题和解决:
基本问题是在一个Linux环境中,调试多线程程序不正常,info threads看不到多线程的信息。
我先用命令maintenance print target-stack看了一下target的装载情况,发现target"multi-thread"没有被装载,用GDB对GDB进行调试,发现在 函数check_for_thread_db在调用libthread_db中的函数td_ta_new的时候,返回了TD_NOLIBTHREAD,所 以没有装载target"multi-thread"。
在时候我就怀疑是不是libpthread有问题,于是检查了一下发现了问题,这个环境中的libpthread是被strip过的,我想可能 就是以为这个影响了td_ta_new对libpthread符号信息的获取。当我换了一个没有strip过的libpthread的时候,问题果然解决 了。
最终我的解决办法是拷贝了一个.debug版本的libpthread到lib目录中,问题解决了。
多线程如果dump,多为段错误,一般都涉及内存非法读写。可以这样处理,使用下面的命令打开系统开关,让其可以在死掉的时候生成core文件。
ulimit -c unlimited
这样的话死掉的时候就可以在当前目录看到core.pid(pid为进程号)的文件。接着使用gdb:
gdb ./bin ./core.pid
进去后,使用bt查看死掉时栈的情况,在使用frame命令。

还有就是里面某个线程停住,也没死,这种情况一般就是死锁或者涉及消息接受的超时问题(听人说的,没有遇到过)。遇到这种情况,可以使用:
gcore pid (调试进程的pid号)
手动生成core文件,在使用pstack(linux下好像不好使)查看堆栈的情况。如果都看不出来,就仔细查看代码,看看是不是在if,return,break,continue这种语句操作是忘记解锁,还有嵌套锁的问题,都需要分析清楚了

GDB调试总结

上一篇:【DB宝49】Oracle如何设置DB、监听和EM开机启动


下一篇:MySQL多表与事务