[commit: ghc] master: Fix stop_thread unwinding information (34e3523)

git at git.haskell.org git at git.haskell.org
Wed Feb 8 15:26:27 UTC 2017


Repository : ssh://git@git.haskell.org/ghc

On branch  : master
Link       : http://ghc.haskell.org/trac/ghc/changeset/34e3523354916b0fb8a0dc93041d25812f7e6181/ghc

>---------------------------------------------------------------

commit 34e3523354916b0fb8a0dc93041d25812f7e6181
Author: Ben Gamari <bgamari.foss at gmail.com>
Date:   Tue Feb 7 23:00:10 2017 -0500

    Fix stop_thread unwinding information
    
    This corrects the unwind information for `stg_stop_thread`, which
    allows us to unwind back to the C stack after reaching the end of the
    STG stack.
    
    Test Plan: Validate
    
    Reviewers: simonmar, austin, erikd
    
    Reviewed By: simonmar
    
    Subscribers: thomie
    
    Differential Revision: https://phabricator.haskell.org/D2746


>---------------------------------------------------------------

34e3523354916b0fb8a0dc93041d25812f7e6181
 includes/rts/Constants.h | 14 ++++++++++++++
 rts/StgCRun.c            |  6 +-----
 rts/StgStartup.cmm       | 14 +++++++++++---
 3 files changed, 26 insertions(+), 8 deletions(-)

diff --git a/includes/rts/Constants.h b/includes/rts/Constants.h
index bd602e7..62fa833 100644
--- a/includes/rts/Constants.h
+++ b/includes/rts/Constants.h
@@ -112,6 +112,20 @@
 #define RESERVED_C_STACK_BYTES (2048 * SIZEOF_LONG)
 
 /* -----------------------------------------------------------------------------
+   How large is the stack frame saved by StgRun?
+   world.  Used in StgCRun.c.
+   -------------------------------------------------------------------------- */
+#if defined(x86_64_HOST_ARCH)
+#  if defined(mingw32_HOST_OS)
+/* 8 larger than necessary to make the alignment right*/
+#    define STG_RUN_STACK_FRAME_SIZE 80
+#  else
+#    define STG_RUN_STACK_FRAME_SIZE 48
+#  endif
+#endif
+
+
+/* -----------------------------------------------------------------------------
    How much Haskell stack space to reserve for the saving of registers
    etc. in the case of a stack/heap overflow.
 
diff --git a/rts/StgCRun.c b/rts/StgCRun.c
index 0610dd3..5f7f2b9 100644
--- a/rts/StgCRun.c
+++ b/rts/StgCRun.c
@@ -320,11 +320,7 @@ StgRunIsImplementedInAssembler(void)
 
         :
         : "i"(RESERVED_C_STACK_BYTES),
-#if defined(mingw32_HOST_OS)
-          "i"(80 /*stack frame size; 8 too large to make the alignment right*/)
-#else
-          "i"(48 /*stack frame size*/)
-#endif
+          "i"(STG_RUN_STACK_FRAME_SIZE /* stack frame size */)
         );
         /*
          * See Note [Stack Alignment on X86]
diff --git a/rts/StgStartup.cmm b/rts/StgStartup.cmm
index a3a75d8..4cc84bc 100644
--- a/rts/StgStartup.cmm
+++ b/rts/StgStartup.cmm
@@ -67,11 +67,19 @@ INFO_TABLE_RET(stg_stop_thread, STOP_FRAME,
        debuggers to find their way back to the C stack.
 
        This is a bit fiddly as we assume the layout of the stack prepared
-       for us by StgRun.
+       for us by StgRun. Note that in most cases StgRun is written in assembler
+       and therefore has no associated unwind information. For this reason we
+       need to identify the platform stack pointer and return address values for
+       the StgRun's caller.
      */
 #ifdef x86_64_HOST_ARCH
-    unwind MachSp = MachSp + RESERVED_C_STACK_BYTES + 0x38 + 8,
-           UnwindReturnReg = W_[MachSp + RESERVED_C_STACK_BYTES + 0x38];
+    // offset of 8 in MachSp value due to return address
+    unwind MachSp = MachSp + RESERVED_C_STACK_BYTES + STG_RUN_STACK_FRAME_SIZE + 8,
+           UnwindReturnReg = W_[MachSp + RESERVED_C_STACK_BYTES + STG_RUN_STACK_FRAME_SIZE];
+#else
+    // FIXME: Fill in for other platforms
+    unwind MachSp = return,
+           UnwindReturnReg = return;
 #endif
 
     Sp = Sp + SIZEOF_StgStopFrame - WDS(2);



More information about the ghc-commits mailing list