Loading... <div class="tip inlineBlock info simple"> 内容来自牛客C++高薪面试项目2.5节,视频链接:https://www.nowcoder.com/study/live/504/2/5 </div> # GDB多进程调试 ## 命令简介 使用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>` Last modification:January 27, 2023 © Allow specification reprint Support Appreciate the author AliPayWeChat Like 0 如果觉得我的文章对你有用,请随意赞赏