diff --git a/lldb/include/lldb/Expression/IRExecutionUnit.h b/lldb/include/lldb/Expression/IRExecutionUnit.h index a4d628429d3b9..31541aa2483a4 100644 --- a/lldb/include/lldb/Expression/IRExecutionUnit.h +++ b/lldb/include/lldb/Expression/IRExecutionUnit.h @@ -19,6 +19,7 @@ #include "llvm/IR/Module.h" #include "llvm/ADT/StringMap.h" +#include "lldb/Core/ModuleList.h" #include "lldb/Expression/IRMemoryMap.h" #include "lldb/Expression/ObjectFileJIT.h" #include "lldb/Symbol/SymbolContext.h" @@ -168,6 +169,12 @@ class IRExecutionUnit : public std::enable_shared_from_this, return m_jitted_global_variables; } + void AppendPreferredSymbolContexts(SymbolContextList const &contexts) { + for (auto const &ctx : contexts) + if (ctx.module_sp) + m_preferred_modules.Append(ctx.module_sp); + } + private: /// Look up the object in m_address_map that contains a given address, find /// where it was copied to, and return the remote address at the same offset @@ -409,6 +416,11 @@ class IRExecutionUnit : public std::enable_shared_from_this, ///< opportunity for relocation. llvm::StringMap m_section_size_map; + + ///< Any Module in this list will be used for symbol/function lookup + ///< before any other module (except for the module corresponding to the + ///< current frame). + ModuleList m_preferred_modules; }; } // namespace lldb_private diff --git a/lldb/include/lldb/Target/Target.h b/lldb/include/lldb/Target/Target.h index 84f59dbdea715..8682f7fad87ff 100644 --- a/lldb/include/lldb/Target/Target.h +++ b/lldb/include/lldb/Target/Target.h @@ -375,6 +375,14 @@ class EvaluateExpressionOptions { m_language = SourceLanguage(language_type); } + void SetPreferredSymbolContexts(SymbolContextList contexts) { + m_preferred_lookup_contexts = std::move(contexts); + } + + const SymbolContextList &GetPreferredSymbolContexts() const { + return m_preferred_lookup_contexts; + } + /// Set the language using a pair of language code and version as /// defined by the DWARF 6 specification. /// WARNING: These codes may change until DWARF 6 is finalized. @@ -579,6 +587,11 @@ class EvaluateExpressionOptions { mutable std::string m_pound_line_file; mutable uint32_t m_pound_line_line = 0; bool m_prepare_playground_stub_functions = true; + + ///< During expression evaluation, any SymbolContext in this list will be + ///< used for symbol/function lookup before any other context (except for + ///< the module corresponding to the current frame). + SymbolContextList m_preferred_lookup_contexts; }; // Target diff --git a/lldb/source/Expression/IRExecutionUnit.cpp b/lldb/source/Expression/IRExecutionUnit.cpp index cbdf08896678f..ae6d7b0c03bc6 100644 --- a/lldb/source/Expression/IRExecutionUnit.cpp +++ b/lldb/source/Expression/IRExecutionUnit.cpp @@ -56,7 +56,7 @@ IRExecutionUnit::IRExecutionUnit(std::unique_ptr &context_up, m_sym_ctx(sym_ctx), m_did_jit(false), m_function_load_addr(LLDB_INVALID_ADDRESS), m_function_end_load_addr(LLDB_INVALID_ADDRESS), - m_reported_allocations(false) {} + m_reported_allocations(false), m_preferred_modules() {} IRExecutionUnit::~IRExecutionUnit() { std::lock_guard global_context_locker( @@ -818,8 +818,12 @@ IRExecutionUnit::FindInSymbols(const std::vector &names, } ModuleList non_local_images = target->GetImages(); - // We'll process module_sp separately, before the other modules. + // We'll process module_sp and any preferred modules separately, before the + // other modules. non_local_images.Remove(sc.module_sp); + for (size_t i = 0; i < m_preferred_modules.GetSize(); ++i) + non_local_images.Remove(m_preferred_modules.GetModuleAtIndex(i)); + // BEGIN SWIFT if (m_in_populate_symtab) if (lldb::ModuleSP module_sp = m_jit_module_wp.lock()) @@ -835,9 +839,11 @@ IRExecutionUnit::FindInSymbols(const std::vector &names, for (const ConstString &name : names) { // The lookup order here is as follows: // 1) Functions in `sc.module_sp` - // 2) Functions in the other modules - // 3) Symbols in `sc.module_sp` - // 4) Symbols in the other modules + // 2) Functions in the preferred modules list + // 3) Functions in the other modules + // 4) Symbols in `sc.module_sp` + // 5) Symbols in the preferred modules list + // 6) Symbols in the other modules if (sc.module_sp) { SymbolContextList sc_list; sc.module_sp->FindFunctions(name, CompilerDeclContext(), @@ -847,6 +853,14 @@ IRExecutionUnit::FindInSymbols(const std::vector &names, return *load_addr; } + { + SymbolContextList sc_list; + m_preferred_modules.FindFunctions(name, lldb::eFunctionNameTypeFull, + function_options, sc_list); + if (auto load_addr = resolver.Resolve(sc_list)) + return *load_addr; + } + { SymbolContextList sc_list; non_local_images.FindFunctions(name, lldb::eFunctionNameTypeFull, @@ -863,6 +877,14 @@ IRExecutionUnit::FindInSymbols(const std::vector &names, return *load_addr; } + { + SymbolContextList sc_list; + m_preferred_modules.FindSymbolsWithNameAndType(name, lldb::eSymbolTypeAny, + sc_list); + if (auto load_addr = resolver.Resolve(sc_list)) + return *load_addr; + } + { SymbolContextList sc_list; non_local_images.FindSymbolsWithNameAndType(name, lldb::eSymbolTypeAny, diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp index b7e368dc881e6..2b00557d2e77b 100644 --- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp +++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp @@ -1483,6 +1483,10 @@ lldb_private::Status ClangExpressionParser::DoPrepareForExecution( function_name, exe_ctx.GetTargetSP(), sc, m_compiler->getTargetOpts().Features); + if (auto *options = m_expr.GetOptions()) + execution_unit_sp->AppendPreferredSymbolContexts( + options->GetPreferredSymbolContexts()); + ClangExpressionHelper *type_system_helper = dyn_cast(m_expr.GetTypeSystemHelper()); ClangExpressionDeclMap *decl_map = diff --git a/lldb/source/Plugins/InstrumentationRuntime/Utility/CMakeLists.txt b/lldb/source/Plugins/InstrumentationRuntime/Utility/CMakeLists.txt index dcca47fb0e253..705fe1503fae2 100644 --- a/lldb/source/Plugins/InstrumentationRuntime/Utility/CMakeLists.txt +++ b/lldb/source/Plugins/InstrumentationRuntime/Utility/CMakeLists.txt @@ -1,5 +1,6 @@ add_lldb_library(lldbPluginInstrumentationRuntimeUtility ReportRetriever.cpp + Utility.cpp LINK_LIBS lldbBreakpoint diff --git a/lldb/source/Plugins/InstrumentationRuntime/Utility/ReportRetriever.cpp b/lldb/source/Plugins/InstrumentationRuntime/Utility/ReportRetriever.cpp index 04ce339d8f661..00761327a694b 100644 --- a/lldb/source/Plugins/InstrumentationRuntime/Utility/ReportRetriever.cpp +++ b/lldb/source/Plugins/InstrumentationRuntime/Utility/ReportRetriever.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "ReportRetriever.h" +#include "Utility.h" #include "lldb/Breakpoint/StoppointCallbackContext.h" #include "lldb/Core/Debugger.h" @@ -82,6 +83,12 @@ ReportRetriever::RetrieveReportData(const ProcessSP process_sp) { options.SetAutoApplyFixIts(false); options.SetLanguage(eLanguageTypeObjC_plus_plus); + if (auto m = GetPreferredAsanModule(process_sp->GetTarget())) { + SymbolContextList sc_list; + sc_list.Append(SymbolContext(std::move(m))); + options.SetPreferredSymbolContexts(std::move(sc_list)); + } + ValueObjectSP return_value_sp; ExecutionContext exe_ctx; frame_sp->CalculateExecutionContext(exe_ctx); diff --git a/lldb/source/Plugins/InstrumentationRuntime/Utility/Utility.cpp b/lldb/source/Plugins/InstrumentationRuntime/Utility/Utility.cpp new file mode 100644 index 0000000000000..3cbd03b24297a --- /dev/null +++ b/lldb/source/Plugins/InstrumentationRuntime/Utility/Utility.cpp @@ -0,0 +1,35 @@ +//===-- Utility.cpp -------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "Utility.h" + +#include "lldb/Core/Module.h" +#include "lldb/Target/Target.h" + +namespace lldb_private { + +///< On Darwin, if LLDB loaded libclang_rt, it's coming from a locally built +///< compiler-rt, and we should prefer it in favour of the system sanitizers. +///< This helper searches the target for such a dylib. Returns nullptr if no +///< such dylib was found. +lldb::ModuleSP GetPreferredAsanModule(const Target &target) { + lldb::ModuleSP module; + llvm::Regex pattern(R"(libclang_rt\.asan_.*_dynamic\.dylib)"); + target.GetImages().ForEach([&](const lldb::ModuleSP &m) { + if (pattern.match(m->GetFileSpec().GetFilename().GetStringRef())) { + module = m; + return false; + } + + return true; + }); + + return module; +} + +} // namespace lldb_private diff --git a/lldb/source/Plugins/InstrumentationRuntime/Utility/Utility.h b/lldb/source/Plugins/InstrumentationRuntime/Utility/Utility.h new file mode 100644 index 0000000000000..813a0c107989e --- /dev/null +++ b/lldb/source/Plugins/InstrumentationRuntime/Utility/Utility.h @@ -0,0 +1,27 @@ +//===-- Utility.h -----------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SOURCE_PLUGINS_INSTRUMENTATIONRUNTIME_UTILITY_UTILITY_H +#define LLDB_SOURCE_PLUGINS_INSTRUMENTATIONRUNTIME_UTILITY_UTILITY_H + +#include "lldb/lldb-forward.h" + +namespace lldb_private { + +class Target; + +///< On Darwin, if LLDB loaded libclang_rt, it's coming from a locally built +///< compiler-rt, and we should prefer it in favour of the system sanitizers +///< when running InstrumentationRuntime utility expressions that use symbols +///< from the sanitizer libraries. This helper searches the target for such a +///< dylib. Returns nullptr if no such dylib was found. +lldb::ModuleSP GetPreferredAsanModule(const Target &target); + +} // namespace lldb_private + +#endif // LLDB_SOURCE_PLUGINS_INSTRUMENTATIONRUNTIME_UTILITY_UTILITY_H diff --git a/lldb/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.cpp b/lldb/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.cpp index 41df0e85199ce..afaaa57b09587 100644 --- a/lldb/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.cpp +++ b/lldb/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.cpp @@ -8,8 +8,10 @@ #include "MemoryHistoryASan.h" +#include "lldb/Symbol/SymbolContext.h" #include "lldb/Target/MemoryHistory.h" +#include "Plugins/InstrumentationRuntime/Utility/Utility.h" #include "Plugins/Process/Utility/HistoryThread.h" #include "lldb/Core/Debugger.h" #include "lldb/Core/Module.h" @@ -174,6 +176,12 @@ HistoryThreads MemoryHistoryASan::GetHistoryThreads(lldb::addr_t address) { options.SetAutoApplyFixIts(false); options.SetLanguage(eLanguageTypeObjC_plus_plus); + if (auto m = GetPreferredAsanModule(process_sp->GetTarget())) { + SymbolContextList sc_list; + sc_list.Append(SymbolContext(std::move(m))); + options.SetPreferredSymbolContexts(std::move(sc_list)); + } + ExpressionResults expr_result = UserExpression::Evaluate( exe_ctx, options, expr.GetString(), "", return_value_sp); if (expr_result != eExpressionCompleted) { diff --git a/lldb/test/API/functionalities/asan/TestMemoryHistory.py b/lldb/test/API/functionalities/asan/TestMemoryHistory.py index d5e1912e1f322..a1dd43d283079 100644 --- a/lldb/test/API/functionalities/asan/TestMemoryHistory.py +++ b/lldb/test/API/functionalities/asan/TestMemoryHistory.py @@ -20,7 +20,7 @@ def test(self): self.asan_tests() @skipIf(oslist=no_match(["macosx"])) - @skipIfDarwin # rdar://142836595 + @skipIf(bugnumber="rdar://144997976") def test_libsanitizers_asan(self): try: self.build(make_targets=["libsanitizers"]) diff --git a/lldb/test/API/functionalities/asan/TestReportData.py b/lldb/test/API/functionalities/asan/TestReportData.py index 390f73e39619e..fabc985d0ed44 100644 --- a/lldb/test/API/functionalities/asan/TestReportData.py +++ b/lldb/test/API/functionalities/asan/TestReportData.py @@ -20,7 +20,7 @@ def test(self): self.asan_tests() @skipIf(oslist=no_match(["macosx"])) - @skipIfDarwin # rdar://142836595 + @skipIf(bugnumber="rdar://144997976") def test_libsanitizers_asan(self): try: self.build(make_targets=["libsanitizers"])