GDB调试的基本使用、GDB调试多进程

1. 编译时加选项-g,生成具有调试信息的程序

gcc -g test.c -o test

2. 启动GDB

(1)启动GDB:

gdb test

(2)设置运行时参数:(主函数中可接收运行时参数)

set args  // 设置运行时参数,如set args 10 20 30
show args // 查看设置的运行时参数

(3)启动程序

run      // 执行程序,若有断点,则停在第一个断点处;简写为r
start    // 程序向下执行一行
continue // 执行到第一个断点处

3. 显示源码

list 或 l       // 显示当前行后面的源代码(默认总共显示10行)
list-           // 显示当前行前面的源代码(默认总共显示10行)
list n          // 显示第n行前后的源代码
list func       // 显示func函数的源代码
set listsize n  // 设置一次显示n行
show listsize   // 查看一次显示行数

4. 断点操作

(1)简单断点:使用b或break命令

b n    // 在第n行设置断点
b func // 在func函数入口处设置断点
info b // 显示所有断点,可简写为 i b

(2)多文件断点,假设程序有add.cpp和test.cpp两个文件

b add.cpp:n                  // 在add.cpp源文件第n行设置断点
b add.cpp:func               // 在add.cpp源文件func函数入口处设置断点
b Animal::func               // 在Animal类的func函数入口处设置断点
b Animal::doSth(int, double) // 有函数重载时,必须指定函数形参的情况
b MyNamespace::Animal::func  // 在NyNamespace的Animal类的func函数入口处设置断点

(3)条件断点:为断点设置条件

b test.c:8 if Value == 5
// test.c第8行,Value为5时就停止
// 若为循环,不能停在for语句,要停在循环体中

 (4)维护断点

delete 10-12 // 删除编号为10、11、12的断点,delete可以简写为d
disable n    //禁用编号为n的断点
enable n     //启用编号为n的断点

5. 调试程序

run      // 执行程序,若有断点,则停在第一个断点处,简写为r
next     // 单步跟踪。函数调用当做一条语句直接执行,简写为n
step     // 单步跟踪。函数调用则进入函数体内,简写为s
finish   // 退出进入的函数
until    // 在循环体内单步跟踪时,执行完循环体并退出,简写为c
continue // 继续执行程序,停在下一个断点处
quit     // 退出gdb,简写为q

6. 查看数据

查看运行时变量、字符串、表达式等的值:

print a  // 查看a的值,print可简写为p

7. 自动查看

自己设置需要查看的值,程序停住或单步跟踪时,会自动显示需要查看的值:

display i         // 设置自动显示i的值
info display      // 查看所有被设置为display的变量
undisplay n       // 不显示编号为n的display设置
delete display n  // 删除编号为n的display设置
disable display n // 禁用编号为n的display设置
enable display n  // 启用编号为n的display设置

8. 查看修改变量的类型、值

ptype i          // 查看变量i的类型
p i              // 查看变量i的值
set var i = 100  // 设置变量i的值为100

 9. GDB调试多进程

 有如下的多进程程序,需要使用GDB分别调试父子进程:

#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<stdlib.h>

int main(int argc, const char* argv[]) {
    pid_t pid = -1;
    int status = 0;
    int ret = -1;

    pid = fork();
    if (-1 == pid) {
        perror("fork");
        return 1;
    }

    if (pid > 0) {
        // 父进程
        printf("父进程说太强了");
        printf("父进程笑尿了");
        printf("父进程哈哈哈哈哈");
    } else {
        // 子进程
        printf("子进程说太强了");
        printf("子进程笑尿了");
        printf("子进程哈哈哈哈哈");
        exit(0);
    }

    ret = wait(&status); // 父进程等待回收子进程资源
    if(-1 == ret) {
        perror("wait");
        return 1;
    }

    return 0;
}

GDB调试默认跟踪父进程,如下:

如何跟踪子进程呢?

在fork函数调用之前设置跟踪子进程:

set follow-fork-mode child

然后就会跟踪子进程,如下:

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

伟大的马师兄

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值