diff options
author | mostang.com!davidm <mostang.com!davidm> | 2005-05-03 09:13:17 +0000 |
---|---|---|
committer | mostang.com!davidm <mostang.com!davidm> | 2005-05-03 09:13:17 +0000 |
commit | d9445c1f46f7f29ec8bed1de2aab3af72f50dfac (patch) | |
tree | f2dfff4185a8b3cf8fbe052d0c82017eb4f5ef36 /tests/Gtest-resume-sig.c | |
parent | 3ff39e9fc9189155c2caffbb7d261d3f7b6f9ed8 (diff) | |
download | libunwind-d9445c1f46f7f29ec8bed1de2aab3af72f50dfac.tar.gz |
(handler): get_bsp() returns an integer, not a pointer.
(main): Do some silly FP computations. On x86-64, this ensures
that the signal handler invocations will always be called
with the FPU-state saved as well. Without this, the first
signal was invoked without FPU-state, the second with, causing
a spurious failure.
2004/11/17 02:06:25-08:00 mostang.com!davidm
(get_bsp): New function.
(handler): Clean up & check for error returns.
(main): Also fail if we didn't get SIGUSR2.
(Logical change 1.290)
Diffstat (limited to 'tests/Gtest-resume-sig.c')
-rw-r--r-- | tests/Gtest-resume-sig.c | 66 |
1 files changed, 52 insertions, 14 deletions
diff --git a/tests/Gtest-resume-sig.c b/tests/Gtest-resume-sig.c index fb28ac12..0f0a6f97 100644 --- a/tests/Gtest-resume-sig.c +++ b/tests/Gtest-resume-sig.c @@ -1,5 +1,5 @@ /* libunwind - a platform-independent unwind library - Copyright (C) 2003 Hewlett-Packard Co + Copyright (C) 2003-2004 Hewlett-Packard Co Contributed by David Mosberger-Tang <davidm@hpl.hp.com> Permission is hereby granted, free of charge, to any person obtaining @@ -45,6 +45,20 @@ int nerrors; int got_usr1, got_usr2; char *sigusr1_sp; +uintptr_t +get_bsp (void) +{ +#if UNW_TARGET_IA64 +# ifdef __INTEL_COMPILER + return __getReg (_IA64_REG_AR_BSP); +# else + return (uintptr_t) __builtin_ia64_bsp (); +# endif +#else + return 0; +#endif +} + void handler (int sig) { @@ -53,15 +67,11 @@ handler (int sig) unw_context_t uc; unw_cursor_t c; char foo; + int ret; #if UNW_TARGET_IA64 -# ifdef __ECC - void *bsp = (void *) __getReg(_IA64_REG_AR_BSP); -# else - void *bsp = __builtin_ia64_bsp (); -#endif if (verbose) - printf ("bsp = %p\n", bsp); + printf ("bsp = %llx\n", (unsigned long long) get_bsp ()); #endif if (verbose) @@ -80,15 +90,23 @@ handler (int sig) signal (SIGUSR1, SIG_IGN); signal (SIGUSR2, handler); - unw_getcontext(&uc); - unw_init_local(&c, &uc); - unw_step(&c); /* step to signal trampoline */ - unw_step(&c); /* step to signaller frame (main ()) */ - unw_get_reg(&c, UNW_REG_IP, &ip); + if ((ret = unw_getcontext (&uc)) < 0) + panic ("unw_getcontext() failed: ret=%d\n", ret); + if ((ret = unw_init_local (&c, &uc)) < 0) + panic ("unw_init_local() failed: ret=%d\n", ret); + + if ((ret = unw_step (&c)) < 0) /* step to signal trampoline */ + panic ("unw_step(1) failed: ret=%d\n", ret); + + if ((ret = unw_step (&c)) < 0) /* step to signal trampoline */ + panic ("unw_step(2) failed: ret=%d\n", ret); + + if ((ret = unw_get_reg (&c, UNW_REG_IP, &ip)) < 0) + panic ("unw_get_reg(IP) failed: ret=%d\n", ret); if (verbose) printf ("resuming at 0x%lx, with SIGUSR2 pending\n", (unsigned long) ip); - unw_resume(&c); + unw_resume (&c); } else if (sig == SIGUSR2) { @@ -110,17 +128,37 @@ handler (int sig) int main (int argc, char **argv) { + float d = 1.0; + int n = 0; + if (argc > 1) verbose = 1; signal (SIGUSR1, handler); + /* Use the FPU a bit; otherwise we get spurious errors should the + signal handler need to use the FPU for any reason. This seems to + happen on x86-64. */ + while (d > 0.0) + { + d /= 2.0; + ++n; + } + if (n > 9999) + return -1; /* can't happen, but don't tell the compiler... */ + if (verbose) printf ("sending SIGUSR1\n"); kill (getpid (), SIGUSR1); + if (!got_usr2) + panic ("failed to get SIGUSR2\n"); + if (nerrors) - fprintf (stderr, "FAILURE: detected %d errors\n", nerrors); + { + fprintf (stderr, "FAILURE: detected %d errors\n", nerrors); + exit (-1); + } if (verbose) printf ("SUCCESS\n"); |