C++ 如何迭代所有malloc块(glibc)
我正在尝试迭代所有竞技场中的所有malloc_块。(基于核心文件进行调试,用于内存泄漏和内存损坏调查) 正如我所知,每个竞技场都有top_块,它指向一个竞技场内的top_块,基于top_块,在它的内部,有prev_大小和大小,基于代码(glibc/malloc/malloc.c): 我可以得到之前的连续块,然后在一个竞技场中循环所有块。(我可以用大小和数字统计数据块,如WinDBG:!heap-stat-h),还可以根据上一个大小和大小检查数据块是否损坏 在arena(malloc_状态)中,有一个成员变量:next which point to next arena。然后我可以循环所有竞技场的区块 但我遇到的一个问题是,如果没有分配块,上一个大小无效,如何获取上一个malloc_块??或者这种方式是不正确的C++ 如何迭代所有malloc块(glibc),c++,debugging,gdb,malloc,C++,Debugging,Gdb,Malloc,我正在尝试迭代所有竞技场中的所有malloc_块。(基于核心文件进行调试,用于内存泄漏和内存损坏调查) 正如我所知,每个竞技场都有top_块,它指向一个竞技场内的top_块,基于top_块,在它的内部,有prev_大小和大小,基于代码(glibc/malloc/malloc.c): 我可以得到之前的连续块,然后在一个竞技场中循环所有块。(我可以用大小和数字统计数据块,如WinDBG:!heap-stat-h),还可以根据上一个大小和大小检查数据块是否损坏 在arena(malloc_状态)中,有
问题背景: 我们遇到的内存泄漏bug是在几个在线数据节点中报告的内存泄漏(我们的项目是分布式存储集群) 我们的做法和结果:
我将深入了解gdb堆源代码,以了解更多关于glic malloc结构的信息。首先,在深入了解
malloc
的实现细节之前,最好使用类似于或甚至在环境变量下运行的工具,让内部堆一致性检查为您完成工作
但是,既然你问了……
glibc's对查看前一块有一些有用的评论
其中一些特别有趣的是:
/*请注意,我们甚至不能查看prev,除非它未使用*/
以及:
如果为任何给定的块设置了prev\u inuse,则无法确定上一个块的大小,甚至在尝试这样做时可能会出现内存寻址错误。
这只是malloc实现的一个限制。当使用上一个块时,将存储大小的页脚将由分配的用户数据使用
虽然这对您的情况没有帮助,但您可以按照prev\u-inuse
宏的操作来检查前一个块是否正在使用
#define PREV_INUSE 0x1
#define prev_inuse(p) ((p)->size & PREV_INUSE)
它检查当前块大小的低位。(所有数据块大小都可以被4整除,因此较低的2位可以用作状态。)这将帮助您在进入无人区之前停止迭代
不幸的是,在访问每个块之前,您仍然会提前终止循环
如果你真的想迭代所有的块,我建议您从
malloc\u state::top
开始,然后按照next\u chunk
操作,直到next\u chunk
指向top尝试pmap-XX
命令,从不同方面跟踪内存使用情况。免费开源程序为glibc malloc提供您想要的功能。只需抓取一个内核(因为内核崩溃,或者使用gcore或使用gdb中的generate命令抓取一个lib内核)。然后通过执行以下操作打开核心:
chap yourCoreFileName
到达chap提示符后,如果要遍历所有块(包括自由块和非自由块),可以根据所需的详细程度执行以下任何操作,但请记住,chap中的“分配”不包含块头,而是从malloc返回的地址开始
请尝试以下任一操作:
count allocations
summarize allocations
describe allocations
show allocations
count used
summarize used
describe used
show used
count leaked
summarize leaked
describe leaked
show leaked
如果您只关心当前正在使用的分配,请尝试以下任一操作:
count allocations
summarize allocations
describe allocations
show allocations
count used
summarize used
describe used
show used
count leaked
summarize leaked
describe leaked
show leaked
如果您只关心泄漏的分配,请尝试以下任一操作:
count allocations
summarize allocations
describe allocations
show allocations
count used
summarize used
describe used
show used
count leaked
summarize leaked
describe leaked
show leaked
以上提到的github URL提供的文档中提供了更多详细信息
在损坏方面,chap在启动时进行一些检查,并报告多种损坏,尽管输出有时可能有点神秘。这是GDB问题或WinDbg问题,但我认为不能两者兼而有之。尽管如此,我还是建议删除WinDbg标签(“核心转储”和“竞技场”在我看来不像WinDbg术语)是的,这是一个gdb问题,而不是WinDbg问题。你可能对gdb堆
项目感兴趣,该项目包括在gdb中运行的Python代码,它知道如何解析glibc malloc竞技场。@TomTromey,是的,Tom我知道这个项目,并试图使用它,但不幸的是运行时错误弹出。稍后我将在gdb堆中挖掘更多关于源代码的信息。@orbitcowboy,thx,我们已经将cppcheck集成到我们的项目中,但没有发现漏洞。thx Sean,我不确定我是否理解您提到的方式,“如果你真的想迭代所有的块,我建议你从malloc_state::top开始,然后跟随下一个_块,直到下一个_块指向顶部。,tmalloc_state::top不是第一个块,而是物理上的最后一个块。我试图用valgrind复制这个bug,不幸的是,没有泄漏报告。在我们的一个数据节点中报告了错误,该节点将运行几天,然后内存达到限制。我们必须花时间来复制它。