[newlib-cygwin] Reuse __unwind_single_frame where appropriate
Corinna Vinschen
corinna@sourceware.org
Fri Jul 17 14:29:00 GMT 2015
https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=b3ccf998ccc7b45a3df442b8f5ca8989f5c874a6
commit b3ccf998ccc7b45a3df442b8f5ca8989f5c874a6
Author: Corinna Vinschen <corinna@vinschen.de>
Date: Fri Jul 17 16:29:41 2015 +0200
Reuse __unwind_single_frame where appropriate
* exceptions.cc (__unwind_single_frame): Move up in file to be
accessible from other places. Move comment to getcontext.
(stack_info::walk): Call __unwind_single_frame in 64 bit case. Fix
preceeding comment.
(myfault_altstack_handler): Call __unwind_single_frame.
(getcontext): Give comment from __unwind_single_frame a new home.
(swapcontext): Fix comment.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
Diff:
---
winsup/cygwin/ChangeLog | 10 +++++
winsup/cygwin/exceptions.cc | 90 ++++++++++++++++-----------------------------
2 files changed, 42 insertions(+), 58 deletions(-)
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index f2aabf7..0537eea 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,5 +1,15 @@
2015-07-17 Corinna Vinschen <corinna@vinschen.de>
+ * exceptions.cc (__unwind_single_frame): Move up in file to be
+ accessible from other places. Move comment to getcontext.
+ (stack_info::walk): Call __unwind_single_frame in 64 bit case. Fix
+ preceeding comment.
+ (myfault_altstack_handler): Call __unwind_single_frame.
+ (getcontext): Give comment from __unwind_single_frame a new home.
+ (swapcontext): Fix comment.
+
+2015-07-17 Corinna Vinschen <corinna@vinschen.de>
+
* common.din (getcontext): Export.
(makecontext): Export.
(setcontext): Export.
diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc
index eea2be3..7e10ba9 100644
--- a/winsup/cygwin/exceptions.cc
+++ b/winsup/cygwin/exceptions.cc
@@ -280,17 +280,36 @@ stack_info::init (PUINT_PTR framep, bool wantargs, PCONTEXT ctx)
extern "C" void _cygwin_exit_return ();
-/* Walk the stack by looking at successive stored 'bp' frames.
- This is not foolproof. */
-int
-stack_info::walk ()
-{
#ifdef __x86_64__
+static inline void
+__unwind_single_frame (PCONTEXT ctx)
+{
PRUNTIME_FUNCTION f;
ULONG64 imagebase;
+ UNWIND_HISTORY_TABLE hist;
DWORD64 establisher;
PVOID hdl;
+ f = RtlLookupFunctionEntry (ctx->Rip, &imagebase, &hist);
+ if (f)
+ RtlVirtualUnwind (0, imagebase, ctx->Rip, f, ctx, &hdl, &establisher,
+ NULL);
+ else
+ {
+ ctx->Rip = *(ULONG_PTR *) ctx->Rsp;
+ ctx->Rsp += 8;
+ }
+}
+#endif
+
+/* Walk the stack.
+
+ On 32 bit we're doing this by looking at successive stored 'ebp' frames.
+ This is not foolproof. */
+int
+stack_info::walk ()
+{
+#ifdef __x86_64__
if (!c.Rip)
return 0;
@@ -306,15 +325,7 @@ stack_info::walk ()
sigstackptr--;
return 1;
}
-
- f = RtlLookupFunctionEntry (c.Rip, &imagebase, &hist);
- if (f)
- RtlVirtualUnwind (0, imagebase, c.Rip, f, &c, &hdl, &establisher, NULL);
- else
- {
- c.Rip = *(ULONG_PTR *) c.Rsp;
- c.Rsp += 8;
- }
+ __unwind_single_frame (&c);
if (needargs && c.Rip)
{
PULONG_PTR p = (PULONG_PTR) c.Rsp;
@@ -605,28 +616,13 @@ myfault_altstack_handler (EXCEPTION_POINTERS *exc)
if (me.andreas)
{
- PRUNTIME_FUNCTION f;
- ULONG64 imagebase;
- UNWIND_HISTORY_TABLE hist;
- DWORD64 establisher;
- PVOID hdl;
CONTEXT *c = exc->ContextRecord;
/* Unwind the stack manually and call RtlRestoreContext. This
is necessary because RtlUnwindEx checks the stack for validity,
which, as outlined above, fails for the alternate stack. */
while (c->Rsp < me.andreas->frame)
- {
- f = RtlLookupFunctionEntry (c->Rip, &imagebase, &hist);
- if (f)
- RtlVirtualUnwind (0, imagebase, c->Rip, f, c, &hdl, &establisher,
- NULL);
- else
- {
- c->Rip = *(ULONG_PTR *) c->Rsp;
- c->Rsp += 8;
- }
- }
+ __unwind_single_frame (c);
c->Rip = me.andreas->ret;
RtlRestoreContext (c, NULL);
}
@@ -1865,33 +1861,6 @@ _cygtls::signal_debugger (siginfo_t& si)
}
}
-#ifdef __x86_64__
-static inline void
-__unwind_single_frame (PCONTEXT ctx)
-{
- /* Amazing, but true: On 32 bit, RtlCaptureContext returns the context
- matching the caller of getcontext, so all we have to do is call it.
- On 64 bit, RtlCaptureContext returns the exact context of its own
- caller, so we have to unwind virtually by a single frame to get the
- context of the caller of getcontext. */
- PRUNTIME_FUNCTION f;
- ULONG64 imagebase;
- UNWIND_HISTORY_TABLE hist;
- DWORD64 establisher;
- PVOID hdl;
-
- f = RtlLookupFunctionEntry (ctx->Rip, &imagebase, &hist);
- if (f)
- RtlVirtualUnwind (0, imagebase, ctx->Rip, f, ctx, &hdl, &establisher,
- NULL);
- else
- {
- ctx->Rip = *(ULONG_PTR *) ctx->Rsp;
- ctx->Rsp += 8;
- }
-}
-#endif
-
extern "C" int
setcontext (const ucontext_t *ucp)
{
@@ -1917,6 +1886,11 @@ getcontext (ucontext_t *ucp)
PCONTEXT ctx = (PCONTEXT) &ucp->uc_mcontext;
ctx->ContextFlags = CONTEXT_FULL;
RtlCaptureContext (ctx);
+ /* Amazing, but true: On 32 bit, RtlCaptureContext returns the context
+ matching the caller of getcontext, so all we have to do is call it.
+ On 64 bit, RtlCaptureContext returns the exact context of its own
+ caller, so we have to unwind virtually by a single frame to get the
+ context of the caller of getcontext. */
__unwind_single_frame (ctx);
/* Successful getcontext is supposed to return 0. If we don't set rax to 0
here, there's a chance that code like this:
@@ -1937,8 +1911,8 @@ swapcontext (ucontext_t *oucp, const ucontext_t *ucp)
PCONTEXT ctx = (PCONTEXT) &oucp->uc_mcontext;
ctx->ContextFlags = CONTEXT_FULL;
RtlCaptureContext (ctx);
+ /* See comments in getcontext. */
__unwind_single_frame (ctx);
- /* See above. */
oucp->uc_mcontext.rax = 0;
oucp->uc_sigmask = oucp->uc_mcontext.oldmask = _my_tls.sigmask;
return setcontext (ucp);
More information about the Cygwin-cvs
mailing list