怎么用 gdb find 命令搜索内存

本文详细介绍了如何使用GDB的find命令在程序内存中搜索特定字节序列。通过示例展示了如何确定搜索范围,以及如何处理字符串和字符序列的搜索。强调了注意内存映射范围和完整字符串匹配的重要性,并提示了find命令的其他选项和参数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原文

怎么用 gdb find 命令搜索内存 ?

本文,我们讲讲 GDB 命令 find

当调试程序时,你可能需要查找程序内存中的特定字节序列。或者,你想查找特定目标的所有地址。内存中每 8 个字节一个字节序列,表示你想确定的地址。

提醒一下,find 命令会返回所有匹配的地址;因此我们必须接受可能存在的错误结果。

没什么-我觉得。

find 命令提供了另一种审查程序的方式。

我们看看怎么用。

Hello, world!

首先,写个简单的程序,用作示例。

打开你喜欢的编辑器(例如,emacs 或 vi)并输入下面的代码。

#include <stdio.h>

int
main(void)
{
  printf(“Hello, world!\n”);
  printf(“That is all, goodbye.\n”);
  Return 0;
}

保存文件名为 hello.c

编译

$ gcc -g3 hello.c

加载。

$ gdb a.out

启动。

(gdb) start

就绪。

现在我们看看 GDB 的 find 命令。

find 命令

find 语法如下所示:

find [/SIZE-CHAR] [/MAX-COUNT] START-ADDRESS, END-ADDRESS, EXPR1 [, EXPR2, ...]

或者

find [/SIZE-CHAR] [/MAX-COUNT] START-ADDRESS, +LENGTH, EXPR1 [, EXPR2, ...]

你可以通过指定 EXPR1EXRP2 … 搜索程序的内存空间。

搜索从 START-ADDRESS 开始的 +LENGTH字节或到 END-ADDRESS 结束 。

下文中,我会讲如何获取程序的内存布局,来决定搜索的开始和结束地址。

[ /SIZE-CHAR][/MAX-COUNT] 是可选项。

[ /SIZE-CHAR] 指定每个搜索目标的大小。

b 字节

h 半字(2 字节)

w 字(4 字节)

g 双字(8 字节)

所有的搜索目标使用程序的编程语言去解释。例如,hello.c 的语言是 C/C++; 所以当我们查找 “Hello,world!” 时,它会包含字符串结束标志 ‘\0’。

如果不指定 [/SIZE-CHAR],这个值会从源程序语言中获取。当你想查找的序列是复杂类型时这个参数就派上用场了。

[/MAX-COUNT] 设置了最大返回值数量。默认打印所有结果。

你可以将字符串作为查找对象。确保用 “” 括住。字符串会逐字节的复制到查找模式中,不管目标的字节序和指定的大小。

返回值是每个匹配的地址和匹配到的数量。

查找内存

如果想查找程序的内存空间,你得知道进程的内存布局,用来决定起始地址,结束地址。

怎么告诉 GDB 查找范围呢?

可以像下面这样使用 info proc 命令获取进程的有用信息

(gdb) info proc mappings

此命令会显示进程的所有内存布局;我们的 hello.c 程序,可以访问的所有虚拟地址范围。

内存布局

按理说,“Hello,world!” 字符一定在 0x5555555540000x555555559000这个范围内。但是,有一点很重要,0x555555559000 不是结束地址。它是没有被映射的第一个字节!在查找命令中使用这个地址会报错,因为它超出了内存映射的范围。我会在视频中展示。所以,需要后退一个字节,到 0x555555558fff

现在,输入下面的命令。

(gdb) find 0x555555554000 to 0x555555558fff, “Hello, world!

示例的结果表明内存中有两个实例。

结果

验证一下:

(gdb) print (char*) 0x555555556004

不出所料,真是 “Hello, world!”。

验证

小提示

除了确保在映射内存范围内查找,还有其他需要注意的点。

如果要搜索字符串,你必须匹配完整的字符串,例如,我的视频中,忘记输入感叹号,就没返回结果,因为没命中了 \0

helloworld

find 命令查找的是 hello,world\0

你可以用别的方法搜索,比如,字符序列。

(gdb) find 0x555555554000 to 0x555555558fff, ‘H’, ‘e’, ‘l’, ‘l’, ‘o’

注意用的是单引号 (')

字符

到这里就结束了!

find help 命令提供了更多的查找选项和参数。花点时间去用用。我相信,你会觉得,在调试程序时,GDB 命令 find提供了一种有用的审查方式。

不要忘了向同事们分享你的收获,这样每个人都受益。

在进行C语言项目开发时,内存泄漏是一种常见的低级错误,它会导致程序运行一段时间后出现性能下降或崩溃。为了有效地诊断和修复这类问题,推荐您学习和使用GDB(GNU Debugger)。GDB是一个功能强大的调试工具,它可以帮助开发者在运行时检查程序的状态,从而发现内存泄漏。 参考资源链接:[华为常见C、C++软件编程低级错误:内存泄漏](https://wenku.csdn.net/doc/6412b750be7fbd1778d49d96?spm=1055.2569.3001.10343) 首先,确保在编译C程序时加入`-g`选项,以生成调试信息,这对于GDB来说是必须的。例如,使用gcc编译器的命令行可能是这样的: ```bash gcc -g -o my_program my_program.c ``` 接下来,在程序运行时启动GDB调试器: ```bash gdb ./my_program ``` 一旦GDB启动,您可以使用以下命令来运行您的程序并设置断点: ```bash run ``` 当您怀疑发生了内存泄漏时,可以使用GDB的`heap`命令来检查堆内存的使用情况,或使用`backtrace`命令来查看当前的函数调用堆栈。此外,`info leaks`命令能够提供关于内存泄漏的详细信息。 如果GDB没有直接提供内存泄漏的解决方案,您可以记录下可疑的内存分配点和释放点,然后使用GDB内存检查命令,如`check leak`,`find`等来进一步分析。 在定位问题之后,您需要回到代码中,仔细检查相关的内存分配和释放逻辑,确保每个`malloc`或`calloc`都有对应的`free`调用,并且在释放后不要再访问该内存区域。 《华为常见C、C++软件编程低级错误:内存泄漏》这本书详细描述了内存泄漏的各种情况和排查方法,提供了很多实践案例,是解决内存泄漏问题的宝贵资源。通过这本书,您可以学习到更多专业的内存管理技巧和调试技术,帮助您在未来的C/C++项目开发中避免类似问题,提升代码质量。 总结来说,使用GDB进行内存泄漏的诊断和修复是一个细致且系统的工作,需要您熟练掌握GDB的使用技巧,并结合实际代码逻辑进行综合分析。在解决内存泄漏问题后,继续深入学习内存管理相关的知识和技巧,将有助于您编写出更加健壮的软件产品。 参考资源链接:[华为常见C、C++软件编程低级错误:内存泄漏](https://wenku.csdn.net/doc/6412b750be7fbd1778d49d96?spm=1055.2569.3001.10343)
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值