Teach stackinfo::walk() how to virtually unwind the tls sigstack
This improves how stackinfo::dumpstack() dumps _sigbe and sigdelayed frames * exceptions.cc (stack_info): Add sigstackptr member. (walk): Unwind sigstackptr inside _sigbe and sigdelayed. * gendef (_sigdelayed_end): Add symbol to mark end of sigdelayed. Signed-off-by: Jon TURNEY <jon.turney@dronecode.org.uk>
This commit is contained in:
parent
63c9ffeed8
commit
e9e47b8ce6
|
@ -1,3 +1,9 @@
|
||||||
|
2015-03-12 Jon TURNEY <jon.turney@dronecode.org.uk>
|
||||||
|
|
||||||
|
* 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-13 Corinna Vinschen <corinna@vinschen.de>
|
2015-03-13 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
* include/cygwin/sys_time.h: Remove. Definitions moved to newlib's
|
* include/cygwin/sys_time.h: Remove. Definitions moved to newlib's
|
||||||
|
|
|
@ -45,6 +45,8 @@ details. */
|
||||||
#define CALL_HANDLER_RETRY_INNER 10
|
#define CALL_HANDLER_RETRY_INNER 10
|
||||||
|
|
||||||
char debugger_command[2 * NT_MAX_PATH + 20];
|
char debugger_command[2 * NT_MAX_PATH + 20];
|
||||||
|
extern u_char _sigbe;
|
||||||
|
extern u_char _sigdelayed_end;
|
||||||
|
|
||||||
static BOOL WINAPI ctrl_c_handler (DWORD);
|
static BOOL WINAPI ctrl_c_handler (DWORD);
|
||||||
|
|
||||||
|
@ -224,6 +226,7 @@ class stack_info
|
||||||
#ifdef __x86_64__
|
#ifdef __x86_64__
|
||||||
CONTEXT c;
|
CONTEXT c;
|
||||||
UNWIND_HISTORY_TABLE hist;
|
UNWIND_HISTORY_TABLE hist;
|
||||||
|
__stack_t *sigstackptr;
|
||||||
#endif
|
#endif
|
||||||
public:
|
public:
|
||||||
STACKFRAME sf; /* For storing the stack information */
|
STACKFRAME sf; /* For storing the stack information */
|
||||||
|
@ -252,6 +255,7 @@ stack_info::init (PUINT_PTR framep, bool wantargs, PCONTEXT ctx)
|
||||||
memset (&c, 0, sizeof c);
|
memset (&c, 0, sizeof c);
|
||||||
c.ContextFlags = CONTEXT_ALL;
|
c.ContextFlags = CONTEXT_ALL;
|
||||||
}
|
}
|
||||||
|
sigstackptr = _my_tls.stackptr;
|
||||||
#endif
|
#endif
|
||||||
memset (&sf, 0, sizeof (sf));
|
memset (&sf, 0, sizeof (sf));
|
||||||
if (ctx)
|
if (ctx)
|
||||||
|
@ -287,6 +291,15 @@ stack_info::walk ()
|
||||||
sf.AddrStack.Offset = c.Rsp;
|
sf.AddrStack.Offset = c.Rsp;
|
||||||
sf.AddrFrame.Offset = c.Rbp;
|
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);
|
f = RtlLookupFunctionEntry (c.Rip, &imagebase, &hist);
|
||||||
if (f)
|
if (f)
|
||||||
RtlVirtualUnwind (0, imagebase, c.Rip, f, &c, &hdl, &establisher, NULL);
|
RtlVirtualUnwind (0, imagebase, c.Rip, f, &c, &hdl, &establisher, NULL);
|
||||||
|
|
|
@ -311,6 +311,8 @@ sigdelayed:
|
||||||
xchgq %r10,(%rsp)
|
xchgq %r10,(%rsp)
|
||||||
ret
|
ret
|
||||||
.seh_endproc
|
.seh_endproc
|
||||||
|
_sigdelayed_end:
|
||||||
|
.global _sigdelayed_end
|
||||||
|
|
||||||
# _cygtls::pop
|
# _cygtls::pop
|
||||||
.global _ZN7_cygtls3popEv
|
.global _ZN7_cygtls3popEv
|
||||||
|
|
Loading…
Reference in New Issue