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