GDB(调试工具)

本文介绍GDB——一个强大的Linux下的程序调试工具。涵盖GDB的基本使用方法,包括启动程序、设置断点、单步执行等操作,以及如何利用GDB进行变量值检查和程序状态跟踪。

什么是GDB

GDB是GNU开源组织发布的一个强大的Linux下的程序调试工具。
一般来说,GDB主要帮助你完成下面四个方面的功能:

  1. 启动你的程序,可以按照你的自定义的要求随心所欲的运行程序。

  2. 可让被调试的程序在你所指定的调置的断点处停住。(断点可以是条件表达式)

  3. 当程序被停住时,可以检查此时你的程序中所发生的事。

  4. 动态的改变你程序的执行环境。

GDB调试的对象

GDB主要来调试C/C++语言写的程序,当然也就可以调试其他语言程序。GDB调试一定要是可执行文件而不是.c文件。
要用gcc进行编译,具体的命令如下:

gcc -g 源文件.c -o 输出的目标文件

-g,-o参数缺一不可。

GDB常用的调试命令

  1. 启动
    使用命令 gdb 程序名启动,启动成功的标志就是最终输出的 (gdb)。
[root@bogon demo]# gdb main.exe
GNU gdb (GDB) 8.0.1
Copyright (C) 2017 Free Software Foundation, Inc.
......
(gdb) 
  1. GDB常用的调试指令
调试指令作 用
(gdb) break xxx;(gdb) b xxx在源代码指定的某一行设置断点,其中 xxx 用于指定具体打断点的位置。
(gdb) run;(gdb) r执行被调试的程序,其会自动在第一个断点处暂停执行。
(gdb) continue;(gdb) c当程序在某一断点处停止运行后,使用该指令可以继续执行,直至遇到下一个断点或者程序结束。
(gdb) next;(gdb) n令程序一行代码一行代码的执行(逐过程,函数直接执行)。
(gdb)step;(gdb)s单步调试(逐语句:跳入自定义函数内部执行)
(gdb)backtrace;(gdb)bt查看函数的调用的栈帧和层级关系
(gdb) print xxx;(gdb) p xxx打印指定变量的值,其中 xxx 指的就是某一变量名。
(gdb)info breakpoints查看当前设置的所有断点
(gdb)delete breakpoints num删除第num个断点
(gdb)display追踪查看具体变量值
(gdb)undisplay取消追踪观察变量
(gdb)watch被设置观察点的变量发生修改时,打印显示
(gdb)i watch显示观察点
(gdb) list;(gdb) l显示源程序代码的内容,包括各行代码所在的行号。
(gdb) quit;(gdb) q终止调试。
(gdb) run argv[1] argv[2]调试时命令行传参

实例:

(gdb) l                      <-- 显示带行号的源代码
1 #include <stdio.h>
2 int main ()
3 {
4     unsigned long long int n, sum;
5     n = 1;
6     sum = 0;
7     while (n <= 100)
8     {
9         sum = sum + n;
10         n = n + 1;
(gdb)                      <-- 默认情况下,l 选项只显示 10 行源代码,如果查看后续代码,安装 Enter 回车即可                                                               
11     }
12     return 0;
13 }
(gdb) b 7               <-- 在第 7 行源代码处打断点
Breakpoint 1 at 0x400504: file main.c, line 7.
(gdb) r                   <-- 运行程序,遇到断点停止
Starting program: /home/mozhiyan/demo1/main.exe

Breakpoint 1, main () at main.c:7
7     while (n <= 100)
Missing separate debuginfos, use: debuginfo-install glibc-2.17-55.el7.x86_64
(gdb) p n               <-- 查看代码中变量 n 的值
$1 = 1                   <-- 当前 n 的值为 1,$1 表示该变量所在存储区的名称
(gdb) b 12             <-- 在程序第 12 行处打断点
Breakpoint 2 at 0x40051a: file main.c, line 12.
(gdb) c                  <-- 继续执行程序
Continuing.

Breakpoint 2, main () at main.c:12
12     return 0;
(gdb) p n               <-- 查看当前 n 变量的值
$2 = 101               <-- 当前 n 的值为 101
(gdb) q                  <-- 退出调试
A debugging session is active.

Inferior 1 [process 3080] will be killed.

Quit anyway? (y or n) y                 <-- 确实是否退出调试,y 为退出,n 为不退出
[root@bogon demo]#

注:
监视点
大型软件或大量使用指针的程序中,很难弄清变量在什么地方被改变,要想找到变量在何处被改变,可以使用 watch 命令(监视点,watchpoint)。格式如下:

watch <表达式>:表达式发生变化时暂停运行。
awatch <表达式>:表达式被访问、改变时暂停运行。
rwatch <表达式>:表达式被访问时暂停运行。

需要注意,设置监视点可能会降低运行速度。

改变变量的值
格式:set variable <变量=表达式>。例如命令 set variable options = 0,将变量 options 的值改成了 0。

内核转储

内核转储(core dump)的最大好处是,它能保存问题发生时的状态只要有问题发生时程序的可执行文件和内核转储,就可以知道进程当前的状态。
大多数 Linux 发行版默认关闭了内核转储功能,使用 ulimit 命令可以查看当前的内核转储功能是否有效。

$ ulimit -c
0

-c 选项表示内核转储文件的大小限制,0 表示内核转储无效。开启内核转储执行命令:

$ ulimit -c unlimited
or
$ ulimit -c 上限

unlimited 意思是不限制内核转储文件的大小,发生问题时进程的内存就可以全部转储到内核转储文件中。或者设置内核转储文件的上限,在参数中指定上限大小,单位为 Kb。
  
程序发生异常时会在当前目录下生成内核转储文件。例如程序 a.out 生成转储文件 core,使用以下方式启动 GDB:

$ gdb -c core ./a.out

参考:
http://c.biancheng.net/view/8255.html
https://blog.youkuaiyun.com/horotororensu/article/details/82256832
https://blog.youkuaiyun.com/awm_kar98/article/details/82840811

08-20
<think>首先,用户的问题是:“请问gdb usage tutorial”,这是中文,意思是“请问GDB使用教程”。用户想了解GDB(GNU Debugger)的基本用法教程。 根据系统级指令: - 所有行内数学表达式必须使用$...$格式。但在这个问题中,可能没有数学表达式,所以我不需要担心这个。 - 独立公式必须使用$$...$$格式并单独成段。同样,可能不适用。 - LaTeX语法正确:确保在需要时正确使用。 - 使用中文回答:整个回答必须用中文。 - 生成相关问题:在回答结束时,生成相关问题。 - 回答中引用的段落末尾自然地添加引用标识:参考提供的引用内容,如[^1]和[^2]。我需要基于这些引用构建回答。 提供的引用: - 引用[1]:是关于加载GDB的示例,显示了GDB的启动信息。 - 引用[2]:是关于GDB和CGDB的笔记,包括常用命令和为什么使用CGDB。 用户意图是GDB使用教程,所以我应该提供一个结构清晰的GDB入门教程。 回答结构: - 结构清晰,帮助用户逐步解决问题。 - 尽量保证回答真实可靠:基于我的知识和提供的引用。 大纲回答: 1. **介绍GDB**:简要解释GDB是什么。 2. **基本用法**: - 如何启动GDB。 - 常用命令:如设置断点、运行程序、单步执行等。 - 基于引用[1]和[2]中的信息。 3. **示例**:提供一个简单的示例,展示GDB的使用。 4. **高级技巧**:提及一些高级用法,如.gdbinit文件(基于引用[2])。 5. **CGDB简介**:既然引用[2]提到CGDB,我可以简要介绍它作为GDB的替代。 6. **生成相关问题**:在最后,添加相关问题。 使用引用: - 在回答中自然地添加引用标识。例如,当提到GDB启动时,引用[1];当提到常用命令或CGDB时,引用[2]。 完整回答: - 用中文。 - 确保语言流畅。 相关问题生成: - 基于GDB教程,生成如“如何调试多线程程序?”或“GDB的替代工具有哪些?”等。 最终输出: - 以用户可见层格式。</think>### GDB 使用教程 GDB(GNU Debugger)是 Linux 下常用的开源调试工具,用于分析程序运行中的错误、检查内存状态和单步执行代码。本教程将逐步介绍 GDB 的基本用法,帮助您快速上手。内容基于真实可靠的参考资料,确保实用性。 #### 1. **GDB 简介** GDB 支持多种编程语言(如 C/C++),能帮助开发者定位段错误、内存泄漏等问题。它通过命令行交互方式工作,提供断点设置、变量监视和堆栈跟踪功能。在开发中,GDB调试复杂程序的首选工具[^1]。 #### 2. **基本用法** 以下是 GDB 的核心步骤,适用于大多数调试场景。操作前,请确保程序已编译为可调试版本(使用 `gcc -g` 选项)。 - **启动 GDB** 在终端输入 `gdb <可执行文件>` 启动调试器。例如: ```bash gdb a.out ``` 启动后会显示 GDB 版本信息,并进入交互提示符 `(gdb)` 状态[^1]。 - **常用命令列表** 这些命令是调试的基础: - `b <行号或函数名>`:设置断点(例如 `b main` 在主函数开头暂停)。 - `run`:启动程序执行(如果程序有参数,使用 `run arg1 arg2`)。 - `n`(next):单步执行,跳过函数调用。 - `s`(step):单步执行,进入函数内部。 - `c`(continue):从断点处继续运行到下一个断点或结束。 - `print <变量名>`:打印变量值(如 `print x`)。 - `bt`(backtrace):显示当前调用堆栈,帮助定位错误位置。 - `quit`:退出 GDB。 这些命令在 GDB 交互模式中直接输入即可[^2]。 - **简单示例** 假设有一个 C 程序 `test.c`,编译为 `a.out`: ```c #include <stdio.h> int main() { int x = 5; printf("x = %d\n", x); return 0; } ``` 调试过程: ```bash # 编译时添加调试信息 gcc -g test.c -o a.out # 启动 GDB gdb a.out ``` 在 GDB 中: ``` (gdb) b main # 在 main 函数设置断点 (gdb) run # 运行程序,停在 main 开头 (gdb) n # 单步执行,跳过 printf (gdb) print x # 打印变量 x 的值(输出 x = 5) (gdb) quit # 退出 ``` 此示例展示了如何暂停程序并检查变量。 #### 3. **高级技巧** - **多线程调试** 使用 `info threads` 查看所有线程,`thread <ID>` 切换线程。这在并发程序调试中非常有用[^2]。 - **.gdbinit 文件** 创建 `~/.gdbinit` 文件来自定义 GDB 行为。例如,添加 `set disassembly-flavor intel` 可设置反汇编风格,提升调试效率[^2]。 - **CGDB 替代工具** 如果 GDB 的文本界面不够友好,可以尝试 CGDB(Curses-based GDB)。它提供更稳定的 TUI 模式、语法高亮和滚动功能,特别适合 SSH 终端环境。安装后使用 `cgdb` 命令启动[^2]。 #### 4. **常见问题解决** - **段错误调试**:运行程序时崩溃,使用 `bt` 查看堆栈跟踪,定位错误行。 - **内存泄漏检测**:结合 Valgrind 工具分析。 - **性能优化**:GDB 不直接处理性能,但可帮助识别瓶颈代码区。 GDB 的学习曲线较陡,但掌握后能大幅提升调试效率。建议从简单程序开始练习,逐步深入复杂场景。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值