Linux调试工具GDB(2)

举报
yd_274589494 发表于 2023/07/29 12:25:00 2023/07/29
【摘要】 @TOC 前言本篇文章我们继续讲解GDB调试。 一、数据断点在 GDB (GNU Debugger) 中,数据断点是一种断点类型,它允许你在程序访问指定内存地址的数据时暂停程序的执行。通过设置数据断点,你可以监视和调试特定内存位置的读取或写入操作。以下是在 GDB 中设置数据断点的基本用法:1.启动 GDB 并加载可执行文件:gdb executable_file2.选择要设置数据断点的内存...

@TOC


前言

本篇文章我们继续讲解GDB调试。

一、数据断点

在 GDB (GNU Debugger) 中,数据断点是一种断点类型,它允许你在程序访问指定内存地址的数据时暂停程序的执行。通过设置数据断点,你可以监视和调试特定内存位置的读取或写入操作。

以下是在 GDB 中设置数据断点的基本用法:

1.启动 GDB 并加载可执行文件:

gdb executable_file

2.选择要设置数据断点的内存地址。你可以使用以下方式之一:

使用变量名或指针来指定内存地址
使用表达式计算所需内存地址

3.使用 watch 命令设置数据断点:

(gdb) watch *address

其中 address 是你选择的内存地址。通过在地址前加上 * 来指示监视该地址的数据访问。

例如,如果你要监视一个 int 类型的变量 x,你可以这样设置数据断点:

(gdb) watch *(&x)

当程序访问被设置为数据断点的内存地址时,程序的执行将暂停,并返回到 GDB 提示符下。

5.在数据断点暂停时,你可以执行各种调试操作,如打印变量值、单步执行、查看回溯信息等。

二、x查看内存命令

在 GDB(GNU Debugger)中,x 命令用于以指定格式打印内存区域的内容。它允许你查看内存中存储的数据,并以不同的格式(例如十六进制、十进制、ASCII 码等)对数据进行呈现。

x 命令的基本语法如下:

x/[显示数量][打印格式] 内存地址

显示数量 是要显示的单位数量,默认为1。

打印格式 是指定要使用的输出格式,例如 x(十六进制)、d(十进制)、o(八进制)、u(无符号十进制)、t(二进制)等。GDB 还支持其他格式选项,可以参考 GDB 的文档了解更多细节。

内存地址 是你要查看的内存区域的地址表达式。

下面是一些示例,演示了不同的使用方式:

(gdb) x address

在这里插入图片描述
2.查看一定数量的内存地址的值:

(gdb) x/5 address

首先定义一个大小为5的一维数组:

#include <stdio.h>
#include <unistd.h>

int main(int argc, char** argv)
{
    int i = 0;

    int a[5] = {1, 2, 3, 4, 5};

    for(i = 0; i < 5; i++)
    {
        printf("%d\n", i);
        sleep(1);
    }

    printf("success complte\n");

    return 0;
}

查看一维数组中的数据值:
在这里插入图片描述

3.使用不同的打印格式:

(gdb) x/d address   # 十进制格式
(gdb) x/o address   # 八进制格式
(gdb) x/t address   # 二进制格式
(gdb) x/s address   # 字符串格式

在这里插入图片描述

4.查看结构体或数组的内存内容:

(gdb) x/4w &struct_var   # 以四个字为单位查看结构体的内容
(gdb) x/16xb &array     # 以字节为单位查看数组的内容

在这里插入图片描述

三、深入info命令

在讲解info命令之前我们先来讲解一下step命令:

GDB中的"step"命令用于逐行执行代码并进入函数内部。它允许你以单步模式执行程序,逐行跟踪代码执行过程,包括进入调用的子函数内部。

“step n”:执行完当前行后进入下一个函数调用的内部n次,然后暂停执行,n为整数。

“stepi”:逐指令执行程序,而不是逐行执行。

“finish”:执行到当前函数的结尾,并停在调用该函数的下一行。

这里编写了一个Test函数:

#include <stdio.h>
#include <unistd.h>

int Test(int a, int b)
{
    int c = a + b;

    return c;
}

int main(int argc, char** argv)
{
    int i = 0;

    Test(2, 3);

    printf("success complte\n");

    return 0;
}

首先将断点打在Test函数这里,使用step命令进入函数内部:
在这里插入图片描述

下面是有关一些info命令的讲解:

1.info registers:该命令用于显示当前CPU寄存器的状态和值。它可以显示通用目的寄存器(如EAX、EBX、ECX等)以及特殊寄存器(如程序计数器PC、堆栈指针SP等)。这对于理解程序执行状态和调试寄存器相关问题非常有用。
在这里插入图片描述

2.info args:该命令用于显示当前函数的参数及其值。它会列出函数的参数名称和值,可帮助你了解函数调用时传递的实际参数值。
在这里插入图片描述

3.info locals:该命令用于显示当前函数的局部变量及其值。它会列出函数内部声明的局部变量的名称和值,可帮助你了解函数内部变量的状态。
在这里插入图片描述

4.info frame:该命令用于显示当前帧(函数调用栈帧)的信息。它会显示函数名称、参数、返回地址等与当前帧相关的信息。
在这里插入图片描述

5.info variables:该命令用于显示当前作用域内的所有变量和它们的值。它会列出当前作用域中定义的变量的名称和值。可以使用该命令查看全局变量或其他作用域的变量状态。
在这里插入图片描述

6.info functions:该命令用于显示已加载程序的所有函数列表。它会列出可执行文件中定义的所有函数的名称,提供了一个快速查看程序中可用函数的方式。

在这里插入图片描述

四、调试中的技巧

1.display /f expression:
该命令用于设置一个表达式的自动显示。每次程序暂停时,GDB 将自动显示该表达式的值。 /f 可以是省略号(…)、空格或/format,用于指定显示格式。例如,display /x $eax 将以十六进制格式显示寄存器 $eax 的值。
在这里插入图片描述
2.undisplay:
该命令用于取消之前设置的自动显示。你可以提供要取消显示的显示编号,也可以不带参数使用该命令来取消所有的显示。

3.whatis:
该命令用于获取给定标识符的类型信息。例如,whatis variable_name 将显示变量 variable_name 的类型。

在这里插入图片描述
4.ptype:
该命令用于显示给定类型的详细信息。例如,ptype struct_name 将显示结构体 struct_name 的详细成员变量和类型信息。
在这里插入图片描述

5.list:
该命令用于显示源代码中的代码片段。你可以指定一个函数名、行号或文件名作为参数。例如,list function_name 将显示函数 function_name 的代码。
在这里插入图片描述

6.set listsize N:
该命令用于设置 list 命令显示的代码行数。默认情况下,它显示 10 行代码,但可以通过设置 N 来更改显示的行数。

7.shell:该命令用于在 GDB 提示符下运行操作系统的命令。例如,shell ls 将执行 ls 命令,并显示目录中的文件列表。
在这里插入图片描述

总结

本篇文章就讲解到这里,掌握了GDB调试,在编写Linux程序中寻找BUG和调试将会非常高效。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。