Hi David, thanks for the fixup, understood. A new context store is not much a problem, OK. Sorry I did not read your book.
Best Regards, Jan On Fri, 26 Jan 2007 16:05:50 +0100, David Mosberger-Tang wrote: > Jan, > > I'm afraid what Oliver is trying to do can't really work. The ia64 > linux book actually goes into a fair amount of detail on this topic, > but the quick summary is that a signal-context cannot be used to > initialize an unwind-context. The proper way to do this is to either > create do an unw_get_context() in the signal handler or to initiate > unwinding at the inner-most frame and then do unw_step() until the > signal handler is reached (both methods are described with examples in > the book). > > The reason you can't unwind directly out of a signal context is > because the kernel optimizes for speed and doesn't save any > "preserved" (callee-saved) registers in the signal context. > > Best regards, > > --david > > On 1/26/07, Jan Kratochvil <[EMAIL PROTECTED]> wrote: > >Hi, > > > >this issue is _ia64_ libunwind specific. > > > >Currently libunwind: > > after call of libunwind unw_getcontext(): PASS > > after call of glibc getcontext(): PASS > > after reusing ucontext_t of sa_sigaction: FAIL > > > >It is because during called storage of the unwind frame SOL registers are > >stored (omitting the output parameters). While on asynchronous exception > >processor stores all the SOF registers (including the output parameters). > > > >Detecting whether ucontext_t is the SOL or SOF type is questionable. > >I believe the intention was to use the bit 63 > >(IA64_SC_FLAG_SYNCHRONOUS_BIT) > >of SC_FLAGS, according to `libunwind/src/ia64/getcontext.S'. > >Unfortunately glibc does not initialize SC_FLAGS at all. > > > >libunwind: > > Attaching SOL/SOF differentiation for libunwind based on the bit > > IA64_SC_FLAG_SYNCHRONOUS_BIT. Updated the testsuite to verify it. > > Unfortunately it is not backward compatible with legacy glibc > > (as it did not initialize the differentiating SC_FLAGS at all). > >glibc: > > Attaching fix to initialize SC_FLAGS with > > IA64_SC_FLAG_SYNCHRONOUS_BIT, > > also define this bit for the userland glibc header files. > >Linux kernel: > > Attaching headers update for this bit, not seriously needed. > > Linux Kernel fortunately initializes SC_FLAGS to 0. > > > >Attached `bz223954.c' is IMO just a more convenient debugging testcase. > > > >Original bugreport by the courtesy of Oliver Stabel > ><oliver.stabel(at)sap.com>, > >more info there: > > https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=223954 > > > > > > > >Regards, > >Jan > > > > > >diff -u -X /root/jkratoch/.diffi.list -r -x config.h -x Makefile.in -x > >Makefile -N libunwind-0.99-alpha-orig/src/ia64/Ginit_local.c > >libunwind-0.99-alpha/src/ia64/Ginit_local.c > >--- libunwind-0.99-alpha-orig/src/ia64/Ginit_local.c 2006-07-26 > >23:13:14.000000000 -0400 > >+++ libunwind-0.99-alpha/src/ia64/Ginit_local.c 2007-01-26 > >05:50:08.000000000 -0500 > >@@ -23,6 +23,7 @@ > > OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION > > WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ > > > >+#include <ucontext.h> > > #include "init.h" > > #include "unwind_i.h" > > > >@@ -52,18 +53,32 @@ > > unw_word_t *sp, unw_word_t *bsp) > > { > > #if defined(__linux) > >- unw_word_t sol, bspstore; > >+ unw_word_t skip_regs, bspstore; > > > > #ifdef __KERNEL__ > >- sol = (uc->sw.ar_pfs >> 7) & 0x7f; > >+ skip_regs = (uc->sw.ar_pfs >> 7) & 0x7f; /* SOL */ > > bspstore = uc->sw.ar_bspstore; > > *sp = uc->ksp; > > # else > >- sol = (uc->uc_mcontext.sc_ar_pfs >> 7) & 0x7f; > >+ /* Please note the `synchronous system call' bit > >IA64_SC_FLAG_IN_SYSCALL_BIT > >+ is unrelated. */ > >+ if (uc->uc_mcontext.sc_flags & (1UL << IA64_SC_FLAG_SYNCHRONOUS_BIT)) > >+ { > >+ /* Synchronous (by userland) store - only SOL registers were stored. > >+ Stored by glibc getcontext(), libunwind unw_getcontext() > >+ or other synchronous function calls. */ > >+ skip_regs = (uc->uc_mcontext.sc_ar_pfs >> 7) & 0x7f; > >+ } > >+ else > >+ { > >+ /* Asynchronous (by kernel) store - full SOF registers were stored. > >+ Stored by glibc setcontext() or other function calls. */ > >+ skip_regs = (uc->uc_mcontext.sc_ar_pfs >> 0) & 0x7f; > >+ } > > bspstore = uc->uc_mcontext.sc_ar_bsp; > > *sp = uc->uc_mcontext.sc_gr[12]; > > # endif > >- *bsp = rse_skip_regs (bspstore, -sol); > >+ *bsp = rse_skip_regs (bspstore, -skip_regs); > > #elif defined(__hpux) > > int ret; > > > >diff -u -X /root/jkratoch/.diffi.list -r -x config.h -x Makefile.in -x > >Makefile -N libunwind-0.99-alpha-orig/tests/Makefile.am > >libunwind-0.99-alpha/tests/Makefile.am > >--- libunwind-0.99-alpha-orig/tests/Makefile.am 2006-07-26 > >23:13:14.000000000 -0400 > >+++ libunwind-0.99-alpha/tests/Makefile.am 2007-01-26 > >08:48:09.000000000 -0500 > >@@ -29,6 +29,8 @@ > > check_SCRIPTS_cdep = run-ptrace-mapper run-ptrace-misc > > check_PROGRAMS_cdep = Gtest-bt Ltest-bt Gtest-exc Ltest-exc \ > > Gtest-init Ltest-init \ > >+ Gtest-init-libc Ltest-init-libc \ > >+ Gtest-init-sigaction Ltest-init-sigaction \ > > Gtest-concurrent Ltest-concurrent \ > > Gtest-resume-sig Ltest-resume-sig \ > > Gtest-dyn1 Ltest-dyn1 \ > >@@ -71,6 +73,10 @@ > > ia64_test_dyn1_SOURCES = ia64-test-dyn1.c ia64-dyn-asm.S flush-cache.S > > Gtest_init_SOURCES = Gtest-init.cxx > > Ltest_init_SOURCES = Ltest-init.cxx > >+Gtest_init_libc_SOURCES = Gtest-init-libc.cxx > >+Ltest_init_libc_SOURCES = Ltest-init-libc.cxx > >+Gtest_init_sigaction_SOURCES = Gtest-init-sigaction.c > >+Ltest_init_sigaction_SOURCES = Ltest-init-sigaction.c > > Gtest_dyn1_SOURCES = Gtest-dyn1.c flush-cache.S > > Ltest_dyn1_SOURCES = Ltest-dyn1.c flush-cache.S > > test_static_link_SOURCES = test-static-link-loc.c test-static-link-gen.c > >diff -u -X /root/jkratoch/.diffi.list -r -x config.h -x Makefile.in -x > >Makefile -N libunwind-0.99-alpha-orig/tests/Gtest-init-libc.cxx > >libunwind-0.99-alpha/tests/Gtest-init-libc.cxx > >--- libunwind-0.99-alpha-orig/tests/Gtest-init-libc.cxx 1969-12-31 > >19:00:00.000000000 -0500 > >+++ libunwind-0.99-alpha/tests/Gtest-init-libc.cxx 2007-01-25 > >19:17:16.000000000 -0500 > >@@ -0,0 +1,30 @@ > >+/* libunwind - a platform-independent unwind library > >+ Copyright (C) 2007 Red Hat, Inc. > >+ Contributed by Jan Kratochvil <[EMAIL PROTECTED]> > >+ > >+This file is part of libunwind. > >+ > >+Permission is hereby granted, free of charge, to any person obtaining > >+a copy of this software and associated documentation files (the > >+"Software"), to deal in the Software without restriction, including > >+without limitation the rights to use, copy, modify, merge, publish, > >+distribute, sublicense, and/or sell copies of the Software, and to > >+permit persons to whom the Software is furnished to do so, subject to > >+the following conditions: > >+ > >+The above copyright notice and this permission notice shall be > >+included in all copies or substantial portions of the Software. > >+ > >+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, > >+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF > >+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND > >+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE > >+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION > >+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION > >+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ > >+ > >+/* This file tests if libc getcontext() provides (unidirectionally) > >+ libunwind compatible `ucontext_t'. */ > >+ > >+#define LIBC_GETCONTEXT_TEST 1 > >+#include "Gtest-init.cxx" > >diff -u -X /root/jkratoch/.diffi.list -r -x config.h -x Makefile.in -x > >Makefile -N libunwind-0.99-alpha-orig/tests/Gtest-init-sigaction.c > >libunwind-0.99-alpha/tests/Gtest-init-sigaction.c > >--- libunwind-0.99-alpha-orig/tests/Gtest-init-sigaction.c 1969-12-31 > >19:00:00.000000000 -0500 > >+++ libunwind-0.99-alpha/tests/Gtest-init-sigaction.c 2007-01-26 > >08:49:27.000000000 -0500 > >@@ -0,0 +1,114 @@ > >+/* libunwind - a platform-independent unwind library > >+ Copyright (C) 2002-2003 Hewlett-Packard Co > >+ Contributed by David Mosberger-Tang <[EMAIL PROTECTED]> > >+ > >+This file is part of libunwind. > >+ > >+Permission is hereby granted, free of charge, to any person obtaining > >+a copy of this software and associated documentation files (the > >+"Software"), to deal in the Software without restriction, including > >+without limitation the rights to use, copy, modify, merge, publish, > >+distribute, sublicense, and/or sell copies of the Software, and to > >+permit persons to whom the Software is furnished to do so, subject to > >+the following conditions: > >+ > >+The above copyright notice and this permission notice shall be > >+included in all copies or substantial portions of the Software. > >+ > >+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, > >+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF > >+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND > >+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE > >+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION > >+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION > >+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ > >+ > >+/* This file tests unwinding from the 3rd argument of `(*sa_sigaction)'. > >*/ > >+ > >+#include <stdio.h> > >+#include <stdlib.h> > >+#include <unistd.h> > >+#include <string.h> > >+#include <setjmp.h> > >+ > >+#include <libunwind.h> > >+ > >+int verbose, errors; > >+ > >+#define panic(args...) \ > >+ { ++errors; fprintf (stderr, args); return; } > >+ > >+static void > >+backtrace (unw_context_t *ucp) > >+{ > >+ char name[128], off[32]; > >+ unw_word_t ip, offset; > >+ unw_cursor_t cursor; > >+ int ret, count = 0; > >+ > >+ /* `ucp' accepted. */ > >+ unw_init_local (&cursor, ucp); > >+ > >+ do > >+ { > >+ unw_get_reg (&cursor, UNW_REG_IP, &ip); > >+ name[0] = '\0'; > >+ off[0] = '\0'; > >+ if (unw_get_proc_name (&cursor, name, sizeof (name), &offset) == 0 > >+ && off > 0) > >+ snprintf (off, sizeof (off), "+0x%lx", (long) offset); > >+ if (verbose) > >+ printf (" [%lx] <%s%s>\n", (long) ip, name, off); > >+ if (++count > 32) > >+ panic ("FAILURE: didn't reach beginning of unwind-chain\n"); > >+ } > >+ while ((ret = unw_step (&cursor)) > 0); > >+ > >+ if (ret < 0) > >+ panic ("FAILURE: unw_step() returned %d\n", ret); > >+} > >+ > >+static sigjmp_buf b_env; > >+ > >+static void > >+b_sigaction (int signum, siginfo_t *siginfo, void *context) > >+{ > >+ backtrace ((unw_context_t *) context); > >+ > >+ siglongjmp (b_env, 1); > >+ panic ("FAILURE: NOTREACHED 2"); > >+} > >+ > >+static void > >+b (void) > >+{ > >+ struct sigaction sa; > >+ > >+ if (sigsetjmp (b_env, 1) != 0) > >+ return; > >+ > >+ memset (&sa, 0, sizeof (sa)); > >+ sa.sa_sigaction = b_sigaction; > >+ if (sigemptyset (&sa.sa_mask) != 0) > >+ panic ("FAILURE: sigemptyset()\n"); > >+ sa.sa_flags = SA_SIGINFO | SA_RESETHAND; > >+ > >+ if (sigaction (SIGSEGV, &sa, NULL) != 0) > >+ panic ("FAILURE: sigaction()\n"); > >+ > >+ *(volatile int *) 0 = 0; > >+ > >+ panic ("FAILURE: NOTREACHED 1\n "); > >+} > >+ > >+int > >+main (int argc, char **argv) > >+{ > >+ verbose = argc > 1; > >+ if (verbose) > >+ printf ("backtrace() from atexit()-handler:\n"); > >+ b(); > >+ if (errors) > >+ exit (1); > >+ return 0; > >+} > >diff -u -X /root/jkratoch/.diffi.list -r -x config.h -x Makefile.in -x > >Makefile -N libunwind-0.99-alpha-orig/tests/Gtest-init.cxx > >libunwind-0.99-alpha/tests/Gtest-init.cxx > >--- libunwind-0.99-alpha-orig/tests/Gtest-init.cxx 2006-07-26 > >23:13:14.000000000 -0400 > >+++ libunwind-0.99-alpha/tests/Gtest-init.cxx 2007-01-26 > >08:54:35.000000000 -0500 > >@@ -29,13 +29,17 @@ > > #include <stdio.h> > > #include <stdlib.h> > > #include <unistd.h> > >+#include <string.h> > >+#ifdef LIBC_GETCONTEXT_TEST > >+#include <ucontext.h> > >+#endif > > > > #include <libunwind.h> > > > > int verbose, errors; > > > > #define panic(args...) \ > >- { ++errors; fprintf (stderr, args); return; } > >+ do { ++errors; fprintf (stderr, args); return; } while (0) > > > > class Test_Class { > > public: > >@@ -50,10 +54,27 @@ > > char name[128], off[32]; > > unw_word_t ip, offset; > > unw_cursor_t cursor; > >- unw_context_t uc; > > int ret, count = 0; > >+ unw_context_t uc; > >+ static int filler = 0; > >+ > >+ memset (&uc, filler, sizeof (uc)); > >+ filler = ~filler; > >+ > >+#ifndef LIBC_GETCONTEXT_TEST > >+ > >+ if (unw_getcontext (&uc)) > >+ panic ("FAILURE: unw_getcontext() failed\n"); > >+ > >+#else /* LIBC_GETCONTEXT_TEST */ > >+ > >+ if (sizeof (ucontext_t) != sizeof (unw_context_t)) > >+ panic ("FAILURE: sizeof (ucontext_t) does not match\n"); > >+ else if (getcontext ((ucontext_t *) &uc)) > >+ panic ("FAILURE: getcontext() failed\n"); > >+ > >+#endif /* LIBC_GETCONTEXT_TEST */ > > > >- unw_getcontext (&uc); > > unw_init_local (&cursor, &uc); > > > > do > >@@ -78,7 +99,9 @@ > > static void > > b (void) > > { > >- backtrace(); > >+ /* Try both the FILLERs for uninitialized `sc_flags'. */ > >+ backtrace (); > >+ backtrace (); > > } > > > > static void > >diff -u -X /root/jkratoch/.diffi.list -r -x config.h -x Makefile.in -x > >Makefile -N libunwind-0.99-alpha-orig/tests/Ltest-init-libc.cxx > >libunwind-0.99-alpha/tests/Ltest-init-libc.cxx > >--- libunwind-0.99-alpha-orig/tests/Ltest-init-libc.cxx 1969-12-31 > >19:00:00.000000000 -0500 > >+++ libunwind-0.99-alpha/tests/Ltest-init-libc.cxx 2007-01-25 > >19:32:39.000000000 -0500 > >@@ -0,0 +1,5 @@ > >+#define UNW_LOCAL_ONLY > >+#include <libunwind.h> > >+#if !defined(UNW_REMOTE_ONLY) > >+#include "Gtest-init-libc.cxx" > >+#endif > >diff -u -X /root/jkratoch/.diffi.list -r -x config.h -x Makefile.in -x > >Makefile -N libunwind-0.99-alpha-orig/tests/Ltest-init-sigaction.c > >libunwind-0.99-alpha/tests/Ltest-init-sigaction.c > >--- libunwind-0.99-alpha-orig/tests/Ltest-init-sigaction.c 1969-12-31 > >19:00:00.000000000 -0500 > >+++ libunwind-0.99-alpha/tests/Ltest-init-sigaction.c 2007-01-26 > >08:48:27.000000000 -0500 > >@@ -0,0 +1,5 @@ > >+#define UNW_LOCAL_ONLY > >+#include <libunwind.h> > >+#if !defined(UNW_REMOTE_ONLY) > >+#include "Gtest-init-sigaction.c" > >+#endif > > > > > >diff -u -ru > >glibc-2.5-20061008T1257-orig/sysdeps/unix/sysv/linux/ia64/bits/sigcontext.h > >glibc-2.5-20061008T1257/sysdeps/unix/sysv/linux/ia64/bits/sigcontext.h > >--- > >glibc-2.5-20061008T1257-orig/sysdeps/unix/sysv/linux/ia64/bits/sigcontext.h > >2004-10-13 22:22:38.000000000 -0400 > >+++ glibc-2.5-20061008T1257/sysdeps/unix/sysv/linux/ia64/bits/sigcontext.h > >2007-01-26 04:41:30.000000000 -0500 > >@@ -71,9 +71,11 @@ > > #define IA64_SC_FLAG_ONSTACK_BIT 0 /* is handler running on > > signal stack? */ > > #define IA64_SC_FLAG_IN_SYSCALL_BIT 1 /* did signal interrupt a > > syscall? */ > > #define IA64_SC_FLAG_FPH_VALID_BIT 2 /* is state in > > f[32]-f[127] valid? */ > >+#define IA64_SC_FLAG_SYNCHRONOUS_BIT 63 /* Stored SOL number of > >registers (not SOF). */ > > > > #define IA64_SC_FLAG_ONSTACK (1 << IA64_SC_FLAG_ONSTACK_BIT) > > #define IA64_SC_FLAG_IN_SYSCALL (1 << > > IA64_SC_FLAG_IN_SYSCALL_BIT) > > #define IA64_SC_FLAG_FPH_VALID (1 << IA64_SC_FLAG_FPH_VALID_BIT) > >+#define IA64_SC_FLAG_SYNCHRONOUS (1 << IA64_SC_FLAG_SYNCHRONOUS_BIT) > > > > #endif /* _BITS_SIGCONTEXT_H */ > >diff -u -ru > >glibc-2.5-20061008T1257-orig/sysdeps/unix/sysv/linux/ia64/getcontext.S > >glibc-2.5-20061008T1257/sysdeps/unix/sysv/linux/ia64/getcontext.S > >--- glibc-2.5-20061008T1257-orig/sysdeps/unix/sysv/linux/ia64/getcontext.S > >2005-05-26 10:30:47.000000000 -0400 > >+++ glibc-2.5-20061008T1257/sysdeps/unix/sysv/linux/ia64/getcontext.S > >2007-01-26 04:47:45.000000000 -0500 > >@@ -146,9 +146,11 @@ > > ;; > > st8 [r2] = rB0, 16 > > st8 [r3] = rB1, 16 > >+ dep.z r4 = -1, IA64_SC_FLAG_SYNCHRONOUS_BIT, 1 > > ;; > > st8 [r2] = rB2, 16 > > st8 [r3] = rB3, 16 > >+ st8 [r32] = r4 // sc_flags = IA64_SC_FLAG_SYNCHRONOUS > > ;; > > st8 [r2] = rB4 > > st8 [r3] = rB5 > >diff -u -ru > >glibc-2.5-20061008T1257-orig/sysdeps/unix/sysv/linux/ia64/ucontext_i.h > >glibc-2.5-20061008T1257/sysdeps/unix/sysv/linux/ia64/ucontext_i.h > >--- glibc-2.5-20061008T1257-orig/sysdeps/unix/sysv/linux/ia64/ucontext_i.h > >2003-06-02 15:56:22.000000000 -0400 > >+++ glibc-2.5-20061008T1257/sysdeps/unix/sysv/linux/ia64/ucontext_i.h > >2007-01-26 04:41:30.000000000 -0500 > >@@ -26,6 +26,8 @@ > > > > #include <sigcontext-offsets.h> > > > >+#define IA64_SC_FLAG_SYNCHRONOUS_BIT 63 /* Stored SOL number of > >registers (not SOF). */ > >+ > > #define rTMP r16 > > #define rPOS r16 > > #define rCPOS r17 > > > > > >--- linux-2.6.18.ia64/include/asm-ia64/sigcontext.h-orig 2006-09-19 > >23:42:06.000000000 -0400 > >+++ linux-2.6.18.ia64/include/asm-ia64/sigcontext.h 2007-01-26 > >04:53:10.000000000 -0500 > >@@ -11,10 +11,12 @@ > > #define IA64_SC_FLAG_ONSTACK_BIT 0 /* is handler > > running on signal stack? */ > > #define IA64_SC_FLAG_IN_SYSCALL_BIT 1 /* did signal > > interrupt a syscall? */ > > #define IA64_SC_FLAG_FPH_VALID_BIT 2 /* is state in > > f[32]-f[127] valid? */ > >+#define IA64_SC_FLAG_SYNCHRONOUS_BIT 63 /* Stored SOL > >number of registers (not SOF). */ > > > > #define IA64_SC_FLAG_ONSTACK (1 << IA64_SC_FLAG_ONSTACK_BIT) > > #define IA64_SC_FLAG_IN_SYSCALL (1 << > > IA64_SC_FLAG_IN_SYSCALL_BIT) > > #define IA64_SC_FLAG_FPH_VALID (1 << IA64_SC_FLAG_FPH_VALID_BIT) > >+#define IA64_SC_FLAG_SYNCHRONOUS (1 << IA64_SC_FLAG_SYNCHRONOUS_BIT) > > > > # ifndef __ASSEMBLY__ > > > > > > > >/* > > compile with > > gcc 1.c -lunwind -ldl > >*/ > > > > > >#define _GNU_SOURCE > >#include <sys/time.h> > >#include <sys/resource.h> > >#include <unistd.h> > >#include <stdio.h> > >#include <signal.h> > >#include <string.h> > >#include <errno.h> > >#include <dlfcn.h> > >#include <elf.h> > >#include <ucontext.h> > >#include <assert.h> > >#include <stdlib.h> > > > >#define UNW_LOCAL_ONLY > >#include <libunwind.h> > > > >void stackdump(ucontext_t* ucp) > >{ > > unw_cursor_t cursor; > > unw_word_t ip, sp; > > int rc; > > > > fprintf(stderr,"stack dump start (ucontext %p)\n", ucp); > > > > if (0!= unw_init_local(&cursor, ucp)) { > > fprintf(stderr,"unw_init_local failed\n"); > > return; > > } > > > > while ( (rc = unw_step(&cursor)) > 0) { > > unw_get_reg(&cursor, UNW_REG_IP, &ip); > > unw_get_reg(&cursor, UNW_REG_SP, &sp); > > fprintf (stderr, "ip = %lx, sp = %lx\n", (long) ip, (long) sp); > > } > >unw_get_reg(&cursor, UNW_REG_IP, &ip); > >unw_get_reg(&cursor, UNW_REG_SP, &sp); > >fprintf (stderr, "post ip = %lx, post sp = %lx\n", (long) ip, (long) sp); > > > > if (rc <0) { > > fprintf(stderr,"unw_step failed rc = %d\n", rc); > > } > > > > fprintf(stderr,"stack dump end\n"); > >} > > > >void handleSegv(int sig, siginfo_t* info, void* ucpPtr) > >{ > > struct sigaction sa; > > > >write(2,"handleSegv\n",strlen("handleSegv\n")); > > > >int j; > >for (j=0;j<5;j++) > >{ > > > >if (j==0) > >puts("METHOD: sighandler argument 3"); > >if (j==1 || j == 2) > >{ > >printf("METHOD: libunwind unw_getcontext() [clear=%d]\n",(j-1)%2); > >int i; > >ucontext_t uc; > >memset(&uc,((j-1)%2 ? 0xFF : 0x00),sizeof(uc)); > >i = unw_getcontext(&uc); > >assert( i== 0); > >ucpPtr=&uc; > >} > >if (j==3 || j == 4) > >{ > >printf("METHOD: glibc getcontext() [clear=%d]\n",(j-1)%2); > >int i; > >ucontext_t uc; > >memset(&uc,((j-1)%2 ? 0xFF : 0x00),sizeof(uc)); > >i = getcontext(&uc); > >assert( i== 0); > >ucpPtr=&uc; > >} > >printf("sc_ip=0x%lx\n",((ucontext_t*)ucpPtr)->uc_mcontext.sc_ip); > >printf("sc_br[0]=0x%lx\n",((ucontext_t*)ucpPtr)->uc_mcontext.sc_br[0]); > >printf("sc_cfm=0x%lx\n",((ucontext_t*)ucpPtr)->uc_mcontext.sc_cfm); > >printf("uc_link=%p\n",((ucontext_t*)ucpPtr)->uc_link); > >{ unsigned long pfs = ((ucontext_t*)ucpPtr)->uc_mcontext.sc_ar_pfs; > >printf("sc_ar_pfs=0x%lx (sol=%lu,sof=%lu)\n",pfs, (pfs>>7)&0x7f,pfs&0x7f); > >} > >printf("sc_ar_bsp=0x%lx\n",((ucontext_t*)ucpPtr)->uc_mcontext.sc_ar_bsp); > > > > stackdump((ucontext_t*)ucpPtr); > >} > > > > sa.sa_handler = SIG_DFL; > > sigemptyset(&sa.sa_mask); > > sigaction(SIGSEGV, &sa, NULL); > >} > > > >static void (*plemming1)(); > >static void (*plemming2)(); > > > >void lemming2() { > > > > volatile char* p = 0; > >volatile unsigned pfs; > >volatile void *bsp; > >volatile void *bspstore; > > > > printf("9999 causes me to crash, for test purposes.\n"); > > > >asm("mov ar.rsc=0"); > >asm("mov %0=ar.pfs":"=r"(pfs)); > >asm("mov %0=ar.bsp":"=r"(bsp)); > >asm("mov %0=ar.bspstore":"=r"(bspstore)); > >asm("mov ar.rsc=3"); > > > >printf("pfs=0x%x(sol=%u,sof=%u),bsp=%p,bspstore=%p\n",pfs,(pfs>>7)&0x7f,pfs&0x7f,bsp,bspstore); > > > > > > *p = 0; > > > > printf("."); > > > > printf("I'm still alive, so I guess writing to a NULL pointer is > > okay... :-)\n"); > > exit(-1); > > > >} > > > >void lemming1() { > > printf("Called with -Xtest="); > > plemming2(); > > printf("."); > >} > > > > > >int main(void) > >{ > >setbuf(stdout,NULL); > >#if 0 > > // prevent writing of a core file > > struct rlimit rl; > > if (getrlimit(RLIMIT_CORE, &rl) != 0) { > > fprintf(stderr, "Cannot switch off core-files (getrlimit > > failed, %d (%s)\n", > > errno, strerror(errno)); > > } else { > > rl.rlim_cur = 0; > > if (setrlimit(RLIMIT_CORE, &rl) != 0) { > > fprintf(stderr, "Cannot switch off core-files > > (setrlimit failed, %d (%s)\n", > > errno, strerror(errno)); > > } > > } > >#endif > > plemming1 = lemming1; > > plemming2 = lemming2; > > > > { > > int signals[] = {SIGSEGV}; > > int i; > > int result = 0; > > > > for (i = 0; result != -1 && i < (sizeof signals / sizeof > > signals[0]); ++i) { > > struct sigaction sa; > > sa.sa_sigaction = handleSegv; > >#if 1 > > sa.sa_flags = SA_RESTART | SA_SIGINFO; > >#else > > sa.sa_flags = SA_SIGINFO; > >#endif > > sigemptyset(&sa.sa_mask); > > result = sigaction(signals[i], &sa, NULL); > > } > > } > > plemming1(); > > return 0; > >} > > > > > >_______________________________________________ > >Libunwind-devel mailing list > >[email protected] > >http://lists.nongnu.org/mailman/listinfo/libunwind-devel > > > > > > > > > -- > Mosberger Consulting LLC, http://www.mosberger-consulting.com/ _______________________________________________ Libunwind-devel mailing list [email protected] http://lists.nongnu.org/mailman/listinfo/libunwind-devel
