segfault with static programs that don't use stdio functions
Tino Keitel
tino.keitel at innominate.com
Wed Dec 10 14:57:30 UTC 2008
Hi,
as the bug tracker is down, I try it here.
I discovered that all statically linked programs without stdio usage
segfault with uclibc 0.9.29 and later. Here is the example program I
used:
#include <unistd.h>
#include <stdio.h>
int main(void) {
write(1, "test\n", 5);
#ifdef USE_STDIO
puts("test2");
#endif
return 0;
}
I got this segfault with uclibc 0.9.29 and gcc 4.1 first. It happens on
i386, but not on big endian ARM. Here is the procedure how I tracked
this down with buildroot from latest git, using uclibc 0.9.30 and gcc
4.3.2:
This is the behaviour with stdio usage:
$ ./i386_build/staging/usr/bin/i386-linux-uclibc-gcc -o test -Wall -W
-g3 -O0 -static ~/test.c -DUSE_STDIO
$ ./test
test
test2
$
Without stdio usage:
$ ./i386_build/staging/usr/bin/i386-linux-uclibc-gcc -o test -Wall -W
-g3 -O0 -static ~/test.c
Segmentation fault
$
I built uclibc with DODEBUG enabled, and funnily segfault went away,
because it seems to be triggered with -O2 only. I changed the -O0 in
Rules.mak to -O2 to get debugging information and the segfault.
In gdb, I traced the bug to the invocation of _stdio_init():
$ gdb ./test
(gdb) break __uClibc_main.c:232
Breakpoint 1 at 0x8048311: file libc/misc/internals/__uClibc_main.c,
line 232.
(gdb) run
Starting program: /home/tkeitel/src/buildroot/test
Breakpoint 1, *__GI___uClibc_init () at
libc/misc/internals/__uClibc_main.c:233
233 _stdio_init();
(gdb) print _stdio_init
No symbol "_stdio_init" in current context.
(gdb) step
Program received signal SIGSEGV, Segmentation fault.
0x00000000 in ?? ()
(gdb) bt
#0 0x00000000 in ?? ()
#1 0x080483ca in __uClibc_main (main=0x8048188 <main>, argc=1,
argv=0xff87dac4, app_init=0x8048094 <_init>, app_fini=0x8048c10
#<_fini>,
rtld_fini=0, stack_end=0xff87dabc)
at libc/misc/internals/__uClibc_main.c:318
#2 0x080480d1 in _start () at libc/sysdeps/linux/i386/crt1.S:128
So, _stdio_init() was called because the NULL check failed for some
reason:
if (likely(_stdio_init != NULL))
_stdio_init();
Without the likely(), the segfault also happens.
In uclibc 0.9.29, the weak _stdio_init declaration was extended by
attribute_hidden. I removed this attribute, and the segfault didn't
happen anymore. However, another segfault happend at the invocation of
_stdio_term(), which had the same problem with attribute_hidden.
Regards,
Tino
--
Tino Keitel
Software Engineer
Innominate Security Technologies AG
/protecting industrial networks/
Tel: +49.30.6392-3309
Fax: +49.30.6392-3307
Albert-Einstein-Str. 14
D-12489 Berlin
http://www.innominate.com/
Register Court: AG Charlottenburg, HRB 81603
Management Board: Dirk Seewald
Chairman of the Supervisory Board: Volker Bibelhausen
INNOMINATE IS MOVING. FROM 17.12.2008 OUR BUSINESS CONTACT DATA WILL BE
CHANGED:
Rudower Chaussee 13, 12489Berlin / Germany
tel: +49.30.921028-0 (head office)
tel: +49.30.921028-206 (personal extension)
fax: +49.30. 921028-020
More information about the uClibc
mailing list