Hi,
I'm getting a glibc double-free crash on Fedora i686, and I think it may be an elfutils regression. With 0.145 and 0.146 I get a crash, but 0.144 seems fine. I see this on i686 F12, F13, and F14. x86_64 is fine.
I'm about to try a git-bisect on elfutils, but here's the crash info in the mean time:
$ rpm -qa systemtap* elfutils* | sort elfutils-0.146-1.fc12.i686 elfutils-debuginfo-0.146-1.fc12.i686 elfutils-devel-0.146-1.fc12.i686 elfutils-libelf-0.146-1.fc12.i686 elfutils-libelf-devel-0.146-1.fc12.i686 elfutils-libs-0.146-1.fc12.i686 systemtap-1.2-1.fc12.i686 systemtap-debuginfo-1.2-1.fc12.i686 systemtap-runtime-1.2-1.fc12.i686 systemtap-sdt-devel-1.2-1.fc12.i686 systemtap-testsuite-1.2-1.fc12.i686
$ stap -p2 /usr/share/systemtap/testsuite/semok/thirtysix.stp *** glibc detected *** stap: double free or corruption (!prev): 0x05e97560 *** ======= Backtrace: ========= /lib/libc.so.6(-0xff53280f)[0xa6d7f1] /usr/lib/libdw.so.1(+0x11d9e)[0x7f7d9e] /usr/lib/libdw.so.1(dwarf_cfi_addrframe+0x68)[0x7f8428] stap(+0x1142a5)[0xd4e2a5] [...]
With valgrind: [...] ==5136== Invalid free() / delete / delete[] ==5136== at 0x48057F6: free (vg_replace_malloc.c:325) ==5136== by 0x4890D9D: __libdw_frame_at_address (cfi.c:495) ==5136== by 0x4891427: dwarf_cfi_addrframe (dwarf_cfi_addrframe.c:70) ==5136== by 0x21C2A4: dwflpp::get_cfa_ops(unsigned long long) (dwflpp.cxx:2816) [...] ==5136== Address 0x82fbf10 is 0 bytes inside a block of size 432 free'd ==5136== at 0x48057F6: free (vg_replace_malloc.c:325) ==5136== by 0x488F41D: execute_cfi (cfi.c:395) ==5136== by 0x4890C0B: __libdw_frame_at_address (cfi.c:491) ==5136== by 0x4891427: dwarf_cfi_addrframe (dwarf_cfi_addrframe.c:70) ==5136== by 0x21C2A4: dwflpp::get_cfa_ops(unsigned long long) (dwflpp.cxx:2816) [...]
The only thing to touch thte related code since 0.144 was commit ee29a31. That fixed a bug that most likely prevented most of the CFI code from being used in this case. (That bug caused a false-positive error detection and bail out before trying to use the CFI.) So I'd guess that reverting this change does avoid the failure you're seeing now, but only because it masks a bug that never got exercised before. That's just a guess.
I'm updating my 32-bit install now and assuming I can then reproduce it, I'll look into this ASAP.
Thanks, Roland
On 04/22/2010 02:24 PM, Roland McGrath wrote:
The only thing to touch thte related code since 0.144 was commit ee29a31. That fixed a bug that most likely prevented most of the CFI code from being used in this case. (That bug caused a false-positive error detection and bail out before trying to use the CFI.) So I'd guess that reverting this change does avoid the failure you're seeing now, but only because it masks a bug that never got exercised before. That's just a guess.
Sure enough. :)
I'm updating my 32-bit install now and assuming I can then reproduce it, I'll look into this ASAP.
Just to update, Roland and I narrowed down what stap was doing, and he got this simpler test to fail:
tests/addrcfi -e /usr/bin/stap 0x183f1
Josh
As mentioned, this was indeed a "regression" only because of the other fix unmasking it when before we wrongly bailed out.
The double-free and crash was due to a logic error in the failure recovery path for declaring the CFI invalid. It would bite only when there had been more DW_CFA_remember_state operations than DW_CFA_restore_state operations processed at the point in the CFI program where it was diagnosed as invalid. After fixing, that this case doesn't crash but reports:
tests/addrcfi: dwarf_addrframe (.eh_frame): no error
which is not very helpful either. But after fixing the test to fetch the error code from the right place, it reports:
tests/addrcfi: dwarf_addrframe (.eh_frame): invalid CFI section
It's entirely possible this is as it should be. The CFI in question uses an ill-specified sequence of operations (see my dwarf-discuss thread about that). But, GCC has produced this sequence and it might very well be correct to interpret it as GDB does. So I've made it handle this case in that way rather than citing it as invalid. Now the test works and delivers expressions for the CFA and registers.
That should make the stap case work to the extent that if it gets wrong values now it's because that dubious CFI is actually wrong.
Thanks, Roland
elfutils-devel@lists.fedorahosted.org