跳到主要内容
🔍

代码示例: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)而不同,原理一致