[DragonFlyBSD - Bug #2305] dmalloc calls malloc before malloc_init constructor called.

Venkatesh Srinivas via Redmine bugtracker-admin at leaf.dragonflybsd.org
Fri May 18 22:52:09 PDT 2012


Issue #2305 has been updated by Venkatesh Srinivas.


--- /usr/src/lib/libc/stdlib/dmalloc.c	2012-05-10 17:31:04.234525000 -0700
+++ dmalloc.c	2012-05-18 22:50:07.624198000 -0700
@@ -303,6 +303,7 @@
 static int opt_utrace = 0;
 static int g_malloc_flags = 0;
 static int malloc_panic;
+static int malloc_started = 0;
 
 static const int32_t weirdary[16] = {
 	WEIRD_ADDR, WEIRD_ADDR, WEIRD_ADDR, WEIRD_ADDR,
@@ -320,11 +321,7 @@
 static void *_vmem_alloc(int ri, size_t slab_size);
 static void _vmem_free(void *ptr, size_t slab_size);
 static void _mpanic(const char *ctl, ...) __printflike(1, 2);
-#ifndef STANDALONE_DEBUG
-static void malloc_init(void) __constructor(0);
-#else
-static void malloc_init(void) __constructor(101);
-#endif
+static void malloc_init(void);
 
 struct nmalloc_utrace {
 	void *p;
@@ -353,6 +350,18 @@
 malloc_init(void)
 {
 	const char *p = NULL;
+	static spinlock_t malloc_init_lock;
+
+	if (malloc_started)
+		return;
+
+	if (__isthreaded) {
+		_SPINLOCK(&malloc_init_lock);
+		if (malloc_started) {
+			_SPINUNLOCK(&malloc_init_lock);
+			return;
+		}
+	}
 
 	Regions[0].mask = -1; /* disallow activity in lowest region */
 
@@ -399,6 +408,10 @@
 
 	UTRACE((void *) -1, 0, NULL);
 	_nmalloc_thr_init();
+	malloc_started = 1;
+
+	if (__isthreaded)
+		_SPINUNLOCK(&malloc_init_lock);
 }
 
 /*
@@ -712,6 +725,9 @@
 	size_t off;
 	char *obj;
 
+	if (!malloc_started)
+		malloc_init();
+
 	/*
 	 * If 0 bytes is requested we have to return a unique pointer, allocate
 	 * at least one byte.


Is a diff that does solve this problem (and is tested). However, it adds a (hopefully) minor cost to malloc() calls, a test of the malloc_started variable. I'd like to apply it after some review, but other opinions welcome.
----------------------------------------
Bug #2305: dmalloc calls malloc before malloc_init constructor called.
http://bugs.dragonflybsd.org/issues/2305

Author: John Marino
Status: New
Priority: Normal
Assignee: Venkatesh Srinivas
Category: 
Target version: 


During the development of the .preinit_array ELF section support, it was discovered that a test passed on i386 but failed on x86_64 regardless if the binary was statically or dynamically linked.  The program segfaulted on the first preinit function in the dmalloc function.

i386 uses nmalloc rather than dmalloc and the preinit test case passes just fine on that architecture.

The test case is here: http://leaf.dragonflybsd.org/~marino/preinit.c
The backtrace:
Program received signal SIGSEGV, Segmentation fault.
0x0000000800891269 in slaballoc (chunk_size=<optimized out>, chunking=<optimized out>, zi=<optimized out>)
    at /usr/src/lib/libc/../libc/stdlib/dmalloc.c:1069
1069		while ((slab = zinfo->avail_base) != NULL) {
#0  0x0000000800891269 in slaballoc (chunk_size=<optimized out>, chunking=<optimized out>, zi=<optimized out>)
    at /usr/src/lib/libc/../libc/stdlib/dmalloc.c:1069
#1  memalloc (size=4096, flags=0) at /usr/src/lib/libc/../libc/stdlib/dmalloc.c:744
#2  0x0000000800891cf1 in malloc (size=1344) at /usr/src/lib/libc/../libc/stdlib/dmalloc.c:593
#3  0x00000008008fe89b in __smakebuf (fp=0x800b2e850) at /usr/src/lib/libc/../libc/stdio/makebuf.c:70
#4  0x00000008008fe74f in __swsetup (fp=0x800b2e850) at /usr/src/lib/libc/../libc/stdio/wsetup.c:79
#5  0x00000008008fde15 in __sfvwrite (fp=0x800b2e850, uio=0x0) at /usr/src/lib/libc/../libc/stdio/fvwrite.c:62
#6  0x00000008008e6473 in puts (s=0x540 <Address 0x540 out of bounds>) at /usr/src/lib/libc/../libc/stdio/puts.c:65
#7  0x0000000000400742 in preinit_0 () at preinit.c:6
#8  0x000000080060ba71 in preinitialize_main_object () at /usr/src/libexec/rtld-elf/rtld.c:2051
#9  _rtld_call_init () at /usr/src/libexec/rtld-elf/rtld.c:703
#10 0x00000000004005ba in _start (ap=<optimized out>, cleanup=0x80060d65b <rtld_exit>)
    at /usr/src/lib/csu/x86_64/crt1.c:96



-- 
You have received this notification because you have either subscribed to it, or are involved in it.
To change your notification preferences, please click here: http://bugs.dragonflybsd.org/my/account





More information about the Bugs mailing list