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.
#1 Updated by marino about 3 years ago
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:
#3 Updated by profmakx over 2 years ago
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.
#5 Updated by profmakx over 2 years ago
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)
#6 Updated by profmakx over 2 years ago
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.