欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【Linux】gdb调试多进程多线程

程序员文章站 2024-03-17 17:45:28
...

对下面代码进行调试:

#include <stdio.h>
#include <pthread.h>

void processA();
void processB();
void * processAworker(void *arg);

int main(int argc, const char *argv[])
  {
  int pid;

  pid = fork();

  if(pid != 0)
    processA();
  else
    processB();

  return 0;
  }

void processA()
  {
  pid_t pid = getpid();
  char prefix[] = "ProcessA: ";
  char tprefix[] = "thread ";
  int tstatus;
  pthread_t pt;

  printf("%s%lu %s\n", prefix, pid, "step1");

  tstatus = pthread_create(&pt, NULL, processAworker, NULL);
  if( tstatus != 0 )
    {
    printf("ProcessA: Can not create new thread.");
    }

  processAworker(NULL);
  sleep(1);
  }

void * processAworker(void *arg)
  {
  pid_t pid = getpid();
  pthread_t tid = pthread_self();
  char prefix[] = "ProcessA: ";
  char tprefix[] = "thread ";

  printf("%s%lu %s%lu %s\n", prefix, pid, tprefix, tid, "step2");
  printf("%s%lu %s%lu %s\n", prefix, pid, tprefix, tid, "step3");

  return NULL;
  }

void processB()
  {
  pid_t pid = getpid();
  char prefix[] = "ProcessB: ";
  printf("%s%lu %s\n", prefix, pid, "step1");
  printf("%s%lu %s\n", prefix, pid, "step2");
  printf("%s%lu %s\n", prefix, pid, "step3");

  }

运行结果:
【Linux】gdb调试多进程多线程
【1】多进程调试
1、调试父进程,block子进程

[aaa@qq.com 公共]$ gdb a.out 
GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-100.el7
Copyright (C) 2013 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/billy/公共/a.out...done.
(gdb) aet detach-on-fork off
Undefined command: "aet".  Try "help".
(gdb) set detach-on-fork off
(gdb) show detach-on-fork
Whether gdb will detach the child of a fork is off.
(gdb) catch fork
Catchpoint 1 (fork)
(gdb) r
Starting program: /home/billy/公共/a.out 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".

Catchpoint 1 (forked process 13378), 0x00007ffff78bb291 in fork ()
   from /lib64/libc.so.6
Missing separate debuginfos, use: debuginfo-install glibc-2.17-196.el7.x86_64
(gdb) break test.c :14
Breakpoint 2 at 0x400796: file test.c, line 14.
(gdb) cont
Continuing.
[New process 13378]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
ProcessA: 13374 step1
[New Thread 0x7ffff77fb700 (LWP 13393)]
ProcessA: 13374 thread 140737354004288 step2
ProcessA: 13374 thread 140737354004288 step3
ProcessA: 13374 thread 140737345730304 step2
ProcessA: 13374 thread 140737345730304 step3
[Thread 0x7ffff77fb700 (LWP 13393) exited]
[Inferior 1 (process 13374) exited normally]
Missing separate debuginfos, use: debuginfo-install glibc-2.17-196.el7.x86_64
(gdb) info inferiors
  Num  Description       Executable        
  2    process 13378     /home/billy/公共/a.out 
* 1    <null>            /home/billy/公共/a.out 

2、切换到子进程

(gdb) inferior 2
[Switching to inferior 2 [process 13378] (/home/billy/公共/a.out)]
[Switching to thread 2 (Thread 0x7ffff7fdf740 (LWP 13378))] 
#0  0x00007ffff78bb291 in fork () from /lib64/libc.so.6
(gdb) info inferiors
  Num  Description       Executable        
* 2    process 13378     /home/billy/公共/a.out 
  1    <null>            /home/billy/公共/a.out 
(gdb) iniferior 1
Undefined command: "iniferior".  Try "help".
(gdb) inferior 1
[Switching to inferior 1 [<null>] (/home/billy/公共/a.out)]
(gdb) info inferiors
  Num  Description       Executable        
  2    process 13378     /home/billy/公共/a.out 
* 1    <null>            /home/billy/公共/a.out 
(gdb) 

3、设断点继续调试主进程,主进程产生两个线程

(gdb) break test.c:50
Breakpoint 3 at 0x4008c0: test.c:50. (2 locations)
(gdb) cont
Continuing.
ProcessA: 13815 step1
[New Thread 0x7ffff77fb700 (LWP 13862)]
ProcessA: 13815 thread 140737354004288 step2

Breakpoint 3, processAworker (arg=0x0) at test.c:50
50                                           printf("%s%lu %s%lu %s\n", prefix, pid, tprefix, tid, "step3");
(gdb) info inferiors
  Num  Description       Executable        
  2    process 13819     /home/billy/公共/a.out 
* 1    process 13815     /home/billy/公共/a.out 
(gdb) info threads
  Id   Target Id         Frame 
  3    Thread 0x7ffff77fb700 (LWP 13862) "a.out" 0x00007ffff78f4311 in clone ()
   from /lib64/libc.so.6
  2    Thread 0x7ffff7fdf740 (LWP 13819) "a.out" 0x00007ffff78bb291 in fork ()
   from /lib64/libc.so.6
* 1    Thread 0x7ffff7fdf740 (LWP 13815) "a.out" processAworker (arg=0x0)
    at test.c:50

4、切换到主进程中的子线程,注意线程2是前面产生的子进程

(gdb) thread 3
[Switching to thread 3 (Thread 0x7ffff77fb700 (LWP 13862))]
#0  0x00007ffff78f4311 in clone () from /lib64/libc.so.6
(gdb) cont
Continuing.
ProcessA: 13815 thread 140737345730304 step2
ProcessA: 13815 thread 140737354004288 step3

Breakpoint 3, processAworker (arg=0x0) at test.c:50
50                                           printf("%s%lu %s%lu %s\n", prefix, pid, tprefix, tid, "step3");
(gdb) info threads
  Id   Target Id         Frame 
* 3    Thread 0x7ffff77fb700 (LWP 13862) "a.out" processAworker (arg=0x0)
    at test.c:50
  2    Thread 0x7ffff7fdf740 (LWP 13819) "a.out" 0x00007ffff78bb291 in fork ()
   from /lib64/libc.so.6
  1    Thread 0x7ffff7fdf740 (LWP 13815) "a.out" 0x00007ffff78bb1ad in nanosleep () from /lib64/libc.so.6
(gdb) thread 1
[Switching to thread 1 (Thread 0x7ffff7fdf740 (LWP 13815))]
#0  0x00007ffff78bb1ad in nanosleep () from /lib64/libc.so.6
(gdb) 

上面就是对多进程多线程调试的过程,下面进行介绍所用的命令。
1、默认设置下,在调试多进程程序时gdb只会调试主进程,但是gdb(>v7.0)支持多进程的分别以及同时调试,或者说gdb可以同时调试多个程序,只需要设置follow-fork-mode(默认值:parent)和detach-on-fork(默认值 :on )即可
【Linux】gdb调试多进程多线程
设置方法:

set follow-fork-mode  [parent|child]          set  detach-on-fork   
[on|off]

查询正在调试的进程:

info  inferiors;

切换调试的进程:

inferior <infer number>

添加新线程:

add-inferior [-copies n] [-exec executable]

,可以用

file executable

来分配给inferior可执行文件。
其他:

remove-inferiors infno, detach inferior

2.GDB默认支持调试多线程,跟主线程,子线程block在create thread。
info threads
切换调试线程:

   thread <thread number>