~ chicken-core (chicken-5) 73c083a9f04ea64f0c84eea68d1c69b22d822e50
commit 73c083a9f04ea64f0c84eea68d1c69b22d822e50
Author: Peter Bex <peter@more-magic.net>
AuthorDate: Wed Dec 28 19:11:35 2016 +0100
Commit: Christian Kellermann <ckeen@pestilenz.org>
CommitDate: Thu Dec 29 03:19:04 2016 +0100
Fix crashes in callbacks after GC (#1337).
This was caused by keeping argvector in temp stack, similar to 9eed2742.
Instead, we also copy the argvector into the stack before re-invoking
the trampoline when in a callback context, just like a regular CPS
context.
Also, fix an off-by-one in the number of arguments which
allocate_vector_2 accepts; simply passing the original argcount doesn't
allow for the extra 'mode' argument which gets added onto the front of
the stack.
Signed-off-by: Christian Kellermann <ckeen@pestilenz.org>
diff --git a/NEWS b/NEWS
index 79403b99..38af2d23 100644
--- a/NEWS
+++ b/NEWS
@@ -71,6 +71,7 @@
- Runtime system:
- "time" macro now shows peak memory usage (#1318, thanks to Kooda).
+ - Avoid crashes in ffi callbacks after GC (#1337, thanks to cosarara).
- Core libraries:
- Keywords are more consistently read/written, like symbols (#1332).
diff --git a/runtime.c b/runtime.c
index 146da1b7..bfaae1a6 100644
--- a/runtime.c
+++ b/runtime.c
@@ -1559,6 +1559,9 @@ C_word CHICKEN_run(void *toplevel)
serious_signal_occurred = 0;
if(!return_to_host) {
+ /* We must copy the argvector onto the stack, because
+ * any subsequent save() will otherwise clobber it.
+ */
int argcount = C_temporary_stack_bottom - C_temporary_stack;
C_word *p = C_alloc(argcount);
@@ -2134,8 +2137,11 @@ C_word C_fcall C_callback(C_word closure, int argc)
serious_signal_occurred = 0;
if(!callback_returned_flag) {
- C_word *p = C_temporary_stack;
-
+ /* We must copy the argvector onto the stack, because
+ * any subsequent save() will otherwise clobber it.
+ */
+ C_word *p = C_alloc(C_restart_c);
+ C_memcpy(p, C_temporary_stack, C_restart_c * sizeof(C_word));
C_temporary_stack = C_temporary_stack_bottom;
((C_proc)C_restart_trampoline)(C_restart_c, p);
}
@@ -9975,7 +9981,10 @@ void C_ccall C_allocate_vector(C_word c, C_word *av)
C_fromspace_top = C_fromspace_limit; /* trigger major GC */
C_save(C_SCHEME_TRUE);
- C_reclaim((void *)allocate_vector_2, c);
+ /* We explicitly pass 7 here, that's the number of things saved.
+ * That's the arguments, plus one additional thing: the mode.
+ */
+ C_reclaim((void *)allocate_vector_2, 7);
}
C_save(C_SCHEME_FALSE);
Trap