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

2012-03-29 Thread Peter Waechtler

On 19.03.2012 17:38, Daniel Jacobowitz wrote:

On Mon, Mar 19, 2012 at 12:12 PM, Andrew Stubbsa...@codesourcery.com  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.



Here's another version using siglongjmp to avoid VERIFY in signal handler:
Can someone (maybe you) put that at the appropriate place?
Please don't let the integration being a pain as well

Peter

seehttp://gcc.gnu.org/ml/gcc-patches/2012-03/msg01161.html


/*
author: Peter Waechtler (pwaechtler at mac.com)
Copyright FSF or whatever is needed

A simple test case to verify if backtrace(3) goes into
a loop while unwinding on ARM with cxx_personality routine.
*/
#includeunistd.h
#includestdlib.h
#includestring.h
#includesignal.h
#includeexecinfo.h
#includesetjmp.h

#includeiostream
#includevector
using namespace std;

//#include testsuite.h

#define WE_PASSED 42
#define WE_FAILED 0xff

sigjmp_buf env;

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*))
siglongjmp(env, WE_FAILED);
else
siglongjmp(env, WE_PASSED);
}

static int tst_eh01(void)
{
int rc = 0;

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

return rc;
}

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

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

sigaction(SIGABRT,sa, NULL);

switch (sigsetjmp(env, 1)) {
case 0: /* the context was set */
c = tst_eh01();
break;
case WE_PASSED:
// VERIFY( true );
cerr  PASSED  endl;
break;
default:
// VERIFY( false );
cerr  FAILED  endl;
break;
}

return c;
}




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 unistd.h
#include stdlib.h
#include string.h
#include signal.h
#include execinfo.h

#include iostream
#include vector
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::vectorint  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: [PATCH] eh_personality.cc: unwinding on ARM

2012-03-19 Thread Andrew Stubbs

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.


Andrew
2010-02-04  Daniel Jacobowitz  d...@codesourcery.com

	libstdc++-v3/
	* libsupc++/eh_personality.cc (PERSONALITY_FUNCTION): For
	ARM EABI, skip handlers for _US_VIRTUAL_UNWIND_FRAME
	| _US_FORCE_UNWIND.

--- libstdc++-v3/libsupc++/eh_personality.cc
+++ libstdc++-v3/libsupc++/eh_personality.cc
@@ -384,6 +384,8 @@
   switch (state  _US_ACTION_MASK)
 {
 case _US_VIRTUAL_UNWIND_FRAME:
+  if (state  _US_FORCE_UNWIND)
+	CONTINUE_UNWINDING;
   actions = _UA_SEARCH_PHASE;
   break;


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

2012-03-19 Thread Daniel Jacobowitz
On Mon, Mar 19, 2012 at 12:12 PM, Andrew Stubbs a...@codesourcery.com 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.


 Anyway, as far as copyright goes, I don't believe CodeSourcery has any
 problem with this being committed.

 Andrew



-- 
Thanks,
Daniel


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
 a...@codesourcery.com 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::vectorint  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 noreturns 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++.so.6( 

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







[PATCH] eh_personality.cc: unwinding on ARM

2012-03-16 Thread EXTERNAL Waechtler Peter (Fa. TCP, CM-AI/PJ-CF31)
Hi,

I noticed a bug in the __ARM_EABI_UNWINDER__ case that shows up
as a loop in backtrace():

=== Backtrace: =
/lib/libc.so.6[0x4c8c11cc]
/lib/libc.so.6[0x4c8c62a8]
/lib/libc.so.6(cfree+0x38)[0x4c8c63a8]
./bt(_Z6nqueenPiii+0xf0)[0xa8e0]
./bt(_Z6nqueenPiii+0xf0)[0xa8e0]
./bt(_Z6nqueenPiii+0xf0)[0xa8e0]
./bt(_Z6nqueenPiii+0xf0)[0xa8e0]
[.. and so on]

while a proper callstack (with demangled names and libunwind) looks like:

== backtrace (libunwind):
./bt( libunwind_backtrace +0x30)[0xb4a4]
./bt( eh_stack_unwind +0xe0)[0xb3c0]
./bt[0xc704]
/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/libc.so.6[0x4c8b726c]
/lib/libc.so.6[0x4c8c11cc]
/lib/libc.so.6[0x4c8c62a8]
/lib/libc.so.6( cfree +0x38)[0x4c8c63a8]
./bt( nqueen(int*, int, int) +0xf0)[0xa8e0]
./bt( main +0x230)[0xac6c]
/lib/libc.so.6( __libc_start_main +0x120)[0x4c86d104]
./bt[0xa510]


The CodeSourcery toolchain contains a fix like the following,
please consider for adding it.

Best regards

Peter Wächtler


--- eh_personality.cc.orig  2012-02-28 16:35:20.0 +0100
+++ eh_personality.cc   2012-02-28 18:12:03.0 +0100
@@ -387,6 +386,9 @@
   switch (state  _US_ACTION_MASK)
 {
 case _US_VIRTUAL_UNWIND_FRAME:
+ if (state  _US_FORCE_UNWIND)
+   CONTINUE_UNWINDING;
+
   actions = _UA_SEARCH_PHASE;
   break;





[PATCH] eh_personality.cc: unwinding on ARM

2012-03-16 Thread EXTERNAL Waechtler Peter (Fa. TCP, CM-AI/PJ-CF31)
Sorry this is a resend with corrected email addresses,


I noticed a bug in the __ARM_EABI_UNWINDER__ case that shows up
as a loop in backtrace():

=== Backtrace: =
/lib/libc.so.6[0x4c8c11cc]
/lib/libc.so.6[0x4c8c62a8]
/lib/libc.so.6(cfree+0x38)[0x4c8c63a8]
./bt(_Z6nqueenPiii+0xf0)[0xa8e0]
./bt(_Z6nqueenPiii+0xf0)[0xa8e0]
./bt(_Z6nqueenPiii+0xf0)[0xa8e0]
./bt(_Z6nqueenPiii+0xf0)[0xa8e0]
[.. and so on]

while a proper callstack (with demangled names and libunwind) looks like:

== backtrace (libunwind):
./bt( libunwind_backtrace +0x30)[0xb4a4]
./bt( eh_stack_unwind +0xe0)[0xb3c0]
./bt[0xc704]
/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/libc.so.6[0x4c8b726c]
/lib/libc.so.6[0x4c8c11cc]
/lib/libc.so.6[0x4c8c62a8]
/lib/libc.so.6( cfree +0x38)[0x4c8c63a8]
./bt( nqueen(int*, int, int) +0xf0)[0xa8e0]
./bt( main +0x230)[0xac6c]
/lib/libc.so.6( __libc_start_main +0x120)[0x4c86d104]
./bt[0xa510]


The CodeSourcery toolchain contains a fix like the following,
please consider for adding it.

Best regards

Peter Wächtler


--- eh_personality.cc.orig  2012-02-28 16:35:20.0 +0100
+++ eh_personality.cc   2012-02-28 18:12:03.0 +0100
@@ -387,6 +386,9 @@
   switch (state  _US_ACTION_MASK)
 {
 case _US_VIRTUAL_UNWIND_FRAME:
+ if (state  _US_FORCE_UNWIND)
+   CONTINUE_UNWINDING;
+
   actions = _UA_SEARCH_PHASE;
   break;