【Linux】使用gdb调试多进程多线程程序

xiaoxiao2021-02-28  150

一、调试多进程 默认设置下,在调试多进程程序时GDB只会调试主进程。但是GDB(>V7.0)支持多进程的分别以及同时调试,换句话说,GDB可以同时调试多个程序。只需要设置follow-fork-mode(默认值:parent)和detach-on-fork(默认值:on)即可。

设置方法: set follow-fork-mode [parent|child] set detach-on-fork [on|off]

查询正在调试的进程:info inferiors 切换调试的进程: inferior 添加新的调试进程: add-inferior [-copies n] [-exec executable] ,可以用file executable来分配给inferior可执行文件。 其他:remove-inferiors infno, detach inferior

我们先编写多进程的代码,如下:

#include<stdio.h> #include<unistd.h> #include<stdlib.h> #include<pthread.h> void Child() { pid_t pid = getpid(); char str[] = "Child Process"; int count = 0; while(count < 3) { printf("%s %u count =%d\n",str,pid,count); count++; } } void Father() { pid_t pid = getpid(); char str[] = "Father Process"; int count = 0; while(count < 3) { printf("%s %u count =%d\n",str,pid,count); count++; } } int main() { gid_t id = fork(); if(id == 0) { //child Child(); } else if(id > 0) { //father Father(); } else { perror("fork"); exit(1); } return 0; }

因为gcc默认编译程序是在Release版本,而要调试程序必须在Debug版本下,所以要对程序进行调试,记得在gcc编译时,在文件名后加上-g将其变为Debug版本的。 如:gcc -o test1 gdbtest1.c -g

gdb test1 打开调试文件,由于我们对父子进程同时调试,让gdb跟主进程,按照上面的方法,设置:set follow-fork-mode parent set detach-on-fork off

并在fork()函数处打断点

在主进程单步执行一下,显示有新进程被创建,我们看一下正在调试的进程,有*代表跟进的是当前进程。因为之前让父子进程同时调试,gdb跟进主进程,所以此处的1号就是父进程。

我们可以用 inferior 指令切换调试的进程,我们将调试的进程切换成子进程,如下。

因为子进程执行Child函数,我们在Child函数那儿打断点观察,发现跳到了此处,证明当前确实是在调试子进程

单步执行将子进程调试完(中间截图省略)

上图所示,子进程已经执行完毕,我们可以再切换回主进程,继续调试主进程即可。

二、调试多线程

先给出多线程调试的代码示例:

#include<stdio.h> #include<pthread.h> void *id_run(void *arg) { printf("id%d run gdb success\n",(int )arg); } int main() { pthread_t pid1; pthread_t pid2; void* tmp; pthread_create(&pid1,NULL,id_run,(void *)1); pthread_create(&pid2,NULL,id_run,(void *)2); pthread_join (pid1, &tmp); pthread_join (pid1, &tmp); return 0; }

编译的时候记得一定要在后面加上链接库的名称 -lpthread

下面来看一下调试多线程经常使用的命令:

我们在创建线程函数pthread_create 处打下断点,设置单一线程调试set scheduler-locking on,单步执行一下,提示有新线程被创建。

此时就有了两个线程,当前跟进的是主线程。我们要调试子线程,用thread ID ID命令切换当前调试的进程。

我们在子线程调用函数出设置断点,发现跳到了此处,证明当前确实是在调试子线程

将子线程2单步执行完,我们发现执行完线程2的时候,线程3随即被创建了,并且此时正在跟进线程3。我们也可以再切换回主线程。

以上就是gdb调试多进程和多线程间的过程,如有错误,敬请指出。

转载请注明原文地址: https://www.6miu.com/read-41887.html

最新回复(0)