Bug #2305

dmalloc calls malloc before malloc_init constructor called.

Added by John Marino 3 months ago. Updated about 1 month ago.

Status:New Start date:02/11/2012
Priority:Normal Due date:
Assignee:Venkatesh Srinivas % Done:

0%

Category:-
Target version:-

Description

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


Related todos

History

Updated by John Marino 3 months ago

I forgot: To test this, one must have world built at least to commit b28bf640312db2b299faff75052fbb01d67fd821
Sat, 11 Feb 2012 20:04:12 +0000 (21:04 +0100)
rtld: Add support for preinit, init, and fini arrays

Updated by Venkatesh Srinivas 2 months ago

dmalloc is unhappy because the preinit code is calling malloc() before the malloc_init constructor has had a chance to run.

malloc_init() for dmalloc is called by a reserved-priority constructor; that call is set to happen after the preinit vector is executed, however. nmalloc is okay because malloc_init does nothing of urgent need there; dmalloc uses it to call its own (misnamed) _nmalloc_thr_init() for the first thread. [nmalloc calls that from the thread library and doesn't need it in the first thread].

Possible fixes:
* Have dmalloc check if it has run malloc_init, and if not, run it. {remember to interlock correctly!}
* Force malloc's initialization to happen before preinit
* something else?

Updated by John Marino about 1 month ago

Which fix do you recommend?
Or to put it another way: Who do you want to answer this question? It seems to me that you are more qualified than most...

Also available in: Atom PDF