All the functions mentioned in this block are library functions. How can I rectify this memory leak?
It is listed under the "Still reachable" category. (There are 4 more, which are very similar, but of varying sizes)
630 bytes in 1 blocks are still reachable in loss record 5 of 5
at 0x4004F1B: calloc (vg_replace_malloc.c:418)
by 0x931CD2: _dl_new_object (dl-object.c:52)
by 0x92DD36: _dl_map_object_from_fd (dl-load.c:972)
by 0x92EFB6: _dl_map_object (dl-load.c:2251)
by 0x939F1B: dl_open_worker (dl-open.c:255)
by 0x935965: _dl_catch_error (dl-error.c:178)
by 0x9399C5: _dl_open (dl-open.c:584)
by 0xA64E31: do_dlopen (dl-libc.c:86)
by 0x935965: _dl_catch_error (dl-error.c:178)
by 0xA64FF4: __libc_dlopen_mode (dl-libc.c:47)
by 0xAE6086: pthread_cancel_init (unwind-forcedunwind.c:53)
by 0xAE61FC: _Unwind_ForcedUnwind (unwind-forcedunwind.c:126)
Catch: Once I ran my program, it gave no memory leaks, but it had one additional line in the Valgrind output, which wasn't present before:
Discarding syms at 0x5296fa0-0x52af438 in /lib/libgcc_s-4.4.4-20100630.so.1 due to munmap()
If the leak can't be rectified, can someone atleast explain why the munmap() line causes Valgrind to report 0 "still reachable" leaks?
Edit:
Here's a minimal test sample:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void *runner(void *param) {
/* some operations ... */
pthread_exit(NULL);
}
int n;
int main(void) {
int i;
pthread_t *threadIdArray;
n=10; /* for example */
threadIdArray = malloc((n+n-1)*sizeof(pthread_t));
for(i=0;i<(n+n-1);i++) {
if( pthread_create(&threadIdArray[i],NULL,runner,NULL) != 0 ) {
printf("Couldn't create thread %d\n",i);
exit(1);
}
}
for(i=0;i<(n+n-1);i++) {
pthread_join(threadIdArray[i],NULL);
}
free(threadIdArray);
return(0);
}
Run with:
valgrind -v --leak-check=full --show-reachable=yes ./a.out
For future readers, "Still Reachable" might mean you forgot to close something like a file. While it doesn't seem that way in the original question, you should always make sure you've done that.
Since there is some routine from the the pthread family on the bottom (but I don't know that particular one), my guess would be that you have launched some thread as joinable that has terminated execution.
The exit state information of that thread is kept available until you call pthread_join
. Thus, the memory is kept in a loss record at program termination, but it is still reachable since you could use pthread_join
to access it.
If this analysis is correct, either launch these threads detached, or join them before terminating your program.
Edit: I ran your sample program (after some obvious corrections) and I don't have errors but the following
==18933== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 4 from 4)
--18933--
--18933-- used_suppression: 2 dl-hack3-cond-1
--18933-- used_suppression: 2 glibc-2.5.x-on-SUSE-10.2-(PPC)-2a
Since the dl-
thing resembles much of what you see I guess that you see a known problem that has a solution in terms of a suppression file for valgrind
. Perhaps your system is not up to date, or your distribution doesn't maintain these things. (Mine is ubuntu 10.4, 64bit)
You don't appear to understand what still reachable
means.
Anything still reachable
is not a leak. You don't need to do anything about it.
Here is a proper explanation of "still reachable":
"Still reachable" are leaks assigned to global and static-local variables. Because valgrind tracks global and static variables it can exclude memory allocations that are assigned "once-and-forget". A global variable assigned an allocation once and never reassigned that allocation is typically not a "leak" in the sense that it does not grow indefinitely. It is still a leak in the strict sense, but can usually be ignored unless you are pedantic.
Local variables that are assigned allocations and not free'd are almost always leaks.
Here is an example
int foo(void)
{
static char *working_buf = NULL;
char *temp_buf;
if (!working_buf) {
working_buf = (char *) malloc(16 * 1024);
}
temp_buf = (char *) malloc(5 * 1024);
....
....
....
}
Valgrind will report working_buf as "still reachable - 16k" and temp_buf as "definitely lost - 5k".
Source: Stackoverflow.com