Question

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?

Was it helpful?

Solution

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top