Linux下gdb调试

一、Part1

1.1 测试代码

#include <stdio.h>

int g_var = 0;

int add(int a, int b) {
    printf("add callad, a: %d, b: %d \n", a, b);
    return a + b;
}

int main(int argc, char *argv[]) {
    int n = 1;
    
    printf("one n = %d, g_var = %d\n", n, g_var);
    ++n;
    --n;
    
    g_var += 20;
    g_var -= 10;

    n = add(1, g_var);
    printf("two n = %d, g_var = %d\n", n, g_var);
    
    return 0;
}

编译gcc gdb_test.c -o test,这里生成与一个test可执行文件
运行它./test,可以得到下面的结果
在这里插入图片描述

1.2 使用gdb

像上面那样,我们没有办法看到中间变量,除非去在代码内逐个逐个地去print出来,于是我们使用gdb

1)编译

如果需要使用gdb调试,需添加-g选项去编译程序
gcc -g -Wall gdb_test.c -o test
这里的-Wall表示不显示任何警告

2)进入gdb模式和查看源码

在编译之后会得到一个可执行文件test,
使用gdb加载可执行文件testgdb test
这样,就进入了gdb模式
在这里插入图片描述
在gdb模式下,使用命令l可以加载源码内容,同时还显示了行号
在这里插入图片描述

3)加断点

使用命令b,这里使用的模式有
① 在相应的函数处加断点:b 函数名
② 在指定的行号处加断点:b 行号
在这里插入图片描述

4)运行和打印变量

使用命令r,让调试的程序开始运行
在这里插入图片描述
可以看到,程序在第一个断点的地方停了下来
使用命令n进入过程调试,跳到下一个断点,不管中间过程
此时,变量n的值应当是1,可以使用命令p 变量名查看在这里插入图片描述

5)退出gdb模式

使用命令q,退出gdb模式
在这里插入图片描述


二、Part2

2.1 测试代码

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

/*
 * arr 只能是数组
 * 返回当前数组长度
 */
#define LEN(arr) (sizeof(arr)/sizeof(*arr))

// 简单数组打印函数
static void _parrs(int a[], int len) {
    int i = -1;
    puts("当前数组内容值如下:");

    while(++i < len) 
        printf("%d ", a[i]);    
    putchar('\n');
}

// 简单包装宏, arr必须是数组
#define PARRS(arr) \
    _parrs(arr, LEN(arr))

#define _INT_OLD (23)

/*
 * 主函数,简单测试
 * 测试 core文件, 
 * 测试 宏调试
 * 测试 堆栈内存信息
 */
int main(void) {
    int i;
    int a[_INT_OLD];
    int* ptr = NULL;    

    // 来个随机数填充值吧
    srand((unsigned)time(NULL));
    for(i=0; i<LEN(a); ++i)
        a[i] = rand()%222;
    
    PARRS(a);

    //全员加double, 包含一个错误方便测试
    for(i=1; i<=LEN(a); ++i)
        a[i] <<= 1;
    PARRS(a);

    // 为了错,强制错
    *ptr = 0;

    return 0;
}
1)编译并进入gdb模式

gcc -g -Wall gdb_test.c -o test
gdb test

2)执行它r

发现程序出现了段错误
在这里插入图片描述

3)开始调试

这里首先在43行处设一断点,并执行程序
在这里插入图片描述
这里数组a已经有值了,可以print a查看堆栈信息
在这里插入图片描述

由于此时已经到了子函数调用处,于是在13行处设一个断点b 13
再使用命令n过程调试,进入子函数
在这里插入图片描述

使用命令info args可以查看当前函数的参数值
在这里插入图片描述
这里a就是形参数组的地址

使用命令info locals可以查看当前函数栈上值信息
使用命令info registers可以查看寄存器值
在这里插入图片描述

查看内存信息,命令x
格式为:x /nfu ptr

说明
x 是 examine 的缩写
① n表示要显示的内存单元的个数
② f表示显示方式, 可取如下值
x 按十六进制格式显示变量。
d 按十进制格式显示变量。
u 按十进制格式显示无符号整型。
o 按八进制格式显示变量。
t 按二进制格式显示变量。
a 按十六进制格式显示变量。
i 指令地址格式
c 按字符格式显示变量。
f 按浮点数格式显示变量。
③ u表示一个地址单元的长度
b表示单字节,
h表示双字节,
w表示四字节,
g表示八字节
在这里插入图片描述

删除断点
① 使用命令d 断点索引
② 使用命令clear 行号

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值