GDB:如何查看可访问的内存地址?

时间:2010-09-21 11:30:30

标签: debugging memory assembly gdb postmortem-debugging

假设,在一个调试会话中,我有一个地址,不幸的是它指向一些垃圾。我想检查周围的记忆,看看附近有什么。正如所料,发生以下错误:

(gdb) x/64 $t5
0x842da7ac:     Cannot access memory at address 0x842da7ac

所以,问题是:有没有办法读取一系列地址,其中一些地址无效?

(更准确地说,我怎么知道上面的示例中$t5+n是某个0 < n <= 64的有效地址?)

1 个答案:

答案 0 :(得分:5)

您无法读取无效地址(显然)。

在某些操作系统上,您可以在GDB中停止进程时向操作系统查询有效地址。例如,在Linux cat /proc/<pid>/maps上将为您提供有关哪些地址有效(以及它们有效的访问模式)的信息。其他操作系统可能有类似的机制。

由于您标记了问题post-mortem,因此无法使用上述机制;但是你必须有一个core文件。在Linux(和其他ELF系统)上,readelf -l core将告诉您哪些内存区域被写入内核,这通常可以让您清楚地了解崩溃时哪些内存有效。但是,只读映射通常不会写入core,因此您可能无法在readelf输出中看到此类映射。

所有现代操作系统都使用分页,页面至少为1K(尽管4K更常见),因此您可以告诉$t5最接近可能有效的内存是0x842da800,所以n >= 84(字节)。

最后,如果你要求GDB检查64个单词,并且GDB无法检查第一个单词,它将会停止。

但是,如果您使用的是GDB-7.x,您可以要求GDB在Python中一次检查一个单词,如果GDB无法检查该特定单词,则会抛出Python异常。但是既然你可以捕获Python异常,那么在Python中编写一个实现“检查下N个单词,忽略任何不可读的单词”的脚本是非常简单的(我相信它会回答你的“如何做到这一点”的问题)。