pkgsrc's intl library segfaults when locking a thread (i386 only)
#### DOES NOT AFFECT X86_64, THIS IS I386 ONLY ####
How it was found:
pkgsrc security/libpreludedb wouldn't build, crashed during configuration.
Cause of crash was conftest involving libprelude-config, a program built from security/libprelude.
The program is attached. It could be built with the following flags:
cc -o conftest -O2 -g -I/usr/pkg/include -z relro -z now \
-L/usr/pkg/lib -Wl,-R/usr/pkg/lib -lprelude -lgnutls -lgcrypt -lgpg-error conftest.c
Upon execution, it will segfault with libgcrypt which calls libgpg-error.
libgpg-error, when built with Native Language Support, will invoke bindtextdomain() from libintl (from pkgsrc devel/gettext-lib)
It should be bindtextdomain("libgpg-error", "/usr/pkg/share/locale").
That invocation from gpg-error's init function segfaults when locking a thread.
The backtrace is as follows:
Program received signal SIGSEGV, Segmentation fault.
init_static (thread=0x0, rwlock=0x284da28c)
117 THR_LOCK_ACQUIRE(thread, &_rwlock_static_lock);
#0 init_static (thread=0x0, rwlock=0x284da28c)
#1 0x284c7612 in rwlock_wrlock_common (rwlock=<optimized out>,
#2 0x284c76dc in _pthread_rwlock_wrlock (rwlock=0x284da28c)
#3 0x284d3652 in set_binding_values (domainname=0x282e9bd6 "libgpg-error",
dirnamep=0x284da28c, codesetp=0x0) at ./bindtextdom.c:94
#4 0x284d3a48 in libintl_bindtextdomain (
dirname=0x282e9bc0 "/usr/pkg/share/locale") at ./bindtextdom.c:323
#5 0x282e974a in real_init () at init.c:68
#6 gpg_err_init () at init.c:104
#7 0x282e9b8b in __do_global_ctors_aux () from /usr/pkg/lib/libgpg-error.so.0
#8 0x282e956d in _init () from /usr/pkg/lib/libgpg-error.so.0
#9 0x28060288 in ?? () from /usr/libexec/ld-elf.so.2
#10 0x28054be8 in _rtld_call_init () at /usr/src/libexec/rtld-elf/rtld.c:738
#11 0x080485f0 in _start1 (cleanup=0x28056894 <rtld_exit>, argc=1,
argv=0xbfbff850) at /usr/src/lib/csu/i386/crt1_c.c:71
#12 0x08048598 in _start () at /usr/src/lib/csu/i386/crt1_s.S:46
The problem is problem with pthread library given libintl works on x86_64 and probably every platform supported by pkgsrc.
To repeat this test, you'd have to use a version of gpg-error with NLS support.
Reverse or disable this patch removing NLS from i386-dragonfly if using gpg-error from trunk:
i believe this is also breaking gconf (though glib2 g_logv) on both pkgsrc and dports.
This really needs to be investigated.
I actually get this segfault on x86_64 (in a XEN vm, but I don't think that this is relevant). Discovered it because bitlbee segfaults on startup before even reaching main(), I can also reproduce the problem using the provided conftest.c
Changing the threading lib to libc_r makes it work.
That's interesting that it also happens on x86-64. I've been meaning to make a better test case for this, and I kind of forgot about it. Thanks for reminding me. I think we should try to track this down before version 3.4 is released.
It seems that this is connected to gcc 4.4 vs gcc 4.7:
* using gcc 4.4 for everything (kernel, world, the testcase) does not show the segfault
* using gcc 4.4 or gcc 4.7 for the testcase and gcc 4.7 for kernel and world does show the segfault
* using gcc 4.4 or gcc 4.7 for the testcase and gcc 4.4 for kernel and world does not show the segfault
(everything tested with the default threading lib obviously)
What happens is that the constructor of libpthread is not called early enough on program startup. I have implemented a quick hack that makes the segfault go away, but I want to explore more closely the interactions between gcc 4.4 and 4.7 and the segfault and find a better fix. Simon suggested to initialise libpthread during libc initialisation.
I have made a patch which I am currently testing on a few systems, because it touches libc and libthread_xu. Patch will be pushed soon.