From c4a97b29c6bfe951e76722134ac3751e6d9b89d1 Mon Sep 17 00:00:00 2001 From: Krzysztof Swiecicki Date: Wed, 29 Mar 2023 12:52:10 +0200 Subject: [PATCH 1/2] Add libunwind backtrace --- CMakeLists.txt | 1 + source/loader/CMakeLists.txt | 27 ++++++++- .../layers/validation/backtrace_unwind.cpp | 59 +++++++++++++++++++ 3 files changed, 84 insertions(+), 3 deletions(-) create mode 100644 source/loader/layers/validation/backtrace_unwind.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 9c24936aad..91a3a027c8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,6 +25,7 @@ option(UR_USE_UBSAN "enable UndefinedBehaviorSanitizer" OFF) option(UR_USE_MSAN "enable MemorySanitizer" OFF) option(UMA_BUILD_SHARED_LIBRARY "Build UMA as shared library" OFF) option(UR_ENABLE_TRACING "enable api tracing through xpti" OFF) +option(VAL_USE_LIBUNWIND_BACKTRACE "enable libunwind validation backtrace" OFF) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) diff --git a/source/loader/CMakeLists.txt b/source/loader/CMakeLists.txt index 2510726448..114fb223e2 100644 --- a/source/loader/CMakeLists.txt +++ b/source/loader/CMakeLists.txt @@ -49,7 +49,7 @@ if (UNIX) endif() if(WIN32) - target_link_libraries(loader PRIVATE cfgmgr32.lib dbghelp) + target_link_libraries(loader PRIVATE cfgmgr32.lib) endif() if(UNIX) @@ -90,18 +90,39 @@ if(UR_ENABLE_TRACING) ) endif() + +# link validation backtrace dependencies +find_package(Libunwind) +if (VAL_USE_LIBUNWIND_BACKTRACE AND LIBUNWIND_FOUND) + message(STATUS "Using libunwind backtrace for validation") + + target_sources(loader PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/layers/validation/backtrace_unwind.cpp) + target_link_libraries(loader PRIVATE Libunwind) +else() + message(STATUS "Using default backtrace for validation") + + if(WIN32) + target_sources(loader PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/layers/validation/backtrace_win.cpp) + target_link_libraries(loader PRIVATE dbghelp) + else() + target_sources(loader PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/layers/validation/backtrace_lin.cpp) + endif() +endif() + if(WIN32) target_sources(loader PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/windows/lib_init.cpp ${CMAKE_CURRENT_SOURCE_DIR}/windows/loader_init.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/layers/validation/backtrace_win.cpp + ) else() target_sources(loader PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/linux/lib_init.cpp ${CMAKE_CURRENT_SOURCE_DIR}/linux/loader_init.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/layers/validation/backtrace_lin.cpp ) endif() diff --git a/source/loader/layers/validation/backtrace_unwind.cpp b/source/loader/layers/validation/backtrace_unwind.cpp new file mode 100644 index 0000000000..2476cbbab9 --- /dev/null +++ b/source/loader/layers/validation/backtrace_unwind.cpp @@ -0,0 +1,59 @@ +/* + * + * Copyright (C) 2023 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ +#include "backtrace.hpp" + +#include +#include +#include + +#define UNW_LOCAL_ONLY +#include + +namespace validation_layer { + +std::vector getCurrentBacktrace() { + unw_cursor_t cursor; + unw_context_t context; + unw_getcontext(&context); + unw_init_local(&cursor, &context); + + if (unw_step(&cursor) <= 0) { + return std::vector(1, "Failed to acquire a backtrace"); + } + + std::vector backtrace; + try { + char proc_name[256]; + unw_word_t ip, offset; + std::stringstream backtraceLine; + + do { + if (unw_get_proc_name(&cursor, proc_name, sizeof(proc_name), + &offset) != 0) { + backtrace.push_back("????????"); + } else if (unw_get_reg(&cursor, UNW_REG_IP, &ip) != 0) { + backtraceLine.str(""); + backtraceLine << "(" << proc_name << "+" + << std::to_string(offset) << ") [????????]"; + backtrace.push_back(backtraceLine.str()); + } else { + backtraceLine.str(""); + backtraceLine << "(" << proc_name << "+" + << std::to_string(offset) << ") [0x" << std::hex + << ip << "]"; + backtrace.push_back(backtraceLine.str()); + } + } while (unw_step(&cursor) > 0); + } catch (std::bad_alloc &) { + return std::vector(1, "Failed to acquire a backtrace"); + } + + return backtrace; +} + +} // namespace validation_layer From 04f4607a5fe08e9e39851af531b4b96f45a95982 Mon Sep 17 00:00:00 2001 From: Krzysztof Swiecicki Date: Wed, 29 Mar 2023 12:52:48 +0200 Subject: [PATCH 2/2] Add cmake module that searches for libunwind --- cmake/FindLibunwind.cmake | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 cmake/FindLibunwind.cmake diff --git a/cmake/FindLibunwind.cmake b/cmake/FindLibunwind.cmake new file mode 100644 index 0000000000..8675967399 --- /dev/null +++ b/cmake/FindLibunwind.cmake @@ -0,0 +1,25 @@ +# Copyright (C) 2023 Intel Corporation +# SPDX-License-Identifier: MIT + +# +# FindLibunwind.cmake -- module searching for libunwind library. +# LIBUNWIND_FOUND is set to true if libunwind is found. +# + +find_library(LIBUNWIND_LIBRARIES NAMES unwind) +find_path(LIBUNWIND_INCLUDE_DIR NAMES libunwind.h) + +if (LIBUNWIND_LIBRARIES AND LIBUNWIND_INCLUDE_DIR) + set(LIBUNWIND_FOUND TRUE) +endif() + +if (LIBUNWIND_FOUND) + add_library(Libunwind INTERFACE IMPORTED) + set_target_properties(Libunwind PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${LIBUNWIND_INCLUDE_DIR}" + INTERFACE_LINK_LIBRARIES "${LIBUNWIND_LIBRARIES}" + ) +endif() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(Libunwind DEFAULT_MSG LIBUNWIND_LIBRARIES LIBUNWIND_INCLUDE_DIR)