代码示例:1.1.6 GDB 调试实战
全部示例均标注编译命令、适用环境与实测状态;完整验证记录见《03.5-代码编译运行验证记录》。
examples/ex1-gdb-demo.c · 受控段错误程序(NULL 解引用,配合 ex2 的 gdb 批处理定位)
/* ex1-gdb-demo.c —— GDB 调试演示:受控段错误(1.1.6 ex1) * 适用环境:Linux / Windows(MinGW) 标准:C11 * 编译:gcc ex1-gdb-demo.c -o ex1 -std=c11 -Wall -Wextra -Wpedantic -g -O0 * 运行:直接运行会崩溃(本示例唯一目的);在 gdb 中运行可定位(见 ex1-gdb-batch.txt) * 说明:store() 第 7 行对 NULL 解引用是故意埋的受控 bug;不会破坏环境,仅供调试练习。 */ #include <stdio.h> static void store(int n) { int *p = NULL; /* 第 6 行:故意置空 */ *p = n; /* 第 7 行:段错误触发点 */ printf("%d\n", *p); } static int compute(int n) { int v = n * 2; store(v); /* compute(42) 传 84 给 store */ return v; } int main(void) { printf("before crash\n"); fflush(stdout); /* 确保崩溃前的输出先刷出来 */ printf("result = %d\n", compute(42)); return 0; }examples/ex1-gdb-batch.txt · GDB 批处理命令与实测输出(断点流程 + 崩溃定位流程)
# 1.1.6 ex1 配套 GDB 批处理命令(在 ex1 编译产物所在目录执行;本机实测 gdb 17.1) # 流程一:断点定位(先停在 store,看参数与调用栈) gdb -batch -ex "break store" -ex "run" -ex "print n" -ex "backtrace" -ex "quit" ex1.exe # 流程二:崩溃定位(不带断点直接 run,崩溃后看调用栈与源码行) gdb -batch -ex "run" -ex "backtrace" -ex "frame 0" -ex "list" -ex "quit" ex1.exe # Linux 下把 ex1.exe 换成 ./ex1,其余命令完全一致examples/ex2-optimized-out.c · -O2 优化对调试的影响(行号漂移与变量被消除,预期诊断现象)
/* ex2-optimized-out.c —— -O2 对调试的影响演示(1.1.6 ex3) * 编译:gcc ex2-optimized-out.c -o ex2o2 -std=c11 -Wall -Wextra -Wpedantic -g -O2 * 演示现象(本机实测):断点打在循环内第 6 行,实际命中第 8 行(行号漂移); * 循环变量 i 与累加和 sum 均显示 <optimized out>(变量被优化消除)。 */ int main(void) { int sum = 0; for (int i = 0; i < 100; i++) { sum += i; /* 第 6 行:断点打这里 */ } return sum % 5; /* 第 8 行:-O2 下实际命中这里 */ }examples/ex3-core-dump-linux.txt · core dump 概念命令(Linux 专属;未执行,文档核对)
# 1.1.6 core dump 概念命令(Linux 专属;本机无 Linux 未执行,按官方文档核对) # 1. 允许生成 core 文件(当前 shell 会话) ulimit -c unlimited # 2. 运行崩溃程序 → 产生 core(或 core.<pid>) ./ex1 ls -l core* # 3. 用 gdb 打开 core 回放崩溃现场(无需重新运行程序) gdb ./ex1 core # 进入后执行 bt 查看崩溃调用栈 # 4. core 生成路径与命名随发行版配置(/proc/sys/kernel/core_pattern)而不同,原理一致