mirror of
https://github.com/tobast/libunwind-eh_elf.git
synced 2025-01-08 18:33:42 +01:00
(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)
This commit is contained in:
parent
3ff39e9fc9
commit
d9445c1f46
1 changed files with 52 additions and 14 deletions
|
@ -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");
|
||||
|
|
Loading…
Reference in a new issue