内容来自牛客C++高薪面试项目2.5节,视频链接:https://www.nowcoder.com/study/live/504/2/5
命令简介
使用GDB 调试的时候,GDB 默认只能跟踪一个进程,可以在fork 函数调用之前,通过指令设置GDB 调试工具跟踪父进程或者是跟踪子进程,默认跟踪父进程。
- 设置调试父进程或者子进程:
set follow-fork-mode [parent(默认)| child]
- 设置调试模式:
set detach-on-fork [on | off]
- 默认为on,表示调试当前进程的时候,其它的进程继续运行
- 如果为off,调试当前进程的时候,其它进程被GDB 挂起。
- 查看调试的进程:
info inferiors
- 切换当前调试的进程:
inferior id
- 使进程脱离GDB 调试:
detach inferiors id
实例
- 编译文件:
gcc hello.c -o hello -g
- 启动GDB调试:
gdb hello
- 分别在父进程和子进程里面打断点,并查看断点信息:
(gdb) b 10 Breakpoint 1 at 0x4006b9: file hello.c, line 10. (gdb) b 20 Breakpoint 2 at 0x40070b: file hello.c, line 20. (gdb) i b Num Type Disp Enb Address What 1 breakpoint keep y 0x00000000004006b9 in main at hello.c:10 2 breakpoint keep y 0x000000000040070b in main at hello.c:20
- 启动调试程序,默认是对父进程代码进行的调试,使用
set follow-fork-mode child
切换到子进程:(gdb) r Starting program: /home/wzy1999/cpp/nowcoder/chapter02/lesson03-05/hello begin [Attaching after process 21220 fork to child process 21220] [New inferior 3 (process 21220)] [Detaching after fork from parent process 21219] [Inferior 2 (process 21219) detached] 我是父进程:pid = 21219, ppid = 20241 i = 0 [Switching to process 21220] Breakpoint 2, main () at hello.c:20 20 printf("我是子进程:pid = %d, ppid = %d\n", getpid(), getppid()); (gdb) i = 1 i = 2 i = 3 i = 4 i = 5 i = 6 i = 7 i = 8 i = 9 n 我是子进程:pid = 21220, ppid = 1 23 for(j = 0; j < 10; j++) { (gdb) n 24 printf("j = %d\n", j); (gdb) n j = 0 25 sleep(1); (gdb) n 23 for(j = 0; j < 10; j++) { (gdb) n 24 printf("j = %d\n", j); (gdb) c Continuing. j = 1 j = 2 j = 3 j = 4 j = 5 j = 6 j = 7 j = 8 j = 9 [Inferior 3 (process 21220) exited normally]
- 在对子进程进行调试时,父进程是会继续运行的,使用
set detach-on-fork off
挂起父进程:(gdb) set detach-on-fork off (gdb) r Starting program: /home/wzy1999/cpp/nowcoder/chapter02/lesson03-05/hello begin [Attaching after process 22326 fork to child process 22326] [New inferior 4 (process 22326)] [Switching to process 22326] Breakpoint 2, main () at hello.c:20 20 printf("我是子进程:pid = %d, ppid = %d\n", getpid(), getppid()); Missing separate debuginfos, use: debuginfo-install glibc-2.17-323.el7_9.x86_64 (gdb) n 我是子进程:pid = 22326, ppid = 22325 23 for(j = 0; j < 10; j++) { (gdb) n 24 printf("j = %d\n", j); (gdb) n j = 0 25 sleep(1); (gdb) n 23 for(j = 0; j < 10; j++) { (gdb) n 24 printf("j = %d\n", j); (gdb) c Continuing. j = 1 j = 2 j = 3 j = 4 j = 5 j = 6 j = 7 j = 8 j = 9 [Inferior 4 (process 22326) exited normally]
- 使用
info inferiors
查看当前调试的进程,并使用inferior id
切换到父进程,注意这里的id是info inferiors
显示出来的num:(gdb) r Starting program: /home/wzy1999/cpp/nowcoder/chapter02/lesson03-05/hello begin [Attaching after process 22853 fork to child process 22853] [New inferior 5 (process 22853)] Reading symbols from /home/wzy1999/cpp/nowcoder/chapter02/lesson03-05/hello...done. [Switching to process 22853] Breakpoint 2, main () at hello.c:20 20 printf("我是子进程:pid = %d, ppid = %d\n", getpid(), getppid()); Missing separate debuginfos, use: debuginfo-install glibc-2.17-323.el7_9.x86_64 (gdb) info inferiors Num Description Executable * 5 process 22853 /home/wzy1999/cpp/nowcoder/chapter02/lesson03-05/hello 4 process 22852 /home/wzy1999/cpp/nowcoder/chapter02/lesson03-05/hello 3 process 22325 /home/wzy1999/cpp/nowcoder/chapter02/lesson03-05/hello 2 <null> /home/wzy1999/cpp/nowcoder/chapter02/lesson03-05/hello 1 <null> /home/wzy1999/cpp/nowcoder/chapter02/lesson03-05/hello (gdb) n 我是子进程:pid = 22853, ppid = 22852 23 for(j = 0; j < 10; j++) { (gdb) inferior 4 [Switching to inferior 4 [process 22852] (/home/wzy1999/cpp/nowcoder/chapter02/lesson03-05/hello)] [Switching to thread 3 (process 22852)] #0 0x00007ffff7ad2a02 in fork () from /lib64/libc.so.6 (gdb) n Single stepping until exit from function fork, which has no line number information. Breakpoint 1, main () at hello.c:10 10 printf("我是父进程:pid = %d, ppid = %d\n", getpid(), getppid()); (gdb) info inferiors Num Description Executable 5 process 22853 /home/wzy1999/cpp/nowcoder/chapter02/lesson03-05/hello * 4 process 22852 /home/wzy1999/cpp/nowcoder/chapter02/lesson03-05/hello 3 process 22325 /home/wzy1999/cpp/nowcoder/chapter02/lesson03-05/hello 2 <null> /home/wzy1999/cpp/nowcoder/chapter02/lesson03-05/hello 1 <null> /home/wzy1999/cpp/nowcoder/chapter02/lesson03-05/hello
- 使用
detach inferiors id
可以使进程脱离GDB调试,和continue的效果类似,进程执行完之后,Description
会变成<null>