GDB调试多进程

Gdb调试多进程程序

程序经常使用fork/exec创建多进程程序。多进程程序有自己独立的地址空间,这是多进程调试首要注意的地方。Gdb功能强大,对调试多线程提供很多支持。

方法1:调试多进程最土的办法:attach pid

Attach是调试进程的常用办法,只要有可执行程序以及相应PID,即可工作。当然,为方便调试,可以在进程启动后,设定sleep一段时间,如30s,这样即可有充足的时间来attach。

方法2: set follow-fork-mode child + main断点

当设置set follow-fork-mode child,gdb将在fork之后直接执行子进程,知道碰到断点后停止。如何设置子进程的断点呢?在父进程中是无法知道子进程的地址空间的(只有等程序载入后方可知)。Gdb提供一个很方便的机制:main函数的断点将被子进程继承(毕竟main是任何程序的入口)。

注意:程序在main停下后,可尝试设置断点。断点是否有效,取决于gdb是否已经载入目标程序的地址空间。

方法3: set follow-fork-mode child + catch exec

Cache点是一种特殊的breakpoint。Gdb能够catch的事件很多,如throw/catch/exception/syscall/exec/fork/vfork等。其中和多进程关系最大的就是exec/fork事件。

举例:

?
GNU gdb Fedora (6.8-27.el5)
Copyright (C) 2008 Free Software Foundation, Inc.
(gdb) catch exec
Catchpoint 1 (exec)
(gdb) set follow-fork-mode child
(gdb) r  -d ***
Catchpoint 1 (exec'd /****/ binary), 0x0000003c68800a70 in _start ()
    from /lib64/ld-linux-x86-64.so.2
(gdb) bt
#0  0x0000003c68800a70 in _start () from /lib64/ld-linux-x86-64.so.2
#1  0x0000000000000003 in ?? ()
#2  0x00007fff65c6e85a in ?? ()
#3  0x00007fff65c6e85d in ?? ()
#4  0x00007fff65c6e860 in ?? ()
(gdb) b lib.cc:8720
No symbol table is loaded.  Use the "file" command.
(gdb) c
Continuing
(gdb) bt
#0  0x0000003c68800a70 in _start () from /lib64/ld-linux-x86-64.so.2
#1  0x0000000000000002 in ?? ()
#2  0x00007fff1af7682a in ?? ()
#3  0x0000000000000000 in ?? ()
(gdb)  b lib.cc:8720
Breakpoint 2 at 0x15f9694: file lib.cc, line 8720.
(gdb) c
Continuing.
[Thread debugging using libthread_db enabled]
[Thread 0x40861940 (LWP 12602) exited]
[Switching to process 12630]
0x0000003c6980d81c in vfork () from /lib64/libpthread.so.0
Warning:
Cannot insert breakpoint 2.
Error accessing memory address 0x15f9694: Input/output error.
(gdb) bt
#0  0x0000003c6980d81c in vfork () from /lib64/libpthread.so.0
#1  0x000000000040c3fb in ?? ()
#2  0x00002adeab604000 in ?? ()
#3  0x01000000004051ef in ?? ()
#4  0x00007fffff4a42f0 in ?? ()
#5  0x686365746e6f6972 in ?? ()
#6  0x0000000d0000000c in ?? ()
#7  0x0000000b0000000a in ?? ()
#8  0x0000000000000000 in ?? ()
(gdb) delete 2  --此处当breakpoint无效时,必须删除,否则程序无法继续
(gdb) c
Continuing.
[New process 12630]
Executing new program: /****/ binary
warning: Cannot initialize thread debugging library: generic error
[Switching to process 12630]
  
Catchpoint 1 (exec'd /****/ binary), 0x0000003c68800a70 in _start ()
    from /lib64/ld-linux-x86-64.so.2
(gdb) bt
#0  0x0000003c68800a70 in _start () from /lib64/ld-linux-x86-64.so.2
#1  0x0000000000000009 in ?? ()
Backtrace stopped: previous frame inner to this frame (corrupt stack?)
(gdb) b lib.cc:8720
Breakpoint 4 at 0x15f9694: file lib.cc, line 8720.
(gdb) b type.cc:32
Breakpoint 5 at 0x1693050: file type.cc, line 32.
(gdb) c
Continuing.
(gdb)  -- 和正常程序调试一样

 

说明:catch exec后,程序将在fork/vfork/exec处停下。并非每次停下后,设置断点都是有效的。如提供断点无效,需要删除,否则程序无法继续。要能够在新进程中设置断点,一定要等到新进程的地址空间被载入后,设置断点是才有效(exec将改变原程序的地址空间)。上述例子,主要想展示如何对新进程设置断点!

注意:
1)程序地址非常重要(代码和数据地址一样重要)。使用gdb时,多多注意和利用地址信息。
2)On some systems, when a child process is spawned by vfork, you cannot debug the child or parent until an exec call completes.

方法4info inferiors/inferiors inferiors

设置set detach-on-fork off/set follow-exec-mode new

If you choose to set `detach-on-fork' mode off, then gdb will retain control of all forked processes (including nested forks). You can list the forked processes under the control of gdb by using the info inferiors command, and switch from one fork to another by using the inferior command.

所使用的gdb不支持set detach-on-fork off/set follow-exec-mode new/info inferiors。不清楚。

转载于:https://www.cnblogs.com/cliuwei/p/4654363.html

<think>好的,用户想了解如何使用GDB调试多进程程序,特别是设置调试进程的方法。首先,我需要回忆GDB处理多进程调试的相关命令和策略。记得GDB默认是跟踪父进程,子进程会继续运行不受控制,所以需要配置才能调试子进程。 接下来,应该分步骤说明不同的方法。首先想到的是`follow-fork-mode`,这个选项可以设置为父进程或子进程。需要详细解释如何设置,比如在启动GDB后使用`set follow-fork-mode child`来跟踪子进程,或者用`parent`保持默认。还要提到`show follow-fork-mode`来查看当前模式。 然后,另一个相关的是`detach-on-fork`,它决定在fork之后GDB是否保持对其他进程的控制。如果设置为off,GDB会同时控制父进程和子进程,这时候可能需要配合`inferior`命令来切换不同的进程。这部分需要举例说明,比如切换inferior编号,以及如何查看当前进程。 另外,用户可能需要附加到已运行的进程上,所以需要提到`attach`命令的用法,结合进程ID。还有在代码中插入断点或者`sleep`的方法,以便有时间附加到子进程。 还需要注意不同GDB版本的差异,比如某些命令可能在旧版本中不可用。此外,多线程和多进程的区别可能让用户混淆,需要明确说明这里是多进程的情况。 最后,总结常用方法,提醒用户根据具体情况选择跟踪模式或手动附加,并给出示例命令。确保步骤清晰,让用户能逐步操作,并验证是否有效。可能还要提醒检查GDB版本,或者如何处理常见问题,比如无法附加进程时的权限问题。</think>GDB调试多进程程序时,可通过以下方法设置调试目标进程: ===== 1. 基础设置 ===== 在GDB中通过命令控制fork后的跟踪目标: ```gdb (gdb) set follow-fork-mode parent|child # 设置跟踪父/子进程 (gdb) set detach-on-fork on|off # 控制是否分离未跟踪进程 ``` 示例场景: ```c // 示例代码片段 pid_t pid = fork(); if (pid == 0) { child_process(); // 子进程代码 } else { parent_process(); // 父进程代码 } ``` ===== 2. 多进程调试模式 ===== ◆ 模式1:跟踪单个进程 ```gdb # 默认跟踪父进程 (gdb) set follow-fork-mode parent (gdb) set detach-on-fork on # 或跟踪子进程 (gdb) set follow-fork-mode child ``` ◆ 模式2:同时调试多个进程 ```gdb (gdb) set detach-on-fork off # 保留所有fork的进程 (gdb) info inferiors # 查看进程列表 (gdb) inferior 2 # 切换到第二个进程 ``` ===== 3. 高级调试技巧 ===== ▶ 附加调试已有进程 ```bash # 在终端获取子进程PID ps -ef | grep [程序名] # 在GDB中附加 (gdb) attach <pid> ``` ▶ 代码层控制 ```c // 在子进程代码开始处添加调试桩 void child_process() { volatile int wait_gdb = 1; while(wait_gdb); // 在此处设置断点 //...实际代码... } ``` ===== 4. 验证设置 ===== 调试时使用以下命令确认状态: ```gdb (gdb) show follow-fork-mode # 显示当前跟踪模式 (gdb) info inferiors # 列出所有被控进程 (gdb) inferior # 显示当前调试的进程 ``` ===== 注意事项 ===== 1. Linux内核≥3.9需设置: ```bash echo 0 > /proc/sys/kernel/yama/ptrace_scope ``` 2. 建议使用GDB≥7.0版本 3. 多进程调试时注意断点设置位置(不同进程地址空间独立) 典型调试流程示例: ```gdb $ gdb ./multi_process_prog (gdb) b main (gdb) set detach-on-fork off (gdb) r # 程序fork后暂停 (gdb) info inferiors Num Description Executable 1 process 1234 multi_process_prog 2 process 5678 multi_process_prog (gdb) inferior 2 (gdb) b child_func (gdb) c ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值