有没有办法使用核心文件找到泄漏的内存?

时间:2011-09-16 01:14:04

标签: c++ linux memory-leaks elf

我有来自内存泄漏的应用程序的核心转储。我已经使用strings命令和xdd来检查文件,并且我已经了解了程序的哪个部分可能导致泄漏的一些想法。我可以使用应用程序在gdb中运行核心文件,但是我不能用它做很多测试,因为它是一个嵌入式应用程序,有很多复杂的基于时间的I / O,我无法在办公室模拟

我还听说运行各种内存泄漏检测实用程序会降低我们无法承受的应用程序速度,因为它已经以接近CPU的容量运行。

所以现在,我拥有的只是这个核心文件。我正在寻找的示例:是否有一个指针表我可以检查以找到已分配的内存,然后我可以使用它来尝试找到应该已经释放但尚未被释放的内容?

3 个答案:

答案 0 :(得分:10)

不是很容易,没有。泄露内存的全部意义在于它分配的内存不再具有对它的引用。

你必须遍历整个内存竞技场以获取所有已分配块的列表,然后检查可能指向它的每个可能的变量/内存位置(几乎肯定会有一些误报)。

在分配的块上获取一些统计信息可能值得一试。假设您的内存泄漏导致内存不足问题,大多数块将根据可能的大小或内容而具有特定类型。

例如,如果80%的已分配块长度为31424字节,那么您将寻找该范围的分配(给予或取16个字节,具体取决于内存分配器的工作方式)。

或者,如果它们都包含类似“2011-01-01 15:25:00 Beginning process 42”的字符串,您可能希望在日志记录库中查找泄漏。

在任何情况下,您都必须深入了解C ++运行时源代码,以了解如何定位内存竞技场,然后使用该代码来遍历结构。

答案 1 :(得分:2)

内存泄漏可以使用paxdiablo给出的核心转储进行评估。此外,如果在corefile中重复某些模式,则可以按以下方式评估: 1.我采用了一个示例c ++示例:

class Base  
{  
    public:  
    virtual void fun(){}  
    virtual void xyz(){}  
    virtual void lmv(){}  
    virtual void abc(){}  
};  

class Derived: public Base  
{  
    public:  
    void fun(){}  
    void xyz(){}  
    void lmv(){}  
     void abc(){}  
};  

void fun()  
{  
    Base *obj  = new Derived();  
}  
int main()  
{  
    for(int i=0; i<2500;i++)  
    fun();  
    sleep(3600);  
    return 0; 
}
  1. 使用gcore命令创建核心

  2. 从核心文件中搜索重复的模式。 ayadav @ ajay-PC:〜$ hexdump core.10639 | awk&#39; {printf&#34;%s%s%s%s \ n%s%s%s%s \ n&#34;,$ 5,$ 4,$ 3,$ 2,$ 9,$ 8,$ 7,$ 6 }&#39; |排序| uniq -c | sort -nr |总部6685 0000000000000000
    2502 0000002100000000
    2500 004008d000000000
    726 0000000000007eff
    502个
    125 2e4314d000007eff
     93 006010d000000000
     81 0000000100007eff
     80 0000000100000000
     73 0000000000000001

  3. 0000002100000000和004008d000000000是重复模式

    1. 检查每个qword是什么用的? (gdb)信息符号...... (gdb)x ...

      示例
      (gdb)信息符号0x4008d000
      没有符号匹配0x4008d000 (gdb)信息符号0x4008d0
      vtable for Derived + 16 in section .rodata of / home / ayadav / virtual

    2. 可能最常见的vtable必须与内存泄漏有关,即Derived vtable。

    3. 注意:我同意coredump分析不是查找内存泄漏的最佳做法。内存泄漏可以通过valgrind等不同的静态和动态工具找到。

答案 2 :(得分:0)

正如paxdiablo所说,通过查看事后堆(malloc)数据结构来找出泄露的内容几乎是不可行的。

找出泄漏的对象类型的一种相当轻松的方法是为每个可能泄漏的类提供实例计数器。这样您就可以检查核心文件中的实例计数器。