在gdb调试多线程好人多进程的程序上面,默认的是调试主程序。但是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>
int main(){
pid_t pid;
if((pid = fork())<0){
perror("fork");
exit(-1);
}
if(pid == 0){
int i = 0;
for(;i<10;i++)
printf("I`m child! pid = %d,ppid = %d\n`",getpid(),getppid());
}
else{
int i = 0;
wait();
for(;i<10;i++)
printf("I`m parent! pid = %d,ppid = %d\n`",getpid(),getppid());
}
return 0;
}
1、设置跟进的进程
2、进入子进程
切换进程
查询正在调试的进程:info inferiors
调加新的调试进程:add-inferior[-copies n][-exec executable]
切换调试的进程:inferior num
调试多线程
在gdb里面默认支持多线程的调试。
常见的多线程调试命令:
info+threads:显示可以调试的所有线程。gdb会为每个线程分配一个ID(和tid不同),编号一般从1开始。后面的ID是指这个ID。
thread+ID:切换当前调试的线程为指定ID的线程。
实例
#include<pthread.h>
#include<stdio.h>
pthread_mutex_t lock;
pthread_cond_t cond;
int count = 100;
void* pthread_run(void* arg){
pthread_mutex_lock(&lock);
if(count < 0){
pthread_mutex_unlock(&lock);
return NULL;
}
while(count){
pthread_cond_wait(&cond,&lock);
printf("count = : %d\n",count);
count--;
pthread_mutex_unlock(&lock);
}
}
int main(){
pthread_t tid;
int i = 100;
pthread_mutex_init(&lock,NULL);
pthread_cond_init(&cond,NULL);
pthread_create(&tid,NULL,pthread_run,NULL);
while(i--){
sleep(1);
pthread_cond_broadcast(&cond);
}
pthread_join(tid,NULL);
return 0;
}
查看进程里面的线程号,在跟进指定的线程:
调试多线程用到的其他命令:
- break FileName.cpp:LinuNum thread
all:所有线程都在文件FileName.cpp的第LineNum行有断点。 - thread apply ID1 ID2 IDN command:多个线程执行gdb命令command。
- thread apply all command:所有线程都执行command命令。
- set scheduler-locking
off|on|step:在调式某一个线程时,其他线程是否执行。off,不锁定任何线程,默认值。on,锁定其他线程,只有当前线程执行。step,在step(单步)时,只有被调试线程运行。 - set non-stop on/off:当调式一个线程时,其他线程是否运行。
- set pagination on/off:在使用backtrace时,在分页时是否停止。
- set target-async
on/ff:同步和异步。同步,gdb在输出提示符之前等待程序报告一些线程已经终止的信息。而异步的则是直接返回。