From 94391b7af06f6aec6fc02543b894b0963556118e Mon Sep 17 00:00:00 2001 From: Jon TURNEY Date: Mon, 9 Mar 2015 21:55:29 +0000 Subject: [PATCH] Teach stackinfo::walk() how to virtually unwind the tls sigstack This improves how stackinfo::dumpstack() dumps _sigbe and sigdelayed frames Signed-off-by: Jon TURNEY --- winsup/cygwin/ChangeLog | 6 ++++++ winsup/cygwin/exceptions.cc | 13 +++++++++++++ winsup/cygwin/gendef | 2 ++ 3 files changed, 21 insertions(+) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index d63b359..f0cbeed 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,9 @@ +2015-03-12 Jon TURNEY + + * exceptions.cc (stack_info): Add sigstackptr member. + (walk): Unwind sigstackptr inside _sigbe and sigdelayed. + * gendef (_sigdelayed_end): Add symbol to mark end of sigdelayed. + 2015-03-11 Corinna Vinschen * include/cygwin/types.h: Include diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc index 73de7e7..6035270 100644 --- a/winsup/cygwin/exceptions.cc +++ b/winsup/cygwin/exceptions.cc @@ -45,6 +45,8 @@ details. */ #define CALL_HANDLER_RETRY_INNER 10 char debugger_command[2 * NT_MAX_PATH + 20]; +extern u_char _sigbe; +extern u_char _sigdelayed_end; static BOOL WINAPI ctrl_c_handler (DWORD); @@ -277,6 +279,7 @@ class stack_info #ifdef __x86_64__ CONTEXT c; UNWIND_HISTORY_TABLE hist; + __stack_t *sigstackptr; #endif public: STACKFRAME sf; /* For storing the stack information */ @@ -305,6 +308,7 @@ stack_info::init (PUINT_PTR framep, bool wantargs, PCONTEXT ctx) memset (&c, 0, sizeof c); c.ContextFlags = CONTEXT_ALL; } + sigstackptr = _my_tls.stackptr; #endif memset (&sf, 0, sizeof (sf)); if (ctx) @@ -340,6 +344,15 @@ stack_info::walk () sf.AddrStack.Offset = c.Rsp; sf.AddrFrame.Offset = c.Rbp; + if ((c.Rip >= (DWORD64)&_sigbe) && (c.Rip < (DWORD64)&_sigdelayed_end)) + { + /* _sigbe and sigdelayed don't have SEH unwinding data, so virtually + unwind the tls sigstack */ + c.Rip = sigstackptr[-1]; + sigstackptr--; + return 1; + } + f = RtlLookupFunctionEntry (c.Rip, &imagebase, &hist); if (f) RtlVirtualUnwind (0, imagebase, c.Rip, f, &c, &hdl, &establisher, NULL); diff --git a/winsup/cygwin/gendef b/winsup/cygwin/gendef index ac411ca..01b8c39 100755 --- a/winsup/cygwin/gendef +++ b/winsup/cygwin/gendef @@ -327,6 +327,8 @@ sigdelayed: xchgq %r10,(%rsp) ret .seh_endproc +_sigdelayed_end: + .global _sigdelayed_end # _cygtls::pop .global _ZN7_cygtls3popEv -- 2.1.4