GDB的进阶使用
上一篇文章简单介绍了一下gdb调试工具的基本用法,这里再深入一些。
1,控制输出格式
1 (gdb)p/x var #按十六进制格式输出,或p/a var 2 (gdb)p/c var #按字符格式输出 3 (gdb)p/u var #无符号整型 4 (gdb)p/o var #八进制 5 (gdb)p/t var #二进制 6 (gdb)p/f var #浮点型
2,自动显示,可以设置一些变量在程序停下来时或单步运行时,自动打印出来
1 (gdb)display varlist 2 (gdb)display/i varlist #输出格式为汇编
3,查看内存中的值
(gdb)x/nfu &var #注意命令后面必须跟的是个地址(或指针)
n 是个正整数,表示显示内存的长度;
f表示显示的方式,跟上面描述的print所带的格式一致;
u表示一个地址单元的长度,默认是4bytes,可以设置为:b表示单字节,h表示双字节,w表示四字节,g表示八字节;
这三个选项可以叠加使用。
4,为停止点设置运行命令
(gdb) break foo if x > 0 #断点设在函数foo,当x>0时停止, commands #转而执行command下面的命令, printf "x is %d\n",x continue end #直到end
5,执行shell命令
(gdb)shell command #command 可以是shell环境下的任意命令,如clear,make
6,调试正在运行的程序
linux$gdb ./test pid
或者
linux$gdb
(gdb)attach pid # 加载
... # 正常的调试操作
(gdb)detach # 卸载
7,调试core文件
当出现内存非法访问时,一般会dump进程的镜像到core文件,可以通过ulimit命令查看或设置其大小。
linux$ulimit -c 1024
linux$gdb ./test core
(gdb)where #将会打印当前的堆栈信息,以及出问题的行
8,调试多进程(除了下面介绍的方法,还可以用attach pid的方法)
set follow-fork-mode [parent|child]
- parent: fork之后继续调试父进程,子进程不受影响,系统默认;
- child: fork之后调试子进程,父进程不受影响。
(gdb)set follow-fork-mode child #调试子进程
set detach-on-fork [on|off]
- on: 断开调试follow-fork-mode指定的进程;
- off: gdb将控制父进程和子进程。follow-fork-mode指定的进程将被调试,另一个进程置于暂停(suspended)状态。
多进程调试实例:
1 (gdb) b main 2 (gdb) set follow-fork-mode child 3 (gdb) set detach-on-fork off 4 (gdb) r 5 (gdb) c 6 (gdb) n 7 (gdb) detach 8 (gdb) n 9 (gdb) c
9,调试多线程
1 (gdb)info threads #显示当前可调试的线程 2 (gdb)thread ID #切换到指定ID的线程 3 (gdb)break test.c:11 thread all #所有线程设置断点 4 (gdb)thread apply ID1 ID2 command #所有线程执行GDB命令 5 (gdb)set scheduler-locking off|on|step
#off 不锁定任何线程,当被调试线程执行时,其它线程也执行,默认情况;
#on 锁定当前线程;
#step 在单步的时候,除了next过一个函数的情况以外,只有当前线程会执行。
10,调试带参数的程序
1 (gdb) r input output #把input、output作为程序的参数传入 2 (gdb) set args -x -i input -o output # "-x -i input -o output"
浙公网安备 33010602011771号