[csw-users] 64bit g++ 4.7.2 exception handling ...

Dmitri Shubin sbn at tbricks.com
Wed Mar 20 12:10:20 CET 2013


Hello Edward,

On 02/14/13 02:06, Edward Maros wrote:
> I have a very simple piece of code that behaves differently depending if
> it is compiled 32bit vs 64bit. Is this an issue with the compiler or how
> it was packaged?
>
> #include
> <stdexcept>
>
>
> int
>
> main( int, char**
> )
>
> {
>
>    try
> {
>
>      throw std::runtime_error( "Catch me if you can!"
> );
>    } catch(...)
> {
>
>      return
> 0;
>
>   
> }
>
>    return
> 1;
>
> }
>
> When compiled and executed using "g++ t.cc", the return status is 0
>
> When compiled and executed using "g++ -m64 t.cc", the return status is,
>
> terrminate called after throwing an instance of 'std::runtime_error'
> terminate called recursively
> Abort (core dumped)
I can see the same behaviour on my Solaris 10/11 boxes.
In core I can see the following backtrace:

Program terminated with signal 6, Aborted.
#0  0xfffffd7fff102eba in _lwp_kill () from /lib/64/libc.so.1
(gdb) where
#0  0xfffffd7fff102eba in _lwp_kill () from /lib/64/libc.so.1
#1  0xfffffd7fff0fb7b3 in thr_kill () from /lib/64/libc.so.1
#2  0xfffffd7fff0a7e99 in raise () from /lib/64/libc.so.1
#3  0xfffffd7fff086980 in abort () from /lib/64/libc.so.1
#4  0xfffffd7fff31cf91 in __gnu_cxx::__verbose_terminate_handler () at 
/home/maciej/src/opencsw/pkg/gcc4/trunk/work/solaris10-i386/build-isa-pentium_pro/gcc-4.7.2/libstdc++-v3/libsupc++/vterminate.cc:50
#5  0xfffffd7fff31a1e9 in __cxxabiv1::__terminate (handler=<optimized 
out>) at 
/home/maciej/src/opencsw/pkg/gcc4/trunk/work/solaris10-i386/build-isa-pentium_pro/gcc-4.7.2/libstdc++-v3/libsupc++/eh_terminate.cc:40
#6  0xfffffd7fff31a233 in std::terminate () at 
/home/maciej/src/opencsw/pkg/gcc4/trunk/work/solaris10-i386/build-isa-pentium_pro/gcc-4.7.2/libstdc++-v3/libsupc++/eh_terminate.cc:50
#7  0xfffffd7fff31a4ce in __cxxabiv1::__cxa_rethrow () at 
/home/maciej/src/opencsw/pkg/gcc4/trunk/work/solaris10-i386/build-isa-pentium_pro/gcc-4.7.2/libstdc++-v3/libsupc++/eh_throw.cc:116
#8  0xfffffd7fff31cf55 in __gnu_cxx::__verbose_terminate_handler () at 
/home/maciej/src/opencsw/pkg/gcc4/trunk/work/solaris10-i386/build-isa-pentium_pro/gcc-4.7.2/libstdc++-v3/libsupc++/vterminate.cc:80
#9  0xfffffd7fff31a1e9 in __cxxabiv1::__terminate (handler=<optimized 
out>) at 
/home/maciej/src/opencsw/pkg/gcc4/trunk/work/solaris10-i386/build-isa-pentium_pro/gcc-4.7.2/libstdc++-v3/libsupc++/eh_terminate.cc:40
#10 0xfffffd7fff319239 in __cxa_call_terminate (ue_header=0x411870) at 
/home/maciej/src/opencsw/pkg/gcc4/trunk/work/solaris10-i386/build-isa-pentium_pro/gcc-4.7.2/libstdc++-v3/libsupc++/eh_call.cc:56
#11 0xfffffd7fff319dfe in __cxxabiv1::__gxx_personality_v0 
(version=<optimized out>, actions=6, exception_class=<optimized out>, 
ue_header=<optimized out>, context=0xfffffd7fffdff7a0)
     at 
/home/maciej/src/opencsw/pkg/gcc4/trunk/work/solaris10-i386/build-isa-pentium_pro/gcc-4.7.2/libstdc++-v3/libsupc++/eh_personality.cc:665
#12 0xfffffd7fff1017c5 in _Unwind_RaiseException_Body () from 
/lib/64/libc.so.1
#13 0xfffffd7fff1018a9 in _Unwind_RaiseException () from /lib/64/libc.so.1
#14 0xfffffd7fff31a469 in __cxxabiv1::__cxa_throw (obj=0x411890, 
tinfo=<optimized out>, dest=<optimized out>)
     at 
/home/maciej/src/opencsw/pkg/gcc4/trunk/work/solaris10-i386/build-isa-pentium_pro/gcc-4.7.2/libstdc++-v3/libsupc++/eh_throw.cc:78
#15 0x0000000000401291 in main ()

So as one can see _Unwind_RaiseException() from /lib/64/libc.so.1 is 
called to actually throw exception and perform stack unwinding.
As reported here [1] there is a difference in unwinding implementation 
in libc.so.1 and in libgcc_s.so.1 (although I expect both to conform to 
x86_64 ELF psABI).
To use correct unwinder try to pre-load libgcc_s.so.1 using 
LD_PRELOAD_64=/opt/csw/lib/amd64/libgcc_s.so.1
This fixes the problem for me.

I think the reason why _Unwind_RaiseException is found in libc.so.1 
instead of libgcc_s.so.1 is the order of dependencies given when 
building libstdc++.so:

$ ldd /opt/csw/lib/amd64/libstdc++.so
         libm.so.2 =>     /lib/64/libm.so.2
         libc.so.1 =>     /lib/64/libc.so.1
         libgcc_s.so.1 =>         /opt/csw/lib/amd64/libgcc_s.so.1

ld.so.1 debug output:

$ LD_DEBUG=all LD_DEBUG_OUTPUT=ld.debug ./a.out
terminate called after throwing an instance of 'std::runtime_error'
terminate called recursively
Abort (core dumped)
$ ggrep -C 3 _Unwind_RaiseException ld.debug.04998
04998: 1: symbol=__cxa_throw;  lookup in file=a.out  [ ELF ]
04998: 1: symbol=__cxa_throw;  lookup in 
file=/opt/csw/lib/64/libstdc++.so.6  [ ELF ]
04998: 1: binding file=a.out to file=/opt/csw/lib/64/libstdc++.so.6: 
symbol '__cxa_throw'
04998: 1: symbol=_Unwind_RaiseException;  lookup in 
file=/lib/64/libc.so.1  [ ELF ]
04998: 1: binding file=/opt/csw/lib/64/libstdc++.so.6 to 
file=/lib/64/libc.so.1: symbol '_Unwind_RaiseException'
04998: 1: symbol=dlamd64getunwind;  lookup in file=a.out  [ ELF ]
04998: 1: symbol=dlamd64getunwind;  lookup in 
file=/opt/csw/lib/64/libstdc++.so.6  [ ELF ]
04998: 1: symbol=dlamd64getunwind;  lookup in file=/lib/64/libm.so.2  [ 
ELF ]
--
04998: 1: binding file=/opt/csw/lib/64/libstdc++.so.6 to 
file=/opt/csw/lib/64/libstdc++.so.6: symbol '__cxa_rethrow'
04998: 1: symbol=_Unwind_Resume_or_Rethrow;  lookup in 
file=/opt/csw/lib/64/libgcc_s.so.1  [ ELF ]
04998: 1: binding file=/opt/csw/lib/64/libstdc++.so.6 to 
file=/opt/csw/lib/64/libgcc_s.so.1: symbol '_Unwind_Resume_or_Rethrow'
04998: 1: symbol=_Unwind_RaiseException;  lookup in 
file=/opt/csw/lib/64/libgcc_s.so.1  [ ELF ]
04998: 1: binding file=/opt/csw/lib/64/libgcc_s.so.1 to 
file=/opt/csw/lib/64/libgcc_s.so.1: symbol '_Unwind_RaiseException'
04998: 1: symbol=_Unwind_Find_FDE;  lookup in 
file=/opt/csw/lib/64/libgcc_s.so.1  [ ELF ]
04998: 1: binding file=/opt/csw/lib/64/libgcc_s.so.1 to 
file=/opt/csw/lib/64/libgcc_s.so.1: symbol '_Unwind_Find_FDE'
04998: 1: symbol=strlen;  lookup in file=/lib/64/libc.so.1  [ ELF ]

Bye!

[1] http://www.mail-archive.com/gcc@gcc.gnu.org/msg64911.html


More information about the users mailing list