一、简介

GDB是一个由GNU开源组织发布的、UNIX/LINUX操作系统下的、基于命令行的、功能强大的程序调试工具。目前gdb v10.1,默认支持ada、asm、c、c++、d、fortran、go、minimal、modula-2、objective-c、opencl、pascal、rust语言。

gdb默认支持的语言

程序员在编译程序时,需加上-g参数,方可将调试信息植入可执行程序,然后运行gdb *.exe 才可对程序进行调试。

编译时添加调试信息

调试思路一般是进入程序,设置断点,即让程序运行到断点处自动停止,然后单步运行程序,可单步运行高级语言程序,也可单步运行汇编代码。在程序员自己单步运行程序的时候,程序员可以查看内存栈的信息,寄存器的信息、内存信息、程序中变量等。根据这些信息对程序的bug进行定位。

二、单进程/线程

下面以调试0~10累加为例,介绍gdb调试单进程/线程程序。

源码:

输入命令:gdb testgdb3或者gdb --se testgdb3均可调试界面。

输入 list(简写l)可显示代码。

输入break(简写b)$line_number可给程序加上断点。

输入tbreak $line_nunber可给第$line_number加上只起一次作用的临时断点。

输入info breakpoints可显示该程序的所有断点。

其中Type列表示point类型(breakpoint,watchpoint,catchpoint),Disp列表示当程序运行到该point时,该point是否删除,Enb列表示该point是否生效。

输入run使程序运行到断点处。

可见临时断点已删除。

输入nextstep都可单步运行程序,只是step会进入子函数内部,next则不进入子函数内部。

输入info local可显示程序运行到此处时,附近的变量值。

输入display $var可在单步运行时自动显示$var的值。

输入bt可显示当前程序堆栈函数调用信息。

输入disas可显示程序的汇编语言。

输入stepi可单步运行汇编语言。

输入info registers可显示当前程序用到的寄存器信息。

输入display $eax可显示eax寄存器内容。

输入display /i $pc可显示pc指针内容。

显示内存信息

x /nfu $memory_address

n表示要显示的内存单元的个数

f表示显示方式,可取如下值

  1. x 按十六进制格式显示变量。
  2. d 按十进制格式显示变量。
  3. u 按十进制格式显示无符号整型。
  4. o 按八进制格式显示变量。
  5. t 按二进制格式显示变量。
  6. a 按十六进制格式显示变量。
  7. i 指令地址格式
  8. c 按字符格式显示变量。
  9. f 按浮点数格式显示变量

u表示一个地址单元的长度,可取如下值

  1. b表示单字节 1 byte
  2. h表示双字节 2 byte
  3. w表示四字节 4 byte
  4. g表示八字节 8 byte

三、多线程

下面以调试一个简单的多线程为例,介绍gdb调试多线程的命令。

源码:

输入info threads查看线程。

输入thread $thread_id切换线程。

输入set scheduler-locking off不锁定任何线程,所有线程都执行。

输入set scheduler-locking on只有当前被调试程序会执行。

输入thread apply all next让所有线程都执行run命令。

输入thread apply 2 next让2号线程执行next命令。

四、调试core文件

输入gdb $exefFile $coreFile命令

五、常用命令汇总

1. gdb --silent

进入gdb时,会有gdb版本信息、license信息等。

如果想不显示这些信息,在调用gdb时加上参数 --silent。

2. set listsize $line_size

改变list命令显示的代码行数。

3.disable $breakpoints_id,使断点失效

4.clear $line_number,删除断点

5.info frame显示当前函数栈帧情况