Linux:调试器-gdb/cgdb使用

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

相关推荐
wj3055853786 小时前
课程 9:模型测试记录与 Prompt 策略
linux·人工智能·python·comfyui
为何创造硅基生物7 小时前
C语言 结构体内存对齐规则(通俗易懂版)
c语言·开发语言
abigriver7 小时前
打造 Linux 离线大模型级语音输入法:Whisper.cpp + 3090 显卡加速与 Rime 中英混输终极调优指南
linux·运维·whisper
仰泳之鹅7 小时前
【C语言】自定义数据类型2——联合体与枚举
c语言·开发语言·算法
wangqiaowq7 小时前
windows下nginx的安装
linux·服务器·前端
YYRAN_ZZU8 小时前
Petalinux新建自动脚本启动
linux
jolimark8 小时前
C语言自学攻略:小白入门三步走
c语言·编程入门·学习路线·实践项目·自学攻略
charlie1145141918 小时前
嵌入式Linux驱动开发pinctrl篇(1)——从寄存器到子系统:驱动演进之路
linux·运维·驱动开发
于小猿Sup8 小时前
VMware在Ubuntu22.04驱动Livox Mid360s
linux·c++·嵌入式硬件·自动驾驶
cen__y9 小时前
Linux12(Git01)
linux·运维·服务器·c语言·开发语言·git