Ton*_*Liu 5 c++ debugging malloc gdb
我正在尝试迭代所有领域中的所有malloc_chunk。(基于核心文件进行调试,以进行内存泄漏和内存损坏调查)
据我所知,每个竞技场都有top_chunk,它指向一个竞技场内的顶部块,基于top_chunk,在其内部,基于代码(glibc / malloc / malloc.c)有prev_size和size:
 我可以获取之前的连续块,然后在一个区域中循环所有块。(我可以统计带有大小和数量的块,例如WinDBG:!heap -stat -h),也可以基于prev_size和size来检查块是否损坏。
 
我可以获取之前的连续块,然后在一个区域中循环所有块。(我可以统计带有大小和数量的块,例如WinDBG:!heap -stat -h),也可以基于prev_size和size来检查块是否损坏。
在arena(malloc_state)中,有一个成员变量:next指向下一个arena。然后,我可以循环所有竞技场的块。
但是我遇到的一个问题是,如果未分配块,则prev_size无效,如何获取先前的malloc_chunk?否则这种方式是不正确的。
问题背景:
我们遇到的内存泄漏错误是几个在线数据节点(我们的项目是分布式存储集群)中报告的内存泄漏。
我们的工作和结果:
我们使用valrgind重现测试集群中的错误,但不幸的是我们什么也没得到。
我试图研究有关堆的更多信息,试图分析堆块并遵循我以前在WinDBG中所做的方式(有非常有趣的堆命令来挖掘内存泄漏和内存损坏),但是我被问题所阻止我问。
我们使用valgrind-massif来分析分配(我认为这非常详细和有趣,可以显示哪个分配占用了多少内存)。Massif显示了一些线索,我们遵循了这一条并检查了代码,最终发现了泄漏(一张地图非常大,并且使用不当,但是我会删除holder类的析构函数,这就是为什么valgrind不报告此问题)。
我将进一步挖掘gdb-heap源代码,以更多地了解glic malloc结构。
首先,在深入研究 的实现细节之前malloc,您最好将时间花在类似的工具上valgrind,甚至在MALLOC_CHECK_环境变量下运行,让内部堆一致性检查为您完成工作。
但是,既然你问了……
glibcmalloc.c对于查看前一个块有一些有用的注释。
一些特别有趣的是:
/* Note that we cannot even look at prev unless it is not inuse */
和:
If prev_inuse is set for any given chunk, then you CANNOT determine the size of the previous chunk, and might even get a memory addressing fault when trying to do so.
这只是 malloc 实现的一个限制。当使用前一个块时,存储大小的页脚将由分配的用户数据使用。
虽然它对您的情况没有帮助,但您可以按照宏的操作来检查前一个块是否正在使用prev_inuse。
#define PREV_INUSE 0x1
#define prev_inuse(p) ((p)->size & PREV_INUSE)
它检查当前块大小的低位。(所有块大小均可被 4 整除,因此较低的 2 位可用于状态。)这将帮助您在进入无人区之前停止迭代。
不幸的是,在访问每个块之前,您仍然会提前终止循环。
如果您确实想迭代所有块,我建议您从 at 开始malloc_state::top并遵循next_chunk直到next_chunk指向top.
| 归档时间: | 
 | 
| 查看次数: | 763 次 | 
| 最近记录: |