Linux 调试工具:gdb

调试复习

调试可谓是 “贯穿” 了程序员的一生,调试的重要性,就不再赘述啦!如果你还不知道什么是调试,可以看看 Windows 系统的 Visual Studio 是如何调试的:➡️ visual stuudio 使用调试技巧

下载调试软件 gdb

yum install gdb -y

gdb 的使用

gdb 的使用非常简单:

gdb 可执行文件

这是一段简单的代码:

#include

int main()
{
    printf("hello gdb\n");
    return 0;
}

这是 makefile 文件:

test:test.c
	gcc -o $@ $^ -std=c99
.PHONY:clean
clean:
	rm -f test

make 生成可执行文件之后,我们来看看是否能够启动 gdb 调试:
Linux 调试工具:gdb_第1张图片
我们看到出现了报错:可执行文件中没有调试信息。这是因为 linux 环境下 gcc 形成的可执行程序默认是以 release 的形式发布的,release 版本的可执行程序当然不包含调试信息啦!
于是,我们需要以 debug 的方式发布可执行程序,只需要加一个 -g 的选项就可以啦!

# 这是 makefile 文件
test:test.c
	gcc -o $@ $^ -g -std=c99
.PHONY:clean
clean:
	rm -f test

那么如何看到可执行程序中是否有调试信息呢?我们都知道 linux 环境下的可执行程序是一种 elf 格式的文件,我们只要打开这个 elf 格式的文件,就能看到啦!

readelf -S 可执行程序

我们可以看到 debug 方式发布的可执行程序确实多了调式信息。(文件比较长,下图中只截取了一部分)
Linux 调试工具:gdb_第2张图片

调试前的准备

我们来写一个简单的程序,作为调试之前的准备工作吧!
test.c

#include
#include "function.h"

int multiple(int x, int y)
{
	int ret = x * y;
    return ret;
}
int main()
{
    int a = 2, b = 3;
    int sum = 0;
    sum = Add(a, b);
    printf("a + b: %d\n", sum);
    
    int times = multiple(a, b);
    for(int i = 0; i < times; i++)
    {
    	printf("hello gdb %d\n", i);
    }
    return 0;
}

function.h

#pragma once

int Add(int x, int y);

function.c

#include "function.h"

int Add(int x, int y)
{
    return x + y;
}

调试命令一览

gdb 可执行程序   #开始调试
quit/q          #退出调试
l 数字          #显示代码,默认是 10 行
r               #运行程序
b 行号          #在main函数所在文件的指定行打断点
b 文件名:行号    #在指定文件的指定行号打断点
b 函数名         #在指定函数的第一行代码处打断点
info b          #查看所有断点信息
d 断点编号       #删除断点

# r 开始调试之后

n               #逐过程运行
s               #逐语句执行
p 变量           #查看变量的值
display 变量     #变量值常显示,类似于 visual studio 的监视窗口
undisplay 变量   #取消变量的长显示
untill 行号      #在函数内跳转到指定行
finish          #执行完当前行所在的函数
c               #运行到下一个断点处
disable 断点编号 #禁用指定断点
enable 断点编号  #恢复禁用的断点
set var 变量=#类比 visual studio 中的条件断点
bt              #查看调用堆栈
info locals     #查看本地变量(局部变量)

下面我会选择几个比较不好理解的讲讲

l 数字

l 默认显示 10 行,gdb 会记住上一条命令,回车就可以继续执行上一条命令。
Linux 调试工具:gdb_第3张图片

b 文件名:行号

这个命令在多文件的调试中可能会用到:
在这里插入图片描述

d 断点编号


断点编号是什么呢?查看断点编号需要使用 info b 命令:
Linux 调试工具:gdb_第4张图片
其中这个 Num 就是断点编号啦!


在这里插入图片描述
可以看到删除断点之后就查看不到断点的信息啦!


删除刚刚的断点之后我们再打一个断点,发现断点编号并不是 1,说明断点编号是递增的!
Linux 调试工具:gdb_第5张图片

display 变量

可以动态显示一个变量的内容,类似于监视窗口。
我们使用 r 运行程序,开始调试。display num 看到:sum = 0 没问题,然后 n 逐过程运行。发现 sum 变成了 5。这就相当于监视窗口不是嘛!
Linux 调试工具:gdb_第6张图片

finish

执行完当前行所在的函数,这是什么意思呢?我们在第六 6 行打一个断点,看看效果就知道了!
Linux 调试工具:gdb_第7张图片
效果就是直接完成了当前行所在函数的运行

disable 断点编号

这个命令可以禁用断点,visual studio 也是可以的!
Linux 调试工具:gdb_第8张图片
禁用 1 号断点之后,我们查看断点信息,发现 Enb 属性变成了 n。这就表示这个断点被禁用了!

set var 变量=值

我们在 19 行打一个断点,然后运行程序,开始调试,再然后 set var i=3 运行之后,我们发现打印的就是 hello gdb 3 这是不是和 visual studio 中的条件断点一个味儿!
Linux 调试工具:gdb_第9张图片

你可能感兴趣的:(Linux保姆级教程,linux,运维,服务器)