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]
接下来看一个实例:
调试代码有两个进程,父进程执行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;
}
我们在创建线程的时候设置断点,然后切换到调试单一线程的模式,然后执行一步,可以看到新线程被创建。
接下来,我们在线程调用函数处设置断点,并用continu命令,执行到断点处停止
我们可以看到,已经在函数处停止了,接下来,我们一步步将子线程调试完,切回到主线程。
现在可以继续调试主线程了。以上就是gdb对多线程多进程的简单调试