linux GDB 调试多进程多线程

来源:互联网 发布:linux内核usb驱动架构 编辑:程序博客网 时间:2024/05/16 15:08

在Windows下调试程序我们直接打断点F10,F11等键加上监事窗口的调试程序就很方便了,但是在Linux下并没有集成的开发调试环境这时就要用到GDB
GDB常用调试命令
l ist/l ⾏行号:显⽰示binFile源代码,接着上次的位置往下列,每次列10⾏行。
list/l 函数名:列出某个函数的源代码。
r或run:运⾏行程序。
s或step:进⼊入函数调⽤用
breaktrace(或bt):查看各级函数调⽤用及参数
info(i) locals:查看当前栈帧局部变量的值
info break :查看断点信息。
finish:执⾏行到当前函数返回,然后挺下来等待命令
print(p):打印表达式的值,通过表达式可以修改变量的值或者调⽤用函数
set var:修改变量的值
quit:退出gdb
break(b) ⾏行号:在某⼀一⾏行设置断点
break 函数名:在某个函数开头设置断点
continue(或c):从当前位置开始连续⽽而⾮非单步执⾏行程序
run(或r):从开始连续⽽而⾮非单步执⾏行程序
delete breakpoints:删除所有断点
delete breakpoints n:删除序号为n的断点
disable breakpoints:禁⽤用断点
enable breakpoints:启⽤用断点
info(或i) breakpoints:参看当前设置了哪些断点
display 变量名:跟踪查看⼀一个变量,每次停下来都显⽰示它的值
undisplay:取消对先前设置的那些变量的跟踪
until X⾏行号:跳⾄至X⾏
n 或 next:单条执⾏行。
p 变量:打印变量值。

对于多进程程序

set follow-fork-mode child     //GDB调试子进程set follow-fork-mode parent    //GDB调试父进程

gdb 默认调试主进程

#include <stdio.h>#include <unistd.h>#include <stdlib.h>void child(){    int i=0;    printf("child pid = %d,ppid == %d\n",getpid(),getppid());    for(i;i<10;i++){        sleep(1);        printf("child: %d\n",i);    }}void father(){    int i=20;    printf("father pid = %d,ppid = %d\n",getpid(),getppid());    for(i;i>0;i--){        sleep(1);        printf("father:%d\n",i);    }}int main(){    pid_t id = fork();    if (0 == id){        child();    }else{        sleep(1);        father();    }}

正常这段代码执行的结果是这样的
这里写图片描述
使用set follow-fork-mode child在GDB中调试的结果是这样
这里写图片描述
调试父进程
这里写图片描述

GDB中还有set detach-on-fork on/off这个命令和set follow-fork-mode parent/child 组合使用

follow-fork-mode detach-on-fork 说明
parent on GDB默认的调试方式;只调试主进程
child on 只调试子进程
parent off 同时调试两个进程,gdb跟主进程,子进程block在fork位置
child off 同时调试两个进程,gdb跟子进程,主进程block在fork位置
这次没有在子进程中下断点

调试线程
查询线程 info threads

#include <stdio.h>#include <pthread.h>#include <stdlib.h>#include <unistd.h>void* thread1(void* arg){    int i=0;    for (i;i<10;i++){        printf("%d\n",i);        sleep(1);    }}void* thread2(void* arg){    int i=10;    for (i;i>0;i--){        sleep(1);        printf("%d\n",i);    }}int main(){    pthread_t tid1;    pthread_t tid2;    pthread_create(&tid1,NULL,thread1,NULL);    pthread_create(&tid2,NULL,thread2,NULL);    pthread_join(tid1,NULL);    pthread_join(tid2,NULL);    return 0;}

提示创建新进程
提示创建新线程

黄色部分为线程编号LWP后面为线程号

线程切换thread 加线程编号调试该线程
这里写图片描述