GLIBC: memory leak: how to interpret mtrace () output

Im trying to debug a memory leak problem. I use mtrace () to get the malloc / free / realloc trace. Ive launched my program and now has a huge log file. So far, so good. But I have problems interpreting the file. Look at these lines:

@ /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 

It is strange that one call (the same return address) is responsible for 4 distributions.

Even a stranger:

 @ /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 

Between these two lines, the 0x2aaab43a1700 block is never freed.

Does anyone know how to explain this? How can I call the result in 4 distributions? And how can malloc return the previously allocated address?

edit 2008/09/30: a script to analyze the mtrace () output provided by GLIBC (mtrace.pl) will not help here. It will simply say: Alloc 0x2aaab43a1700 duplicate. But how could this happen?

+4
source share
4 answers

A function that allocates memory is called more than once. The caller's address indicates the code that performed the allocation, and this code simply runs more than once.

Here is an example in C:

 void *allocate (void) { return (malloc(1000)); } int main() { mtrace(); allocate(); allocate(); } 

Exiting mtrace:

  Memory not freed:
 -----------------
            Address Size Caller
 0x0000000000601460 0x3e8 at 0x4004f6
 0x0000000000601850 0x3e8 at 0x4004f6

Notice how the caller’s address is identical? This is why the analysis of the mtrace script says that they are identical, because the same error is more visible, which leads to several memory leaks.

Compiling with debugs (-g) flags is useful if you can:

  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
+4
source

You are looking at the direct output of mtrace, which is extremely confusing and inconsistent. Fortunately, there is a perl script (called mtrace found in glibc-utils) that can very easily help parse this output.

Compile your build using debugging and run mtrace as follows:

 $ 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 

The result should be much easier to digest.

+7
source

One possible explanation is that the same function allocates different buffer sizes? One such example is strdup.

For the second question, it is possible that the runtime allocates some β€œstatic” region of zero, which is not intended to be released until the process is complete. And at this point, the OS will be cleaned up after the process anyway.

Think of it this way: Java has no destructors and there is no guarantee that finalization will ever be called for any object.

0
source

Try running the application under valgrind. This may give you a better idea of ​​what is actually leaking.

0
source

Source: https://habr.com/ru/post/1277328/


All Articles