以十六进制格式(作为字节/字/ dwords /
qwords)打开此核心转储。从文件的中间开始,尝试注意任何重复的模式。如果找到任何内容,请尝试确定起始地址和某些可能的数据结构的长度。使用此结构的长度和内容,尝试猜测可能是什么。使用该地址,尝试找到一些指向此结构的指针。重复直到您进入堆栈或某个全局变量。如果使用堆栈变量,您将很容易知道此链从哪个函数开始。对于全局变量,至少要知道其类型。
如果您在核心转储中找不到任何模式,则泄漏结构的可能性很大。只需将文件中看到的内容与程序中所有大型结构的可能内容进行比较即可。
更新资料
如果您的coredump具有有效的调用栈,则可以从检查其功能开始。搜索任何异常的东西。检查调用堆栈顶部附近的内存分配是否请求过多。检查调用堆栈函数中是否存在无限循环。
词语“ 仅使用智能指针
”使我感到恐惧。如果这些智能指针的重要部分是共享指针(shared_ptr,intrusive_ptr等),则与其搜索大型容器,不如搜索共享指针周期。
更新2
尝试确定堆在corefile中结束的位置(
brk值)。在gdb下运行coredumped进程并使用
pmap命令(从其他终端)。gdb也应该知道这个值,但是我不知道该怎么问…如果大多数进程的内存都在上方
brk,则可以通过较大的内存分配(很可能是std
:: vector)来限制搜索。
为了增加在现有核心转储的堆区域中发现泄漏的机会,可以使用一些编码(我自己并没有这样做,只是一个理论):
- 读取coredump文件,将每个值解释为一个指针(忽略代码段,未对齐的值以及指向非堆区域的指针)。对列表进行排序,计算相邻元素的差异。
- 此时,整个内存将拆分为许多可能的结构。计算结构大小的直方图,删除任何无关紧要的值。
- 计算这些指针所属的指针和结构的地址差。对于每种结构大小,计算指针位移的直方图,然后再次删除所有无关紧要的值。
- 现在,您有足够的信息来猜测结构类型或构造结构的有向图。查找该图的源节点和周期。您甚至可以像在“列出“冷”存储区”中一样可视化该图。
Coredump文件为
elf格式。从其标头仅需要数据段的开始和大小。为了简化过程,只需将其读取为线性文件,忽略结构即可。



