1 示例代码
objectivec
#include <stdio.h>
int Sum(int s, int e)
{
int result = 0;
for(int i = s; i <= e; ++i)
{
result += i;
}
return result;
}
int main()
{
int start = 1;
int end = 100;
printf("I will begin\n");
int n = Sum(start, end);
printf("running done, result is: [%d-%d]=%d\n", start, end, n);
while(1)
{
printf("我是一个进程\n");
}
return 0;
}
2 预备知识
程序的发布方式有两种,debug 模式和 release 模式,Liunx gcc/g++ 出来的二进制程序,默认是 release 模式。
要是 gdb 和 cgdb 调试,必须在源代码生成二进制程序的时候,加上 -g 选项,如果没有添加,程序无法被编译。
bash
~/mydir/linux/gdb_tools$ gcc -o code code.c # 默认 release 版本,不支持调试
~/mydir/linux/gdb_tools$ file code
code: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=913822b416c73e5294e4b424d8c4f04ea9b42c1e, for GNU/Linux 3.2.0, not stripped
~/mydir/linux/gdb_tools$ gcc -o code.exe code.c -g # debug 版本,支持调试
code.exe: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=770c3ba5aa1d5c7c996be9c7944cba0c6bb9f263, for GNU/Linux 3.2.0, with debug_info, not stripped
3 常见使用
开始:
bash
gdb 可执行程序 # 一般我们不这么用
cgdb 可执行程序 # 一般我们用cgdb
退出:
bash
ctrl + d 或者 quit
|--------------------|-----------------------|-------------------------|
| 命令 | 作⽤ | 样例 |
| list/l | 显⽰源代码,从上次位置开始,每次列出10⾏ | list/l 10 |
| list/l 函数名 | 列出指定函数的源代码 | list/l main |
| list/l ⽂件名:⾏号 | 列出指定⽂件的源代码 | list/l mycmd.c:1 |
| r/run | 从程序开始连续执⾏ | run |
| n/next | 单步执⾏,不进⼊函数内部 | next |
| s/step | 单步执⾏,进⼊函数内部 | step |
| break/b [⽂件名:]⾏号 | 在指定⾏号设置断点 | break 10break test.c:10 |
| break/b 函数名 | 在函数开头设置断点 | break main |
| info break/b | 查看当前所有断点的信息 | info break |
| finish | 执⾏到当前函数返回,然后停⽌ | finish |
|------------------------|-------------------|----------------------|
| print/p 表达式 | 打印表达式的值 | print start+end |
| p 变量 | 打印指定变量的值 | p x |
| set var 变量=值 | 修改变量的值 | set var i=10 |
| continue/c | 从当前位置开始连续执⾏程序 | continue |
| delete/d breakpoints | 删除所有断点 | delete breakpoints |
| delete/d breakpoints n | 删除序号为n的断点 | delete breakpoints 1 |
| disable breakpoints | 禁⽤所有断点 | disable breakpoints |
| enable breakpoints | 启⽤所有断点 | enable breakpoints |
| info/i breakpoints | 查看当前设置的断点列表 | info breakpoints |
| display 变量名 | 跟踪显⽰指定变量的值(每次停⽌时 | display x |
| undisplay 编号 | 取消对指定编号的变量的跟踪显⽰ | undisplay 1 |
| until X⾏号 | 执⾏到指定⾏号 | until 20 |
| backtrace/bt | 查看当前执⾏栈的各级函数调⽤及参数 | backtrace |
| info/i locals | 查看当前栈帧的局部变量值 | info locals |
| quit | 退出GDB调试器 | quit |
gdb 调试效果(模式不太友好):

cgdb 调试效果:代码和调试界面上下分开,比较方便

3.1 打断点: 对应的行号会高亮

**3.2 运行:**r 命令会从当前的断点开始运行

**3.3 单步运行:**s 会进入具体的函数步骤

**3.4 逐过程运行:**n 会跳过相应函数

**3.5 查看断点:**info b

**3.6 查看变量:**display 变量名

**3.7 取消查看变量:**undisplay 变量名号,undisplay 1 这时就看不到 result

**3.8 监视一个变量:**watch 变量名

**3.9 跳转到指定行:**until 行号(前提中间没有断点)

3.10 从当前行开始连续执行程序: c在断点之间连续执行


**3.11 执行到当前函数返回,然后停止:**finish(前提是中间没有断点,要不然会跳到断点处)


3.12 查看栈帧:bt

**3.13 查看当前当前栈帧局部变量值:**i locals

**3.14 禁用断点:**disable 断点编号,禁用的断点hui'bia

**3.15 启用断点:**enable 断点编号

**3.16 设置临时变量值:set var 变量名=num,**方便调试是否这个变量导致的问题

3.17 打条件断点:b 行号 if 变量名==num

3.18 在已有断点的情况下新增、修改条件:condition 断点编号 变量名==num
