From ffa8e2cd5d7cf9343bc169ff3a6cebffaa7720df Mon Sep 17 00:00:00 2001 From: Yi LIU Date: Thu, 12 Feb 2026 09:24:32 +0800 Subject: [PATCH] Fix SafeHeap crash when start function calls an imported function findCalledFunctions transitively walks all functions called from the start function to determine which functions should not be instrumented. When the start function calls an imported function, the import was added to the worklist and then FindAll was called on its null body, causing an assertion failure in the walker (assert(*currp) in wasm-traversal.h). Skip imported functions in the traversal since they have no body to walk. --- src/passes/SafeHeap.cpp | 3 +++ test/lit/passes/safe-heap-start-import.wast | 28 +++++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 test/lit/passes/safe-heap-start-import.wast diff --git a/src/passes/SafeHeap.cpp b/src/passes/SafeHeap.cpp index 7ac077d7501..f81dc60bcbc 100644 --- a/src/passes/SafeHeap.cpp +++ b/src/passes/SafeHeap.cpp @@ -139,6 +139,9 @@ static std::set findCalledFunctions(Module* module, Name startFunc) { auto next = toVisit.back(); toVisit.pop_back(); auto* func = module->getFunction(next); + if (func->imported()) { + continue; + } for (auto* call : FindAll(func->body).list) { addFunction(call->target); } diff --git a/test/lit/passes/safe-heap-start-import.wast b/test/lit/passes/safe-heap-start-import.wast new file mode 100644 index 00000000000..1d32bf251bb --- /dev/null +++ b/test/lit/passes/safe-heap-start-import.wast @@ -0,0 +1,28 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited. +;; RUN: wasm-opt %s --safe-heap --enable-threads --enable-simd -S -o - | filecheck %s + +;; Test that safe-heap does not crash when the start function calls an imported +;; function. The findCalledFunctions helper transitively walks all called +;; functions from the start, and must skip imported functions which have no body. + +(module + ;; CHECK: (import "env" "some_import" (func $import)) + (import "env" "some_import" (func $import)) + ;; CHECK: (import "env" "emscripten_get_sbrk_ptr" (func $emscripten_get_sbrk_ptr (result i32))) + (import "env" "emscripten_get_sbrk_ptr" (func $emscripten_get_sbrk_ptr (result i32))) + (memory 1 1 shared) + + ;; CHECK: (start $start) + + ;; CHECK: (func $start + ;; CHECK-NEXT: (call $import) + ;; CHECK-NEXT: ) + (func $start + ;; The start function calls an imported function. Previously this would + ;; crash because findCalledFunctions would try to walk the null body of + ;; the imported function. + (call $import) + ) + + (start $start) +)