https://github.com/Michael137 updated https://github.com/llvm/llvm-project/pull/129733
>From da950b7a55c8ee0a35bcfb7e3565fbc11095ab6e Mon Sep 17 00:00:00 2001 From: Michael Buch <michaelbuc...@gmail.com> Date: Tue, 4 Mar 2025 16:14:59 +0000 Subject: [PATCH 1/3] [lldb][Expression] Allow specifying a preferred ModuleList for lookup during expression evaluation --- .../include/lldb/Expression/IRExecutionUnit.h | 6 +++++ lldb/include/lldb/Target/Target.h | 10 ++++++++ lldb/source/Expression/IRExecutionUnit.cpp | 25 ++++++++++++++++++- .../Clang/ClangExpressionParser.cpp | 3 +++ .../MemoryHistory/asan/MemoryHistoryASan.cpp | 15 +++++++++++ 5 files changed, 58 insertions(+), 1 deletion(-) diff --git a/lldb/include/lldb/Expression/IRExecutionUnit.h b/lldb/include/lldb/Expression/IRExecutionUnit.h index 58f12bf8b64f5..a0978f9f5063d 100644 --- a/lldb/include/lldb/Expression/IRExecutionUnit.h +++ b/lldb/include/lldb/Expression/IRExecutionUnit.h @@ -12,6 +12,7 @@ #include <atomic> #include <memory> #include <string> +#include <unordered_set> #include <vector> #include "llvm/ExecutionEngine/SectionMemoryManager.h" @@ -161,6 +162,10 @@ class IRExecutionUnit : public std::enable_shared_from_this<IRExecutionUnit>, return m_jitted_global_variables; } + void SetPreferredModules(std::unordered_set<lldb::ModuleSP> modules) { + m_preferred_modules = std::move(modules); + } + 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 @@ -396,6 +401,7 @@ class IRExecutionUnit : public std::enable_shared_from_this<IRExecutionUnit>, ///< defining no functions using that variable, would do this.) If this ///< is true, any allocations need to be committed immediately -- no ///< opportunity for relocation. + std::unordered_set<lldb::ModuleSP> m_preferred_modules; }; } // namespace lldb_private diff --git a/lldb/include/lldb/Target/Target.h b/lldb/include/lldb/Target/Target.h index f31ac381391b4..369b5633492bb 100644 --- a/lldb/include/lldb/Target/Target.h +++ b/lldb/include/lldb/Target/Target.h @@ -332,6 +332,14 @@ class EvaluateExpressionOptions { m_language = SourceLanguage(language_type); } + void SetPreferredModules(std::unordered_set<lldb::ModuleSP> modules) { + m_preferred_modules = std::move(modules); + } + + const std::unordered_set<lldb::ModuleSP> &GetPreferredModules() const { + return m_preferred_modules; + } + /// 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. @@ -500,6 +508,8 @@ class EvaluateExpressionOptions { // originates mutable std::string m_pound_line_file; mutable uint32_t m_pound_line_line = 0; + + std::unordered_set<lldb::ModuleSP> m_preferred_modules; }; // Target diff --git a/lldb/source/Expression/IRExecutionUnit.cpp b/lldb/source/Expression/IRExecutionUnit.cpp index c8b4ddf705ec4..8e5f26544c84f 100644 --- a/lldb/source/Expression/IRExecutionUnit.cpp +++ b/lldb/source/Expression/IRExecutionUnit.cpp @@ -52,7 +52,7 @@ IRExecutionUnit::IRExecutionUnit(std::unique_ptr<llvm::LLVMContext> &context_up, m_cpu_features(cpu_features), m_name(name), 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() {} lldb::addr_t IRExecutionUnit::WriteNow(const uint8_t *bytes, size_t size, Status &error) { @@ -785,6 +785,13 @@ IRExecutionUnit::FindInSymbols(const std::vector<ConstString> &names, // We'll process module_sp separately, before the other modules. non_local_images.Remove(sc.module_sp); + ModuleList preferred_images; + // TODO: make m_preferred_modules a ModuleList + for (auto const &m : m_preferred_modules) { + non_local_images.Remove(m); + preferred_images.Append(m); + } + LoadAddressResolver resolver(target, symbol_was_missing_weak); ModuleFunctionSearchOptions function_options; @@ -806,6 +813,14 @@ IRExecutionUnit::FindInSymbols(const std::vector<ConstString> &names, return *load_addr; } + { + SymbolContextList sc_list; + preferred_images.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, @@ -822,6 +837,14 @@ IRExecutionUnit::FindInSymbols(const std::vector<ConstString> &names, return *load_addr; } + { + SymbolContextList sc_list; + preferred_images.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 f1573bae2651b..4e1eb27339af2 100644 --- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp +++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp @@ -1539,6 +1539,9 @@ lldb_private::Status ClangExpressionParser::DoPrepareForExecution( function_name, exe_ctx.GetTargetSP(), sc, m_compiler->getTargetOpts().Features); + if (auto *options = m_expr.GetOptions()) + execution_unit_sp->SetPreferredModules(options->GetPreferredModules()); + ClangExpressionHelper *type_system_helper = dyn_cast<ClangExpressionHelper>(m_expr.GetTypeSystemHelper()); ClangExpressionDeclMap *decl_map = diff --git a/lldb/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.cpp b/lldb/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.cpp index 41df0e85199ce..a772d03784e7f 100644 --- a/lldb/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.cpp +++ b/lldb/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.cpp @@ -174,6 +174,21 @@ HistoryThreads MemoryHistoryASan::GetHistoryThreads(lldb::addr_t address) { options.SetAutoApplyFixIts(false); options.SetLanguage(eLanguageTypeObjC_plus_plus); + const auto &target = process_sp->GetTarget(); + std::unordered_set<ModuleSP> preferred_modules; + target.GetImages().ForEach([&](const lldb::ModuleSP &m) { + llvm::Regex pattern("libclang_rt.asan_.*_dynamic.dylib"); + if (pattern.match(m->GetFileSpec().GetFilename().GetStringRef())) { + preferred_modules.insert(m); + return false; + } + + return true; + }); + + if (!preferred_modules.empty()) + options.SetPreferredModules(std::move(preferred_modules)); + ExpressionResults expr_result = UserExpression::Evaluate( exe_ctx, options, expr.GetString(), "", return_value_sp); if (expr_result != eExpressionCompleted) { >From 29bdb9629e0dca3a50d2dd9fa4d70f23ecd0cb8f Mon Sep 17 00:00:00 2001 From: Michael Buch <michaelbuc...@gmail.com> Date: Wed, 5 Mar 2025 12:22:21 +0000 Subject: [PATCH 2/3] fixup! turn ModuleList into SymbolContextList --- .../include/lldb/Expression/IRExecutionUnit.h | 13 +++++++-- lldb/include/lldb/Target/Target.h | 11 ++++---- lldb/source/Expression/IRExecutionUnit.cpp | 28 +++++++++---------- .../Clang/ClangExpressionParser.cpp | 3 +- .../MemoryHistory/asan/MemoryHistoryASan.cpp | 11 ++++---- 5 files changed, 37 insertions(+), 29 deletions(-) diff --git a/lldb/include/lldb/Expression/IRExecutionUnit.h b/lldb/include/lldb/Expression/IRExecutionUnit.h index a0978f9f5063d..406373ad6a663 100644 --- a/lldb/include/lldb/Expression/IRExecutionUnit.h +++ b/lldb/include/lldb/Expression/IRExecutionUnit.h @@ -18,6 +18,7 @@ #include "llvm/ExecutionEngine/SectionMemoryManager.h" #include "llvm/IR/Module.h" +#include "lldb/Core/ModuleList.h" #include "lldb/Expression/IRMemoryMap.h" #include "lldb/Expression/ObjectFileJIT.h" #include "lldb/Symbol/SymbolContext.h" @@ -162,8 +163,10 @@ class IRExecutionUnit : public std::enable_shared_from_this<IRExecutionUnit>, return m_jitted_global_variables; } - void SetPreferredModules(std::unordered_set<lldb::ModuleSP> modules) { - m_preferred_modules = std::move(modules); + void SetPreferredModules(SymbolContextList const &modules) { + for (auto const &m : modules) + if (m.module_sp) + m_preferred_modules.Append(m.module_sp); } private: @@ -401,7 +404,11 @@ class IRExecutionUnit : public std::enable_shared_from_this<IRExecutionUnit>, ///< defining no functions using that variable, would do this.) If this ///< is true, any allocations need to be committed immediately -- no ///< opportunity for relocation. - std::unordered_set<lldb::ModuleSP> m_preferred_modules; + + ///< 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 369b5633492bb..c38efc640de1e 100644 --- a/lldb/include/lldb/Target/Target.h +++ b/lldb/include/lldb/Target/Target.h @@ -25,6 +25,7 @@ #include "lldb/Core/UserSettingsController.h" #include "lldb/Expression/Expression.h" #include "lldb/Host/ProcessLaunchInfo.h" +#include "lldb/Symbol/SymbolContext.h" #include "lldb/Symbol/TypeSystem.h" #include "lldb/Target/ExecutionContextScope.h" #include "lldb/Target/PathMappingList.h" @@ -332,12 +333,12 @@ class EvaluateExpressionOptions { m_language = SourceLanguage(language_type); } - void SetPreferredModules(std::unordered_set<lldb::ModuleSP> modules) { - m_preferred_modules = std::move(modules); + void SetPreferredSymbolContexts(SymbolContextList modules) { + m_preferred_lookup_contexts = std::move(modules); } - const std::unordered_set<lldb::ModuleSP> &GetPreferredModules() const { - return m_preferred_modules; + const SymbolContextList &GetPreferredSymbolContexts() const { + return m_preferred_lookup_contexts; } /// Set the language using a pair of language code and version as @@ -509,7 +510,7 @@ class EvaluateExpressionOptions { mutable std::string m_pound_line_file; mutable uint32_t m_pound_line_line = 0; - std::unordered_set<lldb::ModuleSP> m_preferred_modules; + SymbolContextList m_preferred_lookup_contexts; }; // Target diff --git a/lldb/source/Expression/IRExecutionUnit.cpp b/lldb/source/Expression/IRExecutionUnit.cpp index 8e5f26544c84f..06b0cb7769f64 100644 --- a/lldb/source/Expression/IRExecutionUnit.cpp +++ b/lldb/source/Expression/IRExecutionUnit.cpp @@ -782,15 +782,11 @@ IRExecutionUnit::FindInSymbols(const std::vector<ConstString> &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); - - ModuleList preferred_images; - // TODO: make m_preferred_modules a ModuleList - for (auto const &m : m_preferred_modules) { - non_local_images.Remove(m); - preferred_images.Append(m); - } + for (size_t i = 0; i < m_preferred_modules.GetSize(); ++i) + non_local_images.Remove(m_preferred_modules.GetModuleAtIndex(i)); LoadAddressResolver resolver(target, symbol_was_missing_weak); @@ -801,9 +797,11 @@ IRExecutionUnit::FindInSymbols(const std::vector<ConstString> &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(), @@ -815,8 +813,8 @@ IRExecutionUnit::FindInSymbols(const std::vector<ConstString> &names, { SymbolContextList sc_list; - preferred_images.FindFunctions(name, lldb::eFunctionNameTypeFull, - function_options, sc_list); + m_preferred_modules.FindFunctions(name, lldb::eFunctionNameTypeFull, + function_options, sc_list); if (auto load_addr = resolver.Resolve(sc_list)) return *load_addr; } @@ -839,8 +837,8 @@ IRExecutionUnit::FindInSymbols(const std::vector<ConstString> &names, { SymbolContextList sc_list; - preferred_images.FindSymbolsWithNameAndType(name, lldb::eSymbolTypeAny, - sc_list); + m_preferred_modules.FindSymbolsWithNameAndType(name, lldb::eSymbolTypeAny, + sc_list); if (auto load_addr = resolver.Resolve(sc_list)) return *load_addr; } diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp index 4e1eb27339af2..cefa226175855 100644 --- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp +++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp @@ -1540,7 +1540,8 @@ lldb_private::Status ClangExpressionParser::DoPrepareForExecution( m_compiler->getTargetOpts().Features); if (auto *options = m_expr.GetOptions()) - execution_unit_sp->SetPreferredModules(options->GetPreferredModules()); + execution_unit_sp->SetPreferredModules( + options->GetPreferredSymbolContexts()); ClangExpressionHelper *type_system_helper = dyn_cast<ClangExpressionHelper>(m_expr.GetTypeSystemHelper()); diff --git a/lldb/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.cpp b/lldb/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.cpp index a772d03784e7f..4d4cf82f3b577 100644 --- a/lldb/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.cpp +++ b/lldb/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.cpp @@ -8,6 +8,7 @@ #include "MemoryHistoryASan.h" +#include "lldb/Symbol/SymbolContext.h" #include "lldb/Target/MemoryHistory.h" #include "Plugins/Process/Utility/HistoryThread.h" @@ -175,19 +176,19 @@ HistoryThreads MemoryHistoryASan::GetHistoryThreads(lldb::addr_t address) { options.SetLanguage(eLanguageTypeObjC_plus_plus); const auto &target = process_sp->GetTarget(); - std::unordered_set<ModuleSP> preferred_modules; + SymbolContextList preferred_modules; + llvm::Regex pattern(R"(libclang_rt\.asan_.*_dynamic\.dylib)"); target.GetImages().ForEach([&](const lldb::ModuleSP &m) { - llvm::Regex pattern("libclang_rt.asan_.*_dynamic.dylib"); if (pattern.match(m->GetFileSpec().GetFilename().GetStringRef())) { - preferred_modules.insert(m); + preferred_modules.Append(SymbolContext(m)); return false; } return true; }); - if (!preferred_modules.empty()) - options.SetPreferredModules(std::move(preferred_modules)); + if (!preferred_modules.IsEmpty()) + options.SetPreferredSymbolContexts(std::move(preferred_modules)); ExpressionResults expr_result = UserExpression::Evaluate( exe_ctx, options, expr.GetString(), "", return_value_sp); >From a14ed1391610db3c7db262ff45b0155e30c345f4 Mon Sep 17 00:00:00 2001 From: Michael Buch <michaelbuc...@gmail.com> Date: Wed, 5 Mar 2025 12:34:00 +0000 Subject: [PATCH 3/3] fixup! create helper in MemoryHistoryASan --- .../include/lldb/Expression/IRExecutionUnit.h | 1 - lldb/include/lldb/Target/Target.h | 3 ++ .../MemoryHistory/asan/MemoryHistoryASan.cpp | 38 ++++++++++++------- 3 files changed, 27 insertions(+), 15 deletions(-) diff --git a/lldb/include/lldb/Expression/IRExecutionUnit.h b/lldb/include/lldb/Expression/IRExecutionUnit.h index 406373ad6a663..77d53daf80c1b 100644 --- a/lldb/include/lldb/Expression/IRExecutionUnit.h +++ b/lldb/include/lldb/Expression/IRExecutionUnit.h @@ -12,7 +12,6 @@ #include <atomic> #include <memory> #include <string> -#include <unordered_set> #include <vector> #include "llvm/ExecutionEngine/SectionMemoryManager.h" diff --git a/lldb/include/lldb/Target/Target.h b/lldb/include/lldb/Target/Target.h index c38efc640de1e..a4059cdb2a819 100644 --- a/lldb/include/lldb/Target/Target.h +++ b/lldb/include/lldb/Target/Target.h @@ -510,6 +510,9 @@ class EvaluateExpressionOptions { mutable std::string m_pound_line_file; mutable uint32_t m_pound_line_line = 0; + ///< 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; }; diff --git a/lldb/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.cpp b/lldb/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.cpp index 4d4cf82f3b577..b806bbf15ac5f 100644 --- a/lldb/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.cpp +++ b/lldb/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.cpp @@ -62,6 +62,25 @@ MemoryHistoryASan::MemoryHistoryASan(const ProcessSP &process_sp) { m_process_wp = process_sp; } +///< 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. +static ModuleSP GetPreferredAsanModule(const Target &target) { + 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; +} + const char *memory_history_asan_command_prefix = R"( extern "C" { @@ -175,20 +194,11 @@ HistoryThreads MemoryHistoryASan::GetHistoryThreads(lldb::addr_t address) { options.SetAutoApplyFixIts(false); options.SetLanguage(eLanguageTypeObjC_plus_plus); - const auto &target = process_sp->GetTarget(); - SymbolContextList preferred_modules; - llvm::Regex pattern(R"(libclang_rt\.asan_.*_dynamic\.dylib)"); - target.GetImages().ForEach([&](const lldb::ModuleSP &m) { - if (pattern.match(m->GetFileSpec().GetFilename().GetStringRef())) { - preferred_modules.Append(SymbolContext(m)); - return false; - } - - return true; - }); - - if (!preferred_modules.IsEmpty()) - options.SetPreferredSymbolContexts(std::move(preferred_modules)); + 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); _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits