From 627ddc0e36912297d5fb92d36257e80f499bec06 Mon Sep 17 00:00:00 2001 From: Sri Latha Ayyannagari Date: Mon, 24 Aug 2026 16:36:34 -0700 Subject: [PATCH 1/7] Add XRT api for generating core dump ELF Signed-off-by: Sri Latha Ayyannagari --- src/runtime_src/core/common/api/elf_int.h | 14 ++++++ src/runtime_src/core/common/api/xrt_elf.cpp | 46 +++++++++++++++++ .../core/common/api/xrt_hw_context.cpp | 40 +++++++++++++++ .../core/include/xrt/xrt_hw_context.h | 50 +++++++++++++++++++ 4 files changed, 150 insertions(+) diff --git a/src/runtime_src/core/common/api/elf_int.h b/src/runtime_src/core/common/api/elf_int.h index c9b6825345f..173164bd79c 100644 --- a/src/runtime_src/core/common/api/elf_int.h +++ b/src/runtime_src/core/common/api/elf_int.h @@ -30,6 +30,11 @@ #include #include +// Forward declaration — full definition in xrt/xrt_hw_context.h +namespace xrt::aie { +struct coredump_meta; +} // namespace xrt::aie + namespace xrt { //////////////////////////////////////////////////////////////// @@ -542,6 +547,15 @@ get_kernel_properties_and_args(std::shared_ptr elf_impl, std::string get_filename(const xrt::elf_impl* elf_impl); +// Package a raw AIE coredump blob into an ET_CORE ELF. +// The AIE architecture is derived from the ELF's OS/ABI byte. +std::vector +make_aie_coredump_elf(const xrt::elf& elf, const std::vector& blob); + +std::vector +make_aie_coredump_elf(const xrt::elf& elf, const std::vector& blob, + const xrt::aie::coredump_meta& meta); + } // namespace xrt_core::elf_int #endif diff --git a/src/runtime_src/core/common/api/xrt_elf.cpp b/src/runtime_src/core/common/api/xrt_elf.cpp index 6783056e78e..fb0135f3544 100644 --- a/src/runtime_src/core/common/api/xrt_elf.cpp +++ b/src/runtime_src/core/common/api/xrt_elf.cpp @@ -5,10 +5,13 @@ #define XRT_CORE_COMMON_SOURCE // in same dll as core_common #include "xrt/experimental/xrt_aie.h" #include "xrt/experimental/xrt_elf.h" +#include "xrt/xrt_hw_context.h" #include "xrt/xrt_uuid.h" #include "elf_int.h" #include "elf_patcher.h" +#include "core/common/aiebu/src/cpp/elf/aie_elf_constants.h" +#include "core/common/aiebu/src/cpp/include/aiebu/aiebu_assembler.h" #include "core/common/config_reader.h" #include "core/common/error.h" #include "core/common/message.h" @@ -1661,6 +1664,49 @@ get_filename(const xrt::elf_impl* elf_impl) : ""; } +namespace { + +aiebu::aiebu_assembler::buffer_type +osabi_to_coredump_type(uint8_t os_abi) +{ + switch (os_abi) { + case aiebu::osabi_aie2p: return aiebu::aiebu_assembler::buffer_type::coredump_aie2p; + case aiebu::osabi_aie2ps: return aiebu::aiebu_assembler::buffer_type::coredump_aie2ps; + case aiebu::osabi_aie4: return aiebu::aiebu_assembler::buffer_type::coredump_aie4; + case aiebu::osabi_aie4a: return aiebu::aiebu_assembler::buffer_type::coredump_aie4a; + case aiebu::osabi_aie4z: return aiebu::aiebu_assembler::buffer_type::coredump_aie4z; + default: throw std::runtime_error("AIE coredump not supported for this ELF architecture"); + } +} + +aiebu::aie_coredump_meta +to_aiebu_meta(const xrt::aie::coredump_meta& m) +{ + return aiebu::aie_coredump_meta{ + m.timestamp_ns, m.driver_version, m.fw_version, m.device_info, + static_cast(m.ctx_status), m.uuid + }; +} + +} // namespace + +std::vector +make_aie_coredump_elf(const xrt::elf& elf, const std::vector& blob) +{ + auto buf_type = osabi_to_coredump_type(elf.get_handle()->get_os_abi()); + aiebu::aiebu_assembler a(buf_type, blob, aiebu::aiebu_assembler::no_meta); + return a.get_elf(); +} + +std::vector +make_aie_coredump_elf(const xrt::elf& elf, const std::vector& blob, + const xrt::aie::coredump_meta& meta) +{ + auto buf_type = osabi_to_coredump_type(elf.get_handle()->get_os_abi()); + aiebu::aiebu_assembler a(buf_type, blob, to_aiebu_meta(meta)); + return a.get_elf(); +} + } // xrt_core::elf_int //////////////////////////////////////////////////////////////// diff --git a/src/runtime_src/core/common/api/xrt_hw_context.cpp b/src/runtime_src/core/common/api/xrt_hw_context.cpp index 16c468b3af9..371fb4a66c8 100644 --- a/src/runtime_src/core/common/api/xrt_hw_context.cpp +++ b/src/runtime_src/core/common/api/xrt_hw_context.cpp @@ -718,6 +718,32 @@ class hw_context_impl : public std::enable_shared_from_this } } + std::vector + get_aie_coredump_elf() const + { + xrt::elf elf = [this] { + std::lock_guard lk(m_mutex); + if (m_elf_map.empty()) + throw std::runtime_error("AIE coredump ELF not available: no ELF loaded in this context"); + // All ELFs in one hw_context target the same AIE partition — any entry yields correct OS/ABI + return m_elf_map.begin()->second; + }(); + return xrt_core::elf_int::make_aie_coredump_elf(elf, get_aie_coredump()); + } + + std::vector + get_aie_coredump_elf(const xrt::aie::coredump_meta& meta) const + { + xrt::elf elf = [this] { + std::lock_guard lk(m_mutex); + if (m_elf_map.empty()) + throw std::runtime_error("AIE coredump ELF not available: no ELF loaded in this context"); + // All ELFs in one hw_context target the same AIE partition — any entry yields correct OS/ABI + return m_elf_map.begin()->second; + }(); + return xrt_core::elf_int::make_aie_coredump_elf(elf, get_aie_coredump(), meta); + } + // Returns map of kernel names to their corresponding elf files // registered with this hardware context std::map @@ -1015,6 +1041,20 @@ get_aie_coredump() const return get_handle()->get_aie_coredump(); } +std::vector +hw_context:: +get_aie_coredump_elf() const +{ + return get_handle()->get_aie_coredump_elf(); +} + +std::vector +hw_context:: +get_aie_coredump_elf(const xrt::aie::coredump_meta& meta) const +{ + return get_handle()->get_aie_coredump_elf(meta); +} + } // xrt //////////////////////////////////////////////////////////////// diff --git a/src/runtime_src/core/include/xrt/xrt_hw_context.h b/src/runtime_src/core/include/xrt/xrt_hw_context.h index 544bd6611ac..a06f24255dc 100644 --- a/src/runtime_src/core/include/xrt/xrt_hw_context.h +++ b/src/runtime_src/core/include/xrt/xrt_hw_context.h @@ -13,7 +13,31 @@ #ifdef __cplusplus +#include #include +#include +#include + +namespace xrt::aie { + +enum class context_status : uint32_t { + idle = 0, ///< Context is idle — no work queued or running + ready = 1, ///< Context is ready to run but not yet scheduled + running = 2, ///< Context is actively executing on the hardware + timeout = 3, ///< Context timed out waiting for hardware completion + error = 4, ///< Context encountered any other error +}; + +struct coredump_meta { + uint64_t timestamp_ns; ///< Capture timestamp in nanoseconds + std::string driver_version; ///< Driver version string + std::string fw_version; ///< Firmware version string + std::string device_info; ///< Device identification string + context_status ctx_status; ///< Context state at time of dump + std::string uuid; ///< UUID of the AIE ELF loaded on target +}; + +} // namespace xrt::aie // Opaque handle for internal use namespace xrt_core { @@ -357,6 +381,32 @@ class hw_context : public detail::pimpl std::vector get_aie_coredump() const; + /** + * get_aie_coredump_elf() - Returns the coredump of AIE Array as an ET_CORE ELF. + * Fetches the raw AIE dump blob and packages it into a coredump ELF. + * The AIE architecture is derived from the ELF loaded in this context. + * This function can throw. + * + * @return + * ELF bytes of the ET_CORE coredump ELF + */ + XRT_API_EXPORT + std::vector + get_aie_coredump_elf() const; + + /** + * get_aie_coredump_elf() - Returns the coredump of AIE Array as an ET_CORE ELF with metadata. + * + * @param meta + * Metadata to embed (timestamp, versions, uuid, context status) + * + * @return + * ELF bytes of the ET_CORE coredump ELF + */ + XRT_API_EXPORT + std::vector + get_aie_coredump_elf(const xrt::aie::coredump_meta& meta) const; + public: /// @cond // Undocumented internal access to low level context handle From ec9db67e29b651636add1001d698dec3a077ecda Mon Sep 17 00:00:00 2001 From: Sri Latha Ayyannagari Date: Thu, 27 Aug 2026 11:48:30 -0700 Subject: [PATCH 2/7] Address PR comments Signed-off-by: Sri Latha Ayyannagari --- src/runtime_src/core/common/api/elf_int.h | 10 +- src/runtime_src/core/common/api/xrt_elf.cpp | 26 ++-- .../core/common/api/xrt_hw_context.cpp | 52 ++++---- .../core/common/api/xrt_kernel.cpp | 3 +- .../xrt/experimental/xrt_aie_coredump.h | 122 ++++++++++++++++++ .../core/include/xrt/xrt_hw_context.h | 43 ++---- 6 files changed, 175 insertions(+), 81 deletions(-) create mode 100644 src/runtime_src/core/include/xrt/experimental/xrt_aie_coredump.h diff --git a/src/runtime_src/core/common/api/elf_int.h b/src/runtime_src/core/common/api/elf_int.h index 173164bd79c..6390efb5783 100644 --- a/src/runtime_src/core/common/api/elf_int.h +++ b/src/runtime_src/core/common/api/elf_int.h @@ -30,10 +30,7 @@ #include #include -// Forward declaration — full definition in xrt/xrt_hw_context.h -namespace xrt::aie { -struct coredump_meta; -} // namespace xrt::aie +#include "core/include/xrt/experimental/xrt_aie_coredump.h" namespace xrt { @@ -547,11 +544,8 @@ get_kernel_properties_and_args(std::shared_ptr elf_impl, std::string get_filename(const xrt::elf_impl* elf_impl); -// Package a raw AIE coredump blob into an ET_CORE ELF. +// Package a raw AIE coredump blob into an ET_CORE ELF with metadata. // The AIE architecture is derived from the ELF's OS/ABI byte. -std::vector -make_aie_coredump_elf(const xrt::elf& elf, const std::vector& blob); - std::vector make_aie_coredump_elf(const xrt::elf& elf, const std::vector& blob, const xrt::aie::coredump_meta& meta); diff --git a/src/runtime_src/core/common/api/xrt_elf.cpp b/src/runtime_src/core/common/api/xrt_elf.cpp index fb0135f3544..ef4a2b5a251 100644 --- a/src/runtime_src/core/common/api/xrt_elf.cpp +++ b/src/runtime_src/core/common/api/xrt_elf.cpp @@ -1670,12 +1670,18 @@ aiebu::aiebu_assembler::buffer_type osabi_to_coredump_type(uint8_t os_abi) { switch (os_abi) { - case aiebu::osabi_aie2p: return aiebu::aiebu_assembler::buffer_type::coredump_aie2p; - case aiebu::osabi_aie2ps: return aiebu::aiebu_assembler::buffer_type::coredump_aie2ps; - case aiebu::osabi_aie4: return aiebu::aiebu_assembler::buffer_type::coredump_aie4; - case aiebu::osabi_aie4a: return aiebu::aiebu_assembler::buffer_type::coredump_aie4a; - case aiebu::osabi_aie4z: return aiebu::aiebu_assembler::buffer_type::coredump_aie4z; - default: throw std::runtime_error("AIE coredump not supported for this ELF architecture"); + case aiebu::osabi_aie2p: + return aiebu::aiebu_assembler::buffer_type::coredump_aie2p; + case aiebu::osabi_aie2ps: + return aiebu::aiebu_assembler::buffer_type::coredump_aie2ps; + case aiebu::osabi_aie4: + return aiebu::aiebu_assembler::buffer_type::coredump_aie4; + case aiebu::osabi_aie4a: + return aiebu::aiebu_assembler::buffer_type::coredump_aie4a; + case aiebu::osabi_aie4z: + return aiebu::aiebu_assembler::buffer_type::coredump_aie4z; + default: + throw std::runtime_error("AIE coredump not supported for this ELF architecture"); } } @@ -1690,14 +1696,6 @@ to_aiebu_meta(const xrt::aie::coredump_meta& m) } // namespace -std::vector -make_aie_coredump_elf(const xrt::elf& elf, const std::vector& blob) -{ - auto buf_type = osabi_to_coredump_type(elf.get_handle()->get_os_abi()); - aiebu::aiebu_assembler a(buf_type, blob, aiebu::aiebu_assembler::no_meta); - return a.get_elf(); -} - std::vector make_aie_coredump_elf(const xrt::elf& elf, const std::vector& blob, const xrt::aie::coredump_meta& meta) diff --git a/src/runtime_src/core/common/api/xrt_hw_context.cpp b/src/runtime_src/core/common/api/xrt_hw_context.cpp index 371fb4a66c8..b63e526e406 100644 --- a/src/runtime_src/core/common/api/xrt_hw_context.cpp +++ b/src/runtime_src/core/common/api/xrt_hw_context.cpp @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -719,29 +720,41 @@ class hw_context_impl : public std::enable_shared_from_this } std::vector - get_aie_coredump_elf() const + get_aie_coredump_elf(std::optional meta) const { xrt::elf elf = [this] { std::lock_guard lk(m_mutex); if (m_elf_map.empty()) throw std::runtime_error("AIE coredump ELF not available: no ELF loaded in this context"); - // All ELFs in one hw_context target the same AIE partition — any entry yields correct OS/ABI - return m_elf_map.begin()->second; - }(); - return xrt_core::elf_int::make_aie_coredump_elf(elf, get_aie_coredump()); - } - std::vector - get_aie_coredump_elf(const xrt::aie::coredump_meta& meta) const - { - xrt::elf elf = [this] { - std::lock_guard lk(m_mutex); - if (m_elf_map.empty()) - throw std::runtime_error("AIE coredump ELF not available: no ELF loaded in this context"); // All ELFs in one hw_context target the same AIE partition — any entry yields correct OS/ABI return m_elf_map.begin()->second; }(); - return xrt_core::elf_int::make_aie_coredump_elf(elf, get_aie_coredump(), meta); + + if (!meta) { + xrt::aie::coredump_meta m{}; + m.timestamp_ns = xrt_core::time_ns(); + m.ctx_status = xrt::aie::context_status::timeout; //default + m.uuid = elf.get_cfg_uuid().to_string(); + + try { + auto fw = xrt_core::device_query( + m_core_device.get(), + xrt_core::query::firmware_version::firmware_type::npu_firmware); + m.fw_version = std::to_string(fw.major) + "." + std::to_string(fw.minor) + + "." + std::to_string(fw.patch) + "." + std::to_string(fw.build); + } + catch (const std::exception&) { /* leave empty if not supported */ } + + try { + m.device_info = xrt_core::device_query(m_core_device.get()); + } + catch (const std::exception&) { /* leave empty if not supported */ } + + meta = std::move(m); + } + + return xrt_core::elf_int::make_aie_coredump_elf(elf, get_aie_coredump(), *meta); } // Returns map of kernel names to their corresponding elf files @@ -1043,16 +1056,9 @@ get_aie_coredump() const std::vector hw_context:: -get_aie_coredump_elf() const -{ - return get_handle()->get_aie_coredump_elf(); -} - -std::vector -hw_context:: -get_aie_coredump_elf(const xrt::aie::coredump_meta& meta) const +get_aie_coredump_elf(std::optional meta) const { - return get_handle()->get_aie_coredump_elf(meta); + return get_handle()->get_aie_coredump_elf(std::move(meta)); } } // xrt diff --git a/src/runtime_src/core/common/api/xrt_kernel.cpp b/src/runtime_src/core/common/api/xrt_kernel.cpp index ae4bdfbfdf1..ede19f5874a 100644 --- a/src/runtime_src/core/common/api/xrt_kernel.cpp +++ b/src/runtime_src/core/common/api/xrt_kernel.cpp @@ -3167,12 +3167,13 @@ class run_impl : public std::enable_shared_from_this try { auto hwctx = kernel->get_hw_context(); - auto core = hwctx.get_aie_coredump(); // may throw + auto core = hwctx.get_aie_coredump_elf(); // may throw std::ofstream ostr{file, std::ios::binary}; if (!ostr) throw std::runtime_error("Could not open '" + file + "' for writing"); ostr.write(core.data(), static_cast(core.size())); + ostr.flush(); // flush before abort — destructors do not run after std::abort() std::abort(); } catch (const std::exception& ex) { diff --git a/src/runtime_src/core/include/xrt/experimental/xrt_aie_coredump.h b/src/runtime_src/core/include/xrt/experimental/xrt_aie_coredump.h new file mode 100644 index 00000000000..852763e418b --- /dev/null +++ b/src/runtime_src/core/include/xrt/experimental/xrt_aie_coredump.h @@ -0,0 +1,122 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright (C) 2025 Advanced Micro Devices, Inc. All rights reserved. +#ifndef XRT_AIE_COREDUMP_H_ +#define XRT_AIE_COREDUMP_H_ + +#ifdef __cplusplus + +#include +#include + +namespace xrt::aie { + +/** + * enum class context_status - State of an AIE hardware context at the time + * a coredump was captured. + * + * This enum is embedded in coredump_meta and describes what the hardware + * context was doing when the dump was triggered. It mirrors the internal + * aiebu::aie_context_status enum and must stay in sync with it. + * + * @var idle + * The context has no work queued or executing on the hardware. + * This is the default value used when the status cannot be determined. + * + * @var ready + * The context has been prepared and is waiting to be scheduled onto + * the hardware but has not yet started executing. + * + * @var running + * The context is actively executing on the AIE hardware at the time + * the coredump was captured. + * + * @var timeout + * The context timed out while waiting for hardware to complete an + * operation. The coredump was likely captured as part of timeout + * error handling. + * + * @var error + * The context encountered an error other than a timeout (e.g. a + * hardware fault or driver error). + */ +enum class context_status : uint32_t { + idle = 0, + ready = 1, + running = 2, + timeout = 3, + error = 4, +}; + +/** + * struct coredump_meta - Metadata embedded in an AIE ET_CORE coredump ELF. + * + * This structure carries diagnostic metadata that is written into the + * coredump ELF produced by xrt::hw_context::get_aie_coredump_elf(). + * The metadata is stored in a dedicated ELF note section alongside the + * raw AIE register/memory dump, allowing post-mortem tools to correlate + * the dump with the system state at capture time. + * + * Callers may supply a fully populated coredump_meta to + * get_aie_coredump_elf(); if none is provided, XRT populates the fields + * it can determine automatically (timestamp, firmware version, device + * info, ELF UUID) and defaults context_status to idle. + * + * All string fields are UTF-8 and may be empty if the information is + * not available on a given platform. + */ +struct coredump_meta { + /** + * Monotonic capture timestamp in nanoseconds since system epoch. + * Populated automatically from the system clock when metadata is + * built internally. Callers that supply their own coredump_meta + * should set this to the time the error or timeout was detected. + */ + uint64_t timestamp_ns = 0; + + /** + * Human-readable driver version string + * May be empty if the driver does not expose version information + * on this platform. + */ + std::string driver_version; + + /** + * Human-readable NPU/AIE firmware version string + * (e.g. "major.minor.patch.build"). + * Populated automatically from the firmware_version device query + * when metadata is built internally. May be empty if the platform + * does not support the query. + */ + std::string fw_version; + + /** + * Device identification string + * Populated automatically from device query when + * metadata is built internally. May be empty if not available. + */ + std::string device_info; + + /** + * State of the AIE hardware context at the time of the dump. + * See xrt::aie::context_status for valid values. + * Defaults to context_status::timeout when metadata is built internally, + * as the driver does not currently expose context state. + */ + context_status ctx_status = context_status::timeout; + + /** + * UUID string of the AIE configuration ELF that was loaded into this + * hardware context (e.g. "550e8400-e29b-41d4-a716-446655440000"). + * Populated automatically from the loaded ELF when metadata is built + * internally. + */ + std::string uuid; +}; + +} // namespace xrt::aie + +#else +# error xrt_aie_coredump.h is only implemented for C++ +#endif // __cplusplus + +#endif diff --git a/src/runtime_src/core/include/xrt/xrt_hw_context.h b/src/runtime_src/core/include/xrt/xrt_hw_context.h index a06f24255dc..615d4624fa3 100644 --- a/src/runtime_src/core/include/xrt/xrt_hw_context.h +++ b/src/runtime_src/core/include/xrt/xrt_hw_context.h @@ -9,36 +9,16 @@ #include "xrt/xrt_device.h" #include "xrt/xrt_uuid.h" +#include "xrt/experimental/xrt_aie_coredump.h" #include "xrt/experimental/xrt_elf.h" #ifdef __cplusplus -#include #include +#include #include #include -namespace xrt::aie { - -enum class context_status : uint32_t { - idle = 0, ///< Context is idle — no work queued or running - ready = 1, ///< Context is ready to run but not yet scheduled - running = 2, ///< Context is actively executing on the hardware - timeout = 3, ///< Context timed out waiting for hardware completion - error = 4, ///< Context encountered any other error -}; - -struct coredump_meta { - uint64_t timestamp_ns; ///< Capture timestamp in nanoseconds - std::string driver_version; ///< Driver version string - std::string fw_version; ///< Firmware version string - std::string device_info; ///< Device identification string - context_status ctx_status; ///< Context state at time of dump - std::string uuid; ///< UUID of the AIE ELF loaded on target -}; - -} // namespace xrt::aie - // Opaque handle for internal use namespace xrt_core { class hwctx_handle; @@ -382,30 +362,23 @@ class hw_context : public detail::pimpl get_aie_coredump() const; /** - * get_aie_coredump_elf() - Returns the coredump of AIE Array as an ET_CORE ELF. + * get_aie_coredump_elf() - Returns the coredump of AIE Array as an ET_CORE ELF with metadata. * Fetches the raw AIE dump blob and packages it into a coredump ELF. * The AIE architecture is derived from the ELF loaded in this context. + * Metadata (timestamp, versions, device info, uuid) is always embedded. + * If @meta is provided it is used as-is; otherwise metadata is built + * internally from the hw_context and device. * This function can throw. * - * @return - * ELF bytes of the ET_CORE coredump ELF - */ - XRT_API_EXPORT - std::vector - get_aie_coredump_elf() const; - - /** - * get_aie_coredump_elf() - Returns the coredump of AIE Array as an ET_CORE ELF with metadata. - * * @param meta - * Metadata to embed (timestamp, versions, uuid, context status) + * Optional metadata to embed. When omitted, metadata is populated internally. * * @return * ELF bytes of the ET_CORE coredump ELF */ XRT_API_EXPORT std::vector - get_aie_coredump_elf(const xrt::aie::coredump_meta& meta) const; + get_aie_coredump_elf(std::optional meta = std::nullopt) const; public: /// @cond From 4faa92dbe456994d08c91600fef801d49c03c377 Mon Sep 17 00:00:00 2001 From: Sri Latha Ayyannagari Date: Thu, 27 Aug 2026 16:36:02 -0700 Subject: [PATCH 3/7] Address PR comments Signed-off-by: Sri Latha Ayyannagari --- src/runtime_src/core/common/api/elf_int.h | 6 +- src/runtime_src/core/common/api/xrt_elf.cpp | 56 ++++++-- .../core/common/api/xrt_hw_context.cpp | 33 +---- .../xrt/experimental/xrt_aie_coredump.h | 122 ------------------ .../core/include/xrt/xrt_hw_context.h | 14 +- 5 files changed, 58 insertions(+), 173 deletions(-) delete mode 100644 src/runtime_src/core/include/xrt/experimental/xrt_aie_coredump.h diff --git a/src/runtime_src/core/common/api/elf_int.h b/src/runtime_src/core/common/api/elf_int.h index 6390efb5783..5d977b5d2cf 100644 --- a/src/runtime_src/core/common/api/elf_int.h +++ b/src/runtime_src/core/common/api/elf_int.h @@ -30,7 +30,7 @@ #include #include -#include "core/include/xrt/experimental/xrt_aie_coredump.h" +namespace xrt_core { class device; } namespace xrt { @@ -545,10 +545,12 @@ std::string get_filename(const xrt::elf_impl* elf_impl); // Package a raw AIE coredump blob into an ET_CORE ELF with metadata. +// Metadata (timestamp, firmware version, device info, context status, UUID) +// is built internally by querying device and the loaded ELF. // The AIE architecture is derived from the ELF's OS/ABI byte. std::vector make_aie_coredump_elf(const xrt::elf& elf, const std::vector& blob, - const xrt::aie::coredump_meta& meta); + const xrt_core::device* device, uint32_t slot); } // namespace xrt_core::elf_int diff --git a/src/runtime_src/core/common/api/xrt_elf.cpp b/src/runtime_src/core/common/api/xrt_elf.cpp index ef4a2b5a251..b843aa7603f 100644 --- a/src/runtime_src/core/common/api/xrt_elf.cpp +++ b/src/runtime_src/core/common/api/xrt_elf.cpp @@ -13,8 +13,11 @@ #include "core/common/aiebu/src/cpp/elf/aie_elf_constants.h" #include "core/common/aiebu/src/cpp/include/aiebu/aiebu_assembler.h" #include "core/common/config_reader.h" +#include "core/common/device.h" #include "core/common/error.h" #include "core/common/message.h" +#include "core/common/query_requests.h" +#include "core/common/time.h" #include "core/common/trace.h" #include "core/common/xclbin_parser.h" #include "core/common/runner/capture.h" @@ -1685,23 +1688,54 @@ osabi_to_coredump_type(uint8_t os_abi) } } -aiebu::aie_coredump_meta -to_aiebu_meta(const xrt::aie::coredump_meta& m) -{ - return aiebu::aie_coredump_meta{ - m.timestamp_ns, m.driver_version, m.fw_version, m.device_info, - static_cast(m.ctx_status), m.uuid - }; -} - } // namespace std::vector make_aie_coredump_elf(const xrt::elf& elf, const std::vector& blob, - const xrt::aie::coredump_meta& meta) + const xrt_core::device* device, uint32_t slot) { + // Fail fast: verify arch is supported before doing any device queries or blob fetch auto buf_type = osabi_to_coredump_type(elf.get_handle()->get_os_abi()); - aiebu::aiebu_assembler a(buf_type, blob, to_aiebu_meta(meta)); + + aiebu::aie_coredump_meta meta{}; + meta.timestamp_ns = xrt_core::time_ns(); + meta.uuid = elf.get_cfg_uuid().to_string(); + + try { + auto data = xrt_core::device_query(device); + auto islot = static_cast(slot); + for (const auto& entry : data) { + if (std::stoi(entry.metadata.id) == islot) { + meta.context_status = entry.is_suspended + ? aiebu::aie_context_status::idle + : aiebu::aie_context_status::running; + break; + } + } + } + catch (const std::exception&) { + /* leave as default idle if query not supported */ + } + + try { + auto fw = xrt_core::device_query( + device, + xrt_core::query::firmware_version::firmware_type::npu_firmware); + meta.fw_version = std::to_string(fw.major) + "." + std::to_string(fw.minor) + + "." + std::to_string(fw.patch) + "." + std::to_string(fw.build); + } + catch (const std::exception&) { + /* leave empty if not supported */ + } + + try { + meta.device_info = xrt_core::device_query(device); + } + catch (const std::exception&) { + /* leave empty if not supported */ + } + + aiebu::aiebu_assembler a(buf_type, blob, meta); return a.get_elf(); } diff --git a/src/runtime_src/core/common/api/xrt_hw_context.cpp b/src/runtime_src/core/common/api/xrt_hw_context.cpp index b63e526e406..26c7995e4df 100644 --- a/src/runtime_src/core/common/api/xrt_hw_context.cpp +++ b/src/runtime_src/core/common/api/xrt_hw_context.cpp @@ -33,7 +33,6 @@ #include #include #include -#include #include #include #include @@ -720,7 +719,7 @@ class hw_context_impl : public std::enable_shared_from_this } std::vector - get_aie_coredump_elf(std::optional meta) const + get_aie_coredump_elf() const { xrt::elf elf = [this] { std::lock_guard lk(m_mutex); @@ -731,30 +730,8 @@ class hw_context_impl : public std::enable_shared_from_this return m_elf_map.begin()->second; }(); - if (!meta) { - xrt::aie::coredump_meta m{}; - m.timestamp_ns = xrt_core::time_ns(); - m.ctx_status = xrt::aie::context_status::timeout; //default - m.uuid = elf.get_cfg_uuid().to_string(); - - try { - auto fw = xrt_core::device_query( - m_core_device.get(), - xrt_core::query::firmware_version::firmware_type::npu_firmware); - m.fw_version = std::to_string(fw.major) + "." + std::to_string(fw.minor) - + "." + std::to_string(fw.patch) + "." + std::to_string(fw.build); - } - catch (const std::exception&) { /* leave empty if not supported */ } - - try { - m.device_info = xrt_core::device_query(m_core_device.get()); - } - catch (const std::exception&) { /* leave empty if not supported */ } - - meta = std::move(m); - } - - return xrt_core::elf_int::make_aie_coredump_elf(elf, get_aie_coredump(), *meta); + return xrt_core::elf_int::make_aie_coredump_elf( + elf, get_aie_coredump(), m_core_device.get(), m_hdl->get_slotidx()); } // Returns map of kernel names to their corresponding elf files @@ -1056,9 +1033,9 @@ get_aie_coredump() const std::vector hw_context:: -get_aie_coredump_elf(std::optional meta) const +get_aie_coredump_elf() const { - return get_handle()->get_aie_coredump_elf(std::move(meta)); + return get_handle()->get_aie_coredump_elf(); } } // xrt diff --git a/src/runtime_src/core/include/xrt/experimental/xrt_aie_coredump.h b/src/runtime_src/core/include/xrt/experimental/xrt_aie_coredump.h deleted file mode 100644 index 852763e418b..00000000000 --- a/src/runtime_src/core/include/xrt/experimental/xrt_aie_coredump.h +++ /dev/null @@ -1,122 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright (C) 2025 Advanced Micro Devices, Inc. All rights reserved. -#ifndef XRT_AIE_COREDUMP_H_ -#define XRT_AIE_COREDUMP_H_ - -#ifdef __cplusplus - -#include -#include - -namespace xrt::aie { - -/** - * enum class context_status - State of an AIE hardware context at the time - * a coredump was captured. - * - * This enum is embedded in coredump_meta and describes what the hardware - * context was doing when the dump was triggered. It mirrors the internal - * aiebu::aie_context_status enum and must stay in sync with it. - * - * @var idle - * The context has no work queued or executing on the hardware. - * This is the default value used when the status cannot be determined. - * - * @var ready - * The context has been prepared and is waiting to be scheduled onto - * the hardware but has not yet started executing. - * - * @var running - * The context is actively executing on the AIE hardware at the time - * the coredump was captured. - * - * @var timeout - * The context timed out while waiting for hardware to complete an - * operation. The coredump was likely captured as part of timeout - * error handling. - * - * @var error - * The context encountered an error other than a timeout (e.g. a - * hardware fault or driver error). - */ -enum class context_status : uint32_t { - idle = 0, - ready = 1, - running = 2, - timeout = 3, - error = 4, -}; - -/** - * struct coredump_meta - Metadata embedded in an AIE ET_CORE coredump ELF. - * - * This structure carries diagnostic metadata that is written into the - * coredump ELF produced by xrt::hw_context::get_aie_coredump_elf(). - * The metadata is stored in a dedicated ELF note section alongside the - * raw AIE register/memory dump, allowing post-mortem tools to correlate - * the dump with the system state at capture time. - * - * Callers may supply a fully populated coredump_meta to - * get_aie_coredump_elf(); if none is provided, XRT populates the fields - * it can determine automatically (timestamp, firmware version, device - * info, ELF UUID) and defaults context_status to idle. - * - * All string fields are UTF-8 and may be empty if the information is - * not available on a given platform. - */ -struct coredump_meta { - /** - * Monotonic capture timestamp in nanoseconds since system epoch. - * Populated automatically from the system clock when metadata is - * built internally. Callers that supply their own coredump_meta - * should set this to the time the error or timeout was detected. - */ - uint64_t timestamp_ns = 0; - - /** - * Human-readable driver version string - * May be empty if the driver does not expose version information - * on this platform. - */ - std::string driver_version; - - /** - * Human-readable NPU/AIE firmware version string - * (e.g. "major.minor.patch.build"). - * Populated automatically from the firmware_version device query - * when metadata is built internally. May be empty if the platform - * does not support the query. - */ - std::string fw_version; - - /** - * Device identification string - * Populated automatically from device query when - * metadata is built internally. May be empty if not available. - */ - std::string device_info; - - /** - * State of the AIE hardware context at the time of the dump. - * See xrt::aie::context_status for valid values. - * Defaults to context_status::timeout when metadata is built internally, - * as the driver does not currently expose context state. - */ - context_status ctx_status = context_status::timeout; - - /** - * UUID string of the AIE configuration ELF that was loaded into this - * hardware context (e.g. "550e8400-e29b-41d4-a716-446655440000"). - * Populated automatically from the loaded ELF when metadata is built - * internally. - */ - std::string uuid; -}; - -} // namespace xrt::aie - -#else -# error xrt_aie_coredump.h is only implemented for C++ -#endif // __cplusplus - -#endif diff --git a/src/runtime_src/core/include/xrt/xrt_hw_context.h b/src/runtime_src/core/include/xrt/xrt_hw_context.h index 615d4624fa3..56a734c9a0e 100644 --- a/src/runtime_src/core/include/xrt/xrt_hw_context.h +++ b/src/runtime_src/core/include/xrt/xrt_hw_context.h @@ -9,13 +9,11 @@ #include "xrt/xrt_device.h" #include "xrt/xrt_uuid.h" -#include "xrt/experimental/xrt_aie_coredump.h" #include "xrt/experimental/xrt_elf.h" #ifdef __cplusplus #include -#include #include #include @@ -362,23 +360,19 @@ class hw_context : public detail::pimpl get_aie_coredump() const; /** - * get_aie_coredump_elf() - Returns the coredump of AIE Array as an ET_CORE ELF with metadata. + * get_aie_coredump_elf() - Returns the coredump of AIE Array as an ET_CORE ELF. * Fetches the raw AIE dump blob and packages it into a coredump ELF. * The AIE architecture is derived from the ELF loaded in this context. - * Metadata (timestamp, versions, device info, uuid) is always embedded. - * If @meta is provided it is used as-is; otherwise metadata is built - * internally from the hw_context and device. + * Metadata (timestamp, firmware version, device info, ELF UUID) is always + * embedded and populated internally from the hw_context and device. * This function can throw. * - * @param meta - * Optional metadata to embed. When omitted, metadata is populated internally. - * * @return * ELF bytes of the ET_CORE coredump ELF */ XRT_API_EXPORT std::vector - get_aie_coredump_elf(std::optional meta = std::nullopt) const; + get_aie_coredump_elf() const; public: /// @cond From 6eb994fab12a4e79a402d0bb1d0ed701aeb27bac Mon Sep 17 00:00:00 2001 From: Sri Latha Ayyannagari Date: Fri, 28 Aug 2026 00:09:34 -0700 Subject: [PATCH 4/7] fix driver info in metadata Signed-off-by: Sri Latha Ayyannagari --- src/runtime_src/core/common/api/xrt_elf.cpp | 30 +++++++++++++++++-- .../core/common/api/xrt_kernel.cpp | 6 ++-- 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/src/runtime_src/core/common/api/xrt_elf.cpp b/src/runtime_src/core/common/api/xrt_elf.cpp index b843aa7603f..44c902ebe6e 100644 --- a/src/runtime_src/core/common/api/xrt_elf.cpp +++ b/src/runtime_src/core/common/api/xrt_elf.cpp @@ -17,7 +17,7 @@ #include "core/common/error.h" #include "core/common/message.h" #include "core/common/query_requests.h" -#include "core/common/time.h" +#include "core/common/system.h" #include "core/common/trace.h" #include "core/common/xclbin_parser.h" #include "core/common/runner/capture.h" @@ -25,6 +25,7 @@ #include #include +#include #include #include #include @@ -1698,9 +1699,34 @@ make_aie_coredump_elf(const xrt::elf& elf, const std::vector& blob, auto buf_type = osabi_to_coredump_type(elf.get_handle()->get_os_abi()); aiebu::aie_coredump_meta meta{}; - meta.timestamp_ns = xrt_core::time_ns(); + meta.timestamp_ns = static_cast( + std::chrono::duration_cast( + std::chrono::system_clock::now().time_since_epoch()).count()); meta.uuid = elf.get_cfg_uuid().to_string(); + try { + boost::property_tree::ptree pt_xrt; + xrt_core::get_driver_info(pt_xrt); + std::string drv_str; + if (const auto drivers = pt_xrt.get_child_optional("drivers")) { + for (const auto& kv : *drivers) { + const auto& drv = kv.second; + auto name = drv.get("name", ""); + auto ver = drv.get("version", ""); + if (!name.empty() && !ver.empty() && ver != "unknown") { + if (!drv_str.empty()) + drv_str += "; "; + drv_str += name + " " + ver; + } + } + } + meta.driver_version = drv_str; + } + catch (const std::exception&) { + /* leave empty if not available */ + } + + try { auto data = xrt_core::device_query(device); auto islot = static_cast(slot); diff --git a/src/runtime_src/core/common/api/xrt_kernel.cpp b/src/runtime_src/core/common/api/xrt_kernel.cpp index ede19f5874a..db28b87530f 100644 --- a/src/runtime_src/core/common/api/xrt_kernel.cpp +++ b/src/runtime_src/core/common/api/xrt_kernel.cpp @@ -3154,7 +3154,9 @@ class run_impl : public std::enable_shared_from_this } // abort_coredump_or_noop() - AIE coredump if enabled - // Dump core and abort, or do nothing. + // Write AIE coredump ELF to the configured file and return. + // The caller proceeds to throw aie_error so the normal exception message + // is printed. void abort_coredump_or_noop(ert_cmd_state state) const { @@ -3173,8 +3175,6 @@ class run_impl : public std::enable_shared_from_this if (!ostr) throw std::runtime_error("Could not open '" + file + "' for writing"); ostr.write(core.data(), static_cast(core.size())); - ostr.flush(); // flush before abort — destructors do not run after std::abort() - std::abort(); } catch (const std::exception& ex) { xrt_core::send_exception_message(std::string("Failed to create core dump: ") + ex.what()); From a5c4ec7732d7db576ac92c38033cbf8e9152f2d5 Mon Sep 17 00:00:00 2001 From: Sri Latha Ayyannagari Date: Fri, 28 Aug 2026 14:51:01 -0700 Subject: [PATCH 5/7] Address PR comments Signed-off-by: Sri Latha Ayyannagari --- src/runtime_src/core/common/api/elf_int.h | 14 +++++++--- .../core/common/api/hw_context_int.h | 9 +++++++ src/runtime_src/core/common/api/xrt_elf.cpp | 27 +++++++++---------- .../core/common/api/xrt_hw_context.cpp | 16 ++++++++--- .../core/common/api/xrt_kernel.cpp | 18 ++++++++++--- 5 files changed, 59 insertions(+), 25 deletions(-) diff --git a/src/runtime_src/core/common/api/elf_int.h b/src/runtime_src/core/common/api/elf_int.h index 5d977b5d2cf..e64d4b2df1d 100644 --- a/src/runtime_src/core/common/api/elf_int.h +++ b/src/runtime_src/core/common/api/elf_int.h @@ -545,12 +545,18 @@ std::string get_filename(const xrt::elf_impl* elf_impl); // Package a raw AIE coredump blob into an ET_CORE ELF with metadata. -// Metadata (timestamp, firmware version, device info, context status, UUID) -// is built internally by querying device and the loaded ELF. -// The AIE architecture is derived from the ELF's OS/ABI byte. +// Metadata (timestamp, firmware version, device info, context status) is built +// internally by querying the device. The AIE architecture is derived from the +// ELF's OS/ABI byte. +// +// uuid: UUID to embed in the coredump metadata. Pass the UUID of the specific +// ELF that caused the fault (e.g. the timed-out run's ELF). Pass empty string +// when no single ELF is attributable — e.g. a partition-level dump triggered +// from the public API where multiple ELFs may be loaded. std::vector make_aie_coredump_elf(const xrt::elf& elf, const std::vector& blob, - const xrt_core::device* device, uint32_t slot); + const xrt_core::device* device, uint32_t slot, + const std::string& uuid = ""); } // namespace xrt_core::elf_int diff --git a/src/runtime_src/core/common/api/hw_context_int.h b/src/runtime_src/core/common/api/hw_context_int.h index 107ac134f64..5284df74352 100644 --- a/src/runtime_src/core/common/api/hw_context_int.h +++ b/src/runtime_src/core/common/api/hw_context_int.h @@ -100,6 +100,15 @@ XRT_CORE_COMMON_EXPORT std::map get_elf_map(const xrt::hw_context& hwctx); +// get_aie_coredump_elf() - Package AIE coredump for a specific faulting ELF +// +// Use this overload when the caller knows exactly which ELF caused the fault +// (e.g. abort_coredump_or_noop passes the ELF of the timed-out run). +// The UUID embedded in the coredump metadata is taken from the provided ELF. +// The raw AIE dump blob is fetched internally from the hw_context. +std::vector +get_aie_coredump_elf(const xrt::hw_context& hwctx, const xrt::elf& elf); + // Get the configuration parameter / QoS map from the hw context. // The returned map contains key-value pairs // key: string, value: uint32_t for both QoS-related settings and diff --git a/src/runtime_src/core/common/api/xrt_elf.cpp b/src/runtime_src/core/common/api/xrt_elf.cpp index 44c902ebe6e..21cc4282bbd 100644 --- a/src/runtime_src/core/common/api/xrt_elf.cpp +++ b/src/runtime_src/core/common/api/xrt_elf.cpp @@ -1668,8 +1668,6 @@ get_filename(const xrt::elf_impl* elf_impl) : ""; } -namespace { - aiebu::aiebu_assembler::buffer_type osabi_to_coredump_type(uint8_t os_abi) { @@ -1689,20 +1687,19 @@ osabi_to_coredump_type(uint8_t os_abi) } } -} // namespace - std::vector make_aie_coredump_elf(const xrt::elf& elf, const std::vector& blob, - const xrt_core::device* device, uint32_t slot) + const xrt_core::device* device, uint32_t slot, + const std::string& uuid) { - // Fail fast: verify arch is supported before doing any device queries or blob fetch + // Fail fast: verify arch is supported before doing any device queries. auto buf_type = osabi_to_coredump_type(elf.get_handle()->get_os_abi()); aiebu::aie_coredump_meta meta{}; meta.timestamp_ns = static_cast( std::chrono::duration_cast( std::chrono::system_clock::now().time_since_epoch()).count()); - meta.uuid = elf.get_cfg_uuid().to_string(); + meta.uuid = uuid; try { boost::property_tree::ptree pt_xrt; @@ -1716,6 +1713,7 @@ make_aie_coredump_elf(const xrt::elf& elf, const std::vector& blob, if (!name.empty() && !ver.empty() && ver != "unknown") { if (!drv_str.empty()) drv_str += "; "; + drv_str += name + " " + ver; } } @@ -1726,17 +1724,18 @@ make_aie_coredump_elf(const xrt::elf& elf, const std::vector& blob, /* leave empty if not available */ } - try { auto data = xrt_core::device_query(device); auto islot = static_cast(slot); + for (const auto& entry : data) { - if (std::stoi(entry.metadata.id) == islot) { - meta.context_status = entry.is_suspended - ? aiebu::aie_context_status::idle - : aiebu::aie_context_status::running; - break; - } + if (std::stoi(entry.metadata.id) != islot) + continue; + + meta.context_status = entry.is_suspended + ? aiebu::aie_context_status::idle + : aiebu::aie_context_status::running; + break; } } catch (const std::exception&) { diff --git a/src/runtime_src/core/common/api/xrt_hw_context.cpp b/src/runtime_src/core/common/api/xrt_hw_context.cpp index 26c7995e4df..d24b3e04423 100644 --- a/src/runtime_src/core/common/api/xrt_hw_context.cpp +++ b/src/runtime_src/core/common/api/xrt_hw_context.cpp @@ -718,6 +718,8 @@ class hw_context_impl : public std::enable_shared_from_this } } + // Public-API path — picks any ELF for OS/ABI; UUID is left empty because + // no single ELF is attributable for a partition-level dump. std::vector get_aie_coredump_elf() const { @@ -725,13 +727,11 @@ class hw_context_impl : public std::enable_shared_from_this std::lock_guard lk(m_mutex); if (m_elf_map.empty()) throw std::runtime_error("AIE coredump ELF not available: no ELF loaded in this context"); - - // All ELFs in one hw_context target the same AIE partition — any entry yields correct OS/ABI return m_elf_map.begin()->second; }(); return xrt_core::elf_int::make_aie_coredump_elf( - elf, get_aie_coredump(), m_core_device.get(), m_hdl->get_slotidx()); + elf, get_aie_coredump(), m_core_device.get(), m_hdl->get_slotidx(), ""); } // Returns map of kernel names to their corresponding elf files @@ -874,6 +874,16 @@ append_dtrace_result(const xrt::hw_context& hwctx, hwctx.get_handle()->append_dtrace_result(key, result_json); } +std::vector +get_aie_coredump_elf(const xrt::hw_context& hwctx, const xrt::elf& elf) +{ + auto* impl = hwctx.get_handle().get(); + return xrt_core::elf_int::make_aie_coredump_elf( + elf, impl->get_aie_coredump(), impl->get_core_device().get(), + static_cast(static_cast(hwctx)->get_slotidx()), + elf.get_cfg_uuid().to_string()); +} + } // xrt_core::hw_context_int //////////////////////////////////////////////////////////////// diff --git a/src/runtime_src/core/common/api/xrt_kernel.cpp b/src/runtime_src/core/common/api/xrt_kernel.cpp index db28b87530f..8cd040abc67 100644 --- a/src/runtime_src/core/common/api/xrt_kernel.cpp +++ b/src/runtime_src/core/common/api/xrt_kernel.cpp @@ -3154,9 +3154,10 @@ class run_impl : public std::enable_shared_from_this } // abort_coredump_or_noop() - AIE coredump if enabled - // Write AIE coredump ELF to the configured file and return. - // The caller proceeds to throw aie_error so the normal exception message - // is printed. + // Write AIE coredump ELF to the configured file then abort. + // std::abort() ensures the OS reclaims driver resources (hw_context, hardware + // state) after a timeout. Users who set xrt.ini to capture AIE coredump + // have already observed the timeout exception on a prior run. void abort_coredump_or_noop(ert_cmd_state state) const { @@ -3169,12 +3170,21 @@ class run_impl : public std::enable_shared_from_this try { auto hwctx = kernel->get_hw_context(); - auto core = hwctx.get_aie_coredump_elf(); // may throw + // Use the ELF from this run's own module + // Each ELF has its own UUID; using the run's module ensures the + // correct UUID is embedded in the coredump metadata. + if (!m_module) + throw std::runtime_error("AIE coredump ELF not available: no ELF associated with this run"); + auto elf = xrt::elf{xrt_core::module_int::get_elf_handle(m_module)}; + + auto core = xrt_core::hw_context_int::get_aie_coredump_elf(hwctx, elf); std::ofstream ostr{file, std::ios::binary}; if (!ostr) throw std::runtime_error("Could not open '" + file + "' for writing"); ostr.write(core.data(), static_cast(core.size())); + ostr.flush(); // flush before abort — destructors do not run after std::abort() + std::abort(); } catch (const std::exception& ex) { xrt_core::send_exception_message(std::string("Failed to create core dump: ") + ex.what()); From ca1e98ef436251f28c1293665dc636ccb76e33da Mon Sep 17 00:00:00 2001 From: Sri Latha Ayyannagari Date: Fri, 28 Aug 2026 17:24:49 -0700 Subject: [PATCH 6/7] add new line Signed-off-by: Sri Latha Ayyannagari --- src/runtime_src/core/common/api/xrt_kernel.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/runtime_src/core/common/api/xrt_kernel.cpp b/src/runtime_src/core/common/api/xrt_kernel.cpp index 8cd040abc67..1a6b2ef45ef 100644 --- a/src/runtime_src/core/common/api/xrt_kernel.cpp +++ b/src/runtime_src/core/common/api/xrt_kernel.cpp @@ -3175,6 +3175,7 @@ class run_impl : public std::enable_shared_from_this // correct UUID is embedded in the coredump metadata. if (!m_module) throw std::runtime_error("AIE coredump ELF not available: no ELF associated with this run"); + auto elf = xrt::elf{xrt_core::module_int::get_elf_handle(m_module)}; auto core = xrt_core::hw_context_int::get_aie_coredump_elf(hwctx, elf); @@ -3182,6 +3183,7 @@ class run_impl : public std::enable_shared_from_this std::ofstream ostr{file, std::ios::binary}; if (!ostr) throw std::runtime_error("Could not open '" + file + "' for writing"); + ostr.write(core.data(), static_cast(core.size())); ostr.flush(); // flush before abort — destructors do not run after std::abort() std::abort(); From 08078bab5746f54d0e43f3bb19e5684013ba4d97 Mon Sep 17 00:00:00 2001 From: Sri Latha Ayyannagari Date: Sat, 29 Aug 2026 23:31:07 -0700 Subject: [PATCH 7/7] Address PR comments Signed-off-by: Sri Latha Ayyannagari --- src/runtime_src/core/common/api/xrt_elf.cpp | 5 ++--- src/runtime_src/core/common/api/xrt_hw_context.cpp | 4 +--- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/runtime_src/core/common/api/xrt_elf.cpp b/src/runtime_src/core/common/api/xrt_elf.cpp index 21cc4282bbd..d2857f77132 100644 --- a/src/runtime_src/core/common/api/xrt_elf.cpp +++ b/src/runtime_src/core/common/api/xrt_elf.cpp @@ -1668,7 +1668,7 @@ get_filename(const xrt::elf_impl* elf_impl) : ""; } -aiebu::aiebu_assembler::buffer_type +static aiebu::aiebu_assembler::buffer_type osabi_to_coredump_type(uint8_t os_abi) { switch (os_abi) { @@ -1706,8 +1706,7 @@ make_aie_coredump_elf(const xrt::elf& elf, const std::vector& blob, xrt_core::get_driver_info(pt_xrt); std::string drv_str; if (const auto drivers = pt_xrt.get_child_optional("drivers")) { - for (const auto& kv : *drivers) { - const auto& drv = kv.second; + for (const auto& [dummy, drv] : *drivers) { auto name = drv.get("name", ""); auto ver = drv.get("version", ""); if (!name.empty() && !ver.empty() && ver != "unknown") { diff --git a/src/runtime_src/core/common/api/xrt_hw_context.cpp b/src/runtime_src/core/common/api/xrt_hw_context.cpp index d24b3e04423..307fe003296 100644 --- a/src/runtime_src/core/common/api/xrt_hw_context.cpp +++ b/src/runtime_src/core/common/api/xrt_hw_context.cpp @@ -718,8 +718,6 @@ class hw_context_impl : public std::enable_shared_from_this } } - // Public-API path — picks any ELF for OS/ABI; UUID is left empty because - // no single ELF is attributable for a partition-level dump. std::vector get_aie_coredump_elf() const { @@ -731,7 +729,7 @@ class hw_context_impl : public std::enable_shared_from_this }(); return xrt_core::elf_int::make_aie_coredump_elf( - elf, get_aie_coredump(), m_core_device.get(), m_hdl->get_slotidx(), ""); + elf, get_aie_coredump(), m_core_device.get(), m_hdl->get_slotidx()); } // Returns map of kernel names to their corresponding elf files