shithub: sl

Download patch

ref: c214932b4ac9a978d255221bb01d8657c02f6d5a
parent: 85293c684bdb9f0f39fdf37a25ba3acc79e4b233
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Thu Apr 24 00:27:54 EDT 2025

stacktrace: protect against gc/stack shuffling

--- a/src/sl.c
+++ b/src/sl.c
@@ -909,15 +909,16 @@
 static sl_v
 _stacktrace(usize top)
 {
-	sl_v lst = sl_nil, v = sl_nil;
+	sl_v lst = sl_nil, v = sl_nil, fn = sl_nil;
 
 	sl_gc_handle(&lst);
 	sl_gc_handle(&v);
+	sl_gc_handle(&fn);
 	while(top > 0){
 		const u8int *ip1 = (void*)sl.stack[top-1];
 		int sz = sl.stack[top-2]+1;
-		sl_v *bp = sl.stack+top-4-sz;
-		sl_v fn = bp[0];
+		usize bp = top-4-sz;
+		fn = sl.stack[bp+0];
 		v = alloc_vec(sz+1, 0);
 		if(iscbuiltin(fn))
 			vec_elt(v, 0) = lst == sl_nil ? mk_ptr(sl.cpc) : fn;
@@ -928,7 +929,7 @@
 		}
 		vec_elt(v, 1) = fn;
 		for(int i = 1; i < sz; i++){
-			sl_v si = bp[i];
+			sl_v si = sl.stack[bp+i];
 			// if there's an error evaluating argument defaults some slots
 			// might be left set to sl_unbound
 			vec_elt(v, i+1) = si == sl_unbound ? sl_void : si;
@@ -936,7 +937,7 @@
 		lst = mk_cons(v, lst);
 		top = sl.stack[top-3];
 	}
-	sl_free_gc_handles(2);
+	sl_free_gc_handles(3);
 	return lst;
 }