假设,在调试会话中,我有一个地址不幸指向一些垃圾。我想检查它周围的记忆,看看附近有什么。正如预期的那样,出现以下错误:
(gdb) x/64 $t5
0x842da7ac: Cannot access memory at address 0x842da7ac
所以,问题是:有没有办法读取一系列地址,其中一些是无效的?
(更准确地说,我怎么知道在上面的例子$t5+n
中是一个有效的地址0 < n <= 64
?)
假设,在调试会话中,我有一个地址不幸指向一些垃圾。我想检查它周围的记忆,看看附近有什么。正如预期的那样,出现以下错误:
(gdb) x/64 $t5
0x842da7ac: Cannot access memory at address 0x842da7ac
所以,问题是:有没有办法读取一系列地址,其中一些是无效的?
(更准确地说,我怎么知道在上面的例子$t5+n
中是一个有效的地址0 < n <= 64
?)
您无法读取无效地址(显然)。
在某些操作系统上,您可以在 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 异常,因此编写一个脚本来实现“检查接下来的 N 个单词,忽略任何不可读的单词”在 Python 中是微不足道的(我相信这会回答您的“如何做到这一点”的问题)。