TLS-version of libc6/{testing,unstable} breaks libunwind
Hi,
I recently noticed that with Debian/testing or Debian/unstable, many
libunwind [1] checks are failing with a SEGFAULT. The root-cause of
these crashes appears to be that the TLS-version of libc-2.3.2 is
built with -fomit-frame-pointer on i386 (see nptl_extra_cflags in
debian/sysdeps/i386.mk of the package). It would be OK to use
-fomit-frame-pointer if the library provided DWARF2 unwind-info for
all functions compiled in this manner. However, for some reason, the
unwind-info for __libc_start_main is not present in the library.
Specifically:
$ nm -D /lib/tls/libc-2.3.2.so | grep __libc_start_main
000156f0 T __libc_start_main
$ readelf -wf /lib/tls/libc-2.3.2.so |head -17
The section .eh_frame contains:
00000000 00000014 00000000 CIE
Version: 1
Augmentation: "zR"
Code alignment factor: 1
Data alignment factor: -4
Return address column: 8
Augmentation data: 1b
DW_CFA_def_cfa: r4 ofs 4
DW_CFA_offset: r8 at cfa-4
DW_CFA_nop
DW_CFA_nop
00000018 00000018 0000001c FDE cie=00000000 pc=00015b10..00015bb9
DW_CFA_advance_loc: 3 to 00015b13
That is, even though unwind info is present in general, the first
function for which there is unwind-info starts at address 0x15b10.
There is no unwind-info for __libc_start_main.
Because of this, it is _impossible_ to unwind safely through the call
stack. What happens in the case of the failing libunwind checks is
that once unwinding hits __libc_start_main, libunwind starts accessing
"random" memory, because __libc_start_main doesn't maintain the
frame-chain yet it also doesn't provide unwind info.
The problem doesn't show with LD_ASSUME_KERNEL set to 2.4.18 (i.e.,
when /lib/libc-2.3.2.so is in use). Also, I checked on a Red Hat
Enterprise Linux AS release 3 machine and it doesn't show the problem
either. It also uses TLS-enalbed libc-2.3.2, but I suspect it was
built without -fomit-frame-pointer.
--david
[1] http://www.hpl.hp.com/research/linux/libunwind/
Reply to: