转载https://typecodes.com/cseries/multilprocessthreadgdb.html
1 原文整理
默认设置下,在调试多进程程序时gdb只会调试主进程。gdb7以上的版本(gdb --version)支持多进程调试,只需要设置好follow-fork-mode
(fork追踪模式)以及detach-on-fork
(指示GDB在fork之后是否断开某个进程的调试)即可。
这两个参数的设置命令分别是:set follow-fork-mode [parent|child],set detach-on-fork [on|off]。两者结合起来构成了GDB的调试模式:
follow-fork-mode detach-on-fork 说明
parent on GDB默认的调试模式:只调试主进程
child on 只调试子进程
parent off 同时调试两个进程,gdb跟主进程,子进程block在fork位置
child off 同时调试两个进程,gdb跟子进程,主进程block在fork位置
查看gdb默认的参数设置:
(gdb) show follow-fork-mode
Debugger response to a program call of fork or vfork is "parent".
(gdb) show detach-on-fork
Whether gdb will detach the child of a fork is on.
(gdb)
2 演示代码
下面这段代码的主要流程就是在main函数中fork创建一个子进程,然后在父进程中又创建一个线程,接着就使用gdb进行调试(block子进程)。注意,在调试设置断点的时候,由于之前调试的时候代码最前面没有加上这7行说明文字,所以设置断点的行号要加上7。
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 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
/**
* @FileName gdb_pthread.c
* @Describe A simple example for the debug of multiprocess and multithreading using gdb in linux system.
* @Author vfhky 2016-02-25 22:48 https://typecodes.com/cseries/multilprocessthreadgdb.html
* @Compile gcc gdb_pthread.c -g -o gdb_pthread
* @Reference http://blog.csdn.net/pbymw8iwm/article/details/7876797
*/
#include <stdio.h>
#include <pthread.h>
#include <sys/types.h>
#include <unistd.h>
//Parent process handle.
void Parent();
//Child process handle.
void Child();
//Parent process handle after generate a thread.
void * ParentDo( char *argv );
int main( int argc, const char **argv )
{
int pid;
pid = fork();
if(pid != 0) //add the first breakpoint.
Parent();
else
Child();
return 0;
}
//Parent process handle.
void Parent()
{
pid_t pid = getpid();
char cParent[] = "Parent";
char cThread[] = "Thread";
pthread_t pt;
printf( "[%s]: [%d] [%s]\n", cParent, pid, "step1" );
if( pthread_create( &pt, NULL, (void *)*ParentDo, cThread ) )
{
printf( "[%s]: Can not create a thread.\n", cParent );
}
ParentDo( cParent );
sleep(1);
}
void * ParentDo( char *argv )
{
pid_t pid = getpid();
pthread_t tid = pthread_self(); //Get the thread-id selfly.
char tprefix[] = "thread";
printf( "[%s]: [%d] [%s] [%lu] [%s]\n", argv, pid, tprefix, tid, "step2" ); //add the second breakpoint.
printf( "[%s]: [%d] [%s] [%lu] [%s]\n", argv, pid, tprefix, tid, "step3" );
return NULL;
}
void Child()
{
pid_t pid = getpid();
char prefix[] = "Child";
printf( "[%s]: [%d] [%s]\n", prefix, pid |