Some more debugging information: In the failing case stdout get flipped to an unaligned value in _IO_check_libio function defined in libio/oldstdfiles.c, which contains the following code:
static void _IO_check_libio () { if (&_IO_stdin_used == NULL) { /* We are using the old one. */ _IO_stdin = stdin = (_IO_FILE *) &_IO_stdin_; _IO_stdout = stdout = (_IO_FILE *) &_IO_stdout_; _IO_stderr = stderr = (_IO_FILE *) &_IO_stderr_; [...] Why we are taking the 'if' branch is a bit of a mystery to me, because _IO_stdin_used appears to be defined, as this bit of gdb session illustrates: (gdb) break _IO_check_libio Function "_IO_check_libio" not defined. Make breakpoint pending on future shared library load? (y or [n]) y Breakpoint 1 (_IO_check_libio) pending. (gdb) run Starting program: /home/jurij/libc/tmp/foo Breakpoint 1, _IO_check_libio () at oldstdfiles.c:79 warning: Source file is more recent than executable. 79 if (&_IO_stdin_used == NULL) (gdb) print _IO_stdin_used $1 = 131073 (gdb) print &_IO_stdin_used $2 = (const int *) 0x10638 (gdb) next 78 { (gdb) next 79 if (&_IO_stdin_used == NULL) (gdb) next 82 _IO_stdin = stdin = (_IO_FILE *) &_IO_stdin_; (gdb) next 83 _IO_stdout = stdout = (_IO_FILE *) &_IO_stdout_; (gdb) print stdout $3 = (FILE *) 0x207c0 (gdb) print &_IO_stdout_ $4 = (struct _IO_FILE_plus *) 0xf7fc3114 After this line is executed, stdout starts pointing to the new unaligned location, eventually leading to a segfault. An important observation is that symbol is unaligned even in libc, which obviously should not be happening: jurij@debian:~/libc/tmp$ nm /usr/lib/debug/lib/sparc-linux-gnu/libc-2.13.so | grep _IO_stdout_ 0017f114 D _IO_stdout_ To answer why we are hitting the &_IO_stdin_used == NULL check, I've looked at the assembly code, relevant parts of it look like that: .LLADDPC0: jmp %o7+8 add %o7, %l7, %l7 #NO_APP .align 4 .align 32 .type _IO_check_libio, #function .proc 020 _IO_check_libio: .LLFB71: .file 1 "oldstdfiles.c" .loc 1 78 0 .cfi_startproc save %sp, -96, %sp .LLCFI0: .cfi_def_cfa_register 30 .cfi_window_save .loc 1 79 0 sethi %hi(_IO_stdin_used), %g1 .loc 1 78 0 sethi %hi(_GLOBAL_OFFSET_TABLE_-4), %l7 call .LLADDPC0 add %l7, %lo(_GLOBAL_OFFSET_TABLE_+4), %l7 .cfi_register 15, 31 .loc 1 79 0 or %g1, %lo(_IO_stdin_used), %g1 ld [%l7+%g1], %g1 cmp %g1, 0 [...] So it's not simply using _IO_stdin_used address, but doing some resolution of it, which, indeed, returns a NULL. I don't think I can make any further progress on this bug without investing significant amount of time into it, but we have enough debugging information for a good upstream bug report, and I would be glad to provide additional info if needed. One of the main questions we should try to answer is why the _IO_std{in,out,err}_ symbols end up to be not 8-byte aligned in libc, even though it looks like they should be. Best regards, -- Jurij Smakov ju...@wooyd.org Key: http://www.wooyd.org/pgpkey/ KeyID: C99E03CC -- To UNSUBSCRIBE, email to debian-bugs-rc-requ...@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org