Do you have a question? Post it now! No Registration Necessary
Subject
- Posted on
- googlegroups
May 31, 2007, 8:43 pm

I'm having a problem when creating pthreads from a shared object
library. Every pthread that I spawn is accompanied by a 10MB chunk of
anonymous memory.
I manually set the stack size to 17k, and verified that it provides a
seg fault when I use more than I allocate. So I think I can rule-out
the stack.
But here's the perplexing part: If link the same code into an
executable, the 10MB chunks become 12KB.
When I link the offending code into a shared object, it doesn't matter
if I use dlopen or I dynamically link to it with g++, these chunks are
10MB.
Does anyone have any how I can find out what these anonymous memory
pages are? Once I know what they are I can figure out how to reduce
the size.
Thanks.
I'm running on:
Linux version 2.6.9-5.ELsmp ( snipped-for-privacy@decompose.build.redhat.com)
(gcc version 3.4.3 20041212 (Red Hat 3.4.3-9.EL4)) #1 SMP Wed Jan 5
19:30:39 EST 2005
This is currently running on a pentium4 box so I have tools like pmap
available. But our embedded system is an arm9.
The following is the snippet from pmap for 12 threads spawed from the
shared object:
08048000 8K r-x-- /home/brent/MAP/bin/FredInstantiatorDynamic
0804a000 4K rw--- /home/brent/MAP/bin/FredInstantiatorDynamic
091f8000 132K rw--- [ anon ]
b07d7000 4K ----- [ anon ]
b07d8000 10240K rw--- [ anon ]
b11d8000 4K ----- [ anon ]
b11d9000 10240K rw--- [ anon ]
b1bd9000 4K ----- [ anon ]
b1bda000 10240K rw--- [ anon ]
b25da000 4K ----- [ anon ]
b25db000 10240K rw--- [ anon ]
b2fdb000 4K ----- [ anon ]
b2fdc000 10240K rw--- [ anon ]
b39dc000 4K ----- [ anon ]
b39dd000 10240K rw--- [ anon ]
b43dd000 4K ----- [ anon ]
b43de000 10240K rw--- [ anon ]
b4dde000 4K ----- [ anon ]
b4ddf000 10240K rw--- [ anon ]
b57df000 4K ----- [ anon ]
b57e0000 10240K rw--- [ anon ]
b61e0000 4K ----- [ anon ]
b61e1000 10240K rw--- [ anon ]
b6be1000 4K ----- [ anon ]
b6be2000 10240K rw--- [ anon ]
b75e2000 4K ----- [ anon ]
b75e3000 10256K rw--- [ anon ]
b7ffe000 8K rw--- [ anon ]
bfe73000 1588K rw--- [ stack ]
ffffe000 4K ----- [ anon ]
When I run it from an executable, it becomes:
08048000 64K r-x-- /home/brent/MAP/bin/FredInstantiatorStatic
08058000 4K rw--- /home/brent/MAP/bin/FredInstantiatorStatic
084fd000 132K rw--- [ anon ]
b7fc7000 4K ----- [ anon ]
b7fc8000 12K rw--- [ anon ]
b7fcb000 4K ----- [ anon ]
b7fcc000 12K rw--- [ anon ]
b7fcf000 4K ----- [ anon ]
b7fd0000 12K rw--- [ anon ]
b7fd3000 4K ----- [ anon ]
b7fd4000 12K rw--- [ anon ]
b7fd7000 4K ----- [ anon ]
b7fd8000 12K rw--- [ anon ]
b7fdb000 4K ----- [ anon ]
b7fdc000 12K rw--- [ anon ]
b7fdf000 4K ----- [ anon ]
b7fe0000 32K rw--- [ anon ]
b7feb000 4K ----- [ anon ]
b7fec000 12K rw--- [ anon ]
b7fef000 4K ----- [ anon ]
b7ff0000 12K rw--- [ anon ]
b7ff3000 4K ----- [ anon ]
b7ff4000 12K rw--- [ anon ]
b7ff7000 4K ----- [ anon ]
b7ff8000 12K rw--- [ anon ]
b7ffb000 4K ----- [ anon ]
b7ffc000 16K rw--- [ anon ]
bff7f000 516K rw--- [ stack ]
ffffe000 4K ----- [ anon ]
library. Every pthread that I spawn is accompanied by a 10MB chunk of
anonymous memory.
I manually set the stack size to 17k, and verified that it provides a
seg fault when I use more than I allocate. So I think I can rule-out
the stack.
But here's the perplexing part: If link the same code into an
executable, the 10MB chunks become 12KB.
When I link the offending code into a shared object, it doesn't matter
if I use dlopen or I dynamically link to it with g++, these chunks are
10MB.
Does anyone have any how I can find out what these anonymous memory
pages are? Once I know what they are I can figure out how to reduce
the size.
Thanks.
I'm running on:
Linux version 2.6.9-5.ELsmp ( snipped-for-privacy@decompose.build.redhat.com)
(gcc version 3.4.3 20041212 (Red Hat 3.4.3-9.EL4)) #1 SMP Wed Jan 5
19:30:39 EST 2005
This is currently running on a pentium4 box so I have tools like pmap
available. But our embedded system is an arm9.
The following is the snippet from pmap for 12 threads spawed from the
shared object:
08048000 8K r-x-- /home/brent/MAP/bin/FredInstantiatorDynamic
0804a000 4K rw--- /home/brent/MAP/bin/FredInstantiatorDynamic
091f8000 132K rw--- [ anon ]
b07d7000 4K ----- [ anon ]
b07d8000 10240K rw--- [ anon ]
b11d8000 4K ----- [ anon ]
b11d9000 10240K rw--- [ anon ]
b1bd9000 4K ----- [ anon ]
b1bda000 10240K rw--- [ anon ]
b25da000 4K ----- [ anon ]
b25db000 10240K rw--- [ anon ]
b2fdb000 4K ----- [ anon ]
b2fdc000 10240K rw--- [ anon ]
b39dc000 4K ----- [ anon ]
b39dd000 10240K rw--- [ anon ]
b43dd000 4K ----- [ anon ]
b43de000 10240K rw--- [ anon ]
b4dde000 4K ----- [ anon ]
b4ddf000 10240K rw--- [ anon ]
b57df000 4K ----- [ anon ]
b57e0000 10240K rw--- [ anon ]
b61e0000 4K ----- [ anon ]
b61e1000 10240K rw--- [ anon ]
b6be1000 4K ----- [ anon ]
b6be2000 10240K rw--- [ anon ]
b75e2000 4K ----- [ anon ]
b75e3000 10256K rw--- [ anon ]
b7ffe000 8K rw--- [ anon ]
bfe73000 1588K rw--- [ stack ]
ffffe000 4K ----- [ anon ]
When I run it from an executable, it becomes:
08048000 64K r-x-- /home/brent/MAP/bin/FredInstantiatorStatic
08058000 4K rw--- /home/brent/MAP/bin/FredInstantiatorStatic
084fd000 132K rw--- [ anon ]
b7fc7000 4K ----- [ anon ]
b7fc8000 12K rw--- [ anon ]
b7fcb000 4K ----- [ anon ]
b7fcc000 12K rw--- [ anon ]
b7fcf000 4K ----- [ anon ]
b7fd0000 12K rw--- [ anon ]
b7fd3000 4K ----- [ anon ]
b7fd4000 12K rw--- [ anon ]
b7fd7000 4K ----- [ anon ]
b7fd8000 12K rw--- [ anon ]
b7fdb000 4K ----- [ anon ]
b7fdc000 12K rw--- [ anon ]
b7fdf000 4K ----- [ anon ]
b7fe0000 32K rw--- [ anon ]
b7feb000 4K ----- [ anon ]
b7fec000 12K rw--- [ anon ]
b7fef000 4K ----- [ anon ]
b7ff0000 12K rw--- [ anon ]
b7ff3000 4K ----- [ anon ]
b7ff4000 12K rw--- [ anon ]
b7ff7000 4K ----- [ anon ]
b7ff8000 12K rw--- [ anon ]
b7ffb000 4K ----- [ anon ]
b7ffc000 16K rw--- [ anon ]
bff7f000 516K rw--- [ stack ]
ffffe000 4K ----- [ anon ]

Re: 10MB Chunks of anonymous memory for each thread created from shared object

Run the program under gdb, set breakpoint on __mmap and __mmap64,
when hit type 'where' ?
I bet they are still coming from thread stack allocation,
probably due to a bug in libpthread ...
Cheers,
--
In order to understand recursion you must first understand recursion.
Remove /-nsp/ for email.
In order to understand recursion you must first understand recursion.
Remove /-nsp/ for email.

Re: 10MB Chunks of anonymous memory for each thread created from shared object

You are correct. It was the stack.

It could definitely be in libpthread, but it could also be the g++
linker. The behavior was different whether our code that created the
threads was in a shared object or an executable. But both times we
linked to the same libpthread
Thanks for the help

Re: 10MB Chunks of anonymous memory for each thread created from shared object

There is no such thing as 'g++ linker'; it uses the system GNU linker.
I have reproduced the problem you observed, and it turns out to be
a bug in the way you build your shared library (or a rather obscure
interaction between your link line and symbol versioning).
First the result:
$ gcc -shared -fPIC -o create.so create.c # [1]
$ gcc -pthread main.c ./create.so
$ ./a.out
stack size: 163840
&p = 0xb7fee460
in region [0xb75ef000, 0xb7ff1000) (10493952)
Above, I asked for stack size of 160K (10*PTHREAD_STACK_MIN),
but got 10MB (just like you). I am guessing that's exactly what
you did. The problem is that command [1] is incorrect.
Correct command:
$ gcc -pthread -shared -fPIC -o create.so create.c
^^^^^^^^
$ ./a.out
stack size: 163840
&p = 0xb7fee460
in region [0xb7fc8000, 0xb7ff1000) (167936)
produces expected result.
The reason:
$ gcc -shared -fPIC -o create.so create.c &&
objdump -T ./create.so | grep pthread_create
00000000 D *UND* 00000000 pthread_create
$ gcc -pthread -shared -fPIC -o create.so create.c &&
objdump -T ./create.so | grep pthread_create
00000000 DF *UND* 0000018c GLIBC_2.1 pthread_create
When create.so is built correctly, it uses pthread_create@GLIBC_2.1.
When it isn't, it uses pthread_create@GLIBC_2.0:
$ gcc -shared -fPIC -o create.so create.c
$ LD_DEBUG=bindings ./a.out 2>&1 | grep pthread_create
18884: binding file ./create.so to /lib/tls/libpthread.so.0: normal
symbol `pthread_create'
$ gcc -pthread -shared -fPIC -o create.so create.c
$ LD_DEBUG=bindings ./a.out 2>&1 | grep pthread_create
18981: binding file ./create.so to /lib/tls/libpthread.so.0: normal
symbol `pthread_create' [GLIBC_2.1]
Finally, here is the code I used:
$ cat main.c
int main() { create(); return 0; }
$ cat create.c
#include <pthread.h>
#include <limits.h>
#include <stdio.h>
void *fn(void *p)
{
char cmd[1024];
FILE *fp;
fprintf(stderr, "&p = %p\n", &p);
sprintf(cmd, "cat /proc/%d/maps", getpid());
fp = popen(cmd, "r");
while (fgets(cmd, sizeof(cmd), fp)) {
void *low, *hi;
int n = sscanf(cmd, "%x-%x", &low, &hi);
if (n) {
if (low < (void*)&p && (void*)&p < hi) {
fprintf(stderr, "in region [%p, %p) (%d)\n", low, hi, (char*)hi
- (char*)low);
fclose(fp);
break;
}
}
}
return p;
}
void create()
{
pthread_t tid;
size_t size = 10*PTHREAD_STACK_MIN;
pthread_attr_t attr;
fprintf(stderr, "stack size: %d\n", size);
pthread_attr_init(&attr);
pthread_attr_setstacksize(&attr, size);
pthread_create(&tid, &attr, fn, NULL);
pthread_join(tid, NULL);
}
Cheers,
--
In order to understand recursion you must first understand recursion.
Remove /-nsp/ for email.
In order to understand recursion you must first understand recursion.
Remove /-nsp/ for email.
Site Timeline
- » cunit basics
- — Next thread in » Embedded Linux
-
- » GRUB master boot record
- — Previous thread in » Embedded Linux
-
- » Crosscompiling for ARM: reloc type R_ARM_ABS32 is not supported for PIC - ...
- — Newest thread in » Embedded Linux
-
- » Slow (industrial?) SD cards
- — The site's Newest Thread. Posted in » Embedded Programming
-