From f80885e7f281e7c3f5304f06525516fc9a65d7d2 Mon Sep 17 00:00:00 2001 From: Maosu Zhao Date: Fri, 23 Aug 2024 16:41:25 +0800 Subject: [PATCH 1/3] [DeviceSanitizer] Fix libstdc++ and libc++ mismatch problem UR will force link with libstdc++, but in in-tree build, if LLVM is built with libc++, this will cause mismatch problem. So, in such case, we need to build symbolizer.cpp with libc++ abi and link libc++ in. --- source/loader/CMakeLists.txt | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/source/loader/CMakeLists.txt b/source/loader/CMakeLists.txt index edfd8b055d..0053da2d82 100644 --- a/source/loader/CMakeLists.txt +++ b/source/loader/CMakeLists.txt @@ -167,6 +167,26 @@ if(UR_ENABLE_SANITIZER) ) target_include_directories(ur_loader PRIVATE ${LLVM_INCLUDE_DIRS}) target_link_libraries(ur_loader PRIVATE LLVMSupport LLVMSymbolize) + # In in-tree build, if LLVM is built with libc++, we also need to build + # symbolizer.cpp with libc++ abi and link libc++ in. + if(NOT CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR AND LLVM_LIBCXX_USED) + execute_process( + COMMAND ${CMAKE_CXX_COMPILER} --print-file-name=libc++.a + OUTPUT_VARIABLE LIBCXX_PATH + OUTPUT_STRIP_TRAILING_WHITESPACE) + execute_process( + COMMAND ${CMAKE_CXX_COMPILER} --print-file-name=libc++abi.a + OUTPUT_VARIABLE LIBCXX_ABI_PATH + OUTPUT_STRIP_TRAILING_WHITESPACE) + set_property(SOURCE + ${CMAKE_CURRENT_SOURCE_DIR}/layers/sanitizer/linux/symbolizer.cpp + APPEND_STRING PROPERTY COMPILE_FLAGS + " -stdlib=libc++ ") + if(NOT EXISTS ${LIBCXX_PATH} OR NOT EXISTS ${LIBCXX_ABI_PATH}) + message(FATAL_ERROR "libc++ is required but can't find the libraries") + endif() + target_link_libraries(ur_loader PRIVATE ${LIBCXX_PATH} ${LIBCXX_ABI_PATH}) + endif() endif() target_include_directories(ur_loader PRIVATE From 44cf6e9c806623e95060bc15708d2381d251348a Mon Sep 17 00:00:00 2001 From: Maosu Zhao Date: Fri, 23 Aug 2024 16:47:17 +0800 Subject: [PATCH 2/3] minor update --- source/loader/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/loader/CMakeLists.txt b/source/loader/CMakeLists.txt index 0053da2d82..af05c81767 100644 --- a/source/loader/CMakeLists.txt +++ b/source/loader/CMakeLists.txt @@ -169,7 +169,7 @@ if(UR_ENABLE_SANITIZER) target_link_libraries(ur_loader PRIVATE LLVMSupport LLVMSymbolize) # In in-tree build, if LLVM is built with libc++, we also need to build # symbolizer.cpp with libc++ abi and link libc++ in. - if(NOT CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR AND LLVM_LIBCXX_USED) + if(NOT UR_STANDALONE_BUILD AND LLVM_LIBCXX_USED) execute_process( COMMAND ${CMAKE_CXX_COMPILER} --print-file-name=libc++.a OUTPUT_VARIABLE LIBCXX_PATH From ab77d020197ba7012fc7bed86b8003727e50e49a Mon Sep 17 00:00:00 2001 From: "Zhao, Yang2" Date: Mon, 26 Aug 2024 11:35:54 +0200 Subject: [PATCH 3/3] fix SymbolizeCode to c abi --- .../layers/sanitizer/linux/symbolizer.cpp | 15 +++++++++---- source/loader/layers/sanitizer/stacktrace.cpp | 21 ++++++++++++------- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/source/loader/layers/sanitizer/linux/symbolizer.cpp b/source/loader/layers/sanitizer/linux/symbolizer.cpp index 5dd120e1f0..bcc90738f2 100644 --- a/source/loader/layers/sanitizer/linux/symbolizer.cpp +++ b/source/loader/layers/sanitizer/linux/symbolizer.cpp @@ -31,8 +31,9 @@ llvm::symbolize::PrinterConfig GetPrinterConfig() { extern "C" { -bool SymbolizeCode(const std::string ModuleName, uint64_t ModuleOffset, - std::string &Result) { +void SymbolizeCode(const char *ModuleName, uint64_t ModuleOffset, + char *ResultString, size_t ResultSize, size_t *RetSize) { + std::string Result; llvm::raw_string_ostream OS(Result); llvm::symbolize::Request Request{ModuleName, ModuleOffset}; llvm::symbolize::PrinterConfig Config = @@ -51,10 +52,16 @@ bool SymbolizeCode(const std::string ModuleName, uint64_t ModuleOffset, {ModuleOffset, llvm::object::SectionedAddress::UndefSection}); if (!ResOrErr) { - return false; + return; } Printer->print(Request, *ResOrErr); ur_sanitizer_layer::GetSymbolizer()->pruneCache(); - return true; + if (RetSize) { + *RetSize = Result.size() + 1; + } + if (ResultString) { + std::strncpy(ResultString, Result.c_str(), ResultSize); + ResultString[ResultSize - 1] = '\0'; + } } } diff --git a/source/loader/layers/sanitizer/stacktrace.cpp b/source/loader/layers/sanitizer/stacktrace.cpp index e33fcf0416..38bef94811 100644 --- a/source/loader/layers/sanitizer/stacktrace.cpp +++ b/source/loader/layers/sanitizer/stacktrace.cpp @@ -15,9 +15,10 @@ extern "C" { -__attribute__((weak)) bool SymbolizeCode(const std::string ModuleName, +__attribute__((weak)) void SymbolizeCode(const char *ModuleName, uint64_t ModuleOffset, - std::string &Result); + char *ResultString, size_t ResultSize, + size_t *RetSize); } namespace ur_sanitizer_layer { @@ -49,7 +50,7 @@ void ParseBacktraceInfo(BacktraceInfo BI, std::string &ModuleName, // Parse symbolizer output in the following formats: // // :[:] -SourceInfo ParseSymbolizerOutput(std::string Output) { +SourceInfo ParseSymbolizerOutput(const std::string &Output) { SourceInfo Info; // Parse function name size_t End = Output.find_first_of('\n'); @@ -98,8 +99,14 @@ void StackTrace::print() const { std::string ModuleName; uptr Offset; ParseBacktraceInfo(BI, ModuleName, Offset); - if (SymbolizeCode(ModuleName, Offset, Result)) { - SourceInfo SrcInfo = ParseSymbolizerOutput(std::move(Result)); + size_t ResultSize = 0; + SymbolizeCode(ModuleName.c_str(), Offset, nullptr, 0, &ResultSize); + if (ResultSize) { + std::vector ResultVector(ResultSize); + SymbolizeCode(ModuleName.c_str(), Offset, ResultVector.data(), + ResultSize, nullptr); + std::string Result((char *)ResultVector.data()); + SourceInfo SrcInfo = ParseSymbolizerOutput(Result); if (SrcInfo.file != "??") { getContext()->logger.always(" #{} in {} {}:{}:{}", index, SrcInfo.function, SrcInfo.file, @@ -109,10 +116,10 @@ void StackTrace::print() const { SrcInfo.function, ModuleName, (void *)Offset); } - continue; } + } else { + getContext()->logger.always(" #{} {}", index, BI); } - getContext()->logger.always(" #{} {}", index, BI); ++index; } getContext()->logger.always("");