gdb调试多线程多进程

多进程调试

我们使用gdb调试程序,gdb的调试默认是调试父进程的,如果要做到对父进程和子进程都做到调试,所以附加了调试子进程的功能。

1. 设置条件

如果让gdb可以同时调试多个程序,只需要设置follow-fork-mode(默认:parent)和detach-on-fork(默认:on)就好了。

follow-fork-modedetach-on-fork操作
parenton只调试主进程
childon只调试子进程
parentoff同时调试两个进程,gdb跟进父进程,子进程block在fork处
childoff同时调试两个进程,gdb跟进子进程,父进程block在fork处
注:设置方法:
set follow-fork-mode [parent|child]
set detach-on-fork [on|off]
2. 启动方法
  1. gbd program

  2. gdb program core
  #同时调试一个运行程序和core文件

  3. gdb program pid
  # 如果你的程序是一个服务程序,那么你可以指定这个服务程序运行时的进程。
3. 查询进程
  1. 查询正在调试的进程:info inferiors
  2. 切换调试的进程:inferior
  3. 添加新的调试进程:add-inferior [-copies n] [-exec executable].
4. 常见命令
命令功能
I从第一行开始列出源码
break func在函数func的入口处设置断点
break n在第n行处设置断点
info break查看断点信息
r运行程序
n单步执行
c继续运行
p打印变量值
bt查看函数堆栈
finish退出函数
shell 命令行执行shell命令行
set args指定运行时参数
show args查看设置好的参数
show paths查看程序运行路径
clear n清除第n行断点
delete n删除第n个断点
disable n暂停第n个断点
enable n开启第n个断点
step单步调试如果有函数调用,则进入函数
list简记为l,列出程序源代码,默认每次显示十行
list 行号将显示当前文件以行号为中心的前后10行代码
list 函数名将显示函数名所在函数的源代码
run简记为r,运行程序,当遇到断点时,程序会在断点处停止运行。
回车重复上一条命令
print a将显示整数a的值
print name将显示字符串name的值
watch 表达式设置一个监视点一旦被监视的“表达式”的值改变,gdb将强行终止正在被调试的程序。
kill强制终止当前调试程序
helphelp命令将显示常用帮助信息
call 函数调试函数
layout用于分割窗口,可以一边查看代码,一边测试
quit简记为q,退出gdb
set environment varname [=value]设置环境变量。如:set env USER=hchen;
show environment [varname]查看环境变量;
5. 调试多进程

以下面程序为例进行调试:

#include <stdio.h>                                                          
  2 #include <unistd.h>
  3 #include <stdlib.h>
  4 
  5 void son_fun()
  6 {
  7 
  8     pid_t pid=getpid();
  9     printf("son:%d\n",pid);
 10 }
 11 void father_fun()
 12 {
 13     pid_t pid=getpid();
 14     printf("father:%d\n",pid);
 15 }
 16 int main()
 17 {
 18     pid_t id=fork();
 19     if(id<0)
 20     {
 21         perror("fork");
 22         exit (1); 
  else if(id==0)
 25     {
 26       son_fun();
 27     }
 28     else
 29     {
 30         father_fun();
 31     }
 32     return 0;
 33 }                                                                           

这里写图片描述
这里写图片描述
这里写图片描述
其他重要命令

  1. add-inferior [-copies n] [-exec executable]
    添加新的调试进程,可以用file executable来分配给inferior可执行文件。增加n个inferior并执行程序为executable。如果不指定n只增加一个inferior。如果不指定executable,则执行程序留空,增加后可使用file命令重新指定执行程序。这时候创建的inferior其关联的进程并没启动。

  2. remove-inferiors infno
    删除一个infno号的inferior。如果inferior正在运行,则不能删除,所以删除前需要先kill或者detach这个inferior。

  3. clone-inferior [-copies n] [infno]
    复制n个编号是infno的inferior。如果不指定n的话,就只复制一个inferior。如果不指定infno,则就复制正在调试的inferior。

  4. detach inferior infno
    detach去掉编号是infno的inferior。注意这个inferior还存在,可以再次用run命令执行它。

  5. kill inferior infno
    kill掉infno号inferior。注意这个inferior仍然存在,可以再次用run等命令执行它

这里写图片描述

多线程调试

gbd默认支持调试多线程,跟踪主线程,子线程断点在create thread。

1. 常见命令

info thread: 查看当前进程的线程
thread ID :切换调试的线程为指定ID的线程。
break file.c:100 thread all : 在file文件第100行处为所有经过第100行的线程设置断点。

set scheduler-locking off |on|step
在使用step或continue命令调试当前被调试线程的时候,其他线程也同时执行。
如果只让被调试程序执行,我们需要以下命令。

命令含义
off不锁定任何线程,也就是所有线程都执行,默认值。
on只有当前被调试程序执行
step在单步的时候,出来next过一个函数的情况(设置断点然后continue的行为)。
2. 调试程序

以下面程序为例进行调试:

void* thread1(void* arg)
{
    printf("thread1, tid is %lu\n", pthread_self());
    return NULL;
}

void* thread2(void* arg)
{
    printf("thread2, tid is %lu\n", pthread_self());
    return NULL;
}

int main()
{
    pthread_t tid1, tid2;
    pthread_create(&tid1, NULL, thread1, NULL);
    pthread_create(&tid2, NULL, thread2, NULL);

    pthread_join(tid1, NULL);
    pthread_join(tid2, NULL);
    return 0;
}

这里写图片描述
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值