Skip to content

Commit 8dec02c

Browse files
committed
heap: clear thread-local error trace before unmapping pools
Pre-existing latent test crash on macOS-debug, surfaced once the build matrix went green: an earlier test that took an error path populated g_error_trace (lang/eval.c), then ray_heap_destroy munmap'd the pools backing it, leaving the static pointer dangling. The next test's ray_eval_str called ray_clear_error_trace, which dereferenced the now-freed pointer and tripped AddressSanitizer. test_datalog.c datalog/agg_parse_count_scalar (line 786) ray_eval_str("(rule (wcount ?n) (count ?n weight))") -> ray_clear_error_trace -> ray_release(g_error_trace) -> SEGV cow.c:50 macOS asan unmaps freed pages so the deref crashes; Linux asan leaves them mapped, which is why ubuntu-debug stayed green. ray_heap_destroy now calls ray_clear_error_trace as the very first step, while the pools are still mapped. Forward-decl in heap.c keeps the layering intact (no #include of lang/eval.h from mem/). Pre-existing bug — not caused by the fused-correctness branch. The build-failure cascade kept the macOS-debug Test step from running until now.
1 parent b689047 commit 8dec02c

1 file changed

Lines changed: 12 additions & 0 deletions

File tree

src/mem/heap.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1180,10 +1180,22 @@ void ray_heap_init(void) {
11801180
ray_tl_heap = h;
11811181
}
11821182

1183+
/* Forward decl — released before this heap's pools are munmap'd so a
1184+
* stale thread-local trace doesn't survive the destroy and crash a
1185+
* subsequent ray_eval_str → ray_clear_error_trace call when the next
1186+
* heap takes over. Lives in src/lang/eval.c. */
1187+
extern void ray_clear_error_trace(void);
1188+
11831189
void ray_heap_destroy(void) {
11841190
ray_heap_t* h = ray_tl_heap;
11851191
if (!h) return;
11861192

1193+
/* Drop any thread-local refs into THIS heap's memory before we
1194+
* unmap its pools. Ordering matters: release while the backing
1195+
* memory is still mapped; once the for-loop below munmap's the
1196+
* pools, dereferencing g_error_trace becomes UB. */
1197+
ray_clear_error_trace();
1198+
11871199
uint16_t saved_id = h->id;
11881200

11891201
/* Unregister from global heap registry */

0 commit comments

Comments
 (0)