This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug other/26208] Serious problem with unwinding through signal frames



------- Comment #8 from jakub at gcc dot gnu dot org  2006-02-21 13:12 -------
Created an attachment (id=10886)
 --> (http://gcc.gnu.org/bugzilla/attachment.cgi?id=10886&action=view)
linux-2.6.15-pr26208.patch

This is what I have so far (libjava not done yet), but I'm not sure a simple
CIE flag isn't sufficient on all arches.  Consider:
#define _GNU_SOURCE
#include <signal.h>
#include <string.h>
#include <fenv.h>

int *p;
double d = 1.0, e = 0.0;
void sigfpe (int signo) { }
void sigsegv (int signo) { }
void fpe (void) { d /= e; }
void segv (void) { *p = 0; }

int
main (int argc, char **argv)
{
  struct sigaction sa;
  sa.sa_handler = sigfpe;
  sigemptyset (&sa.sa_mask);
  sa.sa_flags = 0;
  sigaction (SIGFPE, &sa, 0);
  feenableexcept (FE_ALL_EXCEPT);
  sa.sa_handler = sigsegv;
  sigemptyset (&sa.sa_mask);
  sa.sa_flags = 0;
  sigaction (SIGSEGV, &sa, 0);
  if (argc < 2)
    return 1;
  if (strcmp (argv[1], "fpe") == 0)
    fpe ();
  else if (strcmp (argv[1], "segv") == 0)
    segv ();
  else
    return 1;
  return 0;
}

For segv the PC saved in sigcontext is always before the faulting instruction,
at least on i386, x86_64, ppc, ppc64, s390x I tried.
For asynchronously sent signals (that's the reason why I opened this PR), saved
PC will be also before the next instruction to be executed, so for SIGSEGV as
well asynchronously sent signals we want the fs->pc <= context->ra in
execute_cfa_program and _Unwind_Find_FDE (context->ra, ) behavior.
But, for SIGFPE things are more difficult.
On s390x, PC is in this case after the ddbr instruction rather than before it,
on i386 when using i387 FPU stack PC is after the fdivrp instruction, but at
the following fstpl instruction; adding nops in between shows that it actually
is always before fstpl), on x86_64 or i386 -mfpmath=sse it is before the
failing divsd, on ppc similarly.
We should avoid doing hacks, because then say if you inside a SIGFPE handler
call a cancellation point function and a thread is cancelled, we can't rely
on hacks like libjava/include/*-signal.h is doing.  And the instruction that
divides by zero can be e.g. at the very beginning of a function, or the last
instruction in it.
So, my preference would be for the S flag to mean there is a CFA expression
present in the FDE augmentation area.  unwind-dw2.c (uw_frame_state_for) would
evaluate that expression (first pushing say context->cfa to the stack) and
set fs->signal_frame to 1 iff it evaluates to non-zero. 
MD_FALLBACK_FRAME_STATE_FOR would conditionally define fs->signal_frame
depending on signal number, or si_code and other stuff.
On i386/x86_64 I guess we want to always set fs->signal_frame (so e.g.
the S CFA expression would be DW_OP_lit1), I'd appreciate feedback for other
arches.

Another issue is that this needs coordination between
libgcc/binutils/glibc/kernel/libjava.
I did a quick check:
alpha libc cfi
i386 vDSO or libc       libjava private sigaction
x86_64 libc (bogus cfi, in the end MD_FALLBACK_FRAME_STATE_FOR)
ppc vDSO
ppc64 vDSO
sparc32 libc, MD_FALLBACK_FRAME_STATE_FOR
sparc64 libc, MD_FALLBACK_FRAME_STATE_FOR
s390 stack, MD_FALLBACK_FRAME_STATE_FOR         libjava private sigaction
s390x stack, MD_FALLBACK_FRAME_STATE_FOR        libjava private sigaction
ia64 irrelevant, doesn't use Dwarf2 unwind info

This is most important for libjava, as libjava is doing ugly hacks around this
problem and thus should know if S flag will be used or not.  In i386 case we
are fine, libjava calls sigaction syscall directly and sets SA_RESTORER, so
sigreturn pad in libjava is used.  Alpha could use the same trick,
MD_FALLBACK_FRAME_STATE_FOR is under GCC's control, but on ppc/ppc64 we are
in trouble when using approx. November 2005 till now kernels (before that
there was no vDSO on ppc{,64}).


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=26208


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]