Linux系统学习:使用GDB调试

基础知识

GDB优化编译

-O0 是gcc编译器的一个优化选项,它表示不进行任何优化。

在编译程序时,编译器可以对程序进行一系列的优化,以提高程序的执行效率和减小程序的空间占用。例如,编译器可以将一些常量表达式进行计算,删除不可达代码,减少函数调用等操作。但是,这些优化操作可能会导致程序的调试变得困难,因为优化后的代码与原始代码可能存在差异,使得调试器难以准确地定位程序中的错误。因此,在调试程序时,通常会使用`-O0`选项来关闭所有的优化操作,以便生成与原始代码最相近的可执行文件,以方便调试。

例如,可以使用以下命令将名为`program.c`的C源文件编译成名为`program`的可执行文件,并关闭所有的优化操作:
gcc -O0 -o program program.c

需要注意的是,关闭所有的优化操作可能会导致程序的执行效率降低,因此在生产环境中,通常会使用其他的优化选项来提高程序的执行效率。但是,在调试程序时,为了方便调试,仍然需要使用`-O0`选项来关闭所有的优化操作。

编译教程

一般调试

1. 编译程序时添加-g选项,以便在程序中嵌入调试符号。例如,在使用gcc编译C程序时,可以使用以下命令:
gcc -g -o program program.c

2. 启动gdb,并加载程序。例如,可以使用以下命令启动gdb,并加载名为program的程序:
gdb program

3. 在gdb中设置断点。使用命令`break`或缩写命令`b`设置断点。例如,在程序的第10行处设置一个断点:
b 10

如果要设置在某个函数内的断点,可以使用以下命令:
b function_name

如果要设置在某个文件内的断点,可以使用以下命令:
b file_name:line_number

4. 运行程序。使用命令`run`或缩写命令`r`运行程序,例如:
r

5. 程序运行到断点处时停止。当程序运行到设置的断点处时,gdb会暂停程序的执行,并显示当前代码行。

6. 使用gdb的命令进行调试。在程序暂停执行时,可以使用gdb的命令进行调试,例如:

- 使用`next`或缩写命令`n`执行下一行代码。
n

- 使用`step`或缩写命令`s`进入函数或跳过函数调用。
s

- 使用`print`或缩写命令`p`打印变量的值。
p variable_name

- 使用`backtrace`或缩写命令`bt`查看函数调用栈。
bt

- 使用`continue`或缩写命令`c`继续执行程序。
c

- 使用`watch`设置变量监视点,当变量的值发生变化时,程序会停止执行。
watch variable_name

- 使用`info`命令查看程序的信息,例如查看当前断点列表、查看内存信息等。
info breakpoints
info memory

7. 在程序执行过程中可以随时添加或删除断点,使用`delete`命令删除断点,例如:

-使用`delete`命令删除所有断点。
delete

- 使用`delete breakpoint`删除指定的断点。
delete breakpoint breakpoint_number

8. 在调试完成后,使用`quit`命令退出gdb。
quit

需要注意的是,在使用gdb进行调试时,需要熟悉gdb的常用命令,并根据实际情况进行调试。

崩溃或段错误

如果程序崩溃或出现段错误,可以使用`coredump`命令查看程序的core文件,以了解程序崩溃的原因。具体使用方法如下:

1. 在编译程序时添加-g选项,并使用`-fno-omit-frame-pointer`选项禁用帧指针优化。
gcc -g -fno-omit-frame-pointer -o program program.c

2. 运行程序,如果程序崩溃,会生成一个名为core的core文件。

3. 使用gdb加载程序和core文件,以查看程序崩溃的原因。
gdb program core
 

4. 使用`bt`命令查看函数调用栈,以找出程序崩溃的原因。
bt
 

总之,使用gdb进行程序调试可以帮助我们快速定位代码中的错误,并提高代码调试的效率。需要注意的是,在使用gdb进行调试时,需要根据具体情况进行调试,并注意代码中的潜在问题,避免在进行调试时出现一些不必要的错误。

实例

准备

文件夹里有两个 .c 文件

编译

gcc -c array.c main.c

添加 -g

gcc -O0 -g -o program array.o main.o

执行发现65被输出了17次,而按设想是输出16次(后面发现数错了,bug不在这里)。

使用gdb调试,进入这个页面表示成功

gdb program

猜测是输出子程序的问题,我直接添加断点

b array_print

运行开始调试,在断点处停下了

r

从这里开始,我发现有问题,第一是我原来gdb的这个文件,没有编译标志,本来直接把两个c文件gcc -g即可,我先编译到两个o文件了,可能是这个原因导致的,

所以我重新编译了一下。

先list一下,展现一下文件,开始调试

添加一个断点,这个断点本来想添加在array_add的,看眼瞟了。

b 11

开始运行.

r

不进入函数跳过

n

找到个问题,i = 16 的时候还执行了一次循环,i = 17 时才跳出,此时 array_add被执 行了17次,此时array_a array_b也有值,说明前面也有 问题。

重新调试一次,找到三个数组第17个数字的值,有错误

结果虽然没因为bug出现问题,但多赋值要修改,节省内存。

使用nano编辑器修改

nano array.c

bug修复!​​​​​​​

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值