假设,在一个调试会话中,我有一个地址,不幸的是它指向一些垃圾。我想检查周围的记忆,看看附近有什么。正如所料,发生以下错误:
(gdb) x/64 $t5
0x842da7ac: Cannot access memory at address 0x842da7ac
所以,问题是:有没有办法读取一系列地址,其中一些地址无效?
(更准确地说,我怎么知道上面的示例中$t5+n
是某个0 < n <= 64
的有效地址?)
答案 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个单词,忽略任何不可读的单词”的脚本是非常简单的(我相信它会回答你的“如何做到这一点”的问题)。