GDB调试多进程程序

GDB调试多进程程序

样例程序:

example

程序含义:父进程1通过fork创建一个子进程,该子进程是父进程的副本,共享代码段。

fork()调用之后,父进程的返回值是非零值;子进程的返回值是0

exec()会覆盖其地址空间,所以execlp之后的代码段不会再执行

所以,子进程是执行了10,1314;父进程是执行了10,13,1621。

进行调试:

常见指令:

  1. g++ -g test.c -o test:编译,并且允许gdb调试,编译对象是test.c,编辑结果是可执行文件test

  2. gdb ./test:开始进行调试

  3. break line_num: 设置断点

  4. r/run:开始运行

  5. next:单步调试,不进入子函数

  6. c/continue:继续执行到下一个断点/程序结束

  7. info thread:查看当前程序的线程信息(>=1)

    标星号的表示,当前跟踪的进程

    image-20200927130215464
  8. info inferiors:查看调试的进程:

    标星号的表示当前跟踪的线程

    image-20200927133907126
  9. inferior num:切换进程

对于多进程的调试,需要进行一定的设置。

一般情况下,父进程 fork 一个子进程,GDB只会继续调试父进程而不会管子进程的运行。如果想跟踪子进程进行调试,可以用:

set follow-fork-mode child:当 fork 子进程后,跟踪子进程,而放弃对父进程的跟踪(所以查看线程只会发现当前线程);

set follow-fork-mode parent:默认状态

(show follow-fork-mode :查看当前的跟踪模式)

由于上面的只会关注一个线程,如果想同时调试父子进程,使用:

set detach-on-fork on:只调试进程中的某一个

set detach-on fork off:父子进程都在GDB的控制之下。其中一个进程正常调试,根据follow-fork-mode来决定;另一个进程会被暂停

(show detach-on-fork)

如果子进程使用 exec 系统函数而装载了新程序执行,那么就使用:

set follow-exec-mode new:新建一个 inferior 给执行起来的子进程,而父进程的 inferior 仍然保留

set follow-exec-mode same:默认值

总结:如何使用gdb调试多线程:

  1. 编译,产生可执行文件

  2. 进入GDB调试

  3. 具体调试指令:

    • break 7

    • set detach-on-fork off

    • set follow-fork-mode child

    • run(执行完行7后暂停)

    • info inferiors(未创建 fork 之前)

      image-20200927142112584
    • info threads(未创建 fork 之前)

      image-20200927142050733
    • next

    • next

    • info inferiors(创建 fork 之后)

      image-20200927141907854
    • info threads(创建 fork 之后)

      image-20200927141935482
    • next….(直到子进程运行结束)

    • info inferiors(子进程已经执行结束,只剩下父进程)

      image-20200927141820889
    • inferior 1

    • info inferiors

      image-20200927142305743
    • next….(直到父进程运行结束)

    • info inferiors

      image-20200927142445469

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!