summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Gamari <bgamari.foss@gmail.com>2017-02-07 23:00:10 -0500
committerBen Gamari <ben@smart-cactus.org>2017-02-08 10:26:00 -0500
commit34e3523354916b0fb8a0dc93041d25812f7e6181 (patch)
tree5a33a3183828a23b130e889eff23b90eae30ba5e
parent5279b08ba3f01e4b7e28d12b2751413d789d9fbe (diff)
downloadhaskell-34e3523354916b0fb8a0dc93041d25812f7e6181.tar.gz
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
-rw-r--r--includes/rts/Constants.h14
-rw-r--r--rts/StgCRun.c6
-rw-r--r--rts/StgStartup.cmm14
3 files changed, 26 insertions, 8 deletions
diff --git a/includes/rts/Constants.h b/includes/rts/Constants.h
index bd602e77a1..62fa833173 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 0610dd3717..5f7f2b910f 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 a3a75d8211..4cc84bc225 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);