From e27589e94c294f8a9a038cc72a1a84ca66a1eefc Mon Sep 17 00:00:00 2001 From: Roman Shaposhnik Date: Thu, 9 Jul 2026 14:47:34 -0700 Subject: [PATCH 1/2] Enabling Host-only sanitizer flags --- ggml/src/ggml-et/et-kernels/CMakeLists.txt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/ggml/src/ggml-et/et-kernels/CMakeLists.txt b/ggml/src/ggml-et/et-kernels/CMakeLists.txt index 4b6baab43ab1..a553f897a49e 100644 --- a/ggml/src/ggml-et/et-kernels/CMakeLists.txt +++ b/ggml/src/ggml-et/et-kernels/CMakeLists.txt @@ -5,6 +5,15 @@ # This keeps kernels in compile_commands.json for full IDE support. # --- RISC-V toolchain setup (scoped to this directory) --- +# Host-only sanitizer flags (-fsanitize=... from GGML_SANITIZE_*) are added at +# the ggml/src scope and would otherwise propagate here and break the baremetal +# RISC-V kernel link. Strip inherited host build flags for this directory only +# when a sanitizer build is requested. +if (GGML_SANITIZE_ADDRESS OR GGML_SANITIZE_THREAD OR GGML_SANITIZE_UNDEFINED) + set_property(DIRECTORY PROPERTY COMPILE_OPTIONS "") + set_property(DIRECTORY PROPERTY LINK_OPTIONS "") + set_property(DIRECTORY PROPERTY LINK_LIBRARIES "") +endif() set(TOOLCHAIN_DIR ${ET_PLATFORM_PATH}) include(${ET_PLATFORM_PATH}/lib/cmake/riscv64-ec-toolchain.cmake) set(CMAKE_ADDR2LINE "${TOOLCHAIN_DIR}/bin/riscv64-unknown-elf-addr2line") From b463cd183a8b1700898095bd993a9d092c235261 Mon Sep 17 00:00:00 2001 From: Roman Shaposhnik Date: Thu, 9 Jul 2026 14:47:52 -0700 Subject: [PATCH 2/2] Vibe-coded coredump fix --- ggml/src/ggml-et/ggml-et.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/ggml/src/ggml-et/ggml-et.cpp b/ggml/src/ggml-et/ggml-et.cpp index 873b1258ec22..189c46834659 100644 --- a/ggml/src/ggml-et/ggml-et.cpp +++ b/ggml/src/ggml-et/ggml-et.cpp @@ -536,7 +536,13 @@ static void ggml_backend_et_get_tensor_async(ggml_backend_t backend, const std::byte * src_ptr = static_cast(tensor->data) + offset; std::byte * dst_ptr = static_cast(data); - runtime->memcpyDeviceToHost(stream, src_ptr, dst_ptr, size, true /*barrier*/); + // The runtime performs the host-side copy on a worker thread. We must wait + // for it here: the caller may free the host destination buffer (e.g. the + // logits/output buffer during llama_context teardown) before the next + // stream-level synchronize, which would leave this copy writing into freed + // memory (heap-use-after-free). + rt::EventId event = runtime->memcpyDeviceToHost(stream, src_ptr, dst_ptr, size, true /*barrier*/); + runtime->waitForEvent(event); } static bool ggml_backend_et_cpy_tensor_async(ggml_backend_t backend_src,