Linux常用命令——gdb命令

news2024/11/16 7:46:34

在线Linux命令查询工具

gdb

功能强大的程序调试器

补充说明

gdb命令包含在GNU的gcc开发套件中,是功能强大的程序调试器。GDB中的命令固然很多,但我们只需掌握其中十个左右的命令,就大致可以完成日常的基本的程序调试工作。

语法

gdb(选项)(参数)

选项

-cd:设置工作目录;
-q:安静模式,不打印介绍信息和版本信息;
-d:添加文件查找路径;
-x:从指定文件中执行GDB指令;
-s:设置读取的符号表文件。

| |
| |
| |
| file <文件名> | 加载被调试的可执行程序文件。
因为一般都在被调试程序所在目录下执行GDB,因而文本名不需要带路径。 | (gdb) file gdb-sample |
| r | Run的简写,运行被调试的程序。
如果此前没有下过断点,则执行完整个程序;如果有断点,则程序暂停在第一个可用断点处。 | (gdb) r |
| c | Continue的简写,继续执行被调试程序,直至下一个断点或程序结束。 | (gdb) c |
| b <行号>
b <函数名称>
b *<函数名称>
b <代码地址> d [编号] | b: Breakpoint的简写,设置断点。两可以使用“行号”“函数名称”“执行地址”等方式指定断点位置。
其中在函数名称前面加“
”符号表示将断点设置在“由编译器生成的prolog代码处”。如果不了解汇编,可以不予理会此用法。 d: Delete breakpoint的简写,删除指定编号的某个断点,或删除所有断点。断点编号从1开始递增。 | (gdb) b 8
(gdb) b main
(gdb) b *main
(gdb) b *0x804835c (gdb) d |
| s, n | s: 执行一行源程序代码,如果此行代码中有函数调用,则进入该函数;
n: 执行一行源程序代码,此行代码中的函数调用也一并执行。 s 相当于其它调试器中的“Step Into (单步跟踪进入)”;
n 相当于其它调试器中的“Step Over (单步跟踪)”。 这两个命令必须在有源代码调试信息的情况下才可以使用(GCC编译时使用“-g”参数)。 | (gdb) s
(gdb) n |
| si, ni | si命令类似于s命令,ni命令类似于n命令。所不同的是,这两个命令(si/ni)所针对的是汇编指令,而s/n针对的是源代码。 | (gdb) si
(gdb) ni |
| p <变量名称> | Print的简写,显示指定变量(临时变量或全局变量)的值。 | (gdb) p i
(gdb) p nGlobalVar |
| display … undisplay <编号> | display,设置程序中断后欲显示的数据及其格式。
例如,如果希望每次程序中断后可以看到即将被执行的下一条汇编指令,可以使用命令
“display /i $pc”
其中 $pc 代表当前汇编指令,/i 表示以十六进行显示。当需要关心汇编代码时,此命令相当有用。 undispaly,取消先前的display设置,编号从1开始递增。 | (gdb) display /i $pc (gdb) undisplay 1 |
| i | info的简写,用于显示各类信息,详情请查阅“help i”。 | (gdb) i r |
| q | Quit的简写,退出GDB调试环境。 | (gdb) q |
| help [命令名称] | GDB帮助命令,提供对GDB名种命令的解释说明。
如果指定了“命令名称”参数,则显示该命令的详细说明;如果没有指定参数,则分类显示所有GDB命令,供用户进一步浏览和查询。 | (gdb) help |

参数

文件:二进制可执行程序。

实例

以下是linux下dgb调试的一个实例,先给出一个示例用的小程序,C语言代码:

#include &lt;stdio.h&gt;
int nGlobalVar = 0;

int tempFunction(int a, int b)
{
    printf("tempFunction is called, a = %d, b = %d /n", a, b);
    return (a + b);
}

int main()
{
    int n;
        n = 1;
        n++;
        n--;

        nGlobalVar += 100;
        nGlobalVar -= 12;

    printf("n = %d, nGlobalVar = %d /n", n, nGlobalVar);

        n = tempFunction(1, 2);
    printf("n = %d", n);

    return 0;
}

请将此代码复制出来并保存到文件 gdb-sample.c 中,然后切换到此文件所在目录,用GCC编译之:

gcc gdb-sample.c -o gdb-sample -g

在上面的命令行中,使用 -o 参数指定了编译生成的可执行文件名为 gdb-sample,使用参数 -g 表示将源代码信息编译到可执行文件中。如果不使用参数 -g,会给后面的GDB调试造成不便。当然,如果我们没有程序的源代码,自然也无从使用 -g 参数,调试/跟踪时也只能是汇编代码级别的调试/跟踪。
下面“gdb”命令启动GDB,将首先显示GDB说明,不管它:

GNU gdb Red Hat Linux (5.3post-0.20021129.18rh)
Copyright 2003 free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i386-redhat-linux-gnu".
(gdb)

上面最后一行“(gdb)”为GDB内部命令引导符,等待用户输入GDB命令。
下面使用“file”命令载入被调试程序 gdb-sample(这里的 gdb-sample 即前面 GCC 编译输出的可执行文件):

(gdb) file gdb-sample
Reading symbols from gdb-sample...done.

上面最后一行提示已经加载成功。
下面使用“r”命令执行(Run)被调试文件,因为尚未设置任何断点,将直接执行到程序结束:

(gdb) r
Starting program: /home/liigo/temp/test_jmp/test_jmp/gdb-sample
n = 1, nGlobalVar = 88
tempFunction is called, a = 1, b = 2
n = 3
Program exited normally.

下面使用“b”命令在 main 函数开头设置一个断点(Breakpoint):

(gdb) b main
Breakpoint 1 at 0x804835c: file gdb-sample.c, line 19.

上面最后一行提示已经成功设置断点,并给出了该断点信息:在源文件 gdb-sample.c 第19行处设置断点;这是本程序的第一个断点(序号为1);断点处的代码地址为 0x804835c(此值可能仅在本次调试过程中有效)。回过头去看源代码,第19行中的代码为“n = 1”,恰好是 main 函数中的第一个可执行语句(前面的“int n;”为变量定义语句,并非可执行语句)。
再次使用“r”命令执行(Run)被调试程序:

(gdb) r
Starting program: /home/liigo/temp/gdb-sample

Breakpoint 1, main () at gdb-sample.c:19
19 n = 1;

程序中断在gdb-sample.c第19行处,即main函数是第一个可执行语句处。
上面最后一行信息为:下一条将要执行的源代码为“n = 1;”,它是源代码文件gdb-sample.c中的第19行。
下面使用“s”命令(Step)执行下一行代码(即第19行“n = 1;”):

(gdb) s
20 n++;

上面的信息表示已经执行完“n = 1;”,并显示下一条要执行的代码为第20行的“n++;”。
既然已经执行了“n = 1;”,即给变量 n 赋值为 1,那我们用“p”命令(Print)看一下变量 n 的值是不是 1 :

(gdb) p n
$1 = 1

果然是 1。($1大致是表示这是第一次使用“p”命令——再次执行“p n”将显示“$2 = 1”——此信息应该没有什么用处。)
下面我们分别在第26行、tempFunction 函数开头各设置一个断点(分别使用命令“b 26”“b tempFunction”):

(gdb) b 26
Breakpoint 2 at 0x804837b: file gdb-sample.c, line 26.
(gdb) b tempFunction
Breakpoint 3 at 0x804832e: file gdb-sample.c, line 12.

使用“c”命令继续(Continue)执行被调试程序,程序将中断在第二 个断点(26行),此时全局变量 nGlobalVar 的值应该是 88;再一次执行“c”命令,程序将中断于第三个断点(12行,tempFunction 函数开头处),此时tempFunction 函数的两个参数 a、b 的值应分别是 1 和 2:

(gdb) c
Continuing.

Breakpoint 2, main () at gdb-sample.c:26
26 printf("n = %d, nGlobalVar = %d /n", n, nGlobalVar);
(gdb) p nGlobalVar
$2 = 88
(gdb) c
Continuing.
n = 1, nGlobalVar = 88

Breakpoint 3, tempFunction (a=1, b=2) at gdb-sample.c:12
12 printf("tempFunction is called, a = %d, b = %d /n", a, b);
(gdb) p a
$3 = 1
(gdb) p b
$4 = 2

上面反馈的信息一切都在我们预料之中~~
再一次执行“c”命令(Continue),因为后面再也没有其它断点,程序将一直执行到结束:

(gdb) c
Continuing.
tempFunction is called, a = 1, b = 2
n = 3
Program exited normally.

有时候需要看到编译器生成的汇编代码,以进行汇编级的调试或跟踪,又该如何操作呢?
这就要用到display命令“display /i $pc”了(此命令前面已有详细解释):

(gdb) display /i $pc
(gdb)

此后程序再中断时,就可以显示出汇编代码了:

(gdb) r
Starting program: /home/liigo/temp/test_jmp/test_jmp/gdb-sample

Breakpoint 1, main () at gdb-sample.c:19
19 n = 1;
1: x/i $pc 0x804835c &lt;main+16&gt;: movl $0x1,0xfffffffc(%ebp)

看到了汇编代码,“n = 1;”对应的汇编代码是“movl $0x1,0xfffffffc(%ebp)”。
并且以后程序每次中断都将显示下一条汇编指定(“si”命令用于执行一条汇编代码——区别于“s”执行一行C代码):

(gdb) si
20 n++;
1: x/i $pc 0x8048363 &lt;main+23&gt;: lea 0xfffffffc(%ebp),%eax
(gdb) si
0x08048366 20 n++;
1: x/i $pc 0x8048366 &lt;main+26&gt;: incl (%eax)
(gdb) si
21 n--;
1: x/i $pc 0x8048368 &lt;main+28&gt;: lea 0xfffffffc(%ebp),%eax
(gdb) si
0x0804836b 21 n--;
1: x/i $pc 0x804836b &lt;main+31&gt;: decl (%eax)
(gdb) si
23 nGlobalVar += 100;
1: x/i $pc 0x804836d &lt;main+33&gt;: addl $0x64,0x80494fc

接下来我们试一下命令“b *<函数名称>”。
为了更简明,有必要先删除目前所有断点(使用“d”命令——Delete breakpoint):

(gdb) d
Delete all breakpoints? (y or n) y
(gdb)

当被询问是否删除所有断点时,输入“y”并按回车键即可。
下面使用命令“b *main”在 main 函数的 prolog 代码处设置断点(prolog、epilog,分别表示编译器在每个函数的开头和结尾自行插入的代码):

(gdb) b *main
Breakpoint 4 at 0x804834c: file gdb-sample.c, line 17.
(gdb) r
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/liigo/temp/test_jmp/test_jmp/gdb-sample

Breakpoint 4, main () at gdb-sample.c:17
17 {
1: x/i $pc 0x804834c &lt;main&gt;: push %ebp
(gdb) si
0x0804834d 17 {
1: x/i $pc 0x804834d &lt;main+1&gt;: mov %esp,%ebp
(gdb) si
0x0804834f in main () at gdb-sample.c:17
17 {
1: x/i $pc 0x804834f &lt;main+3&gt;: sub $0x8,%esp
(gdb) si
0x08048352 17 {
1: x/i $pc 0x8048352 &lt;main+6&gt;: and $0xfffffff0,%esp
(gdb) si
0x08048355 17 {
1: x/i $pc 0x8048355 &lt;main+9&gt;: mov $0x0,%eax
(gdb) si
0x0804835a 17 {
1: x/i $pc 0x804835a &lt;main+14&gt;: sub %eax,%esp
(gdb) si
19 n = 1;
1: x/i $pc 0x804835c &lt;main+16&gt;: movl $0x1,0xfffffffc(%ebp)

此时可以使用“i r”命令显示寄存器中的当前值———“i r”即“Infomation Register”:

(gdb) i r
eax 0xbffff6a4 -1073744220
ecx 0x42015554 1107383636
edx 0x40016bc8 1073834952
ebx 0x42130a14 1108544020
esp 0xbffff6a0 0xbffff6a0
ebp 0xbffff6a8 0xbffff6a8
esi 0x40015360 1073828704
edi 0x80483f0 134513648
eip 0x8048366 0x8048366
eflags 0x386 902
cs 0x23 35
ss 0x2b 43
ds 0x2b 43
es 0x2b 43
fs 0x0 0
gs 0x33 51

当然也可以显示任意一个指定的寄存器值:

(gdb) i r eax
eax 0xbffff6a4 -1073744220

最后一个要介绍的命令是“q”,退出(Quit)GDB调试环境:

(gdb) q
The program is running. exit anyway? (y or n)

补充内容

gdb 教程:
慕课网-Linux C语言指针与内存-第三章
如果删除源代码, 就无法显示行号等辅助信息了

gcc -g gdb.c -o gdb.out # -g 支持gdb调试; -o 输出, 默认为 a.out

gdb gdb.out # 进入 gdb 调试环境
enter # 继续执行上条命令
l # 列出源代码, 默认 10 行, 按 l 继续

start # 开始单步调试, 默认 main() 第一行
p a # 查看 a 变量的值
n # 继续到下一行
s # 进入子函数
bt # 查看函数栈
f 1 # 切换函数栈

q 退出调试

测试用代码

#include &lt;stdio.h&gt;

void change(int a, int b){
    int tmp=a;
    a=b; b=tmp;
}

void change2(int *a, int *b){
    int tmp=*a;
    *a=*b; *b=tmp;
}

int main(){
    int a=5,b=3;
    change(a,b);
    printf("change:\na=%d\nb=%d\n", a,b);
    change2(&amp;a,&amp;b);
    printf("change2:\na=%d\nb=%d\n", a,b);
}

在线Linux命令查询工具

在线Linux命令查询工具
原文链接

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/655591.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

DeepFace:人脸识别库 DeepFace 简单认知

写在前面 工作中遇到&#xff0c;简单整理博文内容为 deepface 的简单介绍理解不足小伙伴帮忙指正 对每个人而言&#xff0c;真正的职责只有一个&#xff1a;找到自我。然后在心中坚守其一生&#xff0c;全心全意&#xff0c;永不停息。所有其它的路都是不完整的&#xff0c;是…

HarmonyOS学习路之开发篇—Java UI框架(使用工具自动生成JS FA调用PA代码)

JS FA&#xff08;Feature Ability&#xff09;调用PA &#xff08;Particle Ability&#xff09;是使用基于JS扩展的类Web开发范式的方舟开发框架所提供的一种跨语言能力调用的机制&#xff0c;用于建立JS能力与Java能力之间传递方法调用、处理数据返回以及订阅事件上报的通道…

代码审计——目录遍历详解

为方便您的阅读&#xff0c;可点击下方蓝色字体&#xff0c;进行跳转↓↓↓ 01 漏洞描述02 审计要点03 漏洞特征04 漏洞案例05 修复方案 01 漏洞描述 目录遍历&#xff0c;即利用路径回溯符“../”跳出程序本身的限制目录实现下载任意文件。 例如Web应用源码目录、Web应用配置…

FastDeploy部署参考

一、FastDeploy的gitee地址 https://gitee.com/leiqing1/FastDeploy/blob/release/0.3.0/docs/cn/faq/use_sdk_on_windows.md#21-%E4%B8%8B%E8%BD%BD%E9%A2%84%E7%BC%96%E8%AF%91%E5%BA%93%E6%88%96%E8%80%85%E4%BB%8E%E6%BA%90%E7%A0%81%E7%BC%96%E8%AF%91%E6%9C%80%E6%96%B0%…

When viruses are good for you 病毒,有时对人体是有益的 | 经济学人20230506版社论双语精翻

本篇来自《经济学人》&#xff08;The Economist&#xff09;2023年5月6日社论&#xff08;Leaders&#xff09;精选&#xff1a;《病毒&#xff0c;有时对人体是有益的》&#xff08;When viruses are good for you&#xff09;。 Bacteriophages 噬菌体 When viruses are goo…

onlyoffice变量提取,处理各种办公文档

onlyoffice变量提取,处理各种办公文档 使用 ONLYOFFICE Docs 在 HumHub 中处理各种办公文档。 带有 HumHub 连接器的 ONLYOFFICE Docs 企业版允许您在灵活的开源社交网络工具包 HumHub 中实时协作查看和编辑办公文档(Word、Excel 或 PowerPoint)。它包括 ONLYOFFICE Docs&#…

代码审计——SQL注入详解

为方便您的阅读&#xff0c;可点击下方蓝色字体&#xff0c;进行跳转↓↓↓ 01 漏洞描述02 审计要点03 漏洞特征04 漏洞案例05 修复方案 01 漏洞描述 当应用程序将用户输入的内容&#xff0c;拼接到SQL语句中&#xff0c;一起提交给数据库执行时&#xff0c;就会产生SQL注入威…

代码随想录训练营Day60|84. 柱状图中最大的矩形

84. 柱状图中最大的矩形 class Solution {public int largestRectangleArea(int[] heights) {int res0;// 数组扩容&#xff0c;在头和尾各加入一个元素int [] newHeights new int[heights.length 2];newHeights[0] 0;newHeights[newHeights.length - 1] 0;for (int index…

Docker desktop 怎么切换docker源

点击setting&#xff0c;点击docker Engine 进行编辑 {"registry-mirrors":["https://registry.docker-cn.com","http://hub-mirror.c.163.com","https://4jup2u41.mirror.aliyuncs.com","https://docker.mirrors.ustc.edu.cn&q…

校园预付费管理系统与水电计量设备仪表的实际应用 安科瑞 许敏

摘要&#xff1a;论文设计了适用于学生公寓的自助式预付费控电控水管理系统&#xff0c;采用多种智能功能&#xff0c;可以监测和显示漏电现象&#xff0c;通过短路、跳线、零线接地等方式防范和记录用户的偷电行为&#xff0c;通过报警和拉闸防止事故的发生。该系统采用先进的…

霍夫变换原理

文章目录 霍夫变换原理当点都在y轴上时&#xff0c;用ykxb形式是无法求出参数空间中的交点&#xff0c;也就是累计都一样。所以就用极坐标来表示参数空间。公式求证过程 霍夫变换原理 当点都在y轴上时&#xff0c;用ykxb形式是无法求出参数空间中的交点&#xff0c;也就是累计都…

linux服务器安装nodejs

注意&#xff1a; 本文针对的是有linux操作基础&#xff0c; 会使用vim的基本操作的同学。故有些很基础的东西没有赘述&#xff0c;如果是纯小白的同学&#xff0c;看起来可能会感觉缺失一些东西。 1.nodejs官网下载自己需要的版本的node node版本选择下载地址 我使用的是14.…

图像边缘检测原理

文章目录 图像边缘检测原理1:2:3:基本边缘检测算子 图像边缘检测原理 1: 图像的边缘指的是图像中像素灰度值突然发生变化的区域&#xff0c;如果将图像的每一行像素和每一列像素都描述成一个关于灰度值的函数&#xff0c;那么图像的边缘对应在灰度值函数中是函数值突然变大的…

Autoware 安装(踩坑指南)

Autoware 安装&#xff08;踩坑指南&#xff09; 【Autoware】2小时安装Autoware1.13&#xff08;保姆级教程&#xff09; Autoware入门学习&#xff08;二&#xff09;——Ubuntu18.04下的源码安装和配置 上面的两篇博客安装都异常顺利&#xff0c;甚至没有一点报错&#xff0…

AMEYA360代理线:艾睿红外热成像仪数据机房监测应用

数据信息时代&#xff0c;数据机房是企业重要的区域。近日某购物平台发生的数据机房宕机事故&#xff0c;引发关注。机房设备温度异常&#xff0c;使得系统崩溃&#xff0c;经济损失超亿元。红外热成像仪作为一种非接触式、精准度高、可视化的温度测量工具&#xff0c;为数据机…

【MyBatis 神级框架】从入门到进阶

&#x1f389;&#x1f389;&#x1f389;点进来你就是我的人了博主主页&#xff1a;&#x1f648;&#x1f648;&#x1f648;戳一戳,欢迎大佬指点! 欢迎志同道合的朋友一起加油喔&#x1f93a;&#x1f93a;&#x1f93a; 目录 1. 什么是 MyBatis 1.1 为什么要学MaBatis&am…

TikTok正测试AI聊天机器人Tako

该功能可以“从根本上改变应用程序中的搜索和导航” 原文链接&#xff1a;TikTok tests AI chatbot called Tako – The Verge TikTok正在测试一个名为Tako的AI聊天机器人&#xff0c;根据与The Verge共享的功能截图&#xff0c;它可以根据人们的问题推荐视频。 如果TikTok最…

总结:公有云产品之CDN

一、介绍 由于公司经常提供CDN相关概念&#xff0c;本文特地总结下。 二、产品说明 百度云的内容分发网络CDN是一款基于互联网的分布式服务平台&#xff0c;可以加速网络上的内容分发和传输&#xff0c;提高网络的稳定性和访问速度。 CDN主要通过将网站的静态和动态资源缓存…

读书笔记-《ON JAVA 中文版》-摘要17[第十七章 文件]

文章目录 第十七章 文件1. 文件和目录路径1.1 选取路径部分片段1.2 路径分析1.3 Paths的增减修改 2. 目录3. 文件系统4. 路径监听5. 文件查找6. 文件读写7. 本章小结 第十七章 文件 在丑陋的 Java I/O 编程方式诞生多年以后&#xff0c;Java终于简化了文件读写的基本操作。 在 …

手机APP测试流程规范模板

一、流程图 二、测试周期 9.25-10.5 1、测试资源 测试任务开始前&#xff0c;检查各项测试资源。 1.1、产品功能需求文档 1&#xff09;产品原型图 2&#xff09;产品效果图 3&#xff09;行为统计分析定义文档 4&#xff09;测试设备&#xff08;Android4.1-Android4.…