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

一、调试多进程
默认设置下,在调试多进程程序时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调试多进程和多线程间的过程,如有错误,敬请指出。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值