[m-rev.] diff: Fix spawn_context bug

Paul Bone paul at bone.id.au
Wed Sep 16 18:24:20 AEST 2015


Branches: upgrade_boehm

Fix spawn_context bug

In low-level C grades spawn_context attempts to use the stack of the new
context to pass the closure and thread ID to the new context once it starts
running.  The first stack slot used has a 0 offset from the stack pointer,
but the second used has a -1 offset.  If the stack pointer is at the
beginning of the memory zone (which happens sometimes but not usually, see
MR_next_offset()) then this can create an invalid memory access.  This
raises a segfault with the new version of Boehm GC.

Create a stack frame for the closure and thread ID in spawn_context.

PS: I still have another very strange bug to find & fix, so I'm not ready to
merge this branch.

library/thread.m:
    As above.
---
 library/thread.m | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/library/thread.m b/library/thread.m
index 1e1748d..0177681 100644
--- a/library/thread.m
+++ b/library/thread.m
@@ -263,8 +263,9 @@ spawn_context_2(_, Res, "", !IO) :-
     /*
     ** Store Goal and ThreadId on the top of the new context's stack.
     */
-    ctxt->MR_ctxt_sp[0] = Goal;
-    ctxt->MR_ctxt_sp[-1] = (MR_Word) ThreadId;
+    ctxt->MR_ctxt_sp += 2;
+    ctxt->MR_ctxt_sp[0] = Goal;                 /* MR_stackvar(1) */
+    ctxt->MR_ctxt_sp[-1] = (MR_Word) ThreadId;  /* MR_stackvar(2) */
 
     MR_schedule_context(ctxt);
 
@@ -439,6 +440,7 @@ INIT mercury_sys_init_thread_modules
         /* Call the closure placed the top of the stack. */
         MR_r1 = MR_stackvar(1); /* Goal */
         MR_r2 = MR_stackvar(2); /* ThreadId */
+        MR_decr_sp(2);
         MR_noprof_call(MR_ENTRY(mercury__do_call_closure_1),
             MR_LABEL(mercury__thread__spawn_end_thread));
     }
-- 
2.5.0




More information about the reviews mailing list