~ chicken-core (chicken-5) 393285a53dd00b18f2cf99bfef0d4a5cb8243a1e


commit 393285a53dd00b18f2cf99bfef0d4a5cb8243a1e
Author:     Peter Bex <peter@more-magic.net>
AuthorDate: Sat Oct 24 21:17:07 2015 +0200
Commit:     felix <felix@call-with-current-continuation.org>
CommitDate: Sun Oct 25 23:15:49 2015 +0100

    Copy thread "state vector" to a fresh argvector before invoking the trampoline function.
    
    Upon resumption of a thread from a "state vector" (rather than a
    closure/continuation), the trampoline function was passed a pointer
    right into the state vector, which doubled as an argument vector.
    
    Now that argvectors may be re-used, their slots can be trashed any
    time in the call history, depending on the exact situation.  These
    argvector slots will eventually contain temporary data which becomes
    invalid over time.  When the original state vector is then copied
    during garbage collection, the mutated slot is also copied.  When the
    Cheney algorithm traverses over this slot, it will break down because
    the data it points to is now invalid.
    
    This hopefully fixes the "random crashes" we've been seeing on
    Salmonella the last few weeks.
    
    Signed-off-by: felix <felix@call-with-current-continuation.org>

diff --git a/runtime.c b/runtime.c
index af108254..05fcd989 100644
--- a/runtime.c
+++ b/runtime.c
@@ -11528,10 +11528,17 @@ void C_ccall C_context_switch(C_word c, C_word *av)
     /* closure = av[ 0 ] */
     state = av[ 2 ],
     n = C_header_size(state) - 1,
-    adrs = C_block_item(state, 0);
+    adrs = C_block_item(state, 0),
+    *av2;
   C_proc tp = (C_proc)C_block_item(adrs,0);
 
-  tp(n, (C_word *)state + 2);
+  /* Copy argvector because it may be mutated in-place.  The state
+   * vector should not be re-invoked(?), but it can be kept alive
+   * during GC, so the mutated argvector/state slots may turn stale.
+   */
+  av2 = C_alloc(n);
+  C_memcpy(av2, (C_word *)state + 2, n * sizeof(C_word));
+  tp(n, av2);
 }
 
 
Trap