gdb启动多进程程序并切换调试进程

前言

gdb是linux环境下调试C/C++程序的强大工具,但是最近在使用gdb启动一个多进程程序的时候总是意外退出,显示信息中包含Detaching after fork from child process 25377.这一句,而用attach命令附加到正在运行的进程却没有问题,因为需要调试启动逻辑的部分代码,所以必须使用gdb启动多进程程序,后来发现可以通过gdb的follow-fork-mode选项来切换进程,达到调试指定进程的目的。

使用方法

1
set follow-fork-mode [parent|child]

这个命令只要gdb启动程序之后,在运行r命令之前敲入即可,如果不设置默认是parent模式,如果调试的child模式,就需要手动切换,我遇到的问题就是,程序启动使用fork()函数创建出子进程之后就把父进程退出了,gdb默认调试parent进程,也跟着结束了,所以出现了之前所说的Detaching after fork from child process 25377.信息,接下来可以写个简单的例子测试一下。

测试环境

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[albert@localhost#20:15:45#/home/albert/gdbtest]$cat /etc/issue
CentOS release 6.3 (Final)
Kernel \r on an \m

[albert@localhost#20:16:25#/home/albert/gdbtest]$gdb --version
GNU gdb (GDB) Red Hat Enterprise Linux (7.2-83.el6)
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
[albert@localhost#20:16:36#/home/albert/gdbtest]$^C

具体例子

  1. 先写一个简单的多进程程序,模拟我遇到的问题,父进程退出,子进程继续工作

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    #include <unistd.h>
    #include <stdlib.h>

    int main ()
    {
    pid_t pid; //pid表示fork函数返回的值,会根据不同进程返回不同值
    pid = fork();
    if (pid < 0)
    {
    exit(-1);
    }
    else if (pid == 0) // 子进程返回pid为0
    {
    unsigned int u = 0;
    while(true)
    {
    ++u;
    sleep(1);
    }
    }
    else // 父进程返回pid为子进程的id,大于0
    {
    exit(1);
    }
    return 0;
    }
  2. 将代码编译成可执行程序

    1
    [albert@localhost#20:04:31#/home/albert/gdbtest]$g++ multiprocess.cpp -o multiprocess
  3. gdb启动程序并运行,其中我只输入了rq两个gdb命令,发现程序运行r之后输出几行信息就退出了

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    [albert@localhost#20:04:45#/home/albert/gdbtest]$gdb ./multiprocess
    GNU gdb (GDB) Red Hat Enterprise Linux (7.2-83.el6)
    Copyright (C) 2010 Free Software Foundation, Inc.
    License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
    This is free software: you are free to change and redistribute it.
    There is NO WARRANTY, to the extent permitted by law. Type "show copying"
    and "show warranty" for details.
    This GDB was configured as "x86_64-redhat-linux-gnu".
    For bug reporting instructions, please see:
    <http://www.gnu.org/software/gdb/bugs/>...
    Reading symbols from /home/albert/gdbtest/multiprocess...(no debugging symbols found)...done.
    (gdb) r
    Starting program: /home/albert/gdbtest/multiprocess
    warning: the debug information found in "ld-2.12.so.debug" does not match "ld-linux-x86-64.so.2" (CRC mismatch).
    warning: the debug information found in "ld-2.12.so.debug" does not match "ld-linux-x86-64.so.2" (CRC mismatch).
    warning: the debug information found in "libm-2.12.so.debug" does not match "libm.so.6" (CRC mismatch).
    warning: the debug information found in "libm-2.12.so.debug" does not match "libm.so.6" (CRC mismatch).
    warning: the debug information found in "libc-2.12.so.debug" does not match "libc.so.6" (CRC mismatch).
    warning: the debug information found in "libc-2.12.so.debug" does not match "libc.so.6" (CRC mismatch).

    Detaching after fork from child process 25377.

    Program exited with code 01.
    Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.209.el6_9.2.x86_64 libstdc++-4.4.7-18.el6_9.2.x86_64
    (gdb) q
    [albert@localhost#20:05:03#/home/albert/gdbtest]
  4. 使用set follow-fork-mode child命令调试子进程,在r之前输入即可,这次发现程序停在了[New process 27522],此时就可以打断点调试了

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    [albert@localhost#20:23:12#/home/albert/gdbtest]$gdb ./multiprocess
    GNU gdb (GDB) Red Hat Enterprise Linux (7.2-83.el6)
    Copyright (C) 2010 Free Software Foundation, Inc.
    License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
    This is free software: you are free to change and redistribute it.
    There is NO WARRANTY, to the extent permitted by law. Type "show copying"
    and "show warranty" for details.
    This GDB was configured as "x86_64-redhat-linux-gnu".
    For bug reporting instructions, please see:
    <http://www.gnu.org/software/gdb/bugs/>...
    Reading symbols from /home/albert/gdbtest/multiprocess...(no debugging symbols found)...done.
    (gdb) set follow-fork-mode child
    (gdb) r
    Starting program: /home/albert/gdbtest/multiprocess
    warning: the debug information found in "ld-2.12.so.debug" does not match "ld-linux-x86-64.so.2" (CRC mismatch).
    warning: the debug information found in "ld-2.12.so.debug" does not match "ld-linux-x86-64.so.2" (CRC mismatch).
    warning: the debug information found in "libm-2.12.so.debug" does not match "libm.so.6" (CRC mismatch).
    warning: the debug information found in "libm-2.12.so.debug" does not match "libm.so.6" (CRC mismatch).
    warning: the debug information found in "libc-2.12.so.debug" does not match "libc.so.6" (CRC mismatch).
    warning: the debug information found in "libc-2.12.so.debug" does not match "libc.so.6" (CRC mismatch).
    [New process 27522]

    ^C
    Program received signal SIGINT, Interrupt.
    [Switching to process 27522]
    0x00007ffff7354c30 in __nanosleep_nocancel () from /lib64/libc.so.6
    Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.209.el6_9.2.x86_64 libstdc++-4.4.7-18.el6_9.2.x86_64
    (gdb) b multiprocess.cpp:17

总结

  1. gdb调试多进程程序时使用set follow-fork-mode [parent|child]命令
  2. 默认调试parent进程,想调试child进程,使用set follow-fork-mode child命令切换
Albert Shi wechat
欢迎您扫一扫上面的微信公众号,订阅我的博客