[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