AW: [PATCH] eh_personality.cc: unwinding on ARM

2012-03-23 Thread EXTERNAL Waechtler Peter (Fa. TCP, CM-AI/PJ-CF31)
> -Ursprüngliche Nachricht-
> Von: Andrew Stubbs [mailto:a...@codesourcery.com]
> Gesendet: Montag, 19. März 2012 17:12
> An: EXTERNAL Waechtler Peter (Fa. TCP, CM-AI/PJ-CF31)
> Cc: gcc-patches@gcc.gnu.org; libstd...@gcc.gnu.org;
> p...@codesourcery.com; pwaecht...@mac.com; d...@false.org
> Betreff: Re: [PATCH] eh_personality.cc: unwinding on ARM
>
> On 16/03/12 13:29, EXTERNAL Waechtler Peter (Fa. TCP,
> CM-AI/PJ-CF31) wrote:
> > The CodeSourcery toolchain contains a "fix" like the following,
> > please consider for adding it.
>
> Here's the full original patch with ChangeLog.
>
> I don't know why Dan never submitted this one. Perhaps it's
> not suitable
> for upstream or not considered the correct fix?
>
> Anyway, as far as copyright goes, I don't believe
> CodeSourcery has any
> problem with this being committed.
>


And here is a stub for a test case.
I don't know how to run the testsuite, just put in include and VERIFY-thingie



#include 
#include 
#include 
#include 
#include 

#include 
#include 
using namespace std;


static void abort_handler(int n_signal, siginfo_t *siginfo, void *ptr);


static void abort_handler(int n_signal, siginfo_t *siginfo, void *ptr)
{
void *address[20];
int depth;

depth = backtrace(address, sizeof(address)/sizeof(void*));

backtrace_symbols_fd(address, depth, 0);
/* this is a dumb check, better look for main */
if (depth == sizeof(address)/sizeof(void*))
cerr << "failed" << endl;
else
cerr << "passed" << endl;
}

int tst_eh01(void)
{
int rc = 0;

std::vector  v(10);
rc = v.at(42);

return rc;
}

int main(int argc, char *argv[])
{
int c;
struct sigaction sa;

memset(&sa, 0 , sizeof(sa));
sa.sa_sigaction = abort_handler;
sa.sa_flags = SA_SIGINFO;

sigaction(SIGABRT, &sa, NULL);

c = tst_eh01();
return c;
}


With a fixed CodeSourcery version:

cs-minimal-sysroot/usr/lib/bin/sysroot-qemu src/bt/tst-eh01
terminate called after throwing an instance of 'std::out_of_range'
  what():  vector::_M_range_check
src/bt/tst-eh01[0x9654]
cs-minimal-sysroot/usr/lib/bin/../../../lib/libc.so.6(__default_rt_sa_restorer_v1+0x0)[0x40a06ce0]
cs-minimal-sysroot/usr/lib/bin/../../../lib/libc.so.6(gsignal+0x40)[0x40a059bc]
cs-minimal-sysroot/usr/lib/bin/../../../lib/libc.so.6(abort+0x1d4)[0x40a0acec]
cs-minimal-sysroot/usr/lib/bin/../../../usr/lib/libstdc++.so.6(_ZN9__gnu_cxx27__verbose_terminate_handlerEv+0x110)[0x408e5f4c]
cs-minimal-sysroot/usr/lib/bin/../../../usr/lib/libstdc++.so.6(+0xa707c)[0x408e407c]
cs-minimal-sysroot/usr/lib/bin/../../../usr/lib/libstdc++.so.6(_ZSt9terminatev+0x1c)[0x408e40a4]
cs-minimal-sysroot/usr/lib/bin/../../../usr/lib/libstdc++.so.6(__cxa_throw+0x9c)[0x408e4220]
cs-minimal-sysroot/usr/lib/bin/../../../usr/lib/libstdc++.so.6(_ZSt20__throw_out_of_rangePKc+0x64)[0x4088dc04]
src/bt/tst-eh01(_ZNKSt6vectorIiSaIiEE14_M_range_checkEj+0x44)[0x9c24]
src/bt/tst-eh01(_ZNSt6vectorIiSaIiEE2atEj+0x20)[0x99a8]
src/bt/tst-eh01(_Z8tst_eh01v+0x5c)[0x972c]
src/bt/tst-eh01(main+0x50)[0x97c8]
cs-minimal-sysroot/usr/lib/bin/../../../lib/libc.so.6(__libc_start_main+0x114)[0x409ee754]
passed
qemu: uncaught target signal 6 (Aborted) - core dumped
Aborted



with an unfixed version:

$ ./tst-eh01
terminate called after throwing an instance of 'std::out_of_range'
  what():  vector::_M_range_check
./tst-eh01[0x9580]
/lib/libc.so.6(__default_rt_sa_restorer_v2+0x0)[0x4c883770]
/lib/libc.so.6(gsignal+0x40)[0x4c88241c]
/lib/libc.so.6(abort+0x1c0)[0x4c88680c]
/lib/libstdc++.so.6(_ZN9__gnu_cxx27__verbose_terminate_handlerEv+0x134)[0x4cb2ca0c]
/lib/libstdc++.so.6(_ZN9__gnu_cxx27__verbose_terminate_handlerEv+0x134)[0x4cb2ca0c]
/lib/libstdc++.so.6(_ZN9__gnu_cxx27__verbose_terminate_handlerEv+0x134)[0x4cb2ca0c]
/lib/libstdc++.so.6(_ZN9__gnu_cxx27__verbose_terminate_handlerEv+0x134)[0x4cb2ca0c]
/lib/libstdc++.so.6(_ZN9__gnu_cxx27__verbose_terminate_handlerEv+0x134)[0x4cb2ca0c]
/lib/libstdc++.so.6(_ZN9__gnu_cxx27__verbose_terminate_handlerEv+0x134)[0x4cb2ca0c]
/lib/libstdc++.so.6(_ZN9__gnu_cxx27__verbose_terminate_handlerEv+0x134)[0x4cb2ca0c]
/lib/libstdc++.so.6(_ZN9__gnu_cxx27__verbose_terminate_handlerEv+0x134)[0x4cb2ca0c]
/lib/libstdc++.so.6(_ZN9__gnu_cxx27__verbose_terminate_handlerEv+0x134)[0x4cb2ca0c]
/lib/libstdc++.so.6(_ZN9__gnu_cxx27__verbose_terminate_handlerEv+0x134)[0x4cb2ca0c]
/lib/libstdc++.so.6(_ZN9__gnu_cxx27__verbose_terminate_handlerEv+0x134)[0x4cb2ca0c]
/lib/libstdc++.so.6(_ZN9__gnu_cxx27__verbose_terminate_handlerEv+0x134)[0x4cb2ca0c]
/lib/libstdc++.so.6(_ZN9__gnu_cxx27__verbose_terminate_handlerEv+0x134)[0x4cb2ca0c]
/lib/libstdc++.so.6(_ZN9__gnu_cxx27__verbose_terminate_handlerEv+0x134)[0x4cb2ca0c]
/lib/libstdc++.so.6(_ZN9__gnu_cxx27__verbose_terminate_handlerEv+0x134)[0x4cb2ca0c]
/lib/libstdc++.so.6(_ZN9__gnu_cxx27__verbose_terminate_handlerEv+0x134)[0x4cb2ca0c]
failed
Aborted


Re: AW: [PATCH] eh_personality.cc: unwinding on ARM

2012-03-19 Thread Peter Waechtler

On 19.03.2012 18:32, Paul Brook wrote:

while I have your attention: what is an virtual unwind frame? ;)

No such thing exists.

Throwing an exception is a muti-stage process.  It requires unwinding the
stack frame twice, taking different actions in the process.  "Forced"
unwinding and backtracing add extra complications.  The _US_* flags tell the
PR which stage in the process we're at.

IIRC the ARM EABI doesn't officially include forced unwinding, it's something
we had to bolt on afterwards.  For added fun the ARM EABI defines the set of
states/actions somewhat differently to the DWARF unwinder.

Forced unwinding is one of the warts that come from interaction between C++
and POSIX.  Almost noone really understands how all these bits fit together.

Thanx Paul, that one gave me a good laugh. :))

I worked several months (not full-time, only every now and then) to nail 
this loop down.


It's definitely  a fix for upstream - saving the sanity of some souls.

Peter







Re: AW: [PATCH] eh_personality.cc: unwinding on ARM

2012-03-19 Thread Paul Brook
> while I have your attention: what is an virtual unwind frame? ;)

No such thing exists.

Throwing an exception is a muti-stage process.  It requires unwinding the 
stack frame twice, taking different actions in the process.  "Forced" 
unwinding and backtracing add extra complications.  The _US_* flags tell the 
PR which stage in the process we're at.

IIRC the ARM EABI doesn't officially include forced unwinding, it's something 
we had to bolt on afterwards.  For added fun the ARM EABI defines the set of 
states/actions somewhat differently to the DWARF unwinder.

Forced unwinding is one of the warts that come from interaction between C++ 
and POSIX.  Almost noone really understands how all these bits fit together.

Paul


AW: [PATCH] eh_personality.cc: unwinding on ARM

2012-03-19 Thread EXTERNAL Waechtler Peter (Fa. TCP, CM-AI/PJ-CF31)
> On Mon, Mar 19, 2012 at 12:12 PM, Andrew Stubbs
>  wrote:
> > On 16/03/12 13:29, EXTERNAL Waechtler Peter (Fa. TCP,
> CM-AI/PJ-CF31) wrote:
> >>
> >> The CodeSourcery toolchain contains a "fix" like the following,
> >> please consider for adding it.
> >
> >
> > Here's the full original patch with ChangeLog.
> >
> > I don't know why Dan never submitted this one. Perhaps it's
> not suitable for
> > upstream or not considered the correct fix?
>
> I think it was just a pain to write a test for.
>

Gentlemen,

while I have your attention: what is an virtual unwind frame? ;)

One test case is quite simple:

std::vector  v(10);
rc = v.at(42);


The versions of glibc and libstdc++ looks quite old, but montavista patches
them up (but if the customer insists on such an old version...)

So this is the unwind entry by readelf -u :

0xa518 <_Z6nqueenPiii>: @0x10c88
 Personality routine: 0xa33c <__gxx_personality_v0@@CXXABI_1.3>
 0x9b  vsp = r11
 0x42  vsp = vsp - 12
 0x84 0x83 pop {r4, r5, r11, r14}
 0xb0  finish
 0xb0  finish
 0xb0  finish

no better output for libstdc++

0xaa1b0 <__gxx_personality_v0>: @0xbd0f4
  Personality routine: 0x3dd10 <_init+0xc8c>

0xad1f0 <_ZN9__gnu_cxx27__verbose_terminate_handlerEv>: @0xbd364
  Personality routine: 0x3dd10 <_init+0xc8c>


So far, I think if the personality routine is called _and_ there is something
like __gnu_cxx::__verbose_terminate_handler on the stack (with attribute 
noreturn)
it enters the loop.
Perhaps a function that "noreturn"s has a virtual unwind frame -
i.e. no unwind entry exists?


Peter


# ./eh -V
Starting up
terminate called after throwing an instance of 'std::out_of_range'
  what():  vector::_M_range_check
sigaction_func:(6, info:0x4dc98, context:0x4dd18) si_code: -6
eh_stack_unwind: enter
eh_stack_unwind: after backtrace: used_pointers: 100 (asm: 0)
** EXCEPTION in process PID=2614 ***
signal "Aborted"
command line : "./eh"
 thread ./eh (TID 2614)
== registers :
TRAP_NO = 0x, ERROR_CODE = 0x, OLDMASK =0x
R0  = 0x, R1  = 0x0a36, R2  = 0x0006, R3  = 0x2aab5460
R4  = 0x0a36, R5  = 0x0006, R6  = 0x4c97f000, R7  = 0x010c
R8  = 0x2aab4fc0, R9  = 0x2aab5460, R10 = 0x0bfc, FP  = 0x7eacec14
IP  = 0x7eaceb98, SP  = 0x7eacea78, LR  = 0x4c8823e8, PC  = 0x4c88241c
CPSR = 0x2010, FAULT_ADDRESS = 0x
== backtrace (orig glibc):
./eh( eh_stack_unwind +0x18c)[0xde0c]
./eh[0xdfac]
/lib/libc.so.6( __default_rt_sa_restorer_v2 +0x0)[0x4c883770]
/lib/libc.so.6( gsignal +0x40)[0x4c88241c]
/lib/libc.so.6( abort +0x1c0)[0x4c88680c]
/lib/libstdc++.so.6( __gnu_cxx::__verbose_terminate_handler() 
+0x134)[0x4cb2ca0c]
/lib/libstdc++.so.6( __gnu_cxx::__verbose_terminate_handler() 
+0x134)[0x4cb2ca0c]
/lib/libstdc++.so.6( __gnu_cxx::__verbose_terminate_handler() 
+0x134)[0x4cb2ca0c]
/lib/libstdc++.so.6( __gnu_cxx::__verbose_terminate_handler() 
+0x134)[0x4cb2ca0c]
/lib/libstdc++.so.6( __gnu_cxx::__verbose_terminate_handler() 
+0x134)[0x4cb2ca0c]
/lib/libstdc++.so.6( __gnu_cxx::__verbose_terminate_handler() 
+0x134)[0x4cb2ca0c]
/lib/libstdc++.so.6( __gnu_cxx::__verbose_terminate_handler() 
+0x134)[0x4cb2ca0c]
/lib/libstdc++.so.6( __gnu_cxx::__verbose_terminate_handler() 
+0x134)[0x4cb2ca0c]
/lib/libstdc++.so.6( __gnu_cxx::__verbose_terminate_handler() 
+0x134)[0x4cb2ca0c]
/lib/libstdc++.so.6( __gnu_cxx::__verbose_terminate_handler() 
+0x134)[0x4cb2ca0c]
/lib/libstdc++.so.6( __gnu_cxx::__verbose_terminate_handler() 
+0x134)[0x4cb2ca0c]
/lib/libstdc++.so.6( __gnu_cxx::__verbose_terminate_handler() 
+0x134)[0x4cb2ca0c]
/lib/libstdc++.so.6( __gnu_cxx::__verbose_terminate_handler() 
+0x134)[0x4cb2ca0c]
/lib/libstdc++.so.6( __gnu_cxx::__verbose_terminate_handler() 
+0x134)[0x4cb2ca0c]
/lib/libstdc++.so.6( __gnu_cxx::__verbose_terminate_handler() 
+0x134)[0x4cb2ca0c]
/lib/libstdc++.so.6( __gnu_cxx::__verbose_terminate_handler() 
+0x134)[0x4cb2ca0c]
/lib/libstdc++.so.6( __gnu_cxx::__verbose_terminate_handler() 
+0x134)[0x4cb2ca0c]
/lib/libstdc++.so.6( __gnu_cxx::__verbose_terminate_handler() 
+0x134)[0x4cb2ca0c]
/lib/libstdc++.so.6( __gnu_cxx::__verbose_terminate_handler() 
+0x134)[0x4cb2ca0c]
/lib/libstdc++.so.6( __gnu_cxx::__verbose_terminate_handler() 
+0x134)[0x4cb2ca0c]
/lib/libstdc++.so.6( __gnu_cxx::__verbose_terminate_handler() 
+0x134)[0x4cb2ca0c]
/lib/libstdc++.so.6( __gnu_cxx::__verbose_terminate_handler() 
+0x134)[0x4cb2ca0c]
/lib/libstdc++.so.6( __gnu_cxx::__verbose_terminate_handler() 
+0x134)[0x4cb2ca0c]
/lib/libstdc++.so.6( __gnu_cxx::__verbose_terminate_handler() 
+0x134)[0x4cb2ca0c]
/lib/libstdc++.so.6( __gnu_cxx::__verbose_terminate_handler() 
+0x134)[0x4cb2ca0c]
/lib/libstdc++.so.6( __gnu_cxx::__verbose_terminate_handler() 
+0x134)[0x4cb2ca0c]
/lib/libstdc++.so.6( __gnu_cxx::__verbose_terminate_handler() 
+0x134)[0x4cb2ca0c]
/lib/libstdc++.so.6( __gnu_cxx::__verbose_terminate_handler() 
+0x134)[0x4cb2ca0c]
/lib/libstdc++.s