Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
GLIBC:调试内存泄漏:如何解释mtrace()的输出_C_Memory Leaks_Glibc_Mtrace - Fatal编程技术网

GLIBC:调试内存泄漏:如何解释mtrace()的输出

GLIBC:调试内存泄漏:如何解释mtrace()的输出,c,memory-leaks,glibc,mtrace,C,Memory Leaks,Glibc,Mtrace,我正在调试内存泄漏问题。我正在使用获取malloc/free/realloc跟踪。我已经运行了我的程序,现在有一个巨大的日志文件。到现在为止,一直都还不错。但是我在解释文件时遇到了问题。请看以下几行: @ /usr/java/ibm-java2-x86_64-50/jre/bin/libj9prt23.so:[0x2b270a384a34] + 0x1502570 0x68 @ /usr/java/ibm-java2-x86_64-50/jre/bin/libj9prt23.so:[0x2b27

我正在调试内存泄漏问题。我正在使用获取malloc/free/realloc跟踪。我已经运行了我的程序,现在有一个巨大的日志文件。到现在为止,一直都还不错。但是我在解释文件时遇到了问题。请看以下几行:

@ /usr/java/ibm-java2-x86_64-50/jre/bin/libj9prt23.so:[0x2b270a384a34] + 0x1502570 0x68
@ /usr/java/ibm-java2-x86_64-50/jre/bin/libj9prt23.so:[0x2b270a384a34] + 0x1502620 0x30
@ /usr/java/ibm-java2-x86_64-50/jre/bin/libj9prt23.so:[0x2b270a384a34] + 0x2aaab43a1700 0xa80
@ /usr/java/ibm-java2-x86_64-50/jre/bin/libj9prt23.so:[0x2b270a384a34] + 0x1501460 0xa64
奇怪的是,一个调用(相同的返回地址)负责4次分配

更奇怪的是:

@ /usr/java/ibm-java2-x86_64-50/jre/bin/libj9prt23.so:[0x2b270a384a34] + 0x2aaab43a1700 0xa2c
…
@ /usr/java/ibm-java2-x86_64-50/jre/bin/libj9prt23.so:[0x2b270a384a34] + 0x2aaab43a1700 0xa80
在这两行之间,永远不会释放块0x2AAB43A1700

有人知道怎么解释吗?一次调用怎么可能导致4次分配?malloc如何返回以前分配的地址

编辑2008/09/30:
GLIBC(mtrace.pl)提供的用于分析mtrace()输出的脚本在这里没有任何帮助。它只会说:Alloc 0x2aab43a1700 replicate。但是这是怎么发生的呢?

一种可能的解释是,同一个函数分配不同的缓冲区大小?其中一个例子就是strdup

对于第二个问题,运行时可能正在分配一些“静态”暂存区域,在进程终止之前不打算释放这些区域。在这一点上,操作系统将在进程结束后进行清理


这样想:在Java中,没有析构函数,也不能保证任何对象都会被调用终结。

尝试在valgrind下运行应用程序。它可能会让您更好地了解实际泄漏的内容。

您看到的是mtrace的直接输出,这极为混乱且违反直觉。幸运的是,有一个perl脚本(称为mtrace,可以在glibc utils中找到),它可以非常轻松地帮助解析此输出

在调试的情况下编译生成,并像这样运行mtrace:

$ gcc -g -o test test.c
$ MALLOC_TRACE=mtrace.out ./test
$ mtrace test mtrace.out

Memory not freed:
-----------------
   Address     Size     Caller
0x094d9378    0x400  at test.c:6

输出应该更容易理解。

分配内存的函数被多次调用。调用方地址指向执行分配的代码,该代码只是被多次运行

下面是C语言中的一个示例:

void *allocate (void)
{
  return (malloc(1000));
}

int main()
{
  mtrace();
  allocate();
  allocate();
}
mtrace的输出为:

Memory not freed: ----------------- Address Size Caller 0x0000000000601460 0x3e8 at 0x4004f6 0x0000000000601850 0x3e8 at 0x4004f6 内存未释放: ----------------- 地址大小调用者 0x4004f6处的0x00000000000601460 0x3e8 0x4004f6处的0x00000000000601850 0x3e8 注意呼叫者地址是如何相同的?这就是为什么mtrace分析脚本说它们是相同的,因为同一个bug被多次看到,从而导致多个内存泄漏

使用调试标志(-g)编译非常有用,如果您可以:

Memory not freed: ----------------- Address Size Caller 0x0000000000601460 0x3e8 at /home/andrjohn/development/playground/test.c:6 0x0000000000601850 0x3e8 at /home/andrjohn/development/playground/test.c:6 内存未释放: ----------------- 地址大小调用者 0x0000000000610460 0x3e8 at/home/andrjohn/development/played/test.c:6 0x00000000000601850 0x3e8 at/home/andrjohn/development/Played/test.c:6
它不仅是一个函数多次调用malloc(),而且实际上是一个对malloc/realloc/calloc的调用,因为返回地址是相同的。如果运行时正在分配scratch区域,为什么它返回指向该区域的指针是第二个malloc()的结果?我的经验是:valgrind不喜欢java。很容易崩溃,我已经查过了。它将为我提供与skcript:Alloc X duplicate相同的输出。