Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 04 Jan 2013 20:00:10 -0500
From:      Nathan Whitehorn <nwhitehorn@freebsd.org>
To:        Konstantin Belousov <kostikbel@gmail.com>
Cc:        Stefan Farfeleder <stefanf@freebsd.org>, Dimitry Andric <dim@freebsd.org>, freebsd-current@freebsd.org
Subject:   Re: clang 3.2 RC2 miscompiles libgcc?
Message-ID:  <50E77B1A.9080401@freebsd.org>
In-Reply-To: <20130104202334.GN82219@kib.kiev.ua>
References:  <20121227150724.GA1431@mole.fafoe.narf.at> <50DC65F5.6060004@freebsd.org> <50E0BD66.4070609@FreeBSD.org> <20130102135950.GA1464@mole.fafoe.narf.at> <20130104154940.GD1430@mole.fafoe.narf.at> <20130104181438.GL82219@kib.kiev.ua> <20130104190602.GE1430@mole.fafoe.narf.at> <20130104202334.GN82219@kib.kiev.ua>

next in thread | previous in thread | raw e-mail | index | archive | help
On 01/04/13 15: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=@0x7fffffffd628)
>>     at atomicity.h:69
>> 69          _Atomic_word __result = *__mem;
>> (gdb) bt
>> #0  std::string::_Rep::_M_dispose (this=0x7fffffffd62fe8, __a=@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.
> 

If this is the same bug I was seeing, recompiling only the file
unwind-dw2.c in libgcc with GCC/old clang, leaving everything else the
same, fixed everything. This would lead me to suspect an error in one of
the many __builtins called by unwind-dw2.c.
-Nathan



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?50E77B1A.9080401>