From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 18645 invoked by alias); 21 Feb 2006 13:12:45 -0000 Received: (qmail 18273 invoked by uid 48); 21 Feb 2006 13:12:39 -0000 Date: Tue, 21 Feb 2006 13:12:00 -0000 Message-ID: <20060221131239.18272.qmail@sourceware.org> X-Bugzilla-Reason: CC References: Subject: [Bug other/26208] Serious problem with unwinding through signal frames In-Reply-To: Reply-To: gcc-bugzilla@gcc.gnu.org To: gcc-bugs@gcc.gnu.org From: "jakub at gcc dot gnu dot org" Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Archive: List-Post: List-Help: Sender: gcc-bugs-owner@gcc.gnu.org X-SW-Source: 2006-02/txt/msg02393.txt.bz2 List-Id: ------- 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 #include #include 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