Re: clang 3.2 RC2 miscompiles libgcc?

From: Stefan Farfeleder <stefanf_at_FreeBSD.org>
Date: Fri, 4 Jan 2013 20:06:02 +0100
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.

Stefan
Received on Fri Jan 04 2013 - 18:06:06 UTC

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