这里写目录标题
- [GDB 常用调试命令全汇总](#GDB 常用调试命令全汇总)
- 调试代码
GDB 常用调试命令全汇总
| 命令 | 简写 | 含义及功能描述 |
|---|---|---|
| list | l | 显示源代码。默认列出 10 行,继续按回车可翻页查看后续代码 |
| list n | l n | 显示从第 n 行开始的源代码 |
| list func | l func | 显示函数名为 func 的源代码 |
| run | r | 开始运行程序(若有断点则停在第一个断点处) |
| next | n | 逐过程调试。单步执行,如果遇到函数调用,不进入函数内部 |
| step | s | 逐语句调试。单步执行,如果遇到函数调用,则进入函数内部 |
| break n | b n | 在第 n 行设置断点 |
| break func | b func | 在函数 func 的起始处设置断点 |
| break file:n | b file:n | 在指定源文件 file 的第 n 行设置断点 |
| info break | i b | 查看当前已设置的所有断点信息(包括编号、状态、地址等) |
| delete num | d num | 删除断点。num 为断点的编号(通过 info break 查看) |
| disable num | dis num | 禁用指定编号的断点,断点位置保留但不触发 |
| enable num | ena num | 启用指定编号的断点 |
| print expr | p expr | 打印表达式或变量的值 |
| display var | display | 常显示变量。设置后每一步执行都会自动打印该变量的值 |
| undisplay id | undisplay | 取消指定标号的追踪显示(注意:此处使用 display 产生的编号) |
| until n | u n | 运行程序直到指定的第 n 行停下(常用于跳出循环) |
| finish | finish | 执行直到当前函数返回。运行完当前函数,停在调用点之后 |
| continue | c | 继续执行程序,直到遇到下一个断点或程序结束 |
| set var v=val | set var | 在调试过程中动态修改变量 v 的值为 val |
| backtrace | bt | 查看当前的函数调用堆栈(栈帧回溯) |
| info locals | i locals | 查看当前函数栈帧中所有局部变量的值 |
| watch var | watch | 设置监视点。当变量 var 的值发生变化时,程序自动停下 |
| quit | q | 退出 GDB 调试 |
| (Enter) | - | 直接回车:重复执行上一条指令 |
| (Tab) | - | 连按两次 Tab 键:指令自动补全或列出候选指令 |
调试代码
test.c
cpp
1 #include <stdio.h>
2
3 int AddToTop(int top)
4 {
5 printf("Enter AddToTop\n");
6
7 int count = 0;
8 for(int i = 1;i <= top; ++i)
9 {
10 count += i;
11 }
12
13 printf("Quit AddToTop\n");
14 return count;
15 }
16
17 int main(void)
18 {
19 int top = 10;
20 int ret = AddToTop(top);
21
22 printf("ret = %d\n", ret);
23 return 0;
24 }
下面是Makefile中的内容,用于自动化编译:
cpp
CC = gcc
CFLAGS = -g -Wall -std=c99 # 在这里统一添加 -g
mytest:test.o
$(CC) $(CFLAGS) -o $@ $^
test.c
.PHONY:clean
clean:
rm -rf mytest
使用 readelf 工具查看 ELF 文件格式中的调试段。
cpp
# 若输出包含 .debug_info 等字段,说明具备调试条件
readelf -S mytest | grep -i debug
https://blog.csdn.net/weixin_45031801/article/details/134399664?