Re[2]: [Gc] trouble with gc-7.2d compiling against musl libc

Ivan Maidanski ivmai at
Tue Jan 15 13:34:13 PST 2013

 Hi John,

Sorry for the delay. But I've not tried to run gc under musl (no time these days).

15 01 2013, 16:24 +01:00 John Spencer <maillist-boehm at>:
>It's now over a week that we didnt hear from you, at first i thought the 
>radio silence is due to holidays or even an accident, but your github 
>activity tab says otherwise.
Yes, my focus is libatomic_ops fixing and improvement (over the last several weeks).

>btw, i forgot to mention that you don't need to use sabotage linux in 
>order to test the GC against musl, it is sufficient if you install musl 
>into a custom prefix (/usr/local/musl) with --enable-wrapper and then 
>use "musl-gcc" wrapper to compile boehm gc.

>also, Rich and I did some debugging and it seems that boehm gc still 
>uses some hacks related to ancient LinuxThreads. like raising 
>SIGPWR/SIGXCPU and similar oddities. any such workarounds/hacks cant 
This is used only in multi-threaded mode, and it is used for thread suspending/resuming.
On other targets might use different ways, like OpenBSD that uses pthread_suspend/resume_np and pthread_stackseg_np.

SIGPWR/SIGXCPU are taken because they are most probably unused by app (there is no standard way to allocate signals). These are not strictly related to LinuxThreads implementation.

>work on musl libc of course, since the pthread implementation was done 
>from scratch and is completely unrelated to LinuxThreads.
>oh, and at least in 6.8, there's a race condition:
>the wrapper for pthread_join performs the join, _then_ removes the 
>pthread_t from the GC's list of threads.
>however the pthread_t value may have already been reused at this point.
Let me not look into ancient v6.8.

>is there a switch that makes the boehm GC disable all ugly hacks ? i 
>guess not...
Unfortunately, gc needs the following uncommon thing for a regular app:
1. Find bottom of current stack  (and of backing register store for IA-64 target) - most "clear" way (for POSIX) is to use pthread_getattr_np or pthread_get_stackaddr_np.
2. Suspend/resume particular threads and get their stack bottom and top - most "clear" way (for POSIX) is pthread_suspend/resume_np and pthread_stackseg_np.
3. Find application static data roots (non-constant data section regions) including those in currently attached shared libraries - seems no good way
4. Ability to intercept thread creation/termination (or ability to get application threads list) - most "standard" way is either client uses manual thread registration or pthread_create/exit/join are redirected in gc.h
5. Ability to completely save data from CPU registers to stack - most reliable way on POSIX is getcontext (or, probably, __builtin_unwind_init).
6. Ability to do stack back-tracing (mostly for memory leak find mode) - optional.

In your case:
1. SIGSEGV is used to determine stack bottom (according to the value you showed in the previous email) - it works.
2. let skip this until get working single-threaded GC
3. there could be a problem - try with -D__GLIBC__=2 (this is tested in gcconfig.h)
4. should work for you
5. there could be a problem because in your case, setjmp (implemented by musl) is used and it might turn that some of registers (that could contain pointers to heap) are not saved - try -DHAVE_BUILTIN_UNWIND_INIT if possible
6. let's omit the discussion about it


>On 01/09/2013 07:55 PM, John Spencer wrote:
>> Hi Ivan,
>> did the results of "make check" give you any clue ?
>> On 01/08/2013 11:31 AM, Ivan Maidanski wrote:
>>>>>>> which algorithm is used for detection of main stack base in your
>>>>>>> case? which macro is defined - STACKBOTTOM, HEURISTIC1,
>>>>>> out of these 3, only LINUX_STACKBOTTOM seems to be defined (i added
>>>>>> #warnings into os_dep.c in order to find out)
>>>>> Seems to be correct.
>>>>> Does GC_get_main_stack_base return reasonable value?
>>>> how can i check ?
>>> What is the difference between this value and address of any local var
>>> of main() function? (It should not be bigger than several K.) Is this
>>> value bigger than that local var address? (stack grows down on your
>>> target, right?)
>> ~/GC/bdwgc # cat test.c
>> #include "include/private/gc_priv.h"
>> #include <stdio.h>
>> int main() {
>> int a;
>> dprintf(2, "a: %p, stack: %p\n", &a, GC_get_main_stack_base());
>> }
>> ~/GC/bdwgc # gcc test.c -L".libs/" -lgc
>> ~/GC/bdwgc # LD_LIBRARY_PATH=.libs ./a.out
>> a: 0x7fff6ff6728c, stack: 0x7fff6ff672e0
>> ~/GC/bdwgc #
This is good value.

>>>>>>>> in any case, i'd welcome advice on how to workaround this issue,
>>>>>>>> so that
>>>>>>>> i get a working in order to use inkscape.
>>>>>>> Thanks for reporting the problem, I'll definitely fix the gc
>>>>>>> source if we understand how to do it correctly. (Typically, first
>>>>>>> I apply the fixes to master branch and, then, cherry-pick to 7.2
>>>>>>> release.)
>>>>>> thank you. is there anything else i can help with in order to get this
>>>>>> fixed ?
>>>>> Also, static data roots should be checked (GC_static_roots[], all
>>>>> global/static variables should be within one of the regions).
>>>> how can i check ? List all root ranges.
>>> Compile with linker map output, it will show addresses of global
>>> variables. These addresses (excluding read-only data) must be inside
>>> of a root range.
>> sorry, i dont know how to do that. please provide a test program and/or
>> required command line.
>> i tried:
>> ~/GC/bdwgc # gcc -shared -fPIC -DPIC .libs/allchblk.o .libs/alloc.o
>> .libs/blacklst.o .libs/checksums.o .libs/db
>> g_mlc.o .libs/dyn_load.o .libs/finalize.o .libs/gc_dlopen.o
>> .libs/gcj_mlc.o .libs/headers.o .libs/mach_dep.o .lib
>> s/malloc.o .libs/mallocx.o .libs/mark.o .libs/mark_rts.o .libs/misc.o
>> .libs/new_hblk.o .libs/obj_map.o .libs/os_d
>> ep.o .libs/pcr_interface.o .libs/ptr_chck.o .libs/real_malloc.o
>> .libs/reclaim.o .libs/specific.o .libs/stubborn.o
>> .libs/thread_local_alloc.o .libs/typd_mlc.o .libs/fnlz_mlc.o -ldl
>> -Wl,-soname -Wl, -o .libs/libgc
>> .so.1.0.3 -Wl,--print-map >
>> but the resulting file does not contain any reference to GC_static_roots
>> maybe objdump or readelf can do what you want ?
>> i uploaded the entire ~/GC directory including all object files (and
>> .git dir) here for your convenience:
>> (10 MB)
>> in case you want to try yourself (i suggest you do so, since i am not an
>> expert with BOEHM GC internals), here is an image file of sabotage linux
>> (150 MB only)
>> extract using
>> xzcat sabotage-0.9.7-x86_64-898897d9.img.xz > sabotage.img
>> you can directly start it in qemu using
>> qemu-system-x86_64 sabotage.img
>> or convert to virtual box hdd format with
>> VBoxManage convertfromraw sabotage.img sabotage.vdi
>> root pass is "sabotage"
>> the only thing missing in the image is libtool, but this is not required
>> if you simply unpack the above GC tarball which has the configure script
>> already generated.
>> otherwise libtool compiles without any patches from source.
>> the other auto* utils, gcc, binutils, gdb, strace, etc are installed.
>> if you need network connectivity, try "dhclient eth0" or the usual
>> ifconfig.
>> if you want to connect to the vm using SSH use :
>> source /src/config
>> butch install sshd-keys
>> /bin/sshd
>> latest musl precompiled is available here
>> (700KB)
>> just unpack into /opt and everything will automatically be up-to-date.
>> (the musl installed in the image is one release behind, i am unsure if
>> it makes any difference though.)
>> thanks,
>> --JS
-------------- next part --------------
An HTML attachment was scrubbed...

More information about the Gc mailing list