一、简介
GDB是一个由GNU开源组织发布的、UNIX/LINUX操作系统下的、基于命令行的、功能强大的程序调试工具。目前gdb v10.1,默认支持ada、asm、c、c++、d、fortran、go、minimal、modula-2、objective-c、opencl、pascal、rust语言。
程序员在编译程序时,需加上-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使程序运行到断点处。
可见临时断点已删除。
输入next和step都可单步运行程序,只是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表示显示方式,可取如下值
- x 按十六进制格式显示变量。
- d 按十进制格式显示变量。
- u 按十进制格式显示无符号整型。
- o 按八进制格式显示变量。
- t 按二进制格式显示变量。
- a 按十六进制格式显示变量。
- i 指令地址格式
- c 按字符格式显示变量。
- f 按浮点数格式显示变量
u表示一个地址单元的长度,可取如下值
- b表示单字节 1 byte
- h表示双字节 2 byte
- w表示四字节 4 byte
- 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显示当前函数栈帧情况