Index: include/lldb/Target/InstrumentationRuntime.h =================================================================== --- include/lldb/Target/InstrumentationRuntime.h +++ include/lldb/Target/InstrumentationRuntime.h @@ -87,6 +87,19 @@ m_is_active = IsActive; } + /// Return a regular expression which can be used to identify a valid version of the runtime library. + virtual const RegularExpression & + GetPatternForRuntimeLibrary() = 0; + + /// Check whether \p module_sp corresponds to a valid runtime library. + virtual bool + CheckIfRuntimeIsValid(const lldb::ModuleSP module_sp) = 0; + + /// Register a breakpoint in the runtime library and perform any other necessary initialization. The runtime library + /// is guaranteed to be loaded. + virtual void + Activate() = 0; + public: static void @@ -94,8 +107,8 @@ /// Look for the instrumentation runtime in \p module_list. Register and activate the runtime if this hasn't already /// been done. - virtual void - ModulesDidLoad(lldb_private::ModuleList &module_list) = 0; + void + ModulesDidLoad(lldb_private::ModuleList &module_list); bool IsActive() const Index: source/Plugins/InstrumentationRuntime/AddressSanitizer/AddressSanitizerRuntime.h =================================================================== --- source/Plugins/InstrumentationRuntime/AddressSanitizer/AddressSanitizerRuntime.h +++ source/Plugins/InstrumentationRuntime/AddressSanitizer/AddressSanitizerRuntime.h @@ -56,15 +56,18 @@ return 1; } - void - ModulesDidLoad(lldb_private::ModuleList &module_list) override; - private: AddressSanitizerRuntime(const lldb::ProcessSP &process_sp) : lldb_private::InstrumentationRuntime(process_sp) {} + const RegularExpression & + GetPatternForRuntimeLibrary() override; + + bool + CheckIfRuntimeIsValid(const lldb::ModuleSP module_sp) override; + void - Activate(); - + Activate() override; + void Deactivate(); Index: source/Plugins/InstrumentationRuntime/AddressSanitizer/AddressSanitizerRuntime.cpp =================================================================== --- source/Plugins/InstrumentationRuntime/AddressSanitizer/AddressSanitizerRuntime.cpp +++ source/Plugins/InstrumentationRuntime/AddressSanitizer/AddressSanitizerRuntime.cpp @@ -12,7 +12,6 @@ #include "lldb/Breakpoint/StoppointCallbackContext.h" #include "lldb/Core/Debugger.h" #include "lldb/Core/Module.h" -#include "lldb/Core/ModuleList.h" #include "lldb/Core/RegularExpression.h" #include "lldb/Core/PluginInterface.h" #include "lldb/Core/PluginManager.h" @@ -69,46 +68,21 @@ Deactivate(); } -bool ModuleContainsASanRuntime(Module * module) +const RegularExpression & +AddressSanitizerRuntime::GetPatternForRuntimeLibrary() { - const Symbol* symbol = module->FindFirstSymbolWithNameAndType( - ConstString("__asan_get_alloc_stack"), - lldb::eSymbolTypeAny); - - return symbol != nullptr; + // FIXME: This shouldn't include the "dylib" suffix. + static RegularExpression regex("libclang_rt.asan_(.*)_dynamic\\.dylib"); + return regex; } -void -AddressSanitizerRuntime::ModulesDidLoad(lldb_private::ModuleList &module_list) +bool +AddressSanitizerRuntime::CheckIfRuntimeIsValid(const lldb::ModuleSP module_sp) { - if (IsActive()) - return; - - if (GetRuntimeModuleSP()) { - Activate(); - return; - } + const Symbol *symbol = + module_sp->FindFirstSymbolWithNameAndType(ConstString("__asan_get_alloc_stack"), lldb::eSymbolTypeAny); - std::lock_guard guard(module_list.GetMutex()); - const size_t num_modules = module_list.GetSize(); - for (size_t i = 0; i < num_modules; ++i) - { - Module *module_pointer = module_list.GetModulePointerAtIndexUnlocked(i); - const FileSpec & file_spec = module_pointer->GetFileSpec(); - if (! file_spec) - continue; - - static RegularExpression g_asan_runtime_regex("libclang_rt.asan_(.*)_dynamic\\.dylib"); - if (g_asan_runtime_regex.Execute (file_spec.GetFilename().GetCString()) || module_pointer->IsExecutable()) - { - if (ModuleContainsASanRuntime(module_pointer)) - { - SetRuntimeModuleSP(module_pointer->shared_from_this()); - Activate(); - return; - } - } - } + return symbol != nullptr; } #define RETRIEVE_REPORT_DATA_FUNCTION_TIMEOUT_USEC 2*1000*1000 Index: source/Plugins/InstrumentationRuntime/ThreadSanitizer/ThreadSanitizerRuntime.h =================================================================== --- source/Plugins/InstrumentationRuntime/ThreadSanitizer/ThreadSanitizerRuntime.h +++ source/Plugins/InstrumentationRuntime/ThreadSanitizer/ThreadSanitizerRuntime.h @@ -56,17 +56,20 @@ return 1; } - void - ModulesDidLoad(lldb_private::ModuleList &module_list) override; - lldb::ThreadCollectionSP GetBacktracesFromExtendedStopInfo(StructuredData::ObjectSP info) override; private: ThreadSanitizerRuntime(const lldb::ProcessSP &process_sp) : lldb_private::InstrumentationRuntime(process_sp) {} + const RegularExpression & + GetPatternForRuntimeLibrary() override; + + bool + CheckIfRuntimeIsValid(const lldb::ModuleSP module_sp) override; + void - Activate(); + Activate() override; void Deactivate(); Index: source/Plugins/InstrumentationRuntime/ThreadSanitizer/ThreadSanitizerRuntime.cpp =================================================================== --- source/Plugins/InstrumentationRuntime/ThreadSanitizer/ThreadSanitizerRuntime.cpp +++ source/Plugins/InstrumentationRuntime/ThreadSanitizer/ThreadSanitizerRuntime.cpp @@ -12,7 +12,6 @@ #include "lldb/Breakpoint/StoppointCallbackContext.h" #include "lldb/Core/Debugger.h" #include "lldb/Core/Module.h" -#include "lldb/Core/ModuleList.h" #include "lldb/Core/RegularExpression.h" #include "lldb/Core/PluginInterface.h" #include "lldb/Core/PluginManager.h" @@ -73,46 +72,6 @@ Deactivate(); } -static bool -ModuleContainsTSanRuntime(ModuleSP module_sp) -{ - static ConstString g_tsan_get_current_report("__tsan_get_current_report"); - const Symbol* symbol = module_sp->FindFirstSymbolWithNameAndType(g_tsan_get_current_report, lldb::eSymbolTypeAny); - return symbol != nullptr; -} - -void -ThreadSanitizerRuntime::ModulesDidLoad(lldb_private::ModuleList &module_list) -{ - if (IsActive()) - return; - - if (GetRuntimeModuleSP()) { - Activate(); - return; - } - - module_list.ForEach ([this](const lldb::ModuleSP module_sp) -> bool - { - const FileSpec & file_spec = module_sp->GetFileSpec(); - if (! file_spec) - return true; // Keep iterating through modules - - llvm::StringRef module_basename(file_spec.GetFilename().GetStringRef()); - if (module_sp->IsExecutable() || module_basename.startswith("libclang_rt.tsan_")) - { - if (ModuleContainsTSanRuntime(module_sp)) - { - SetRuntimeModuleSP(module_sp); - Activate(); - return false; // Stop iterating - } - } - - return true; // Keep iterating through modules - }); -} - #define RETRIEVE_REPORT_DATA_FUNCTION_TIMEOUT_USEC 2*1000*1000 const char * @@ -713,6 +672,20 @@ return false; // Let target run } +const RegularExpression & +ThreadSanitizerRuntime::GetPatternForRuntimeLibrary() { + static RegularExpression regex("libclang_rt.tsan_"); + return regex; +} + +bool +ThreadSanitizerRuntime::CheckIfRuntimeIsValid(const lldb::ModuleSP module_sp) +{ + static ConstString g_tsan_get_current_report("__tsan_get_current_report"); + const Symbol *symbol = module_sp->FindFirstSymbolWithNameAndType(g_tsan_get_current_report, lldb::eSymbolTypeAny); + return symbol != nullptr; +} + void ThreadSanitizerRuntime::Activate() { @@ -768,7 +741,6 @@ } SetActive(false); } - static std::string GenerateThreadName(const std::string &path, StructuredData::Object *o, StructuredData::ObjectSP main_info) { std::string result = "additional information"; Index: source/Target/InstrumentationRuntime.cpp =================================================================== --- source/Target/InstrumentationRuntime.cpp +++ source/Target/InstrumentationRuntime.cpp @@ -13,7 +13,10 @@ // Project includes #include "lldb/lldb-private.h" #include "lldb/Target/Process.h" +#include "lldb/Core/Module.h" +#include "lldb/Core/ModuleList.h" #include "lldb/Core/PluginManager.h" +#include "lldb/Core/RegularExpression.h" #include "lldb/Target/InstrumentationRuntime.h" using namespace lldb; @@ -40,6 +43,38 @@ } } +void +InstrumentationRuntime::ModulesDidLoad(lldb_private::ModuleList &module_list) +{ + if (IsActive()) + return; + + if (GetRuntimeModuleSP()) + { + Activate(); + return; + } + + module_list.ForEach([this](const lldb::ModuleSP module_sp) -> bool { + const FileSpec &file_spec = module_sp->GetFileSpec(); + if (!file_spec) + return true; // Keep iterating. + + const RegularExpression &runtime_regex = GetPatternForRuntimeLibrary(); + if (runtime_regex.Execute(file_spec.GetFilename().GetCString()) || module_sp->IsExecutable()) + { + if (CheckIfRuntimeIsValid(module_sp)) + { + SetRuntimeModuleSP(module_sp); + Activate(); + return false; // Stop iterating, we're done. + } + } + + return true; + }); +} + lldb::ThreadCollectionSP InstrumentationRuntime::GetBacktracesFromExtendedStopInfo(StructuredData::ObjectSP info) {