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

Reply via email to