pthread_create() munging malloc()ed memory? (malloc(), threads, and static linking) [RPI-B+, 10.1]
Molly (Dev Lists)
mollydevlists at icloud.com
Wed Mar 18 05:33:49 UTC 2015
I'm encountering some strange behavior where memory passed as an
argument through pthread_create() is getting zeroed out, under
suspiciously specific conditions; but I haven't figured out the
cause. I've reduced it down to a pretty tiny test case (below)....
Summary:
* Main thread allocates a block of memory and sets the first
four bytes to some non-zero value (it doesn't matter what)
* The block is passed to a new thread via pthread_create();
the main thread then waits on that thread via pthread_join()
* In the thread, the value is printed, the block is free()d,
and the thread exits
After a few iterations of this (in a loop in main()), those "non-zero"
bytes become zeroed out during the call to pthread_create(). This only
occurs a couple of times, and then the behavior seems to return to
normal for subsequent calls.
This only occurs under specific conditions:
* The size of the allocated block must be at least 68 bytes
and no more than 80 bytes
* The block needs to be allocated in the main thread and free()d
in the created thread
* The program must be statically linked (-static)
This seems bizarrely specific and makes me think that either I'm doing
something wrong and wrecking memory somewhere, or I'm relying on fragile
behavior and don't realize it; I'm not sure what it might be, though.
(It seems like maybe the allocator isn't happy with threads, at least
when statically linked; is something going on here that I'm missing?)
Any ideas/suggestions?
This is running on a Raspberry Pi B+ using the 10.1-RELEASE image
(FreeBSD 10.1-RELEASE #0 r274401). clang is version 3.4.1 (the
version included in the base system).
//
// Build with: cc -std=c11 -Weverything -pthread -static thisfile.c
//
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
// Problem occurs if sizeof(TESTITEM) is in the range [68, 80]
typedef struct
{
int testval;
char padding [ 68 - sizeof ( int ) ];
} TESTITEM;
static void * thread_test ( void * arg )
{
fprintf ( stderr, "Value in thread: %d\n", ((TESTITEM*)arg)->testval );
free ( arg );
return NULL;
}
int main ( int argc, char *argv[] )
{
(void)argc; // Unused
(void)argv; // Unused
for ( int i = 0; i < 10; i++ )
{
TESTITEM * p = malloc ( sizeof ( TESTITEM ) );
if ( p == NULL ) abort ();
p->testval = 12345; // Any non-zero value is fine here
pthread_t tid;
if ( pthread_create ( &tid, NULL, thread_test, p ) != 0 ) abort ();
pthread_join ( tid, NULL );
}
return 0;
}
More information about the freebsd-arm
mailing list