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

关键调试输出说明

  1. 断点触发

    Breakpoint 1, main () at test.c:9
    9           int i = 0;
    

    显示程序在指定行暂停执行

  2. 变量监控

    (gdb) p i
    $1 = 0
    

    显示变量i的当前值

  3. 函数调用跟踪

    (gdb) s
    test () at test.c:5
    5           printf("test8\n");
    

    进入test函数后的上下文

  4. 程序输出同步显示

    test1
    test2
    ...
    test8
    

    实时显示程序的标准输出

  5. 退出状态确认

    [Inferior 1 (process 1234) exited normally]
    

    验证程序正常退出


通过这个完整案例可以观察到:

  • 断点设置与触发的实际效果

  • 单步执行时程序状态的变化

  • 函数调用时的堆栈切换

  • 变量值的实时监控能力

  • 程序输出与调试操作的同步显示