L
Louis B. (ldb)
I have a long running program that eventually crashes when valloc()
returns a 0. This program is relatively non-trivial as it's written in
Ada, is multithreaded, has alot of SSE routines. A memory leak would
be the most obvious cause but this appears to be more sinister then a
simple memory leak.
After alot of running around and searching through the code I found an
anomaly that I'd like to explain and understand if it's the cause of
valloc() returning a 0. It may be unrelated to my problem above, but I
can't be sure. I've recreated this anomaly in a very simple program.
Basically, mallinfo() seems to produce garbage results in multi-
threaded code. In a very single program where I fire up 2 pthreads
have them malloc() and free a bunch of stuff, once all the threads are
finished, I print out malloc_stats() and mallinfo() and I seem to get
garbage for the mmap() related fields.
Most of the time I run the code, the hblks and hblkshd fields of
mallinfo() come back 0 and 0, but a fair percentage of the time I get
a strange answer where hblks is either 2, 5, -3 or -1 or something
like that. It's almost like there's a race condition inside the
malloc()/free() code that updates these fields.
This is out-of-the-box Ubuntu with gcc 4.1.2
I've included the code at the bottom, but here is an example output:
Arena 0:
system bytes = 135168
in use bytes = 288
Arena 1:
system bytes = 135168
in use bytes = 1128
Total (incl. mmap):
system bytes = 4045234176
in use bytes = 4044965256
max mmap regions = 1
max mmap bytes = 250003456
hblks : -1 hblkshd : -250003456
The mmap() and hblk (from mallinfo()) data seems to be totally
corrupted, to me. (In this particular case, they've gone negative). In
this code, the "answer" should be 0 since everything has been freed,
should it not? Are these numbers supposed to be meaningful?
(this code has a pretty large malloc, but similar results with more
reasonable sized mallocs like 10 megs)
---------------------------------
Built with:
gcc main.c -lpthread
Here is the code I'm running:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <malloc.h>
void *detection_thread();
main (int argc, char *argv[])
{
pthread_t thread1, thread2;
pthread_t thread3, thread4;
struct mallinfo mi;
// spawn threads
pthread_create(&thread1, NULL, detection_thread, NULL);
pthread_create(&thread2, NULL, detection_thread, NULL);
// wait for threads to return
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
printf("********************************\n");
malloc_stats();
mi = mallinfo();
printf("hblks : %d hblkshd : %d\n", mi.hblks, mi.hblkhd);
}
void *detection_thread()
{
int *slappy;
int i;
struct mallinfo mi;
for (i = 0; i < 5000; i++)
{
slappy = malloc(1000*1000*250);
if (slappy == NULL)
{
printf("CRASH\n");
exit(1);
}
free(slappy);
}
printf("Done!\n");
}
returns a 0. This program is relatively non-trivial as it's written in
Ada, is multithreaded, has alot of SSE routines. A memory leak would
be the most obvious cause but this appears to be more sinister then a
simple memory leak.
After alot of running around and searching through the code I found an
anomaly that I'd like to explain and understand if it's the cause of
valloc() returning a 0. It may be unrelated to my problem above, but I
can't be sure. I've recreated this anomaly in a very simple program.
Basically, mallinfo() seems to produce garbage results in multi-
threaded code. In a very single program where I fire up 2 pthreads
have them malloc() and free a bunch of stuff, once all the threads are
finished, I print out malloc_stats() and mallinfo() and I seem to get
garbage for the mmap() related fields.
Most of the time I run the code, the hblks and hblkshd fields of
mallinfo() come back 0 and 0, but a fair percentage of the time I get
a strange answer where hblks is either 2, 5, -3 or -1 or something
like that. It's almost like there's a race condition inside the
malloc()/free() code that updates these fields.
This is out-of-the-box Ubuntu with gcc 4.1.2
I've included the code at the bottom, but here is an example output:
Arena 0:
system bytes = 135168
in use bytes = 288
Arena 1:
system bytes = 135168
in use bytes = 1128
Total (incl. mmap):
system bytes = 4045234176
in use bytes = 4044965256
max mmap regions = 1
max mmap bytes = 250003456
hblks : -1 hblkshd : -250003456
The mmap() and hblk (from mallinfo()) data seems to be totally
corrupted, to me. (In this particular case, they've gone negative). In
this code, the "answer" should be 0 since everything has been freed,
should it not? Are these numbers supposed to be meaningful?
(this code has a pretty large malloc, but similar results with more
reasonable sized mallocs like 10 megs)
---------------------------------
Built with:
gcc main.c -lpthread
Here is the code I'm running:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <malloc.h>
void *detection_thread();
main (int argc, char *argv[])
{
pthread_t thread1, thread2;
pthread_t thread3, thread4;
struct mallinfo mi;
// spawn threads
pthread_create(&thread1, NULL, detection_thread, NULL);
pthread_create(&thread2, NULL, detection_thread, NULL);
// wait for threads to return
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
printf("********************************\n");
malloc_stats();
mi = mallinfo();
printf("hblks : %d hblkshd : %d\n", mi.hblks, mi.hblkhd);
}
void *detection_thread()
{
int *slappy;
int i;
struct mallinfo mi;
for (i = 0; i < 5000; i++)
{
slappy = malloc(1000*1000*250);
if (slappy == NULL)
{
printf("CRASH\n");
exit(1);
}
free(slappy);
}
printf("Done!\n");
}