c - 如何分析coredump的内存泄漏

标签 c coredump gcore

我想通过核心文件分析来分析内存泄漏。

我已经编写了示例代码来注入(inject)内存泄漏并使用 gcore 命令生成核心文件。

#include <stdlib.h>
#include <unistd.h>
void fun()
{
  int *ptr = new int(1234);
}
int main()
{
  int i=0;
  while(i++<2500)
  {
    fun();
}
sleep(360);
return 0;
}

查找进程号

ayadav@ajay-PC:~$ ps -aef |grep over  
ajay      8735  6016  0 12:57 pts/2    00:00:00 ./over  
ayadav    8739  4659  0 12:57 pts/10   00:00:00 grep over  

和生成的核心

ayadav@ajay-PC:~$ sudo gcore 8735
[sudo] password for ayadav:
0x00007fbb7dda99a0 in __nanosleep_nocancel () at ../sysdeps/unix/syscall-template.S:81
81      ../sysdeps/unix/syscall-template.S: No such file or directory.
Saved corefile core.8735

我从核心文件中找到了如下常见模式(如 stackoverflow 上另一个线程的建议 Is there a way to locate which part of the process used the most of the memory, only looking at a generated core file? )

ayadav@ajay-PC:~$ hexdump core.6015 | awk '{printf "%s%s%s%s\n%s%s%s%s\n", $5,$4,$3,$2,$9,$8,$7,$6}' | sort | uniq -c | sort -nr | head
6913 0000000000000000  
2503 0000002100000000  
2501 000004d200000000  
786 0000000000007ffc  
464  
125 1ccbc4d000007ffc  
 92 1ca7ead000000000  
 91 0000000200007ffc  
 89 0000000100007ffc  
 80 0000000100000000  

下面两个地址是疑似一个

2503 0000002100000000  
2501 000004d200000000  

核心文件有以下重复模式

0003560 0000 0000 0021 0000 0000 0000 04d2 0000  
0003570 0000 0000 0000 0000 0000 0000 0000 0000  
0003580 0000 0000 0021 0000 0000 0000 04d2 0000  
0003590 0000 0000 0000 0000 0000 0000 0000 0000  
00035a0 0000 0000 0021 0000 0000 0000 04d2 0000  
00035b0 0000 0000 0000 0000 0000 0000 0000 0000  
00035c0 0000 0000 0021 0000 0000 0000 04d2 0000  
00035d0 0000 0000 0000 0000 0000 0000 0000 0000  
00035e0 0000 0000 0021 0000 0000 0000 04d2 0000  
00035f0 0000 0000 0000 0000 0000 0000 0000 0000  
0003600 0000 0000 0021 0000 0000 0000 04d2 0000  
0003610 0000 0000 0000 0000 0000 0000 0000 0000  
0003620 0000 0000 0021 0000 0000 0000 04d2 0000  
0003630 0000 0000 0000 0000 0000 0000 0000 0000  
0003640 0000 0000 0021 0000 0000 0000 04d2 0000

但我不太清楚如何从 gdb 信息地址或 x 等命令访问它。 谁能告诉我如何从二进制格式转换符号信息?

最佳答案

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; 
}

2 - 使用 gcore 命令创建了一个核心

3 - 从核心文件中搜索重复模式。

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}' | sort | uniq -c | sort -nr  | head
   6685 0000000000000000  
   2502 0000002100000000  
   2500 004008d000000000  
    726 0000000000007eff  
    502   
    125 2e4314d000007eff  
     93 006010d000000000  
     81 0000000100007eff  
     80 0000000100000000  
     73 0000000000000001  

0000002100000000004008d000000000 是重复的模式

4 - 检查每个 qword 是什么?

(gdb) info symbol ...
(gdb) x ...

例子:

(gdb) info symbol 0x4008d000
No symbol matches 0x4008d000.
(gdb) info symbol 0x4008d0
vtable for Derived + 16 in section .rodata of /home/ayadav/virtual

5 - 可能最常见的 vtable 必须与内存泄漏相关,即 Derived vtable。

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

关于c - 如何分析coredump的内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27598986/

相关文章:

java - Sun JDK 能否在 JVM 崩溃时生成核心/堆转储文件?

python - 如何从核心转储中反转字符串的虚拟地址?

linux - 在退出 linux 时转储进程内存

c++ - 任何用于 RPC over pipes/internal linux sockets 的开源 C/C++ 库/框架?

c - C 中的字符串动态分配

c++ - 如何以编程方式在 C/C++ 中导致核心转储

c - 错误 : Redeclaration with no linkage

c - 是否可以利用以下代码?

java - 使用 Java JNI 时是否可以调试核心转储?