gdb多线程/多进程(守护进程)调试 一 调试多进程 1) follow-fork-mode : set follow-fork-mode [parent|child] parent: fork之后继续调试父进程,子进程不受影响。 child: fork之后调试子进程,父进程不受影响。 在使用如下方法设置完要调试的程序后: gdb命令行的 –-args 参数 gdb环境中 set args命令。 gdb --pid=PID(ps -ef | grep your_prog) 如果需要调试子进程,在启动gdb后: (gdb) set follow-fork-mode child 并在子进程代码设置断点。 此外还有detach-on-fork参数,指示GDB在fork之后是否断开(detach)某个进程的调试,或者都交由GDB控制: set detach-on-fork [on|off] on: 断开调试follow-fork-mode指定的进程。 off: gdb将控制父进程和子进程。follow-fork-mode指定的进程将被调试,另一个进程置于暂停(suspended)状态。 由于follow-fork-mode的调试必然是从父进程开始的,对于fork多次,调试起来并不方便。 2) attach调试: GDB有附着(attach)到正在运行的进程的功能,即attach <pid>命令。因此可以利用该命令attach到子进程然后进行调试。通过ps和pstree可以查看到所要调试的子进程pid。 问题是,子进程一直在运行,attach上去后都不知道运行到哪里了。一个办法是,在要调试的子进程初始代码中,加入一段特殊代码,使子进程在某个条件成立时便循环睡眠等待,attach到进程后在该代码段后设上断点,再把成立的条件取消,使代码可以继续执行下去。 Attach进程方法还是很方便的,它能够应付各种各样复杂的进程系统,比如孙子/曾孙进程,比如守护进程(daemon process),唯一需要的就是加入一小段代码。适合于各种复杂情况,特别是守护进程。 3) gdb wrapper: 专用于fork+exec模式,不用添加额外代码,但需要X环境支持(xterm/VNC)。 可参考: 二 调试多进程 GDB多线程调试的基本命令: info threads 查看当前进程的线程。 thread <ID> 切换调试的线程为指定ID的线程。 break [LOCATION] [thread THREADNUM] [if CONDITION] 在[LOCATION]处为[thread THREADNUM]设置断点在满足条件[if CONDITION]时停住 。 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过一个函数的情况(熟悉情况的人可能知道,这其实是一个设置断点然后continue的行为)以外,只有当前线程会执行。 other: gdb中的变量以$开头,比如你想打印一个数组中的个个元素,你可以这样: (gdb) set $i = 0 (gdb) p a[$i++] 调试宏:在GCC编译程序的时候,加上-ggdb3参数,就可以了 info macro – 你可以查看这个宏在哪些文件里被引用了,以及宏定义是什么样的。 macro – 你可以查看宏展开的样子。 x命令是用来查看内存的,在gdb中 “help x” 你可以查看其帮助。 x/x 以十六进制输出 x/d 以十进制输出 x/c 以单字符输出 x/i 反汇编 – 通常,我们会使用 x/10i $ip-20 来查看当前的汇编($ip是指令寄存器) x/s 以字符串输出 command命令,其就是把一组gdb的命令打包,有点像字处理软件的“宏”。 (gdb) command 1 Type commands for when breakpoint 1 is hit, one per line. End with a line saying just "end". >print arg1 >print arg2 >print arg3 >end (gdb) 参考: |
|
来自: Frank__Library > 《linux》