GDB使用memo

分析core文件

加载符号表

生成符号表文件(.debug)

一般来说,为了避免可执行文件或者库文件过大,会采用分离调试信息的编译方式。前提是gcc编译的时候需要带上-g选项,以生成调试信息。通过objcopy实现:

objcopy --only-keep-debug test test.debug 
&& objcopy --strip-debug test 
&& objcopy --add-gnu-debuglink=test.debug test 
&& chmod -x test.debug

Qt可以通过qmake的CONFIG语法实现:

qmake CONFIG+=release CONFIG+=force_debug_info CONFIG+=separate_debug_info test.pro

查看符号表是否加载成功

将生成的.debug文件放在库和可执行文件同一目录下,或者是同一目录下.debug目录下。gdb 可执行文件 coreFile 就会自动加载相关的符号表文件。可以通过info sharedlibrary查看加载是否成功

  • 不成功的情况:
    在这里插入图片描述
    Yes旁边是一个星号,而且只能定位到调用堆栈的哪个调用函数崩溃了

  • 加载成功的情况
    在这里插入图片描述
    Yes旁边没有星号,而且能够定位到代码的哪个文件哪一行语句执行出错了,并且可以查看到相关的入参、变量等。

分析core文件

  • gdb [产生core文件的程序] [core文件]

生成core文件后,使用gdb [可执行程序] [core文件] 分析core文件,在gdb中输入bt,即可查看到崩溃时的堆栈,输入quit则退出gdb.

查看stl容器内容

当 GDB(即 GNU Project Debugger)启动时,它在当前用户的主目录中寻找一个名为 .gdbinit 的文件;如果该文件存在,则 GDB 就可以执行该文件中的所有命令。添加.gdbinit文件到用户目录下即可。

(gdb) pmap
 Prints std::map<TLeft and TRight> or std::multimap<TLeft and TRight> information. Works for std::multimap as well.
 Syntax: pmap <map> <TtypeLeft> <TypeRight> <valLeft> <valRight>: Prints map size, if T defined all elements or just element(s) with val(s)
 Examples:
 pmap m - prints map size and definition
 pmap m int int - prints all elements and map size
 pmap m int int 20 - prints the element(s) with left-value = 20 (if any) and map size
 pmap m int int 20 200 - prints the element(s) with left-value = 20 and right-value = 200 (if any) and map size
 (gdb) q

调试正在运行的程序

sudo gdb -p PID

多线程调试

  • info threads 显示当前可调试的所有线程,每个线程会有一个GDB为其分配的ID,后面操作线程的时候会用到这个ID。 前面有*的是当前调试的线程。

  • thread ID 切换当前调试的线程为指定ID的线程。

  • break thread_test.c:123 thread all 在所有线程中相应的行上设置断点

  • thread apply ID1 ID2 command 让一个或者多个线程执行GDB命令command。

  • thread apply all command 让所有被调试线程执行GDB命令command。

  • set scheduler-locking off|on|step: 估计是实际使用过多线程调试的人都可以发现,在使用step或者continue命令调试当前被调试线程的时候,其他线程也是同时执行的,怎么只让被调试程序执行呢?通过这个命令就可以实现这个需求。off 不锁定任何线程,也就是所有线程都执行,这是默认值。 on 只有当前被调试程序会执行。 step 在单步的时候,除了next过一个函数的情况(熟悉情况的人可能知道,

查看内存值

使用examine命令(简写是x)来查看内存地址中的值。x命令的语法如下:

x/<n/f/u> <addr>
  • n 是一个正整数, 输出单元的个数 ,也就是说从当前地址向后显示几个地址的内容。

  • f 是输出格式。如果地址所指的是 字符串 ,那么格式可以是 s ,如果 地址是指令 地址 ,那么格式可以是 i 。x是以16进制形式输出,o是以8进制形式输出,u是无符号10进制格式。

  • u 表明一个单元的长度,如果不指定的话,GDB默认是4个bytes 。 u 参数可以用下面的字符来代替, b 表示单字节, h 表示双字节, w 表示四字 节, g 表示八字节。当我们指定了字节长度后, GDB 会从指内存定的内存地址开始,读写指定字节,并把其当作一个值取出来。

  • addr 表示一个内存地址。
    在这里插入图片描述

参考

100个gdb小技巧
gdb 调试总结
gdb 多线程调试

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值