So I'm having a strange problem that I'm hoping someone can shed some light on... I have the following code:
#include <unistd.h>
#include <mcheck.h>
#include <pthread.h>
static void *run(void *args)
{
sleep(1);
return NULL;
}
int main()
{
mtrace();
pthread_t thread;
pthread_create(&thread, NULL, run, NULL);
pthread_join(thread, NULL);
return 0;
}
And I compile I've compiled it in these 2 ways:
g++ -static program.cpp -lpthread
and
g++ program.cpp -ltpthread
When I look at the mtrace's output (mem.out in my case)
I see the following when i use the -static
option, mtrace
reports:
Memory Not freed:
__________________
Address Size Caller
0x085ac350 0x88 program.cpp:0
But when I exclude the -static
option, mtrace
reports the glorious:
No memory leaks.
So any ideas as to whats going on here?
Here's a recipe for reproducing this on my regular desktop Linux system (FC-17):
#include <mcheck.h>
#include <pthread.h>
extern "C" { static void *run(void *) { return 0; } }
int main() {
mtrace();
pthread_t thread;
pthread_create(&thread, 0, run, 0);
pthread_join(thread, 0);
return 0;
}
Compiled with g++ -g -static -pthread
. This is how I executed it to get the mtrace
error:
$ MALLOC_TRACE=mt.txt mtrace ./a.out mt.txt
Memory not freed:
-----------------
Address Size Caller
0x00000000011a9c90 0x110 at 0x43d7f9
I have a 64 bit system, so the size doesn't match. When I disassemble the address in gdb
, it gives this:
(gdb) disass 0x43d7f9
Dump of assembler code for function _dl_allocate_tls:
0x000000000043d7c0 <+0>: mov %rbx,-0x20(%rsp)
0x000000000043d7c5 <+5>: mov %rbp,-0x18(%rsp)
...
0x000000000043d7f4 <+52>: callq 0x428150 <calloc>
0x000000000043d7f9 <+57>: test %rax,%rax
0x000000000043d7fc <+60>: je 0x43d8e0 <_dl_allocate_tls+288>
...
So it looks like some thread local storage was allocated for the thread. It seems like a one time allocation per thread, because there are no additional allocations when I added a pthread_create
call after the join, while there was one when I added it before the join. The _dl_allocate_tls
suggests this is normally a functioned called during dynamic linking, but it seems it is being called during thread stack initialization. A grep through the glibc
code shows it is being called in allocate_stack.c
.
There does seem to be corresponding calls to _dl_deallocate_tls
in glibc
, so I think this error is harmless. valgrind
does not pick up any memory leaks.