天天看点

Linux之gdb基本调试命令与总结

一、常见gdb调试命令

表1 gdb基本调试指令

命令 描述
backtrace(或bt) 查看各级函数调用及参数
finish 连续运行到当前函数返回为止,然后停下来等待命令
frame(或f) 帧编号 选择栈帧
info(或i) locals 查看当前栈帧局部变量的值
list(或l) 列出源代码,接着上次的位置往下列,每次列10行
continue(c) 列出从第几行开始的源代码
list 函数名 继续执行
next(或n) 执行下一行语句
print(或p) 打印表达式的值,通过表达式可以修改变量的值或者调用函数
quit(或q) 退出

gdb

调试环境
set var 修改变量的值
start 开始执行程序,停在

main

函数第一行语句前面等待命令
step(或s) 执行下一行语句,如果有函数调用则进入到函数中
break(b) 设置断点
delete(d) 删除断点
attach <pid> attach到进程 ID 为 pid 的进程

二、info调试指令

表2 info调试命令

命令 描述
info registers 查看除了浮点寄存器以外的寄存器
info all-registers 查看所有寄存器,包括浮点寄存器
info registers <regname …> 查看所指定的寄存器
info break 查看断点信息
info watchpoints  列出当前所设置的所有观察点
info signals info handle 查看有哪些信号正在被GDB检测
info frame 查看当前程序栈的信息
info threads 可以看多线程
info args 查看当前函数参数信息
info locals 查看当前程序栈的局部变量

三、内存查看

3.1 打印内存数据
gdb查看指定地址的内存地址的值:examine 简写 x-----使用gdb> help x 来查看使用方式
     x/ (n,f,u为可选参数)
n: 需要显示的内存单元个数,也就是从当前地址向后显示几个内存单元的内容,一个内存单元的大小由后面的u定义
f:显示格式
               x(hex) 按十六进制格式显示变量。
               d(decimal) 按十进制格式显示变量。
               u(unsigned decimal) 按十进制格式显示无符号整型。
               o(octal) 按八进制格式显示变量。
               t(binary) 按二进制格式显示变量。
               a(address) 按十六进制格式显示变量。
               c(char) 按字符格式显示变量。
               f(float) 按浮点数格式显示变量
u:每个单元的大小,按字节数来计算。默认是4 bytes。GDB会从指定内存地址开始读取指定字节,并把其当作一个值取出来,并使用格式f来显示
               b:1 byte     h:2 bytes     w:4 bytes g:8 bytes
     比如x/3uh 0x54320表示从内存地址0x54320读取内容,h表示以双字节为单位,3表示输出3个单位,u表示按照十六进制显示。
           

3.2 打印数组

比如我有一个数组的定义 :int a[] = {1, 2, 3, 4, 5};

那么想要显示的时候就可以写:

p *[email protected]
           

这样就会显示数组a中的所有元素。

也可以使用display在一部调试的时候都显示:

display *[email protected]
           

四、多线程调试命令

表4 多线程调试命令

命令 描述
info threads 显示当前可调试的所有线程,每个线程会有一个GDB为其分配的ID,后面操作线程的时候会用到这个ID。 前面有*的是当前调试的线程
thread ID(1,2,3…) 切换当前调试的线程为指定ID的线程
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 off 不锁定任何线程,也就是所有线程都执行,这是默认值
set scheduler-locking on 只有当前被调试程序会执行
set scheduler-locking on step 在单步的时候,除了next过一个函数的情况(熟悉情况的人可能知道,这其实是一个设置断点然后continue的行为)以外,只有当前线程会执行

参考:线程的查看以及利用gdb调试多线程