This is the mail archive of the gcc-patches@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]

[PATCH] Fix unwinding through signal frames (PR other/26208, nptl/300)


Hi!

Dwarf2 unwinding assumes RA points to the end of the first not yet fully
executed instruction.  That is true most of the time, e.g. when unwinding
through a call, saved RA is usually the end of the call instruction,
whose effects aren't all visible yet (the call hasn't returned yet).
But, in the frame right above a signal frame this varries, usually
saved return address is right after the last executed instruction
and before first non-executed instruction.
The unwinder in several places uses context->ra - 1 (or e.g.
_Unwind_GetIP (context) - 1) to get some address either at the start
or in the middle of the current instruction.  But for frames above
signal frame context->ra - 1 might very well point to the previous
function.  Additionally, execute_cfa_program executes all CFA instructions
with PCs strictly below context->ra.  But when above sigframe, we
want also to execute instructions with PC equal to context->ra.
Say when we have:
pushq %rax	# some instruction that affects unwind info
.cfi_adjust_cfa_offset 8
# <- PC saved in signal frame points here (i.e. pushq %rax was executed as the last instruction)
...
then without the patch below we don't execute the CFA adjustment
instruction.

I'm also attaching a testcase I was using, but don't plan to commit
it to GCC (it is quite slow and also depends on whether kernel
and/or glibc has signal trampoline marked).

Bootstrapped/regtested on i686-linux, x86_64-linux, s390x-linux and
ppc-linux (no regressions anywhere), built on ia64-linux.
The testcase below failed on i686, x86_64, s390x, s390 and ppc
without this patch, with the patch worked on x86_64, s390x, s390
and ppc.  On i686 vDSO was used and I couldn't replace the kernel
on that box, so it expectedly failed unless the testcase was
compiled with -DSIGACTION_DIRECT_SYSCALL (to force using
MD_FALLBACK_FRAME_STATE_FOR).

Ok for trunk?

I'd appreciate if anyone had better suggestions for the new libgcc{,_s}
function name (currently _Unwind_GetIPInfo).

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=26208 contains also
binutils and Linux kernel patches, I'll submit them afterwards
(the GCC patch doesn't depend on them, but binutils and kernel patches
depend on the codification of the S augmentation flag).

	Jakub

Attachment: gcc-trunk-pr26208.patch
Description: Text document

Attachment: cleanup-12.c
Description: Text document

Attachment: cleanup-12a.S
Description: Text document


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