一、GDB
(1)GDB是什么
GDB(GNU Debugger)是一个功能强大的调试器,它可以用来帮助你查看另一个程序在执行时“内部”发生了什么。你可以使用GDB来执行你的程序,设置断点(在某一行停止执行),在程序执行时检查变量的值,以及查看程序崩溃时的堆栈跟踪。
(2)为什么学习GDB很重要?
- 解决问题:当程序出现问题时,GDB可以帮助你快速定位错误所在,节省你大量的调试时间。
- 深入理解:通过GDB,你可以更深入地了解程序是如何运行的,这有助于提高你的编程技能。
- 职业发展:掌握GDB是成为专业程序员的重要一步,它显示了你对代码质量的重视。
(3)GDB能做什么?
- 设置断点:就像在迷宫中放置标记,告诉程序在哪里暂停,让你有机会检查情况。
- 单步执行:一步一步地执行代码,观察每一步的结果。
- 查看变量:在程序的任何时刻,检查变量的值,就像使用X光透视程序的心脏。
- 堆栈跟踪:当你迷失在函数调用的大海中时,GDB可以帮助你找到回家的路。
二、GDB调试命令
以下是一些常用的GDB调试命令:
- break [file:]function 或 b [file:]function:在指定的函数上设置断点。
- break [file:]line 或 b [file:]line:在指定文件的指定行上设置断点。
- run 或 r:开始执行程序。
- next 或 n:执行下一行代码,但不进入函数内部。
- step 或 s:执行下一行代码,如果是函数则进入函数内部。
- continue 或 c:继续执行程序,直到下一个断点。
- quit 或 q:退出GDB。
三、GDB实战
(1)下列代码存在内存泄露问题
#include <stdio.h>
#include <stdlib.h>
void function_that_causes_null_pointer_exception()
{
int *null_pointer = NULL;
printf("Value at null pointer: %d\n", *null_pointer);
}
void safe_function()
{
int *ptr = malloc(sizeof(int));
if (ptr == NULL)
{
fprintf(stderr, "Memory allocation failed!\n");
exit(EXIT_FAILURE);
}
*ptr = 42;
printf("Value stored safely: %d\n", *ptr);
free(ptr);
}
int main()
{
printf("Program starts.\n");
safe_function();
function_that_causes_null_pointer_exception();
printf("This line may not be executed.\n");
printf("Program ends.\n");
return 0;
}
(2)GDB调试实战
=======================调试过程图放到最后=======================
(1)gcc test.c -o test -g 使用-g选项编译程序,使程序具备可调试功能
(2)gdb ./test 调试可执行程序
(3)在main、line 26 27打上断点,
26行为safe_function()函数,27行为function_that_causes_null_pointer_exception()函数
这是进行函数级别的代码错误排查。
(4)
(5)
gdb ./test运行结果图
b mian、b 26、b 27打断点图
分别按r n n n后的运行结果图
(1)按r并回车后,因为在main处打了断点,因此函数执行到25行停下;下一步是要执行打印函数printf("Program starts.\n");
(2)按n后意味着单步执行不进入函数内部,可以看到打印出Program starts.意味着打印函数执行完毕;
下一步是执行safe_function()函数
(3)n:执行safe_function()完毕,打印出Value stored safely: 42,意味着该函数正常运行不存在内存泄露问题;
下一步执行function_that_causes_null_pointer_exception()函数
(4)n:执行function_that_causes_null_pointer_exception()函数,报错提示段错误,定位内存泄露问题存在于该函数。
我们知道问题所在后退出调试重新打断点;直接b 27在该函数处打断点,并按c进入内部执行。
二次调试过程
分别按s n n后的运行结果图
(1)按s进入function_that_causes_null_pointer_exception()函数内部执行,下一步执行int *null_pointer = NULL
(2)按n意味着int *null_pointer = NULL执行完毕,下一步执行printf("Value at null pointer: %d\n", *null_pointer);
(3)按n继续执行,这里报错,这个打印函数想要打印指针null_pointer的值,这里我们检查一下发现null_pointer初始化时赋值为NULL。那么显而易见:这是一个常见的空指针访问异常问题,排查完毕。
如果你喜欢这篇文章,别忘了点赞收藏,给个关注哦!一键三连,你的支持是我创作的最大动力。让我们共同成长,探索更多精彩内容,期待你的每一次回眸!