gdb调试多进程多线程



      1.调试多进程


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

       接下来,首先介绍一下follow-fork-mode和detach-on-fork


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

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

     接下来看一个实例:

     调试代码有两个进程,父进程执行processA函数,子进程执行processB函数

#include<stdio.h>
#include <pthread.h>
#include<unistd.h>

void processA();
void processB();

int main(int argc, const char *argv[])
{
      pid_t id = fork();
      if(id == 0) //child
      {
          processB();
      }
      else//father
      {
          processA();
      }
      return 0;
}

void processA()
 {
      pid_t pid = getpid();
      char prefix[] = "ProcessA: ";
      printf("%s %u %s\n", prefix, pid, "step1");
      printf("%s %u %s\n", prefix, pid, "step2");
      printf("%s %u %s\n", prefix, pid, "step3");
  }

void processB()
  {
      pid_t pid = getpid();
      char prefix[] = "ProcessB: ";
      printf("%s %u %s\n", prefix, pid, "step1");
      printf("%s %u %s\n", prefix, pid, "step2");
      printf("%s %u %s\n", prefix, pid, "step3");
  }


          我们在fork处设置断点,并且设置set follow-fork-mode 和set detach-on-fork ,同时调试两个进程,gdb跟进主进程。然后主进程执行一步,会提示有一个新进程被创建。


          我们查看一下正在调试的进程


         我们可以看到有两个进程正在被调试,gdb跟进的1这个进程,也就是主进程。现在我们切换到子进程,也就是切换到2这个进程,也就是子进程。


         此时可以看到,已经切换到子进程了,因为子进程执行的processB函数,所以我们在此函数处下一个断点,并且通过continue命令执行到该断点处停下来。


        我们可以看到在processB处已经停了下来,使用n命令将子进程调试完


         现在切到主进程,继续调试主进程即可。


           2.调试多线程:

      首先看一下调试多线程经常使用的命令


        接下来看一下调试代码,

#include<stdio.h>  
#include <stdlib.h>  
#include <pthread.h>  
#include <unistd.h>  
  
void * fun1 (void *arg1)  
{  
    printf ("[pthread1]  -- start\n");  
    sleep (2);  
    printf ("[pthread1]  -- end\n");  
    pthread_exit ((void *) NULL);  
}  
  
void * fun2 (void *arg1)  
{  
    printf ("[pthread2]  -- start\n");  
    sleep (2);  
    printf ("[pthread2]  -- end\n");  
    pthread_exit ((void *) NULL);  
}  
  
int main(void)  
{  
  
    pthread_t pid1, pid2;  
    void *tmp;  
  
    printf ("[main] -- start\n");  
  
    if (pthread_create (&pid1, NULL, fun1, NULL)) {  
        perror ("create pthread1 error\n");  
        exit (1);  
    }  
    if (pthread_create (&pid2, NULL, fun2, NULL)) {  
        perror ("create pthread2 error\n");  
        exit (1);  
    }  
  
    if (pthread_join (pid1, &tmp)) {  
        perror ("join pthread1 error\n");  
        exit (1);  
    }  
  
    if (pthread_join (pid2, &tmp)) {  
        perror ("join pthread2 error\n");  
        exit (1);  
    }  
  
    sleep (2);  
    printf ("[main] -- end\n");  
    return 0;  
}  

             我们在创建线程的时候设置断点,然后切换到调试单一线程的模式,然后执行一步,可以看到新线程被创建。


             现在查看一下正在调试的线程,会看到有两个,并且gdb跟进的是主线程,然后我们把它切换到子线程


          接下来,我们在线程调用函数处设置断点,并用continu命令,执行到断点处停止


    我们可以看到,已经在函数处停止了,接下来,我们一步步将子线程调试完,切回到主线程。



             现在可以继续调试主线程了。以上就是gdb对多线程多进程的简单调试

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值