summaryrefslogtreecommitdiff
path: root/rts/StgStartup.cmm
diff options
context:
space:
mode:
authorBen Gamari <ben@smart-cactus.org>2022-04-04 21:43:27 -0400
committerMarge Bot <ben+marge-bot@smart-cactus.org>2022-04-25 10:20:05 -0400
commite09afbf2a998beea7783e3de5dce5dd3c6ff23db (patch)
tree126afde30070ef8a13cee9a558eb1f5192b5c1ea /rts/StgStartup.cmm
parent41cf758b3f50554e0aa5240a5898b693758d9670 (diff)
downloadhaskell-e09afbf2a998beea7783e3de5dce5dd3c6ff23db.tar.gz
rts: Refactor handling of dead threads' stacks
This fixes a bug that @JunmingZhao42 and I noticed while working on her MMTK port. Specifically, in stg_stop_thread we used stg_enter_info as a sentinel at the tail of a stack after a thread has completed. However, stg_enter_info expects to have a two-field payload, which we do not push. Consequently, if the GC ends up somehow the stack it will attempt to interpret data past the end of the stack as the frame's fields, resulting in unsound behavior. To fix this I eliminate this hacky use of `stg_stop_thread` and instead introduce a new stack frame type, `stg_dead_thread_info`. Not only does this eliminate the potential for the previously mentioned memory unsoundness but it also more clearly captures the intended structure of the dead threads' stacks.
Diffstat (limited to 'rts/StgStartup.cmm')
-rw-r--r--rts/StgStartup.cmm16
1 files changed, 8 insertions, 8 deletions
diff --git a/rts/StgStartup.cmm b/rts/StgStartup.cmm
index 122eace1f3..6d3d47f54f 100644
--- a/rts/StgStartup.cmm
+++ b/rts/StgStartup.cmm
@@ -51,13 +51,13 @@ INFO_TABLE_RET(stg_stop_thread, STOP_FRAME,
We Leave the stack looking like this:
- +----------------+
- | -------------------> return value
- +----------------+
- | stg_enter_info |
- +----------------+
+ +----------------------+
+ | -----------------------> return value
+ +----------------------+
+ | stg_dead_thread_info |
+ +----------------------+
- The stg_enter_info is just a dummy info table so that the
+ The stg_dead_thread_info is just a dummy info table so that the
garbage collector can understand the stack (there must always
be an info table on top of the stack).
*/
@@ -70,9 +70,9 @@ INFO_TABLE_RET(stg_stop_thread, STOP_FRAME,
unwind UnwindReturnReg = return;
#endif
- Sp = Sp + SIZEOF_StgStopFrame - WDS(2);
+ Sp = Sp + SIZEOF_StgStopFrame - SIZEOF_StgDeadThreadFrame;
+ Sp(0) = stg_dead_thread_info;
Sp(1) = R1;
- Sp(0) = stg_enter_info;
StgTSO_what_next(CurrentTSO) = ThreadComplete::I16;