gdb 调试多进程、多线程的小栗子

gdb调试中多线程是一个难点,涉及到诸多线程的相互影响。对于多线程之间的相互影响,这个不在这个小栗子的阐述范围内。这是调试一个简单的子进程中的子线程的小栗子。

使用材料

/*这是一个演示gdb调试子进程、子线程的文件
 */
#include <stdio.h>
#include <pthread.h>

void processSub();
void processMain();
void * threadSub(void *arg);

int main(int argc, const char *argv[])
{
    int pid;
    pid = fork();
    if(pid<0)
    {
        exit(1);
    }else if(0==pid){
        processSub();
    }else{
        processMain();
    }
    return 0;
}
/*子进程处理函数
 */
void processSub()
{
    pid_t pid = getpid();
    char prefix[] = "processSub main thread : ";
    pthread_t thread_id=pthread_self();

    int tstatus;
    pthread_t pt;
    tstatus = pthread_create(&pt, NULL, threadSub, NULL);
    if( tstatus != 0 )
    {
        printf("processSub: Can not create new thread.");
    }
    printf("<%s pid=%lu,thread_id=%lu>\n", prefix, pid,thread_id);
}
/* 子进程的子线程处理函数
 */
void * threadSub(void *arg)
{
    pid_t pid = getpid();
    pthread_t thread_id=pthread_self();
    char prefix[] = "subprocess threadSub: ";
    printf("<%s pid=%lu,thread_id=%lu>\n", prefix, pid,thread_id);
    return NULL;
}
/* 主进程处理函数
 */
void processMain()
{
    pid_t pid = getpid();
    pthread_t thread_id=pthread_self();
    char prefix[] = "processMain: ";
    printf("<%s pid=%lu,thread_id=%lu>\n", prefix, pid,thread_id);
    //在调用子进程之前,主进程不能执行完毕,退出
    sleep(1000);
}

调试过程

1.生成调试文件

[root@localhost test]# gcc gdb_multi.c -g -O0 -Wall -lpthread
//显示信息
gdb_multi.c: 在函数‘main’中:
gdb_multi.c:13:5: 警告:隐式声明函数‘fork’ [-Wimplicit-function-declaration]
     pid = fork();
     ^
...
gdb_multi.c:60:5: 警告:隐式声明函数‘sleep’ [-Wimplicit-function-declaration]
     sleep(1000);
     ^

2.开始调试

[root@localhost test]# 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/gch/test/a.out...done.

3.设置调试子进程

(gdb) set follow-fork-mode child  //指定要调试子进程
(gdb) set detach-on-fork off      //指定其他进程阻塞fork位置
(gdb) show follow-fork-mode //查看设置的信息
Debugger response to a program call of fork or vfork is "child".
(gdb) show detach-on-fork   //查看设置的信息
Whether gdb will detach the child of a fork is off.

4.断点到子进程

(gdb) b 18
Breakpoint 1 at 0x4007ea: file gdb_multi.c, line 18.
(gdb) r
Starting program: /home/gch/test/a.out 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
[New process 13242]
Missing separate debuginfos, use: debuginfo-install glibc-2.17-196.el7.x86_64
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
[Switching to Thread 0x7ffff7fea740 (LWP 13242)]

Breakpoint 1, main (argc=1, argv=0x7fffffffe5a8) at gdb_multi.c:18
18          processSub();
Missing separate debuginfos, use: debuginfo-install glibc-2.17-196.el7.x86_64
(gdb) s
processSub () at gdb_multi.c:28
28      pid_t pid = getpid();
(gdb) n
29      char prefix[] = "processSub main thread : ";
(gdb) 
30      pthread_t thread_id=pthread_self();
(gdb) 
34      tstatus = pthread_create(&pt, NULL, threadSub, NULL);

5.阻塞主线程调试子线程

(gdb) set scheduler-locking on  //调试时,阻塞其他线程
(gdb) show scheduler-locking 
Mode for locking scheduler during execution is "on".

6.查看进程、线程信息

(gdb) n
[New Thread 0x7ffff77fb700 (LWP 13244)]
35      if( tstatus != 0 )
(gdb) info thread           //查看线程信息
  Id   Target Id         Frame 
  3    Thread 0x7ffff77fb700 (LWP 13244) "a.out" 0x00007ffff78f4311 in clone () from /lib64/libc.so.6
* 2    Thread 0x7ffff7fea740 (LWP 13242) "a.out" processSub () at gdb_multi.c:35
  1    Thread 0x7ffff7fea740 (LWP 13238) "a.out" 0x00007ffff78bb291 in fork () from /lib64/libc.so.6
(gdb) info inferior         //查看进程信息
  Num  Description       Executable        
* 2    process 13242     /home/gch/test/a.out 
  1    process 13238     /home/gch/test/a.out 

7.切换到子线程并断点子线程调用的函数

(gdb) thread 3
[Switching to thread 3 (Thread 0x7ffff77fb700 (LWP 13244))]
#0  0x00007ffff78f4311 in clone () from /lib64/libc.so.6
(gdb) b threadSub
Breakpoint 2 at 0x4008b3: threadSub. (2 locations)
(gdb) cont
Continuing.
Breakpoint 2, threadSub (arg=0x0) at gdb_multi.c:45
45      pid_t pid = getpid();
(gdb) n
46      pthread_t thread_id=pthread_self();
(gdb) 
47      char prefix[] = "subprocess threadSub: ";
(gdb) 
48      printf("<%s pid=%lu,thread_id=%lu>\n", prefix, pid,thread_id);
(gdb) 
<subprocess threadSub:  pid=13242,thread_id=140737345730304>
49      return NULL;
(gdb) q
A debugging session is active.

    Inferior 2 [process 13242] will be killed.
    Inferior 1 [process 13238] will be killed.

Quit anyway? (y or n) y
[root@localhost test]# 

ok!

猜你喜欢

转载自blog.csdn.net/guchuanhang/article/details/78513210