Lab01: Debugging Tools & C Programming¶
约 686 个字 41 行代码 预计阅读时间 4 分钟 共被读过 次
Exercise 1: See what you can C¶
目标¶
学习C语言宏定义(Macro)的基础用法,理解预处理阶段的作用。
关键概念¶
- 宏定义:通过
#define
替换文本,分为无参宏和带参宏。
- 调试宏:利用宏输出调试信息,结合条件编译控制是否启用:
- 防止头文件重复包含:
Exercise 2: Catch those bugs (GDB/cgdb 实战)¶
目标¶
掌握GDB调试器核心命令,理解断点、单步执行、变量监控等操作。
核心命令对比表¶
操作 | GDB命令 | 简写 | 说明 |
---|---|---|---|
设置参数 | set args <...> | - | 程序启动参数 |
设置断点 | break <loc> | b | 函数名/行号/文件:行号 |
单步执行(不进入函数) | next | n | 执行下一行代码 |
单步进入函数 | step | s | 进入函数内部 |
继续运行 | continue | c | 运行到下一个断点 |
打印变量 | print <expr> | p | 支持表达式如 p *(arr+5) |
自动显示变量 | display <var> | - | 每步后自动显示值 |
查看局部变量 | info locals | - | 当前栈帧所有局部变量 |
退出GDB | quit | q | 退出调试器 |
高级技巧¶
- 条件断点:当变量满足条件时暂停
- 修改变量值:动态调试时修改运行状态
- 查看内存布局:
- cgdb优势:分屏界面(上代码/下命令),支持Vi快捷键(按
Esc
进入代码窗口,方向键浏览)。
Exercise 3: Debugging with User Input (输入重定向)¶
目标¶
避免调试交互式程序时手动输入,通过重定向预定义输入。
操作步骤¶
- 创建输入文件
input.txt
:
- 命令行重定向:
- 在GDB中使用重定向:
原理¶
<
操作符:将文件内容重定向到程序的标准输入(stdin)。- 管道技巧:结合
echo
快速测试
Exercise 4: Valgrind'ing away (内存检测)¶
目标¶
使用Valgrind检测内存错误(如越界访问、内存泄漏)。
关键命令¶
常见错误类型¶
- Invalid read/write:越界访问内存
- Memory leak:未释放动态分配的内存
- Use of uninitialized value:使用未初始化变量
Valgrind输出解读¶
- Definitely lost:明确的内存泄漏(需优先修复)。
- Indirectly lost:因结构体嵌套导致泄漏。
- Suppression:通过配置文件忽略第三方库的误报。
Exercise 5: Pointers and Structures in C (链表环检测)¶
目标¶
实现快慢指针算法检测链表环。
算法思路¶
C
bool ll_has_cycle(node *head) {
node *fast = head, *slow = head;
while (fast && fast->next) {
slow = slow->next;
fast = fast->next->next;
if (slow == fast) {
return true;
}
}
return false;
}
测试技巧¶
- 编译命令:
- GDB调试指针:
附录:常用调试策略¶
- 最小化复现:将问题代码剥离到最小可编译示例。
- 二分法排查:通过注释代码逐步缩小问题范围。
- 防御性编程:使用
assert()
验证假设条件。 - 日志输出:在关键路径添加
printf
调试(提交前移除)。