Re: [PATCH] eh_personality.cc: unwinding on ARM
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
-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
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
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
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
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
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
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;