Re: clang 3.2 RC2 miscompiles libgcc?

From: Mark Atkinson <atkin901_at_gmail.com>
Date: Fri, 04 Jan 2013 12:53:18 -0800
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 01/04/2013 12:23, Konstantin Belousov wrote:
> On Fri, Jan 04, 2013 at 08:06:02PM +0100, Stefan Farfeleder wrote:
>> On Fri, Jan 04, 2013 at 08:14:38PM +0200, Konstantin Belousov
>> wrote:
>>> On Fri, Jan 04, 2013 at 04:49:41PM +0100, Stefan Farfeleder
>>> wrote:
>>>> Here's a minimal test case that reproduces the bug:
>>>> 
>>>> $ cat throw-crash.cc #include <stdexcept>
>>>> 
>>>> void f2(void) { std::string s; throw
>>>> std::runtime_error("foo"); }
>>>> 
>>>> void f1(void) { f2(); }
>>>> 
>>>> int main(void) { try { std::string s1, s2; f1(); return 0; }
>>>> catch (const std::exception &) { return 1; } } $ g++ -O2
>>>> -finline-limit=0 throw-crash.cc $ ./a.out zsh: bus error
>>>> (core dumped)  ./a.out
>>> 
>>> What is the backtrace ? Compile the system libraries (ld-elf,
>>> libc, libgcc etc) with the debugging information and obtain the
>>> backtrace once more.
>> 
>> I'm afraid the backtrace is not really interesting:
>> 
>> Program received signal SIGBUS, Bus error. 
>> std::string::_Rep::_M_dispose (this=0x7fffffffd62fe8,
>> __a=_at_0x7fffffffd628) at atomicity.h:69 69          _Atomic_word
>> __result = *__mem; (gdb) bt #0  std::string::_Rep::_M_dispose
>> (this=0x7fffffffd62fe8, __a=_at_0x7fffffffd628) at atomicity.h:69 #1
>> 0x000000080089d168 in ~basic_string (this=0x7fffffffd62fe8) at
>> basic_string.h:482 #2  0x0000000000401038 in main () at
>> throw-crash.cc:16
>> 
>> I think the stack is somehow corrupted after the exception was 
>> performed. As with the original test case, loading an old
>> libgcc_s.so.1 instead makes the program run correctly.
>> 
>> It seems the std::string destructor is called with an invalid
>> this pointer for s2:
>> 
>> (gdb) r Starting program: /usr/home/stefan/scratch/a.out
>> 
>> Breakpoint 1, main () at throw-crash.cc:12 12      int main(void)
>> { (gdb) b _Unwind_RaiseException Breakpoint 2 at 0x800d420b4 
>> (gdb) c Continuing.
>> 
>> Breakpoint 2, 0x0000000800d420b4 in _Unwind_RaiseException () 
>> from /lib/libgcc_s.so.1 (gdb) f 2 #2  0x0000000000400f51 in f2 ()
>> at throw-crash.cc:5 5           throw std::runtime_error("foo"); 
>> (gdb) p &s $1 = (string *) 0x7fffffffd600 (gdb) up #3
>> 0x0000000000400fe2 in main () at throw-crash.cc:15 15
>> f1(); (gdb) p &s1 $2 = (string *) 0x7fffffffd650 (gdb) p &s2 $3 =
>> (string *) 0x7fffffffd640 ^^^^ (gdb) b 'std::basic_string<char,
>> std::char_traits<char>, std::allocator<char> >::~basic_string()'
>>  Breakpoint 3 at 0x80089d154: file basic_string.h, line 482. 
>> (gdb) c Continuing.
>> 
>> Breakpoint 3, ~basic_string (this=0x7fffffffd600) at
>> basic_string.h:279 279           _M_data() const (gdb) c 
>> Continuing.
>> 
>> Breakpoint 3, ~basic_string (this=0x7fffffffd640) at
>> basic_string.h:279 279           _M_data() const (gdb) c 
>> Continuing.
>> 
>> Breakpoint 3, ~basic_string (this=0x7fffffffd60f) at
>> basic_string.h:279 ^^^^ 279           _M_data() const
>> 
>> So, the address of s2 is 0x7fffffffd640, but the dtor is called
>> with 0x7fffffffd60f which is also very unaligned. I think this is
>> the reason for the crash.
> 
> Thank you for digging more.
> 
> In fact, it is more likely that there is some bug or
> incompatibility in c++ unwinder than in the libgcc itself, but as
> you noted, a compiler bug is also possible.
> 
> Anyway, I was mostly looking could the backtrace starts in rtld.
> Rtld bug also cannot be excluded at this stage, but it not much
> likely.
> 

Since this is similar to the pain I was seeing rebuilding everything
with clang so I have been following this thread with much interest.

Just to add more data, I get different results.   This is all i386.

gcc v464 built using an earlier clang from -current world/kernel
r243027.  boost was also built using this revision.

$ /usr/local/bin/g++46 -O2 -I/usr/local/include -L/usr/local/lib
- -lboost_program_options -o unwinder unwinder.cc
[atkinson_at_moby ~/dev]$ ldd unwinder
unwinder:
        libboost_program_options.so =>
/usr/local/lib/libboost_program_options.so (0x2806e000)
        libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x280c2000)
        libm.so.5 => /lib/libm.so.5 (0x281a1000)
        libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x281c2000)
        libc.so.7 => /lib/libc.so.7 (0x281cd000)
        libthr.so.3 => /lib/libthr.so.3 (0x28317000)
[atkinson_at_moby ~/dev]$ ./unwinder
Abort trap (core dumped)


clang 32 built from -current world/kernel r244958 works just fine.

$ c++ -O2 -I/usr/local/include -L/usr/local/lib
- -lboost_program_options -o unwinder unwinder.cc
[atkinson_at_moby ~/dev]$ ./unwinder
[atkinson_at_moby ~/dev]$ ldd unwinder
unwinder:
        libboost_program_options.so =>
/usr/local/lib/libboost_program_options.so (0x2806d000)
        libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x280c1000)
        libm.so.5 => /lib/libm.so.5 (0x281a0000)
        libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x281c1000)
        libc.so.7 => /lib/libc.so.7 (0x281cc000)
        libthr.so.3 => /lib/libthr.so.3 (0x28316000)


It might be useful to expand -O2 into all it's -f components and
elminate them one by one until the crash is not reproducable.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.19 (FreeBSD)
Comment: Using GnuPG with undefined - http://www.enigmail.net/

iEYEARECAAYFAlDnQT4ACgkQrDN5kXnx8yZpZgCfXhiKtV1b4H/zu/M0KZvSE/Yi
y5MAnRTejLBvCqCgSP9FTKhGOZpDiQBQ
=8PU9
-----END PGP SIGNATURE-----
Received on Fri Jan 04 2013 - 19:53:36 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:40:33 UTC