使用 gdb 检查指针是不是可能在核心转储中有效 [重复]

Posted

技术标签:

【中文标题】使用 gdb 检查指针是不是可能在核心转储中有效 [重复]【英文标题】:Check to see if a pointer could possibly be valid in a core dump with gdb [duplicate]使用 gdb 检查指针是否可能在核心转储中有效 [重复] 【发布时间】:2021-04-20 14:33:23 【问题描述】:

我有一个来自 linux c++ 程序的核心文件,它因分段错误而崩溃。查看回溯和代码,我发现一个指针/对象可能是垃圾。指针地址是this=0x62900000f200,那么有没有办法可以确定它是否可能是使用 GDB 的有效地址?

我希望有一种方法让 GDB 告诉我分配的内存区域是什么,或者核心转储包含哪些内存。我知道准确度会很低,因为稍微损坏的指针仍有可能指向“有效”内存,但希望有一种方法可以识别不可能有效的指针。

我看到过一些问题,询问指针是否“有效”,并且我知道确定指针是否已经被释放,或者它是否指向错误的对象等的复杂性,但这不是我想要的。我问。我只是想要一个测试,“这个内核包含从地址 0x01 到 0x50 的所有内存,而你的指针是 0x70,所以它显然是无效的。”

【问题讨论】:

您是否总是有完整的核心转储?如果是这样,有一个简单的方法。 x/b 0x62900000f200p *(char *)0x62900000f200 将打印该地址的字节,前提是它是有效地址并且数据存在于核心转储中,否则 GDB 将输出错误消息 Cannot access memory at address 0x62900000f200 @MarkPlotnick,是的,我们总是有完整的转储。我会试一试。我没有考虑“手动”尝试访问该内存。我仍然想知道是否有“这个转储包含什么内存”表或什么的。 【参考方案1】:

我在this answer 中找到了似乎有帮助的内容。它建议使用命令maint info sections 来显示核心文件的所有已加载“部分”。

它会为大型核心文件生成大量输出,但在我的情况下,输出包括以下内容:

...
0x627000000000->0x627001030000 at 0x273c6000: load146 ALLOC LOAD HAS_CONTENTS
0x627001030000->0x627001030000 at 0x283f6000: load147 ALLOC READONLY
0x627e00000000->0x627e00010000 at 0x283f6000: load148 ALLOC LOAD HAS_CONTENTS
0x627e00010000->0x627e00010000 at 0x28406000: load149 ALLOC READONLY
0x628000000000->0x628000030000 at 0x28406000: load150 ALLOC LOAD HAS_CONTENTS
0x628000030000->0x628000030000 at 0x28436000: load151 ALLOC READONLY
0x628e00000000->0x628e00010000 at 0x28436000: load152 ALLOC LOAD HAS_CONTENTS
0x628e00010000->0x628e00010000 at 0x28446000: load153 ALLOC READONLY
0x629000000000->0x6290010b0000 at 0x28446000: load154 ALLOC LOAD HAS_CONTENTS
0x6290010b0000->0x6290010b0000 at 0x294f6000: load155 ALLOC READONLY
0x629e00000000->0x629e00010000 at 0x294f6000: load156 ALLOC LOAD HAS_CONTENTS
0x629e00010000->0x629e00010000 at 0x29506000: load157 ALLOC READONLY
0x62a000000000->0x62a0000c0000 at 0x29506000: load158 ALLOC LOAD HAS_CONTENTS
0x62a0000c0000->0x62a0000c0000 at 0x295c6000: load159 ALLOC READONLY
0x62ae00000000->0x62ae00010000 at 0x295c6000: load160 ALLOC LOAD HAS_CONTENTS
0x62ae00010000->0x62ae00010000 at 0x295d6000: load161 ALLOC READONLY
0x62b000000000->0x62b000070000 at 0x295d6000: load162 ALLOC LOAD HAS_CONTENTS
0x62b000070000->0x62b000070000 at 0x29646000: load163 ALLOC READONLY
0x62be00000000->0x62be00010000 at 0x29646000: load164 ALLOC LOAD HAS_CONTENTS
...

由于存在0x629000000000->0x6290010b0000 区域,并且我的指针值介于两者之间,我可以判断我的指针是有效的。为了更快地搜索,您需要一个脚本来检查所有范围,但输出似乎是按数字顺序排列的(在我的一种情况下),因此手动搜索范围很容易。

【讨论】:

以上是关于使用 gdb 检查指针是不是可能在核心转储中有效 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

在Linux机器上运行C代码时出现分段错误(核心转储)[关闭]

在 Linux 上使用核心转储和 gdb 如何使用近似虚拟内存 (VSZ)?

在核心转储文件上使用 gdb 获取变量的值

python脚本转储ELF(核心和输出)?

核心转储文件分析[重复]

有没有办法用 Xcode 打开(任意)核心转储?