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

Is there a way to find leaked memory using a core file?

本文关键字:内存 核心 文件 泄漏 有没有      更新时间:2023-10-16

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

我也听说使用各种内存泄漏检测工具会减慢应用程序的速度,这是我们无法承受的,因为它已经在CPU容量附近运行了。

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

不太容易。泄漏内存的全部意义在于分配的内存不再有对它的引用。

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

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

例如,如果80%的分配块是31424字节长,您将寻找该范围的分配(根据内存分配器的工作方式,误差为16字节)。

或者,如果它们都包含像"2011-01-01 15:25:00 Beginning process 42"这样的字符串,您可能需要在日志库中查找泄漏。

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

可以使用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; 
}
  • 用gcore命令创建core

  • 从核心文件中搜索重复模式。ayadav@ajay-PC:~$ hexdump core。10639 | awk {printf"% s % s % s % s n % s % s % s % s n",5美元,4美元,3美元,2美元,9美元,8美元,7美元,美元6}"排序| | uniq排序nr - c | |头6685 0000000000000000
    2502 0000002100000000
    2500 004008 d000000000
    726 0000000000007 eff
    502年
    125 2 e4314d000007eff
    93 006010 d000000000
    81 0000000100007 eff
    80 0000000100000000
    73 0000000000000001

  • 0000002100000000和004008d000000000是重复模式

  • 检查每个qword是什么?(gdb)信息符号…(gdb) x…


    例子(gdb)信息符号0x4008d000
    没有符号匹配0x4008d000。
    (gdb)信息符号0x4008d0
    /home/ayadav/virtual

  • 的.rodata节中派生的+ 16的vtable
  • 可能最常见的虚表必须与内存泄漏有关,即派生虚表

  • 注意:我同意coredump分析不是查找内存泄漏的最佳实践。可以使用不同的静态和动态工具(如valgrind等)来查找内存泄漏

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

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