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

来源:互联网 发布:达内java培训北京校区 编辑:程序博客网 时间:2024/06/05 21:59

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

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 苹果平板电脑进水了怎么办 电脑换主机以前的文件怎么办 货车卖了没过户怎么办 微交易出金不了怎么办 直播时出现央视影音客户端怎么办 qq账号暂时无法登录怎么办 饿了吃东西胃疼怎么办 早上不吃饭胃疼怎么办 孕晚期胃疼呕吐怎么办 胃疼了一晚上怎么办 微信视频图像倒立怎么办 ps链接图层锁定怎么办 慕课过时间了怎么办 异地恋又要考研怎么办 阴阳师手机绑定上限了怎么办 高考口令卡丢了怎么办 网易将军令换手机了怎么办 须弥bb有弱点土怎么办 战网密码忘记了怎么办 梦三账号忘了怎么办 快手手机号被注册了怎么办 快手该手机号已注册怎么办 手机号被别人注册了快手怎么办 快手显示手机号已注册怎么办 163的邮箱忘了怎么办 河长制账号密码忘了怎么办 网易登录名忘了怎么办 网易通行证安全手机忘了怎么办 美团数据获取失败怎么办 扣扣图片加载不出来怎么办 电脑qq最小化后不见了怎么办 uwp桌面快捷图标显示异常怎么办 网易云自动切歌怎么办 捡到小米手机怎么办才能自己用 dnf启动安装程序出错怎么办 苹果手机相册视频下载出错怎么办 苹果7软件闪退怎么办 微信上有钱账号就是怎么办 手机网速不给力怎么办 xp系统登录密码忘了怎么办 手机百度云网络出错怎么办