diff options
author | Ben Gamari <bgamari.foss@gmail.com> | 2017-02-07 23:00:10 -0500 |
---|---|---|
committer | Ben Gamari <ben@smart-cactus.org> | 2017-02-08 10:26:00 -0500 |
commit | 34e3523354916b0fb8a0dc93041d25812f7e6181 (patch) | |
tree | 5a33a3183828a23b130e889eff23b90eae30ba5e | |
parent | 5279b08ba3f01e4b7e28d12b2751413d789d9fbe (diff) | |
download | haskell-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.h | 14 | ||||
-rw-r--r-- | rts/StgCRun.c | 6 | ||||
-rw-r--r-- | rts/StgStartup.cmm | 14 |
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); |