如何分析coredump中的内存泄漏

如何分析coredump中的内存泄漏,c,coredump,gcore,C,Coredump,Gcore,我想从核心文件分析中分析内存泄漏 我已经编写了示例代码,用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-

我想从核心文件分析中分析内存泄漏

我已经编写了示例代码,用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:~$ 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另一个线程所建议的)

下面两个地址是可疑的一个

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 info address或x这样的命令访问它。
谁能告诉我如何从二进制格式转换符号信息吗?

我认为没有办法确定某个进程是否导致内存泄漏,或者是否直接查看内核转储。事实上,没有所谓的内存泄漏,我们不能在不知道程序员编写代码意图的情况下做出这样的评论。话虽如此,您可以通过查看核心转储的大小来了解情况。您可以生成多个转储,例如,一个在初始运行后,一个在长时间运行后。如果您看到大小上的巨大差异,您可以猜测可能出现了问题。但同样,内存可以用于生产目的

对于内存泄漏的实际分析和跟踪,应该使用诸如memtrack、valgrind等工具在malloc和free上添加包装,以提供关于每个alloc和free的额外信息

更新:

在您寻找十六进制分析时,我可以看到:
您的每一行是16字节,并在两行中重复。这是32字节一块。0x4D2是十进制的1234。所以,你的数据就在那里。您的一个alloc块可能是32字节。在每一个“new()”之后检查并以十六进制打印地址,并进行比较,看看是否观察到32字节的间隔,然后进行解释

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; 
}
000000210000000
004008d00000000
是重复的模式

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
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必须与内存泄漏有关,即派生vtable


注意:我同意coredump分析不是发现内存泄漏的最佳实践。内存泄漏可以通过不同的静态和动态工具来寻找,比如ValgRing等。< /P>可能的复制,基于您使用的<代码>新的< /代码>。我会说这是C++,不是C。但是您是<代码>包含了< /代码> ING >代码> <代码>,而不是<代码> <代码>,所以我不知道您的程序是用什么语言编写的……嗨,乔,正如我的回答。可以从coredump中找到内存泄漏。我同意我可以使用像Valgrind这样的工具,但为了我的理解,我想从核心文件中进行分析。根据您的要求更新答案。但是我认为这不是调试内存泄漏的正确方法。嗨,乔,非常感谢你的建议。是的,alloc块是32字节间隔。0x12c4010 0x12c4030 0x12c4050 0x12c4070 0x12c4090 0x12c40b0 0x12c40d0 0x12c40f0 0x12c4110 0x12c4130 0x12c4150 0x12c4170但我还有一个疑问,我怎么能看到没有被引用的分配“事实上,没有所谓内存泄漏的东西,我们不能在不知道程序员编写代码的意图的情况下做出评论。”我想说这在某种程度上是正确的,但是如果有人动态分配了内存,而他们不再保留任何指向这些内存的指针,就像在问题的示例中一样,那么这就是内存泄漏。我喜欢Unix的思维方式,但我不得不说,应该可以找出核心文件中当前活动的分配类型。。。在快速浏览谷歌之后,这个问题出现了。
(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