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

相关推荐
乌萨奇也要立志学C++4 分钟前
【Linux】线程池(二)C++ 手写线程池全流程:从核心设计到线程安全、死锁深度解析
linux·c++
feng_you_ying_li5 分钟前
list的介绍与底层实现
数据结构·c++·list
4t4run6 分钟前
29、Linux 防火墙
linux·运维·服务器
星轨初途7 分钟前
C++入门基础指南
开发语言·c++·经验分享·redis
c++逐梦人14 分钟前
Linux进程间通信
linux·运维·服务器
醉卧南楼15 分钟前
vector在不同场景下的最优声明与数据添加策略
c++·性能优化·vector
wanhengidc15 分钟前
服务器硬盘都有哪些功能
大数据·运维·服务器·数据库·科技
guguhaohao18 分钟前
平衡二叉树(AVL),咕咕咕!
数据结构·c++·算法
认真的柯南20 分钟前
深入解析服务器内存架构:从DRAM颗粒到NUMA模式
服务器·架构·numa
wanhengidc20 分钟前
服务器分布式存储的功能
运维·服务器·分布式