From owner-freebsd-arm@FreeBSD.ORG Wed Mar 18 05:33:49 2015 Return-Path: Delivered-To: freebsd-arm@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id B50C25E8 for ; Wed, 18 Mar 2015 05:33:49 +0000 (UTC) Received: from st13p13im-asmtp001.me.com (st13p13im-asmtp001.me.com [17.164.56.160]) (using TLSv1.2 with cipher DHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 89F1DC0A for ; Wed, 18 Mar 2015 05:33:49 +0000 (UTC) Received: from [192.168.1.12] (162-237-206-116.lightspeed.austtx.sbcglobal.net [162.237.206.116]) by st13p13im-asmtp001.me.com (Oracle Communications Messaging Server 7.0.5.35.0 64bit (built Dec 4 2014)) with ESMTPSA id <0NLE002E24L49HB0@st13p13im-asmtp001.me.com> for freebsd-arm@freebsd.org; Wed, 18 Mar 2015 04:31:53 +0000 (GMT) X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:5.13.68,1.0.33,0.0.0000 definitions=2015-03-18_02:2015-03-17,2015-03-18,1970-01-01 signatures=0 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 spamscore=0 suspectscore=3 phishscore=0 adultscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=7.0.1-1412110000 definitions=main-1503180044 From: "Molly (Dev Lists)" Content-type: text/plain; charset=us-ascii Content-transfer-encoding: 7bit Subject: pthread_create() munging malloc()ed memory? (malloc(), threads, and static linking) [RPI-B+, 10.1] Message-id: <6580F1DF-3A9F-42C1-A27F-75546FD73829@icloud.com> Date: Tue, 17 Mar 2015 23:31:52 -0500 To: freebsd-arm@freebsd.org MIME-version: 1.0 (Mac OS X Mail 8.2 \(2070.6\)) X-Mailer: Apple Mail (2.2070.6) X-BeenThere: freebsd-arm@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: "Porting FreeBSD to ARM processors." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 18 Mar 2015 05:33:49 -0000 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 #include #include // 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; }