4. C程序的调试技巧与实战案例(附完整输出)
四、实战案例(含完整调试输出)
1. 示例程序 test.c
#include <stdio.h>
#include <unistd.h>
void test() {
printf("test8\n"); // 添加换行符便于观察输出顺序
}
int main() {
int i = 0;
printf("test1\n");
printf("test2\n");
printf("test3\n");
printf("test4\n");
printf("test5\n");
printf("test6\n");
printf("test7\n");
test();
return 0;
}
2. 完整调试过程记录
# 编译调试版本
gcc -o test.out test.c -g
# 启动GDB
gdb test.out
调试过程及输出:
GNU gdb (Ubuntu 12.1-0ubuntu1~22.04) 12.1
Reading symbols from test.out...
(gdb) l # 列出源代码
1 #include <stdio.h>
2 #include <unistd.h>
3
4 void test() {
5 printf("test8\n");
6 }
7
8 int main() {
9 int i = 0;
10 printf("test1\n");
(gdb) l 11,20 # 继续列出代码
11 printf("test2\n");
12 printf("test3\n");
13 printf("test4\n");
14 printf("test5\n");
15 printf("test6\n");
16 printf("test7\n");
17 test();
18 return 0;
19 }
(gdb) b 9 # 在第9行设置断点
Breakpoint 1 at 0x117d: file test.c, line 9.
(gdb) r # 运行程序
Starting program: /home/user/test.out
Breakpoint 1, main () at test.c:9
9 int i = 0;
(gdb) n # 执行下一条语句
10 printf("test1\n");
(gdb) p i # 查看变量i的值
$1 = 0
(gdb) n # 执行printf("test1\n")
test1
11 printf("test2\n");
(gdb) n # 连续执行直到test调用
test2
12 printf("test3\n");
(gdb)
test3
13 printf("test4\n");
(gdb)
test4
14 printf("test5\n");
(gdb)
test5
15 printf("test6\n");
(gdb)
test6
16 printf("test7\n");
(gdb)
test7
17 test();
(gdb) s # 进入test函数
test () at test.c:5
5 printf("test8\n");
(gdb) n # 执行test函数内部语句
test8
6 }
(gdb) finish # 退出函数
Run till exit from #0 test () at test.c:6
main () at test.c:18
18 return 0;
(gdb) p/x i # 以十六进制格式查看变量
$2 = 0x0
(gdb) c # 继续执行到程序结束
[Inferior 1 (process 1234) exited normally]
(gdb) q # 退出GDB
关键调试输出说明
断点触发
Breakpoint 1, main () at test.c:9 9 int i = 0;
显示程序在指定行暂停执行
变量监控
(gdb) p i $1 = 0
显示变量i的当前值
函数调用跟踪
(gdb) s test () at test.c:5 5 printf("test8\n");
进入test函数后的上下文
程序输出同步显示
test1 test2 ... test8
实时显示程序的标准输出
退出状态确认
[Inferior 1 (process 1234) exited normally]
验证程序正常退出
通过这个完整案例可以观察到:
断点设置与触发的实际效果
单步执行时程序状态的变化
函数调用时的堆栈切换
变量值的实时监控能力
程序输出与调试操作的同步显示