diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2016-07-23 20:50:09 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2016-07-23 20:50:09 +0000 |
commit | f3fbd1c0586ff6ec7895991e6c28f61a503c36a8 (patch) | |
tree | 48d008fd3df8c0e73271a4b18474e0aac6dbfe33 /source/Target | |
parent | 2fc5d2d1dfaf623ce4e24cd8590565902f8c557c (diff) | |
download | src-f3fbd1c0586ff6ec7895991e6c28f61a503c36a8.tar.gz src-f3fbd1c0586ff6ec7895991e6c28f61a503c36a8.zip |
Vendor import of lldb release_39 branch r276489:vendor/lldb/lldb-release_39-r276489
Notes
Notes:
svn path=/vendor/lldb/dist/; revision=303241
svn path=/vendor/lldb/lldb-release_39-r276489/; revision=303242; tag=vendor/lldb/lldb-release_39-r276489
Diffstat (limited to 'source/Target')
41 files changed, 1846 insertions, 1470 deletions
diff --git a/source/Target/ABI.cpp b/source/Target/ABI.cpp index 4d67cb46abe4..f5fd594877f1 100644 --- a/source/Target/ABI.cpp +++ b/source/Target/ABI.cpp @@ -7,6 +7,10 @@ // //===----------------------------------------------------------------------===// +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes #include "lldb/Target/ABI.h" #include "lldb/Core/PluginManager.h" #include "lldb/Core/Value.h" @@ -27,7 +31,7 @@ ABI::FindPlugin (const ArchSpec &arch) ABICreateInstance create_callback; for (uint32_t idx = 0; - (create_callback = PluginManager::GetABICreateCallbackAtIndex(idx)) != NULL; + (create_callback = PluginManager::GetABICreateCallbackAtIndex(idx)) != nullptr; ++idx) { abi_sp = create_callback(arch); @@ -39,19 +43,9 @@ ABI::FindPlugin (const ArchSpec &arch) return abi_sp; } -//---------------------------------------------------------------------- -// Constructor -//---------------------------------------------------------------------- -ABI::ABI() -{ -} +ABI::ABI() = default; -//---------------------------------------------------------------------- -// Destructor -//---------------------------------------------------------------------- -ABI::~ABI() -{ -} +ABI::~ABI() = default; bool ABI::GetRegisterInfoByName (const ConstString &name, RegisterInfo &info) @@ -62,7 +56,7 @@ ABI::GetRegisterInfoByName (const ConstString &name, RegisterInfo &info) { const char *unique_name_cstr = name.GetCString(); uint32_t i; - for (i=0; i<count; ++i) + for (i = 0; i < count; ++i) { if (register_info_array[i].name == unique_name_cstr) { @@ -70,7 +64,7 @@ ABI::GetRegisterInfoByName (const ConstString &name, RegisterInfo &info) return true; } } - for (i=0; i<count; ++i) + for (i = 0; i < count; ++i) { if (register_info_array[i].alt_name == unique_name_cstr) { @@ -92,7 +86,7 @@ ABI::GetRegisterInfoByKind (RegisterKind reg_kind, uint32_t reg_num, RegisterInf const RegisterInfo *register_info_array = GetRegisterInfoArray (count); if (register_info_array) { - for (uint32_t i=0; i<count; ++i) + for (uint32_t i = 0; i < count; ++i) { if (register_info_array[i].kinds[reg_kind] == reg_num) { @@ -148,7 +142,7 @@ ABI::GetReturnValueObject (Thread &thread, ExpressionVariableSP clang_expr_variable_sp(persistent_expression_state->CreatePersistentVariable(return_valobj_sp)); - assert (clang_expr_variable_sp.get()); + assert (clang_expr_variable_sp); // Set flags and live data as appropriate @@ -211,3 +205,27 @@ ABI::PrepareTrivialCall (Thread &thread, assert( !"Should never get here!" ); return false; } + +bool +ABI::GetFallbackRegisterLocation (const RegisterInfo *reg_info, + UnwindPlan::Row::RegisterLocation &unwind_regloc) +{ + // Did the UnwindPlan fail to give us the caller's stack pointer? + // The stack pointer is defined to be the same as THIS frame's CFA, so return the CFA value as + // the caller's stack pointer. This is true on x86-32/x86-64 at least. + if (reg_info->kinds[eRegisterKindGeneric] == LLDB_REGNUM_GENERIC_SP) + { + unwind_regloc.SetIsCFAPlusOffset(0); + return true; + } + + // If a volatile register is being requested, we don't want to forward the next frame's register contents + // up the stack -- the register is not retrievable at this frame. + if (RegisterIsVolatile(reg_info)) + { + unwind_regloc.SetUndefined(); + return true; + } + + return false; +} diff --git a/source/Target/ExecutionContext.cpp b/source/Target/ExecutionContext.cpp index ff584361c296..41f076a205e9 100644 --- a/source/Target/ExecutionContext.cpp +++ b/source/Target/ExecutionContext.cpp @@ -7,8 +7,11 @@ // //===----------------------------------------------------------------------===// +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes #include "lldb/Target/ExecutionContext.h" - #include "lldb/Core/State.h" #include "lldb/Target/ExecutionContextScope.h" #include "lldb/Target/StackFrame.h" @@ -183,18 +186,17 @@ ExecutionContext::ExecutionContext (const ExecutionContextRef *exe_ctx_ref_ptr, } } -ExecutionContext::ExecutionContext (const ExecutionContextRef *exe_ctx_ref_ptr, Mutex::Locker &locker) : - m_target_sp (), - m_process_sp (), - m_thread_sp (), - m_frame_sp () +ExecutionContext::ExecutionContext(const ExecutionContextRef *exe_ctx_ref_ptr, + std::unique_lock<std::recursive_mutex> &lock) + : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() { if (exe_ctx_ref_ptr) { - m_target_sp = exe_ctx_ref_ptr->GetTargetSP(); + m_target_sp = exe_ctx_ref_ptr->GetTargetSP(); if (m_target_sp) { - locker.Lock(m_target_sp->GetAPIMutex()); + lock = std::unique_lock<std::recursive_mutex>(m_target_sp->GetAPIMutex()); + m_process_sp = exe_ctx_ref_ptr->GetProcessSP(); m_thread_sp = exe_ctx_ref_ptr->GetThreadSP(); m_frame_sp = exe_ctx_ref_ptr->GetFrameSP(); @@ -202,18 +204,16 @@ ExecutionContext::ExecutionContext (const ExecutionContextRef *exe_ctx_ref_ptr, } } -ExecutionContext::ExecutionContext (const ExecutionContextRef &exe_ctx_ref, Mutex::Locker &locker) : - m_target_sp (exe_ctx_ref.GetTargetSP()), - m_process_sp (), - m_thread_sp (), - m_frame_sp () +ExecutionContext::ExecutionContext(const ExecutionContextRef &exe_ctx_ref, std::unique_lock<std::recursive_mutex> &lock) + : m_target_sp(exe_ctx_ref.GetTargetSP()), m_process_sp(), m_thread_sp(), m_frame_sp() { if (m_target_sp) { - locker.Lock(m_target_sp->GetAPIMutex()); + lock = std::unique_lock<std::recursive_mutex>(m_target_sp->GetAPIMutex()); + m_process_sp = exe_ctx_ref.GetProcessSP(); - m_thread_sp = exe_ctx_ref.GetThreadSP(); - m_frame_sp = exe_ctx_ref.GetFrameSP(); + m_thread_sp = exe_ctx_ref.GetThreadSP(); + m_frame_sp = exe_ctx_ref.GetFrameSP(); } } @@ -241,9 +241,7 @@ ExecutionContext::Clear() m_frame_sp.reset(); } -ExecutionContext::~ExecutionContext() -{ -} +ExecutionContext::~ExecutionContext() = default; uint32_t ExecutionContext::GetAddressByteSize() const @@ -272,7 +270,7 @@ ExecutionContext::GetRegisterContext () const return m_frame_sp->GetRegisterContext().get(); else if (m_thread_sp) return m_thread_sp->GetRegisterContext().get(); - return NULL; + return nullptr; } Target * @@ -282,7 +280,7 @@ ExecutionContext::GetTargetPtr () const return m_target_sp.get(); if (m_process_sp) return &m_process_sp->GetTarget(); - return NULL; + return nullptr; } Process * @@ -292,7 +290,7 @@ ExecutionContext::GetProcessPtr () const return m_process_sp.get(); if (m_target_sp) return m_target_sp->GetProcessSP().get(); - return NULL; + return nullptr; } ExecutionContextScope * @@ -311,7 +309,7 @@ Target & ExecutionContext::GetTargetRef () const { #if defined (LLDB_CONFIGURATION_DEBUG) || defined (LLDB_CONFIGURATION_RELEASE) - assert (m_target_sp.get()); + assert (m_target_sp); #endif return *m_target_sp; } @@ -320,7 +318,7 @@ Process & ExecutionContext::GetProcessRef () const { #if defined (LLDB_CONFIGURATION_DEBUG) || defined (LLDB_CONFIGURATION_RELEASE) - assert (m_process_sp.get()); + assert (m_process_sp); #endif return *m_process_sp; } @@ -329,7 +327,7 @@ Thread & ExecutionContext::GetThreadRef () const { #if defined (LLDB_CONFIGURATION_DEBUG) || defined (LLDB_CONFIGURATION_RELEASE) - assert (m_thread_sp.get()); + assert (m_thread_sp); #endif return *m_thread_sp; } @@ -338,7 +336,7 @@ StackFrame & ExecutionContext::GetFrameRef () const { #if defined (LLDB_CONFIGURATION_DEBUG) || defined (LLDB_CONFIGURATION_RELEASE) - assert (m_frame_sp.get()); + assert (m_frame_sp); #endif return *m_frame_sp; } @@ -572,7 +570,6 @@ ExecutionContextRef::ExecutionContextRef (const ExecutionContext &exe_ctx) : *this = exe_ctx; } - ExecutionContextRef::ExecutionContextRef (Target *target, bool adopt_selected) : m_target_wp(), m_process_wp(), @@ -583,9 +580,6 @@ ExecutionContextRef::ExecutionContextRef (Target *target, bool adopt_selected) : SetTargetPtr (target, adopt_selected); } - - - ExecutionContextRef::ExecutionContextRef (const ExecutionContextRef &rhs) : m_target_wp (rhs.m_target_wp), m_process_wp(rhs.m_process_wp), @@ -637,9 +631,7 @@ ExecutionContextRef::Clear() ClearFrame(); } -ExecutionContextRef::~ExecutionContextRef() -{ -} +ExecutionContextRef::~ExecutionContextRef() = default; void ExecutionContextRef::SetTargetSP (const lldb::TargetSP &target_sp) @@ -694,7 +686,6 @@ ExecutionContextRef::SetFrameSP (const lldb::StackFrameSP &frame_sp) m_process_wp.reset(); m_target_wp.reset(); } - } void @@ -820,7 +811,7 @@ ExecutionContextRef::GetThreadSP () const } } - // Check that we aren't about to return an invalid thread sp. We might return a NULL thread_sp, + // Check that we aren't about to return an invalid thread sp. We might return a nullptr thread_sp, // but don't return an invalid one. if (thread_sp && !thread_sp->IsValid()) @@ -846,5 +837,3 @@ ExecutionContextRef::Lock (bool thread_and_frame_only_if_stopped) const { return ExecutionContext(this, thread_and_frame_only_if_stopped); } - - diff --git a/source/Target/InstrumentationRuntime.cpp b/source/Target/InstrumentationRuntime.cpp index b3b2393b0234..af7955f9c34b 100644 --- a/source/Target/InstrumentationRuntime.cpp +++ b/source/Target/InstrumentationRuntime.cpp @@ -5,8 +5,12 @@ // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // -//===----------------------------------------------------------------------===// +//===---------------------------------------------------------------------===// +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes #include "lldb/lldb-private.h" #include "lldb/Target/Process.h" #include "lldb/Core/PluginManager.h" @@ -18,12 +22,12 @@ using namespace lldb_private; void InstrumentationRuntime::ModulesDidLoad(lldb_private::ModuleList &module_list, lldb_private::Process *process, InstrumentationRuntimeCollection &runtimes) { - InstrumentationRuntimeCreateInstance create_callback = NULL; + InstrumentationRuntimeCreateInstance create_callback = nullptr; InstrumentationRuntimeGetType get_type_callback; for (uint32_t idx = 0; ; ++idx) { create_callback = PluginManager::GetInstrumentationRuntimeCreateCallbackAtIndex(idx); - if (create_callback == NULL) + if (create_callback == nullptr) break; get_type_callback = PluginManager::GetInstrumentationRuntimeGetTypeCallbackAtIndex(idx); InstrumentationRuntimeType type = get_type_callback(); @@ -46,3 +50,9 @@ InstrumentationRuntime::IsActive() { return false; } + +lldb::ThreadCollectionSP +InstrumentationRuntime::GetBacktracesFromExtendedStopInfo(StructuredData::ObjectSP info) +{ + return ThreadCollectionSP(new ThreadCollection()); +} diff --git a/source/Target/JITLoader.cpp b/source/Target/JITLoader.cpp index 8536d690ece0..2e37fb0ff4e6 100644 --- a/source/Target/JITLoader.cpp +++ b/source/Target/JITLoader.cpp @@ -7,6 +7,10 @@ // //===----------------------------------------------------------------------===// +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes #include "lldb/lldb-private.h" #include "lldb/Target/JITLoader.h" #include "lldb/Target/JITLoaderList.h" @@ -19,8 +23,8 @@ using namespace lldb_private; void JITLoader::LoadPlugins (Process *process, JITLoaderList &list) { - JITLoaderCreateInstance create_callback = NULL; - for (uint32_t idx = 0; (create_callback = PluginManager::GetJITLoaderCreateCallbackAtIndex(idx)) != NULL; ++idx) + JITLoaderCreateInstance create_callback = nullptr; + for (uint32_t idx = 0; (create_callback = PluginManager::GetJITLoaderCreateCallbackAtIndex(idx)) != nullptr; ++idx) { JITLoaderSP instance_sp(create_callback(process, false)); if (instance_sp) @@ -33,6 +37,4 @@ JITLoader::JITLoader(Process *process) : { } -JITLoader::~JITLoader() -{ -} +JITLoader::~JITLoader() = default; diff --git a/source/Target/JITLoaderList.cpp b/source/Target/JITLoaderList.cpp index 24a73b7fd516..76c9dd675355 100644 --- a/source/Target/JITLoaderList.cpp +++ b/source/Target/JITLoaderList.cpp @@ -14,8 +14,7 @@ using namespace lldb; using namespace lldb_private; -JITLoaderList::JITLoaderList() - : m_jit_loaders_vec(), m_jit_loaders_mutex(Mutex::eMutexTypeRecursive) +JITLoaderList::JITLoaderList() : m_jit_loaders_vec(), m_jit_loaders_mutex() { } @@ -26,14 +25,14 @@ JITLoaderList::~JITLoaderList() void JITLoaderList::Append (const JITLoaderSP &jit_loader_sp) { - Mutex::Locker locker(m_jit_loaders_mutex); + std::lock_guard<std::recursive_mutex> guard(m_jit_loaders_mutex); m_jit_loaders_vec.push_back(jit_loader_sp); } void JITLoaderList::Remove (const JITLoaderSP &jit_loader_sp) { - Mutex::Locker locker(m_jit_loaders_mutex); + std::lock_guard<std::recursive_mutex> guard(m_jit_loaders_mutex); m_jit_loaders_vec.erase(std::remove(m_jit_loaders_vec.begin(), m_jit_loaders_vec.end(), jit_loader_sp), m_jit_loaders_vec.end()); @@ -48,14 +47,14 @@ JITLoaderList::GetSize() const JITLoaderSP JITLoaderList::GetLoaderAtIndex (size_t idx) { - Mutex::Locker locker(m_jit_loaders_mutex); + std::lock_guard<std::recursive_mutex> guard(m_jit_loaders_mutex); return m_jit_loaders_vec[idx]; } void JITLoaderList::DidLaunch() { - Mutex::Locker locker(m_jit_loaders_mutex); + std::lock_guard<std::recursive_mutex> guard(m_jit_loaders_mutex); for (auto const &jit_loader : m_jit_loaders_vec) jit_loader->DidLaunch(); } @@ -63,7 +62,7 @@ JITLoaderList::DidLaunch() void JITLoaderList::DidAttach() { - Mutex::Locker locker(m_jit_loaders_mutex); + std::lock_guard<std::recursive_mutex> guard(m_jit_loaders_mutex); for (auto const &jit_loader : m_jit_loaders_vec) jit_loader->DidAttach(); } @@ -71,7 +70,7 @@ JITLoaderList::DidAttach() void JITLoaderList::ModulesDidLoad(ModuleList &module_list) { - Mutex::Locker locker(m_jit_loaders_mutex); + std::lock_guard<std::recursive_mutex> guard(m_jit_loaders_mutex); for (auto const &jit_loader : m_jit_loaders_vec) jit_loader->ModulesDidLoad(module_list); } diff --git a/source/Target/Language.cpp b/source/Target/Language.cpp index d6c7e0a4c4bb..20439b4dc552 100644 --- a/source/Target/Language.cpp +++ b/source/Target/Language.cpp @@ -13,7 +13,6 @@ #include "lldb/Target/Language.h" -#include "lldb/Host/Mutex.h" #include "lldb/Core/PluginManager.h" #include "lldb/Core/Stream.h" @@ -36,23 +35,23 @@ GetLanguagesMap () return *g_map; } -static Mutex& -GetLanguagesMutex () +static std::mutex & +GetLanguagesMutex() { - static Mutex *g_mutex = nullptr; + static std::mutex *g_mutex = nullptr; static std::once_flag g_initialize; - + std::call_once(g_initialize, [] { - g_mutex = new Mutex(); // NOTE: INTENTIONAL LEAK due to global destructor chain + g_mutex = new std::mutex(); // NOTE: INTENTIONAL LEAK due to global destructor chain }); - + return *g_mutex; } Language* Language::FindPlugin (lldb::LanguageType language) { - Mutex::Locker locker(GetLanguagesMutex()); + std::lock_guard<std::mutex> guard(GetLanguagesMutex()); LanguagesMap& map(GetLanguagesMap()); auto iter = map.find(language), end = map.end(); if (iter != end) @@ -80,7 +79,7 @@ Language::FindPlugin (lldb::LanguageType language) void Language::ForEach (std::function<bool(Language*)> callback) { - Mutex::Locker locker(GetLanguagesMutex()); + std::lock_guard<std::mutex> guard(GetLanguagesMutex()); LanguagesMap& map(GetLanguagesMap()); for (const auto& entry : map) { @@ -241,6 +240,7 @@ Language::LanguageIsCPlusPlus (LanguageType language) case eLanguageTypeC_plus_plus_03: case eLanguageTypeC_plus_plus_11: case eLanguageTypeC_plus_plus_14: + case eLanguageTypeObjC_plus_plus: return true; default: return false; @@ -367,6 +367,12 @@ Language::GetTypeScavenger () return nullptr; } +const char* +Language::GetLanguageSpecificTypeLookupHelp () +{ + return nullptr; +} + size_t Language::TypeScavenger::Find (ExecutionContextScope *exe_scope, const char *key, diff --git a/source/Target/LanguageRuntime.cpp b/source/Target/LanguageRuntime.cpp index b1e2b3eb04fc..f61af071e3e4 100644 --- a/source/Target/LanguageRuntime.cpp +++ b/source/Target/LanguageRuntime.cpp @@ -29,10 +29,10 @@ public: ExceptionSearchFilter (const lldb::TargetSP &target_sp, lldb::LanguageType language, bool update_module_list = true) : - SearchFilter (target_sp), - m_language (language), - m_language_runtime (NULL), - m_filter_sp () + SearchFilter(target_sp), + m_language(language), + m_language_runtime(nullptr), + m_filter_sp() { if (update_module_list) UpdateModuleListIfNeeded (); @@ -92,7 +92,7 @@ protected: if (process_sp) { bool refreash_filter = !m_filter_sp; - if (m_language_runtime == NULL) + if (m_language_runtime == nullptr) { m_language_runtime = process_sp->GetLanguageRuntime(m_language); refreash_filter = true; @@ -115,7 +115,7 @@ protected: else { m_filter_sp.reset(); - m_language_runtime = NULL; + m_language_runtime = nullptr; } } }; @@ -128,11 +128,11 @@ public: ExceptionBreakpointResolver (lldb::LanguageType language, bool catch_bp, bool throw_bp) : - BreakpointResolver (NULL, BreakpointResolver::ExceptionResolver), - m_language (language), - m_language_runtime (NULL), - m_catch_bp (catch_bp), - m_throw_bp (throw_bp) + BreakpointResolver(nullptr, BreakpointResolver::ExceptionResolver), + m_language(language), + m_language_runtime(nullptr), + m_catch_bp(catch_bp), + m_throw_bp(throw_bp) { } @@ -207,7 +207,7 @@ protected: if (process_sp) { bool refreash_resolver = !m_actual_resolver_sp; - if (m_language_runtime == NULL) + if (m_language_runtime == nullptr) { m_language_runtime = process_sp->GetLanguageRuntime(m_language); refreash_resolver = true; @@ -230,16 +230,17 @@ protected: else { m_actual_resolver_sp.reset(); - m_language_runtime = NULL; + m_language_runtime = nullptr; } } else { m_actual_resolver_sp.reset(); - m_language_runtime = NULL; + m_language_runtime = nullptr; } return (bool)m_actual_resolver_sp; } + lldb::BreakpointResolverSP m_actual_resolver_sp; lldb::LanguageType m_language; LanguageRuntime *m_language_runtime; @@ -254,16 +255,16 @@ LanguageRuntime::FindPlugin (Process *process, lldb::LanguageType language) LanguageRuntimeCreateInstance create_callback; for (uint32_t idx = 0; - (create_callback = PluginManager::GetLanguageRuntimeCreateCallbackAtIndex(idx)) != NULL; + (create_callback = PluginManager::GetLanguageRuntimeCreateCallbackAtIndex(idx)) != nullptr; ++idx) { language_runtime_ap.reset (create_callback(process, language)); - if (language_runtime_ap.get()) + if (language_runtime_ap) return language_runtime_ap.release(); } - return NULL; + return nullptr; } LanguageRuntime::LanguageRuntime(Process *process) : @@ -336,6 +337,9 @@ LanguageRuntime::InitializeCommands (CommandObject* parent) CommandObjectSP command = command_callback(parent->GetCommandInterpreter()); if (command) { + // the CommandObject vended by a Language plugin cannot be created once and cached because + // we may create multiple debuggers and need one instance of the command each - the implementing function + // is meant to create a new instance of the command each time it is invoked parent->LoadSubCommand(command->GetCommandName(), command); } } @@ -345,5 +349,5 @@ LanguageRuntime::InitializeCommands (CommandObject* parent) lldb::SearchFilterSP LanguageRuntime::CreateExceptionSearchFilter () { - return m_process->GetTarget().GetSearchFilterForModule(NULL); + return m_process->GetTarget().GetSearchFilterForModule(nullptr); } diff --git a/source/Target/Makefile b/source/Target/Makefile deleted file mode 100644 index 0d4be5449ad3..000000000000 --- a/source/Target/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -##===- source/Target/Makefile ------------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -LLDB_LEVEL := ../.. -LIBRARYNAME := lldbTarget -BUILD_ARCHIVE = 1 - -include $(LLDB_LEVEL)/Makefile diff --git a/source/Target/Memory.cpp b/source/Target/Memory.cpp index c89fd5101147..9f0114812125 100644 --- a/source/Target/Memory.cpp +++ b/source/Target/Memory.cpp @@ -25,13 +25,13 @@ using namespace lldb_private; //---------------------------------------------------------------------- // MemoryCache constructor //---------------------------------------------------------------------- -MemoryCache::MemoryCache(Process &process) : - m_mutex (Mutex::eMutexTypeRecursive), - m_L1_cache (), - m_L2_cache (), - m_invalid_ranges (), - m_process (process), - m_L2_cache_line_byte_size (process.GetMemoryCacheLineSize()) +MemoryCache::MemoryCache(Process &process) + : m_mutex(), + m_L1_cache(), + m_L2_cache(), + m_invalid_ranges(), + m_process(process), + m_L2_cache_line_byte_size(process.GetMemoryCacheLineSize()) { } @@ -45,7 +45,7 @@ MemoryCache::~MemoryCache() void MemoryCache::Clear(bool clear_invalid_ranges) { - Mutex::Locker locker (m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); m_L1_cache.clear(); m_L2_cache.clear(); if (clear_invalid_ranges) @@ -62,7 +62,7 @@ MemoryCache::AddL1CacheData(lldb::addr_t addr, const void *src, size_t src_len) void MemoryCache::AddL1CacheData(lldb::addr_t addr, const DataBufferSP &data_buffer_sp) { - Mutex::Locker locker (m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); m_L1_cache[addr] = data_buffer_sp; } @@ -72,13 +72,17 @@ MemoryCache::Flush (addr_t addr, size_t size) if (size == 0) return; - Mutex::Locker locker (m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); // Erase any blocks from the L1 cache that intersect with the flush range if (!m_L1_cache.empty()) { AddrRange flush_range(addr, size); - BlockMap::iterator pos = m_L1_cache.lower_bound(addr); + BlockMap::iterator pos = m_L1_cache.upper_bound(addr); + if (pos != m_L1_cache.begin()) + { + --pos; + } while (pos != m_L1_cache.end()) { AddrRange chunk_range(pos->first, pos->second->GetByteSize()); @@ -119,7 +123,7 @@ MemoryCache::AddInvalidRange (lldb::addr_t base_addr, lldb::addr_t byte_size) { if (byte_size > 0) { - Mutex::Locker locker (m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); InvalidRanges::Entry range (base_addr, byte_size); m_invalid_ranges.Append(range); m_invalid_ranges.Sort(); @@ -131,7 +135,7 @@ MemoryCache::RemoveInvalidRange (lldb::addr_t base_addr, lldb::addr_t byte_size) { if (byte_size > 0) { - Mutex::Locker locker (m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); const uint32_t idx = m_invalid_ranges.FindEntryIndexThatContains(base_addr); if (idx != UINT32_MAX) { @@ -160,7 +164,7 @@ MemoryCache::Read (addr_t addr, // m_L2_cache_line_byte_size bytes in size, so we don't try anything // tricky when reading from them (no partial reads from the L1 cache). - Mutex::Locker locker(m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); if (!m_L1_cache.empty()) { AddrRange read_range(addr, dst_len); @@ -432,11 +436,7 @@ AllocatedBlock::FreeBlock (addr_t addr) return success; } - -AllocatedMemoryCache::AllocatedMemoryCache (Process &process) : - m_process (process), - m_mutex (Mutex::eMutexTypeRecursive), - m_memory_map() +AllocatedMemoryCache::AllocatedMemoryCache(Process &process) : m_process(process), m_mutex(), m_memory_map() { } @@ -448,7 +448,7 @@ AllocatedMemoryCache::~AllocatedMemoryCache () void AllocatedMemoryCache::Clear() { - Mutex::Locker locker (m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); if (m_process.IsAlive()) { PermissionsToBlockMap::iterator pos, end = m_memory_map.end(); @@ -494,8 +494,8 @@ AllocatedMemoryCache::AllocateMemory (size_t byte_size, uint32_t permissions, Error &error) { - Mutex::Locker locker (m_mutex); - + std::lock_guard<std::recursive_mutex> guard(m_mutex); + addr_t addr = LLDB_INVALID_ADDRESS; std::pair<PermissionsToBlockMap::iterator, PermissionsToBlockMap::iterator> range = m_memory_map.equal_range (permissions); @@ -522,7 +522,7 @@ AllocatedMemoryCache::AllocateMemory (size_t byte_size, bool AllocatedMemoryCache::DeallocateMemory (lldb::addr_t addr) { - Mutex::Locker locker (m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); PermissionsToBlockMap::iterator pos, end = m_memory_map.end(); bool success = false; diff --git a/source/Target/MemoryHistory.cpp b/source/Target/MemoryHistory.cpp index b97096b06d76..33860f868ee5 100644 --- a/source/Target/MemoryHistory.cpp +++ b/source/Target/MemoryHistory.cpp @@ -1,4 +1,4 @@ -//===-- MemoryHistory.cpp -------------------------*- C++ -*-===// +//===-- MemoryHistory.cpp ---------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,8 +7,11 @@ // //===----------------------------------------------------------------------===// +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes #include "lldb/Target/MemoryHistory.h" - #include "lldb/Core/PluginManager.h" using namespace lldb; @@ -17,12 +20,12 @@ using namespace lldb_private; lldb::MemoryHistorySP MemoryHistory::FindPlugin (const ProcessSP process) { - MemoryHistoryCreateInstance create_callback = NULL; + MemoryHistoryCreateInstance create_callback = nullptr; - for (uint32_t idx = 0; (create_callback = PluginManager::GetMemoryHistoryCreateCallbackAtIndex(idx)) != NULL; ++idx) + for (uint32_t idx = 0; (create_callback = PluginManager::GetMemoryHistoryCreateCallbackAtIndex(idx)) != nullptr; ++idx) { MemoryHistorySP memory_history_sp (create_callback (process)); - if (memory_history_sp.get()) + if (memory_history_sp) return memory_history_sp; } diff --git a/source/Target/ObjCLanguageRuntime.cpp b/source/Target/ObjCLanguageRuntime.cpp index a18e4c69c571..8911d9dab35e 100644 --- a/source/Target/ObjCLanguageRuntime.cpp +++ b/source/Target/ObjCLanguageRuntime.cpp @@ -16,6 +16,7 @@ #include "lldb/Core/ValueObject.h" #include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/SymbolContext.h" +#include "lldb/Symbol/SymbolFile.h" #include "lldb/Symbol/Type.h" #include "lldb/Symbol/TypeList.h" #include "lldb/Target/ObjCLanguageRuntime.h" @@ -122,11 +123,13 @@ ObjCLanguageRuntime::LookupInCompleteClassCache (ConstString &name) const bool exact_match = true; const uint32_t max_matches = UINT32_MAX; TypeList types; - + + llvm::DenseSet<SymbolFile *> searched_symbol_files; const uint32_t num_types = module_sp->FindTypes (null_sc, name, exact_match, max_matches, + searched_symbol_files, types); if (num_types) diff --git a/source/Target/OperatingSystem.cpp b/source/Target/OperatingSystem.cpp index 8ba526838777..9b4f2120befa 100644 --- a/source/Target/OperatingSystem.cpp +++ b/source/Target/OperatingSystem.cpp @@ -1,4 +1,4 @@ -//===-- OperatingSystem.cpp --------------------------------------------*- C++ -*-===// +//===-- OperatingSystem.cpp -------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,22 +7,21 @@ // //===----------------------------------------------------------------------===// - -#include "lldb/Target/OperatingSystem.h" // C Includes // C++ Includes // Other libraries and framework includes +// Project includes +#include "lldb/Target/OperatingSystem.h" #include "lldb/Core/PluginManager.h" #include "lldb/Target/Thread.h" using namespace lldb; using namespace lldb_private; - OperatingSystem* OperatingSystem::FindPlugin (Process *process, const char *plugin_name) { - OperatingSystemCreateInstance create_callback = NULL; + OperatingSystemCreateInstance create_callback = nullptr; if (plugin_name) { ConstString const_plugin_name(plugin_name); @@ -30,20 +29,20 @@ OperatingSystem::FindPlugin (Process *process, const char *plugin_name) if (create_callback) { std::unique_ptr<OperatingSystem> instance_ap(create_callback(process, true)); - if (instance_ap.get()) + if (instance_ap) return instance_ap.release(); } } else { - for (uint32_t idx = 0; (create_callback = PluginManager::GetOperatingSystemCreateCallbackAtIndex(idx)) != NULL; ++idx) + for (uint32_t idx = 0; (create_callback = PluginManager::GetOperatingSystemCreateCallbackAtIndex(idx)) != nullptr; ++idx) { std::unique_ptr<OperatingSystem> instance_ap(create_callback(process, false)); - if (instance_ap.get()) + if (instance_ap) return instance_ap.release(); } } - return NULL; + return nullptr; } @@ -52,10 +51,7 @@ OperatingSystem::OperatingSystem (Process *process) : { } -OperatingSystem::~OperatingSystem() -{ -} - +OperatingSystem::~OperatingSystem() = default; bool OperatingSystem::IsOperatingSystemPluginThread (const lldb::ThreadSP &thread_sp) @@ -64,4 +60,3 @@ OperatingSystem::IsOperatingSystemPluginThread (const lldb::ThreadSP &thread_sp) return thread_sp->IsOperatingSystemPluginThread(); return false; } - diff --git a/source/Target/PathMappingList.cpp b/source/Target/PathMappingList.cpp index 2fd517829b8c..2372c2f9dd95 100644 --- a/source/Target/PathMappingList.cpp +++ b/source/Target/PathMappingList.cpp @@ -8,10 +8,10 @@ //===----------------------------------------------------------------------===// // C Includes -#include <limits.h> -#include <string.h> - // C++ Includes +#include <climits> +#include <cstring> + // Other libraries and framework includes // Project includes #include "lldb/Core/Error.h" @@ -26,10 +26,10 @@ using namespace lldb_private; // PathMappingList constructor //---------------------------------------------------------------------- PathMappingList::PathMappingList () : - m_pairs (), - m_callback (NULL), - m_callback_baton (NULL), - m_mod_id (0) + m_pairs(), + m_callback(nullptr), + m_callback_baton(nullptr), + m_mod_id(0) { } @@ -42,14 +42,12 @@ PathMappingList::PathMappingList (ChangedCallback callback, { } - PathMappingList::PathMappingList (const PathMappingList &rhs) : - m_pairs (rhs.m_pairs), - m_callback (NULL), - m_callback_baton (NULL), - m_mod_id (0) + m_pairs(rhs.m_pairs), + m_callback(nullptr), + m_callback_baton(nullptr), + m_mod_id(0) { - } const PathMappingList & @@ -58,20 +56,14 @@ PathMappingList::operator =(const PathMappingList &rhs) if (this != &rhs) { m_pairs = rhs.m_pairs; - m_callback = NULL; - m_callback_baton = NULL; + m_callback = nullptr; + m_callback_baton = nullptr; m_mod_id = rhs.m_mod_id; } return *this; } - -//---------------------------------------------------------------------- -// Destructor -//---------------------------------------------------------------------- -PathMappingList::~PathMappingList () -{ -} +PathMappingList::~PathMappingList() = default; void PathMappingList::Append (const ConstString &path, @@ -204,7 +196,7 @@ PathMappingList::RemapPath (const ConstString &path, ConstString &new_path) cons bool PathMappingList::RemapPath (const char *path, std::string &new_path) const { - if (m_pairs.empty() || path == NULL || path[0] == '\0') + if (m_pairs.empty() || path == nullptr || path[0] == '\0') return false; const_iterator pos, end = m_pairs.end(); @@ -223,6 +215,27 @@ PathMappingList::RemapPath (const char *path, std::string &new_path) const } bool +PathMappingList::ReverseRemapPath (const ConstString &path, ConstString &new_path) const +{ + const char *path_cstr = path.GetCString(); + if (!path_cstr) + return false; + + for (const auto& it : m_pairs) + { + const size_t prefixLen = it.second.GetLength(); + if (::strncmp (it.second.GetCString(), path_cstr, prefixLen) == 0) + { + std::string new_path_str (it.first.GetCString()); + new_path_str.append(path.GetCString() + prefixLen); + new_path.SetCString(new_path_str.c_str()); + return true; + } + } + return false; +} + +bool PathMappingList::FindFile (const FileSpec &orig_spec, FileSpec &new_spec) const { if (!m_pairs.empty()) @@ -329,8 +342,6 @@ PathMappingList::GetPathsAtIndex (uint32_t idx, ConstString &path, ConstString & return false; } - - uint32_t PathMappingList::FindIndexForPath (const ConstString &path) const { @@ -345,4 +356,3 @@ PathMappingList::FindIndexForPath (const ConstString &path) const } return UINT32_MAX; } - diff --git a/source/Target/Platform.cpp b/source/Target/Platform.cpp index 5077ca23bf74..f537f70452f4 100644 --- a/source/Target/Platform.cpp +++ b/source/Target/Platform.cpp @@ -7,18 +7,20 @@ // //===----------------------------------------------------------------------===// -#include "lldb/Target/Platform.h" - // C Includes - // C++ Includes #include <algorithm> #include <fstream> #include <vector> // Other libraries and framework includes +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/Path.h" + // Project includes +#include "lldb/Target/Platform.h" #include "lldb/Breakpoint/BreakpointIDList.h" +#include "lldb/Breakpoint/BreakpointLocation.h" #include "lldb/Core/DataBufferHeap.h" #include "lldb/Core/Debugger.h" #include "lldb/Core/Error.h" @@ -39,12 +41,8 @@ #include "lldb/Target/Target.h" #include "lldb/Target/UnixSignals.h" #include "lldb/Utility/Utils.h" -#include "llvm/Support/FileSystem.h" -#include "llvm/Support/Path.h" - #include "Utility/ModuleCache.h" - // Define these constants from POSIX mman.h rather than include the file // so that they will be correct even when compiled on Linux. #define MAP_PRIVATE 2 @@ -164,10 +162,10 @@ GetPlatformList() return g_platform_list; } -static Mutex & -GetPlatformListMutex () +static std::recursive_mutex & +GetPlatformListMutex() { - static Mutex g_mutex(Mutex::eMutexTypeRecursive); + static std::recursive_mutex g_mutex; return g_mutex; } @@ -184,7 +182,7 @@ Platform::Terminate () { if (--g_initialize_count == 0) { - Mutex::Locker locker(GetPlatformListMutex ()); + std::lock_guard<std::recursive_mutex> guard(GetPlatformListMutex()); GetPlatformList().clear(); } } @@ -206,7 +204,7 @@ Platform::SetHostPlatform (const lldb::PlatformSP &platform_sp) if (platform_sp) { - Mutex::Locker locker(GetPlatformListMutex ()); + std::lock_guard<std::recursive_mutex> guard(GetPlatformListMutex()); GetPlatformList().push_back(platform_sp); } } @@ -230,7 +228,7 @@ Platform::LocateExecutableScriptingResources (Target *target, Module &module, St //PlatformSP //Platform::FindPlugin (Process *process, const ConstString &plugin_name) //{ -// PlatformCreateInstance create_callback = NULL; +// PlatformCreateInstance create_callback = nullptr; // if (plugin_name) // { // create_callback = PluginManager::GetPlatformCreateCallbackForPluginName (plugin_name); @@ -248,7 +246,7 @@ Platform::LocateExecutableScriptingResources (Target *target, Module &module, St // } // else // { -// for (uint32_t idx = 0; (create_callback = PluginManager::GetPlatformCreateCallbackAtIndex(idx)) != NULL; ++idx) +// for (uint32_t idx = 0; (create_callback = PluginManager::GetPlatformCreateCallbackAtIndex(idx)) != nullptr; ++idx) // { // PlatformSP platform_sp(create_callback(process, nullptr)); // if (platform_sp) @@ -311,7 +309,7 @@ Platform::Find (const ConstString &name) if (name == g_host_platform_name) return GetHostPlatform(); - Mutex::Locker locker(GetPlatformListMutex ()); + std::lock_guard<std::recursive_mutex> guard(GetPlatformListMutex()); for (const auto &platform_sp : GetPlatformList()) { if (platform_sp->GetName() == name) @@ -324,7 +322,7 @@ Platform::Find (const ConstString &name) PlatformSP Platform::Create (const ConstString &name, Error &error) { - PlatformCreateInstance create_callback = NULL; + PlatformCreateInstance create_callback = nullptr; lldb::PlatformSP platform_sp; if (name) { @@ -334,7 +332,7 @@ Platform::Create (const ConstString &name, Error &error) create_callback = PluginManager::GetPlatformCreateCallbackForPluginName (name); if (create_callback) - platform_sp = create_callback(true, NULL); + platform_sp = create_callback(true, nullptr); else error.SetErrorStringWithFormat ("unable to find a plug-in for the platform named \"%s\"", name.GetCString()); } @@ -343,14 +341,13 @@ Platform::Create (const ConstString &name, Error &error) if (platform_sp) { - Mutex::Locker locker(GetPlatformListMutex ()); + std::lock_guard<std::recursive_mutex> guard(GetPlatformListMutex()); GetPlatformList().push_back(platform_sp); } return platform_sp; } - PlatformSP Platform::Create (const ArchSpec &arch, ArchSpec *platform_arch_ptr, Error &error) { @@ -360,7 +357,7 @@ Platform::Create (const ArchSpec &arch, ArchSpec *platform_arch_ptr, Error &erro // Scope for locker { // First try exact arch matches across all platforms already created - Mutex::Locker locker(GetPlatformListMutex ()); + std::lock_guard<std::recursive_mutex> guard(GetPlatformListMutex()); for (const auto &platform_sp : GetPlatformList()) { if (platform_sp->IsCompatibleArchitecture(arch, true, platform_arch_ptr)) @@ -385,7 +382,7 @@ Platform::Create (const ArchSpec &arch, ArchSpec *platform_arch_ptr, Error &erro platform_sp = create_callback(false, &arch); if (platform_sp && platform_sp->IsCompatibleArchitecture(arch, true, platform_arch_ptr)) { - Mutex::Locker locker(GetPlatformListMutex ()); + std::lock_guard<std::recursive_mutex> guard(GetPlatformListMutex()); GetPlatformList().push_back(platform_sp); return platform_sp; } @@ -399,7 +396,7 @@ Platform::Create (const ArchSpec &arch, ArchSpec *platform_arch_ptr, Error &erro platform_sp = create_callback(false, &arch); if (platform_sp && platform_sp->IsCompatibleArchitecture(arch, false, platform_arch_ptr)) { - Mutex::Locker locker(GetPlatformListMutex ()); + std::lock_guard<std::recursive_mutex> guard(GetPlatformListMutex()); GetPlatformList().push_back(platform_sp); return platform_sp; } @@ -417,37 +414,37 @@ Platform::Create (const ArchSpec &arch, ArchSpec *platform_arch_ptr, Error &erro //------------------------------------------------------------------ /// Default Constructor //------------------------------------------------------------------ -Platform::Platform (bool is_host) : - m_is_host (is_host), - m_os_version_set_while_connected (false), - m_system_arch_set_while_connected (false), - m_sdk_sysroot (), - m_sdk_build (), - m_working_dir (), - m_remote_url (), - m_name (), - m_major_os_version (UINT32_MAX), - m_minor_os_version (UINT32_MAX), - m_update_os_version (UINT32_MAX), - m_system_arch(), - m_mutex (Mutex::eMutexTypeRecursive), - m_uid_map(), - m_gid_map(), - m_max_uid_name_len (0), - m_max_gid_name_len (0), - m_supports_rsync (false), - m_rsync_opts (), - m_rsync_prefix (), - m_supports_ssh (false), - m_ssh_opts (), - m_ignores_remote_hostname (false), - m_trap_handlers(), - m_calculated_trap_handlers (false), - m_module_cache (llvm::make_unique<ModuleCache> ()) -{ - Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT)); +Platform::Platform(bool is_host) + : m_is_host(is_host), + m_os_version_set_while_connected(false), + m_system_arch_set_while_connected(false), + m_sdk_sysroot(), + m_sdk_build(), + m_working_dir(), + m_remote_url(), + m_name(), + m_major_os_version(UINT32_MAX), + m_minor_os_version(UINT32_MAX), + m_update_os_version(UINT32_MAX), + m_system_arch(), + m_mutex(), + m_uid_map(), + m_gid_map(), + m_max_uid_name_len(0), + m_max_gid_name_len(0), + m_supports_rsync(false), + m_rsync_opts(), + m_rsync_prefix(), + m_supports_ssh(false), + m_ssh_opts(), + m_ignores_remote_hostname(false), + m_trap_handlers(), + m_calculated_trap_handlers(false), + m_module_cache(llvm::make_unique<ModuleCache>()) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT)); if (log) - log->Printf ("%p Platform::Platform()", static_cast<void*>(this)); + log->Printf("%p Platform::Platform()", static_cast<void *>(this)); } //------------------------------------------------------------------ @@ -521,18 +518,17 @@ Platform::GetStatus (Stream &strm) std::string specific_info(GetPlatformSpecificConnectionInformation()); - if (specific_info.empty() == false) + if (!specific_info.empty()) strm.Printf("Platform-specific connection: %s\n", specific_info.c_str()); } - bool Platform::GetOSVersion (uint32_t &major, uint32_t &minor, uint32_t &update, Process *process) { - Mutex::Locker locker (m_mutex); + std::lock_guard<std::mutex> guard(m_mutex); bool success = m_major_os_version != UINT32_MAX; if (IsHost()) @@ -631,7 +627,6 @@ Platform::AddClangModuleCompilationOptions (Target *target, std::vector<std::str default_compilation_options.end()); } - FileSpec Platform::GetWorkingDirectory () { @@ -651,7 +646,6 @@ Platform::GetWorkingDirectory () } } - struct RecurseCopyBaton { const FileSpec& dst; @@ -659,7 +653,6 @@ struct RecurseCopyBaton Error error; }; - static FileSpec::EnumerateDirectoryResult RecurseCopy_Callback (void *baton, FileSpec::FileType file_type, @@ -728,6 +721,7 @@ RecurseCopy_Callback (void *baton, return FileSpec::eEnumerateDirectoryResultNext; } break; + case FileSpec::eFileTypeRegular: { // copy the file and keep going @@ -964,7 +958,7 @@ Platform::GetHostname () return "127.0.0.1"; if (m_name.empty()) - return NULL; + return nullptr; return m_name.c_str(); } @@ -999,7 +993,7 @@ Platform::GetUserName (uint32_t uid) return SetCachedUserName (uid, name.c_str(), name.size()); } #endif - return NULL; + return nullptr; } const char * @@ -1016,7 +1010,7 @@ Platform::GetGroupName (uint32_t gid) return SetCachedGroupName (gid, name.c_str(), name.size()); } #endif - return NULL; + return nullptr; } bool @@ -1052,7 +1046,6 @@ Platform::SetOSVersion (uint32_t major, return false; } - Error Platform::ResolveExecutable (const ModuleSpec &module_spec, lldb::ModuleSP &exe_module_sp, @@ -1063,11 +1056,11 @@ Platform::ResolveExecutable (const ModuleSpec &module_spec, { if (module_spec.GetArchitecture().IsValid()) { - error = ModuleList::GetSharedModule (module_spec, - exe_module_sp, - module_search_paths_ptr, - NULL, - NULL); + error = ModuleList::GetSharedModule(module_spec, + exe_module_sp, + module_search_paths_ptr, + nullptr, + nullptr); } else { @@ -1077,11 +1070,11 @@ Platform::ResolveExecutable (const ModuleSpec &module_spec, ModuleSpec arch_module_spec(module_spec); for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, arch_module_spec.GetArchitecture()); ++idx) { - error = ModuleList::GetSharedModule (arch_module_spec, - exe_module_sp, - module_search_paths_ptr, - NULL, - NULL); + error = ModuleList::GetSharedModule(arch_module_spec, + exe_module_sp, + module_search_paths_ptr, + nullptr, + nullptr); // Did we find an executable using one of the if (error.Success() && exe_module_sp) break; @@ -1107,10 +1100,7 @@ Platform::ResolveSymbolFile (Target &target, else error.SetErrorString("unable to resolve symbol file"); return error; - -} - - +} bool Platform::ResolveRemotePath (const FileSpec &platform_path, @@ -1120,7 +1110,6 @@ Platform::ResolveRemotePath (const FileSpec &platform_path, return resolved_platform_path.ResolvePath(); } - const ArchSpec & Platform::GetSystemArchitecture() { @@ -1166,7 +1155,6 @@ Platform::GetSystemArchitecture() return m_system_arch; } - Error Platform::ConnectRemote (Args& args) { @@ -1211,7 +1199,6 @@ Platform::FindProcesses (const ProcessInstanceInfoMatch &match_info, return match_count; } - Error Platform::LaunchProcess (ProcessLaunchInfo &launch_info) { @@ -1254,7 +1241,11 @@ Platform::LaunchProcess (ProcessLaunchInfo &launch_info) { error = ShellExpandArguments(launch_info); if (error.Fail()) + { + error.SetErrorStringWithFormat("shell expansion failed (reason: %s). consider launching with 'process launch'.", + error.AsCString("unknown")); return error; + } } if (log) @@ -1309,7 +1300,7 @@ Platform::KillProcess (const lldb::pid_t pid) lldb::ProcessSP Platform::DebugProcess (ProcessLaunchInfo &launch_info, Debugger &debugger, - Target *target, // Can be NULL, if NULL create a new target, else use existing one + Target *target, // Can be nullptr, if nullptr create a new target, else use existing one Error &error) { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PLATFORM)); @@ -1376,7 +1367,6 @@ Platform::DebugProcess (ProcessLaunchInfo &launch_info, return process_sp; } - lldb::PlatformSP Platform::GetPlatformForArchitecture (const ArchSpec &arch, ArchSpec *platform_arch_ptr) { @@ -1387,7 +1377,6 @@ Platform::GetPlatformForArchitecture (const ArchSpec &arch, ArchSpec *platform_a return platform_sp; } - //------------------------------------------------------------------ /// Lets a platform answer if it is compatible with a given /// architecture and the target triple contained within. @@ -1442,7 +1431,7 @@ Platform::PutFile (const FileSpec& source, uint32_t source_open_options = File::eOpenOptionRead | File::eOpenOptionCloseOnExec; if (source.GetFileType() == FileSpec::eFileTypeSymbolicLink) - source_open_options |= File::eOpenoptionDontFollowSymlinks; + source_open_options |= File::eOpenOptionDontFollowSymlinks; File source_file(source, source_open_options, lldb::eFilePermissionsUserRW); Error error; @@ -1539,11 +1528,11 @@ Platform::ConvertMmapFlagsToPlatform(const ArchSpec &arch, unsigned flags) } lldb_private::Error -Platform::RunShellCommand(const char *command, // Shouldn't be NULL +Platform::RunShellCommand(const char *command, // Shouldn't be nullptr const FileSpec &working_dir, // Pass empty FileSpec to use the current working directory - int *status_ptr, // Pass NULL if you don't want the process exit status - int *signo_ptr, // Pass NULL if you don't want the signal that caused the process to exit - std::string *command_output, // Pass NULL if you don't want the command output + int *status_ptr, // Pass nullptr if you don't want the process exit status + int *signo_ptr, // Pass nullptr if you don't want the signal that caused the process to exit + std::string *command_output, // Pass nullptr if you don't want the command output uint32_t timeout_sec) // Timeout in seconds to wait for shell program to finish { if (IsHost()) @@ -1552,7 +1541,6 @@ Platform::RunShellCommand(const char *command, // Shouldn't be NULL return Error("unimplemented"); } - bool Platform::CalculateMD5 (const FileSpec& file_spec, uint64_t &low, @@ -1579,33 +1567,25 @@ Platform::GetLocalCacheDirectory () static OptionDefinition g_rsync_option_table[] = { - { LLDB_OPT_SET_ALL, false, "rsync" , 'r', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone , "Enable rsync." }, - { LLDB_OPT_SET_ALL, false, "rsync-opts" , 'R', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeCommandName , "Platform-specific options required for rsync to work." }, - { LLDB_OPT_SET_ALL, false, "rsync-prefix" , 'P', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeCommandName , "Platform-specific rsync prefix put before the remote path." }, - { LLDB_OPT_SET_ALL, false, "ignore-remote-hostname" , 'i', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone , "Do not automatically fill in the remote hostname when composing the rsync command." }, + { LLDB_OPT_SET_ALL, false, "rsync" , 'r', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone , "Enable rsync." }, + { LLDB_OPT_SET_ALL, false, "rsync-opts" , 'R', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCommandName , "Platform-specific options required for rsync to work." }, + { LLDB_OPT_SET_ALL, false, "rsync-prefix" , 'P', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCommandName , "Platform-specific rsync prefix put before the remote path." }, + { LLDB_OPT_SET_ALL, false, "ignore-remote-hostname" , 'i', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone , "Do not automatically fill in the remote hostname when composing the rsync command." }, }; static OptionDefinition g_ssh_option_table[] = { - { LLDB_OPT_SET_ALL, false, "ssh" , 's', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone , "Enable SSH." }, - { LLDB_OPT_SET_ALL, false, "ssh-opts" , 'S', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeCommandName , "Platform-specific options required for SSH to work." }, + { LLDB_OPT_SET_ALL, false, "ssh" , 's', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone , "Enable SSH." }, + { LLDB_OPT_SET_ALL, false, "ssh-opts" , 'S', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCommandName , "Platform-specific options required for SSH to work." }, }; static OptionDefinition g_caching_option_table[] = { - { LLDB_OPT_SET_ALL, false, "local-cache-dir" , 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePath , "Path in which to store local copies of files." }, + { LLDB_OPT_SET_ALL, false, "local-cache-dir" , 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePath , "Path in which to store local copies of files." }, }; -OptionGroupPlatformRSync::OptionGroupPlatformRSync () -{ -} - -OptionGroupPlatformRSync::~OptionGroupPlatformRSync () -{ -} - const lldb_private::OptionDefinition* OptionGroupPlatformRSync::GetDefinitions () { @@ -1666,14 +1646,6 @@ Platform::SetThreadCreationBreakpoint (lldb_private::Target &target) return lldb::BreakpointSP(); } -OptionGroupPlatformSSH::OptionGroupPlatformSSH () -{ -} - -OptionGroupPlatformSSH::~OptionGroupPlatformSSH () -{ -} - const lldb_private::OptionDefinition* OptionGroupPlatformSSH::GetDefinitions () { @@ -1718,14 +1690,6 @@ OptionGroupPlatformSSH::GetNumDefinitions () return llvm::array_lengthof(g_ssh_option_table); } -OptionGroupPlatformCaching::OptionGroupPlatformCaching () -{ -} - -OptionGroupPlatformCaching::~OptionGroupPlatformCaching () -{ -} - const lldb_private::OptionDefinition* OptionGroupPlatformCaching::GetDefinitions () { @@ -1777,7 +1741,7 @@ Platform::GetTrapHandlerSymbolNames () { if (!m_calculated_trap_handlers) { - Mutex::Locker locker (m_mutex); + std::lock_guard<std::mutex> guard(m_mutex); if (!m_calculated_trap_handlers) { CalculateTrapHandlerSymbolNames(); @@ -1838,14 +1802,30 @@ Platform::GetRemoteSharedModule (const ModuleSpec &module_spec, { // Try to get module information from the process if (process->GetModuleSpec (module_spec.GetFileSpec (), module_spec.GetArchitecture (), resolved_module_spec)) - got_module_spec = true; + { + if (module_spec.GetUUID().IsValid() == false || module_spec.GetUUID() == resolved_module_spec.GetUUID()) + { + got_module_spec = true; + } + } } if (!got_module_spec) { // Get module information from a target. if (!GetModuleSpec (module_spec.GetFileSpec (), module_spec.GetArchitecture (), resolved_module_spec)) - return module_resolver (module_spec); + { + if (module_spec.GetUUID().IsValid() == false || module_spec.GetUUID() == resolved_module_spec.GetUUID()) + { + return module_resolver (module_spec); + } + } + } + + // If we are looking for a specific UUID, make sure resolved_module_spec has the same one before we search. + if (module_spec.GetUUID().IsValid()) + { + resolved_module_spec.GetUUID() = module_spec.GetUUID(); } // Trying to find a module by UUID on local file system. @@ -2087,3 +2067,115 @@ Platform::ConnectToWaitingProcesses(lldb_private::Debugger& debugger, lldb_priva error.Clear(); return 0; } + +size_t +Platform::GetSoftwareBreakpointTrapOpcode(Target &target, BreakpointSite *bp_site) +{ + ArchSpec arch = target.GetArchitecture(); + const uint8_t *trap_opcode = nullptr; + size_t trap_opcode_size = 0; + + switch (arch.GetMachine()) + { + case llvm::Triple::aarch64: + { + static const uint8_t g_aarch64_opcode[] = {0x00, 0x00, 0x20, 0xd4}; + trap_opcode = g_aarch64_opcode; + trap_opcode_size = sizeof(g_aarch64_opcode); + } + break; + + // TODO: support big-endian arm and thumb trap codes. + case llvm::Triple::arm: + { + // The ARM reference recommends the use of 0xe7fddefe and 0xdefe + // but the linux kernel does otherwise. + static const uint8_t g_arm_breakpoint_opcode[] = {0xf0, 0x01, 0xf0, 0xe7}; + static const uint8_t g_thumb_breakpoint_opcode[] = {0x01, 0xde}; + + lldb::BreakpointLocationSP bp_loc_sp(bp_site->GetOwnerAtIndex(0)); + AddressClass addr_class = eAddressClassUnknown; + + if (bp_loc_sp) + { + addr_class = bp_loc_sp->GetAddress().GetAddressClass(); + if (addr_class == eAddressClassUnknown && (bp_loc_sp->GetAddress().GetFileAddress() & 1)) + addr_class = eAddressClassCodeAlternateISA; + } + + if (addr_class == eAddressClassCodeAlternateISA) + { + trap_opcode = g_thumb_breakpoint_opcode; + trap_opcode_size = sizeof(g_thumb_breakpoint_opcode); + } + else + { + trap_opcode = g_arm_breakpoint_opcode; + trap_opcode_size = sizeof(g_arm_breakpoint_opcode); + } + } + break; + + case llvm::Triple::mips: + case llvm::Triple::mips64: + { + static const uint8_t g_hex_opcode[] = {0x00, 0x00, 0x00, 0x0d}; + trap_opcode = g_hex_opcode; + trap_opcode_size = sizeof(g_hex_opcode); + } + break; + + case llvm::Triple::mipsel: + case llvm::Triple::mips64el: + { + static const uint8_t g_hex_opcode[] = {0x0d, 0x00, 0x00, 0x00}; + trap_opcode = g_hex_opcode; + trap_opcode_size = sizeof(g_hex_opcode); + } + break; + + case llvm::Triple::systemz: + { + static const uint8_t g_hex_opcode[] = {0x00, 0x01}; + trap_opcode = g_hex_opcode; + trap_opcode_size = sizeof(g_hex_opcode); + } + break; + + case llvm::Triple::hexagon: + { + static const uint8_t g_hex_opcode[] = {0x0c, 0xdb, 0x00, 0x54}; + trap_opcode = g_hex_opcode; + trap_opcode_size = sizeof(g_hex_opcode); + } + break; + + case llvm::Triple::ppc: + case llvm::Triple::ppc64: + { + static const uint8_t g_ppc_opcode[] = {0x7f, 0xe0, 0x00, 0x08}; + trap_opcode = g_ppc_opcode; + trap_opcode_size = sizeof(g_ppc_opcode); + } + break; + + case llvm::Triple::x86: + case llvm::Triple::x86_64: + { + static const uint8_t g_i386_opcode[] = {0xCC}; + trap_opcode = g_i386_opcode; + trap_opcode_size = sizeof(g_i386_opcode); + } + break; + + default: + assert(!"Unhandled architecture in Platform::GetSoftwareBreakpointTrapOpcode"); + break; + } + + assert(bp_site); + if (bp_site->SetTrapOpcode(trap_opcode, trap_opcode_size)) + return trap_opcode_size; + + return 0; +} diff --git a/source/Target/Process.cpp b/source/Target/Process.cpp index e4fe419660e2..3d1065450e81 100644 --- a/source/Target/Process.cpp +++ b/source/Target/Process.cpp @@ -9,21 +9,25 @@ // C Includes // C++ Includes +#include <atomic> +#include <mutex> + // Other libraries and framework includes // Project includes -#include "lldb/Target/Process.h" -#include "lldb/Breakpoint/StoppointCallbackContext.h" +#include "Plugins/Process/Utility/InferiorCallPOSIX.h" #include "lldb/Breakpoint/BreakpointLocation.h" -#include "lldb/Core/Event.h" +#include "lldb/Breakpoint/StoppointCallbackContext.h" #include "lldb/Core/Debugger.h" +#include "lldb/Core/Event.h" #include "lldb/Core/Log.h" #include "lldb/Core/Module.h" #include "lldb/Core/ModuleSpec.h" #include "lldb/Core/PluginManager.h" #include "lldb/Core/State.h" #include "lldb/Core/StreamFile.h" -#include "lldb/Expression/UserExpression.h" +#include "lldb/Expression/DiagnosticManager.h" #include "lldb/Expression/IRDynamicChecks.h" +#include "lldb/Expression/UserExpression.h" #include "lldb/Host/ConnectionFileDescriptor.h" #include "lldb/Host/FileSystem.h" #include "lldb/Host/Host.h" @@ -36,17 +40,18 @@ #include "lldb/Symbol/Function.h" #include "lldb/Symbol/Symbol.h" #include "lldb/Target/ABI.h" +#include "lldb/Target/CPPLanguageRuntime.h" #include "lldb/Target/DynamicLoader.h" #include "lldb/Target/InstrumentationRuntime.h" #include "lldb/Target/JITLoader.h" #include "lldb/Target/JITLoaderList.h" +#include "lldb/Target/LanguageRuntime.h" #include "lldb/Target/MemoryHistory.h" #include "lldb/Target/MemoryRegionInfo.h" -#include "lldb/Target/OperatingSystem.h" -#include "lldb/Target/LanguageRuntime.h" -#include "lldb/Target/CPPLanguageRuntime.h" #include "lldb/Target/ObjCLanguageRuntime.h" +#include "lldb/Target/OperatingSystem.h" #include "lldb/Target/Platform.h" +#include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Target/StopInfo.h" #include "lldb/Target/SystemRuntime.h" @@ -57,7 +62,6 @@ #include "lldb/Target/ThreadPlanBase.h" #include "lldb/Target/UnixSignals.h" #include "lldb/Utility/NameMatches.h" -#include "Plugins/Process/Utility/InferiorCallPOSIX.h" using namespace lldb; using namespace lldb_private; @@ -111,17 +115,17 @@ public: static PropertyDefinition g_properties[] = { - { "disable-memory-cache" , OptionValue::eTypeBoolean, false, DISABLE_MEM_CACHE_DEFAULT, NULL, NULL, "Disable reading and caching of memory in fixed-size units." }, - { "extra-startup-command", OptionValue::eTypeArray , false, OptionValue::eTypeString, NULL, NULL, "A list containing extra commands understood by the particular process plugin used. " + { "disable-memory-cache" , OptionValue::eTypeBoolean, false, DISABLE_MEM_CACHE_DEFAULT, nullptr, nullptr, "Disable reading and caching of memory in fixed-size units." }, + { "extra-startup-command", OptionValue::eTypeArray , false, OptionValue::eTypeString, nullptr, nullptr, "A list containing extra commands understood by the particular process plugin used. " "For instance, to turn on debugserver logging set this to \"QSetLogging:bitmask=LOG_DEFAULT;\"" }, - { "ignore-breakpoints-in-expressions", OptionValue::eTypeBoolean, true, true, NULL, NULL, "If true, breakpoints will be ignored during expression evaluation." }, - { "unwind-on-error-in-expressions", OptionValue::eTypeBoolean, true, true, NULL, NULL, "If true, errors in expression evaluation will unwind the stack back to the state before the call." }, - { "python-os-plugin-path", OptionValue::eTypeFileSpec, false, true, NULL, NULL, "A path to a python OS plug-in module file that contains a OperatingSystemPlugIn class." }, - { "stop-on-sharedlibrary-events" , OptionValue::eTypeBoolean, true, false, NULL, NULL, "If true, stop when a shared library is loaded or unloaded." }, - { "detach-keeps-stopped" , OptionValue::eTypeBoolean, true, false, NULL, NULL, "If true, detach will attempt to keep the process stopped." }, - { "memory-cache-line-size" , OptionValue::eTypeUInt64, false, 512, NULL, NULL, "The memory cache line size" }, - { "optimization-warnings" , OptionValue::eTypeBoolean, false, true, NULL, NULL, "If true, warn when stopped in code that is optimized where stepping and variable availability may not behave as expected." }, - { NULL , OptionValue::eTypeInvalid, false, 0, NULL, NULL, NULL } + { "ignore-breakpoints-in-expressions", OptionValue::eTypeBoolean, true, true, nullptr, nullptr, "If true, breakpoints will be ignored during expression evaluation." }, + { "unwind-on-error-in-expressions", OptionValue::eTypeBoolean, true, true, nullptr, nullptr, "If true, errors in expression evaluation will unwind the stack back to the state before the call." }, + { "python-os-plugin-path", OptionValue::eTypeFileSpec, false, true, nullptr, nullptr, "A path to a python OS plug-in module file that contains a OperatingSystemPlugIn class." }, + { "stop-on-sharedlibrary-events" , OptionValue::eTypeBoolean, true, false, nullptr, nullptr, "If true, stop when a shared library is loaded or unloaded." }, + { "detach-keeps-stopped" , OptionValue::eTypeBoolean, true, false, nullptr, nullptr, "If true, detach will attempt to keep the process stopped." }, + { "memory-cache-line-size" , OptionValue::eTypeUInt64, false, 512, nullptr, nullptr, "The memory cache line size" }, + { "optimization-warnings" , OptionValue::eTypeBoolean, false, true, nullptr, nullptr, "If true, warn when stopped in code that is optimized where stepping and variable availability may not behave as expected." }, + { nullptr , OptionValue::eTypeInvalid, false, 0, nullptr, nullptr, nullptr } }; enum { @@ -137,10 +141,10 @@ enum { }; ProcessProperties::ProcessProperties (lldb_private::Process *process) : - Properties (), - m_process (process) // Can be NULL for global ProcessProperties + Properties(), + m_process(process) // Can be nullptr for global ProcessProperties { - if (process == NULL) + if (process == nullptr) { // Global process properties, set them up one time m_collection_sp.reset (new ProcessOptionValueProperties(ConstString("process"))); @@ -171,14 +175,14 @@ bool ProcessProperties::GetDisableMemoryCache() const { const uint32_t idx = ePropertyDisableMemCache; - return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0); + return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, g_properties[idx].default_uint_value != 0); } uint64_t ProcessProperties::GetMemoryCacheLineSize() const { const uint32_t idx = ePropertyMemCacheLineSize; - return m_collection_sp->GetPropertyAtIndexAsUInt64 (NULL, idx, g_properties[idx].default_uint_value); + return m_collection_sp->GetPropertyAtIndexAsUInt64(nullptr, idx, g_properties[idx].default_uint_value); } Args @@ -186,7 +190,7 @@ ProcessProperties::GetExtraStartupCommands () const { Args args; const uint32_t idx = ePropertyExtraStartCommand; - m_collection_sp->GetPropertyAtIndexAsArgs(NULL, idx, args); + m_collection_sp->GetPropertyAtIndexAsArgs(nullptr, idx, args); return args; } @@ -194,84 +198,84 @@ void ProcessProperties::SetExtraStartupCommands (const Args &args) { const uint32_t idx = ePropertyExtraStartCommand; - m_collection_sp->SetPropertyAtIndexFromArgs(NULL, idx, args); + m_collection_sp->SetPropertyAtIndexFromArgs(nullptr, idx, args); } FileSpec ProcessProperties::GetPythonOSPluginPath () const { const uint32_t idx = ePropertyPythonOSPluginPath; - return m_collection_sp->GetPropertyAtIndexAsFileSpec(NULL, idx); + return m_collection_sp->GetPropertyAtIndexAsFileSpec(nullptr, idx); } void ProcessProperties::SetPythonOSPluginPath (const FileSpec &file) { const uint32_t idx = ePropertyPythonOSPluginPath; - m_collection_sp->SetPropertyAtIndexAsFileSpec(NULL, idx, file); + m_collection_sp->SetPropertyAtIndexAsFileSpec(nullptr, idx, file); } bool ProcessProperties::GetIgnoreBreakpointsInExpressions () const { const uint32_t idx = ePropertyIgnoreBreakpointsInExpressions; - return m_collection_sp->GetPropertyAtIndexAsBoolean(NULL, idx, g_properties[idx].default_uint_value != 0); + return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, g_properties[idx].default_uint_value != 0); } void ProcessProperties::SetIgnoreBreakpointsInExpressions (bool ignore) { const uint32_t idx = ePropertyIgnoreBreakpointsInExpressions; - m_collection_sp->SetPropertyAtIndexAsBoolean(NULL, idx, ignore); + m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, ignore); } bool ProcessProperties::GetUnwindOnErrorInExpressions () const { const uint32_t idx = ePropertyUnwindOnErrorInExpressions; - return m_collection_sp->GetPropertyAtIndexAsBoolean(NULL, idx, g_properties[idx].default_uint_value != 0); + return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, g_properties[idx].default_uint_value != 0); } void ProcessProperties::SetUnwindOnErrorInExpressions (bool ignore) { const uint32_t idx = ePropertyUnwindOnErrorInExpressions; - m_collection_sp->SetPropertyAtIndexAsBoolean(NULL, idx, ignore); + m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, ignore); } bool ProcessProperties::GetStopOnSharedLibraryEvents () const { const uint32_t idx = ePropertyStopOnSharedLibraryEvents; - return m_collection_sp->GetPropertyAtIndexAsBoolean(NULL, idx, g_properties[idx].default_uint_value != 0); + return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, g_properties[idx].default_uint_value != 0); } void ProcessProperties::SetStopOnSharedLibraryEvents (bool stop) { const uint32_t idx = ePropertyStopOnSharedLibraryEvents; - m_collection_sp->SetPropertyAtIndexAsBoolean(NULL, idx, stop); + m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, stop); } bool ProcessProperties::GetDetachKeepsStopped () const { const uint32_t idx = ePropertyDetachKeepsStopped; - return m_collection_sp->GetPropertyAtIndexAsBoolean(NULL, idx, g_properties[idx].default_uint_value != 0); + return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, g_properties[idx].default_uint_value != 0); } void ProcessProperties::SetDetachKeepsStopped (bool stop) { const uint32_t idx = ePropertyDetachKeepsStopped; - m_collection_sp->SetPropertyAtIndexAsBoolean(NULL, idx, stop); + m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, stop); } bool ProcessProperties::GetWarningsOptimization () const { const uint32_t idx = ePropertyWarningOptimization; - return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0); + return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, g_properties[idx].default_uint_value != 0); } void @@ -294,7 +298,7 @@ ProcessInstanceInfo::Dump (Stream &s, Platform *platform) const const uint32_t argc = m_arguments.GetArgumentCount(); if (argc > 0) { - for (uint32_t i=0; i<argc; i++) + for (uint32_t i = 0; i < argc; i++) { const char *arg = m_arguments.GetArgumentAtIndex(i); if (i < 10) @@ -307,7 +311,7 @@ ProcessInstanceInfo::Dump (Stream &s, Platform *platform) const const uint32_t envc = m_environment.GetArgumentCount(); if (envc > 0) { - for (uint32_t i=0; i<envc; i++) + for (uint32_t i = 0; i < envc; i++) { const char *env = m_environment.GetArgumentAtIndex(i); if (i < 10) @@ -419,7 +423,7 @@ ProcessInstanceInfo::DumpAsTableRow (Stream &s, Platform *platform, bool show_ar const uint32_t argc = m_arguments.GetArgumentCount(); if (argc > 0) { - for (uint32_t i=0; i<argc; i++) + for (uint32_t i = 0; i < argc; i++) { if (i > 0) s.PutChar (' '); @@ -545,29 +549,29 @@ ProcessLaunchCommandOptions::SetOptionValue (uint32_t option_idx, const char *op OptionDefinition ProcessLaunchCommandOptions::g_option_table[] = { -{ LLDB_OPT_SET_ALL, false, "stop-at-entry", 's', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Stop at the entry point of the program when launching a process."}, -{ LLDB_OPT_SET_ALL, false, "disable-aslr", 'A', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "Set whether to disable address space layout randomization when launching a process."}, -{ LLDB_OPT_SET_ALL, false, "plugin", 'p', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePlugin, "Name of the process plugin you want to use."}, -{ LLDB_OPT_SET_ALL, false, "working-dir", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeDirectoryName, "Set the current working directory to <path> when running the inferior."}, -{ LLDB_OPT_SET_ALL, false, "arch", 'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeArchitecture, "Set the architecture for the process to launch when ambiguous."}, -{ LLDB_OPT_SET_ALL, false, "environment", 'v', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeNone, "Specify an environment variable name/value string (--environment NAME=VALUE). Can be specified multiple times for subsequent environment entries."}, -{ LLDB_OPT_SET_1|LLDB_OPT_SET_2|LLDB_OPT_SET_3, false, "shell", 'c', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeFilename, "Run the process in a shell (not supported on all platforms)."}, +{ LLDB_OPT_SET_ALL, false, "stop-at-entry", 's', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Stop at the entry point of the program when launching a process." }, +{ LLDB_OPT_SET_ALL, false, "disable-aslr", 'A', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Set whether to disable address space layout randomization when launching a process." }, +{ LLDB_OPT_SET_ALL, false, "plugin", 'p', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePlugin, "Name of the process plugin you want to use." }, +{ LLDB_OPT_SET_ALL, false, "working-dir", 'w', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeDirectoryName, "Set the current working directory to <path> when running the inferior." }, +{ LLDB_OPT_SET_ALL, false, "arch", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeArchitecture, "Set the architecture for the process to launch when ambiguous." }, +{ LLDB_OPT_SET_ALL, false, "environment", 'v', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeNone, "Specify an environment variable name/value string (--environment NAME=VALUE). Can be specified multiple times for subsequent environment entries." }, +{ LLDB_OPT_SET_1|LLDB_OPT_SET_2|LLDB_OPT_SET_3, false, "shell", 'c', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeFilename, "Run the process in a shell (not supported on all platforms)." }, -{ LLDB_OPT_SET_1 , false, "stdin", 'i', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFilename, "Redirect stdin for the process to <filename>."}, -{ LLDB_OPT_SET_1 , false, "stdout", 'o', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFilename, "Redirect stdout for the process to <filename>."}, -{ LLDB_OPT_SET_1 , false, "stderr", 'e', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFilename, "Redirect stderr for the process to <filename>."}, +{ LLDB_OPT_SET_1 , false, "stdin", 'i', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFilename, "Redirect stdin for the process to <filename>." }, +{ LLDB_OPT_SET_1 , false, "stdout", 'o', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFilename, "Redirect stdout for the process to <filename>." }, +{ LLDB_OPT_SET_1 , false, "stderr", 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFilename, "Redirect stderr for the process to <filename>." }, -{ LLDB_OPT_SET_2 , false, "tty", 't', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Start the process in a terminal (not supported on all platforms)."}, +{ LLDB_OPT_SET_2 , false, "tty", 't', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Start the process in a terminal (not supported on all platforms)." }, -{ LLDB_OPT_SET_3 , false, "no-stdio", 'n', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Do not set up for terminal I/O to go to running process."}, -{ LLDB_OPT_SET_4, false, "shell-expand-args", 'X', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "Set whether to shell expand arguments to the process when launching."}, -{ 0 , false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } +{ LLDB_OPT_SET_3 , false, "no-stdio", 'n', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Do not set up for terminal I/O to go to running process." }, +{ LLDB_OPT_SET_4, false, "shell-expand-args", 'X', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Set whether to shell expand arguments to the process when launching." }, +{ 0 , false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr } }; bool ProcessInstanceInfoMatch::NameMatches (const char *process_name) const { - if (m_name_match_type == eNameMatchIgnore || process_name == NULL) + if (m_name_match_type == eNameMatchIgnore || process_name == nullptr) return true; const char *match_name = m_match_info.GetName(); if (!match_name) @@ -654,19 +658,19 @@ ProcessInstanceInfoMatch::Clear() } ProcessSP -Process::FindPlugin (lldb::TargetSP target_sp, const char *plugin_name, Listener &listener, const FileSpec *crash_file_path) +Process::FindPlugin (lldb::TargetSP target_sp, const char *plugin_name, ListenerSP listener_sp, const FileSpec *crash_file_path) { static uint32_t g_process_unique_id = 0; ProcessSP process_sp; - ProcessCreateInstance create_callback = NULL; + ProcessCreateInstance create_callback = nullptr; if (plugin_name) { ConstString const_plugin_name(plugin_name); create_callback = PluginManager::GetProcessCreateCallbackForPluginName (const_plugin_name); if (create_callback) { - process_sp = create_callback(target_sp, listener, crash_file_path); + process_sp = create_callback(target_sp, listener_sp, crash_file_path); if (process_sp) { if (process_sp->CanDebug(target_sp, true)) @@ -680,9 +684,9 @@ Process::FindPlugin (lldb::TargetSP target_sp, const char *plugin_name, Listener } else { - for (uint32_t idx = 0; (create_callback = PluginManager::GetProcessCreateCallbackAtIndex(idx)) != NULL; ++idx) + for (uint32_t idx = 0; (create_callback = PluginManager::GetProcessCreateCallbackAtIndex(idx)) != nullptr; ++idx) { - process_sp = create_callback(target_sp, listener, crash_file_path); + process_sp = create_callback(target_sp, listener_sp, crash_file_path); if (process_sp) { if (process_sp->CanDebug(target_sp, false)) @@ -705,113 +709,107 @@ Process::GetStaticBroadcasterClass () return class_name; } -Process::Process(lldb::TargetSP target_sp, Listener &listener) : - Process(target_sp, listener, UnixSignals::Create(HostInfo::GetArchitecture())) +Process::Process(lldb::TargetSP target_sp, ListenerSP listener_sp) : + Process(target_sp, listener_sp, UnixSignals::Create(HostInfo::GetArchitecture())) { // This constructor just delegates to the full Process constructor, // defaulting to using the Host's UnixSignals. } -Process::Process(lldb::TargetSP target_sp, Listener &listener, const UnixSignalsSP &unix_signals_sp) : - ProcessProperties (this), - UserID (LLDB_INVALID_PROCESS_ID), - Broadcaster (&(target_sp->GetDebugger()), Process::GetStaticBroadcasterClass().AsCString()), - m_target_sp (target_sp), - m_public_state (eStateUnloaded), - m_private_state (eStateUnloaded), - m_private_state_broadcaster (NULL, "lldb.process.internal_state_broadcaster"), - m_private_state_control_broadcaster (NULL, "lldb.process.internal_state_control_broadcaster"), - m_private_state_listener ("lldb.process.internal_state_listener"), - m_private_state_control_wait(), - m_mod_id (), - m_process_unique_id(0), - m_thread_index_id (0), - m_thread_id_to_index_id_map (), - m_exit_status (-1), - m_exit_string (), - m_exit_status_mutex(), - m_thread_mutex (Mutex::eMutexTypeRecursive), - m_thread_list_real (this), - m_thread_list (this), - m_extended_thread_list (this), - m_extended_thread_stop_id (0), - m_queue_list (this), - m_queue_list_stop_id (0), - m_notifications (), - m_image_tokens (), - m_listener (listener), - m_breakpoint_site_list (), - m_dynamic_checkers_ap (), - m_unix_signals_sp (unix_signals_sp), - m_abi_sp (), - m_process_input_reader (), - m_stdio_communication ("process.stdio"), - m_stdio_communication_mutex (Mutex::eMutexTypeRecursive), - m_stdin_forward (false), - m_stdout_data (), - m_stderr_data (), - m_profile_data_comm_mutex (Mutex::eMutexTypeRecursive), - m_profile_data (), - m_iohandler_sync (0), - m_memory_cache (*this), - m_allocated_memory_cache (*this), - m_should_detach (false), - m_next_event_action_ap(), - m_public_run_lock (), - m_private_run_lock (), - m_stop_info_override_callback (NULL), - m_finalizing (false), - m_finalize_called (false), - m_clear_thread_plans_on_stop (false), - m_force_next_event_delivery (false), - m_last_broadcast_state (eStateInvalid), - m_destroy_in_process (false), - m_can_interpret_function_calls(false), - m_warnings_issued (), - m_can_jit(eCanJITDontKnow) -{ - CheckInWithManager (); - - Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT)); +Process::Process(lldb::TargetSP target_sp, ListenerSP listener_sp, const UnixSignalsSP &unix_signals_sp) + : ProcessProperties(this), + UserID(LLDB_INVALID_PROCESS_ID), + Broadcaster((target_sp->GetDebugger().GetBroadcasterManager()), Process::GetStaticBroadcasterClass().AsCString()), + m_target_sp(target_sp), + m_public_state(eStateUnloaded), + m_private_state(eStateUnloaded), + m_private_state_broadcaster(nullptr, "lldb.process.internal_state_broadcaster"), + m_private_state_control_broadcaster(nullptr, "lldb.process.internal_state_control_broadcaster"), + m_private_state_listener_sp(Listener::MakeListener("lldb.process.internal_state_listener")), + m_mod_id(), + m_process_unique_id(0), + m_thread_index_id(0), + m_thread_id_to_index_id_map(), + m_exit_status(-1), + m_exit_string(), + m_exit_status_mutex(), + m_thread_mutex(), + m_thread_list_real(this), + m_thread_list(this), + m_extended_thread_list(this), + m_extended_thread_stop_id(0), + m_queue_list(this), + m_queue_list_stop_id(0), + m_notifications(), + m_image_tokens(), + m_listener_sp(listener_sp), + m_breakpoint_site_list(), + m_dynamic_checkers_ap(), + m_unix_signals_sp(unix_signals_sp), + m_abi_sp(), + m_process_input_reader(), + m_stdio_communication("process.stdio"), + m_stdio_communication_mutex(), + m_stdin_forward(false), + m_stdout_data(), + m_stderr_data(), + m_profile_data_comm_mutex(), + m_profile_data(), + m_iohandler_sync(0), + m_memory_cache(*this), + m_allocated_memory_cache(*this), + m_should_detach(false), + m_next_event_action_ap(), + m_public_run_lock(), + m_private_run_lock(), + m_stop_info_override_callback(nullptr), + m_finalizing(false), + m_finalize_called(false), + m_clear_thread_plans_on_stop(false), + m_force_next_event_delivery(false), + m_last_broadcast_state(eStateInvalid), + m_destroy_in_process(false), + m_can_interpret_function_calls(false), + m_warnings_issued(), + m_run_thread_plan_lock(), + m_can_jit(eCanJITDontKnow) +{ + CheckInWithManager(); + + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT)); if (log) - log->Printf ("%p Process::Process()", static_cast<void*>(this)); + log->Printf("%p Process::Process()", static_cast<void *>(this)); if (!m_unix_signals_sp) m_unix_signals_sp = std::make_shared<UnixSignals>(); - SetEventName (eBroadcastBitStateChanged, "state-changed"); - SetEventName (eBroadcastBitInterrupt, "interrupt"); - SetEventName (eBroadcastBitSTDOUT, "stdout-available"); - SetEventName (eBroadcastBitSTDERR, "stderr-available"); - SetEventName (eBroadcastBitProfileData, "profile-data-available"); - - m_private_state_control_broadcaster.SetEventName (eBroadcastInternalStateControlStop , "control-stop" ); - m_private_state_control_broadcaster.SetEventName (eBroadcastInternalStateControlPause , "control-pause" ); - m_private_state_control_broadcaster.SetEventName (eBroadcastInternalStateControlResume, "control-resume"); - - listener.StartListeningForEvents (this, - eBroadcastBitStateChanged | - eBroadcastBitInterrupt | - eBroadcastBitSTDOUT | - eBroadcastBitSTDERR | - eBroadcastBitProfileData); - - m_private_state_listener.StartListeningForEvents(&m_private_state_broadcaster, - eBroadcastBitStateChanged | - eBroadcastBitInterrupt); - - m_private_state_listener.StartListeningForEvents(&m_private_state_control_broadcaster, - eBroadcastInternalStateControlStop | - eBroadcastInternalStateControlPause | - eBroadcastInternalStateControlResume); + SetEventName(eBroadcastBitStateChanged, "state-changed"); + SetEventName(eBroadcastBitInterrupt, "interrupt"); + SetEventName(eBroadcastBitSTDOUT, "stdout-available"); + SetEventName(eBroadcastBitSTDERR, "stderr-available"); + SetEventName(eBroadcastBitProfileData, "profile-data-available"); + + m_private_state_control_broadcaster.SetEventName(eBroadcastInternalStateControlStop, "control-stop"); + m_private_state_control_broadcaster.SetEventName(eBroadcastInternalStateControlPause, "control-pause"); + m_private_state_control_broadcaster.SetEventName(eBroadcastInternalStateControlResume, "control-resume"); + + m_listener_sp->StartListeningForEvents(this, eBroadcastBitStateChanged | eBroadcastBitInterrupt | + eBroadcastBitSTDOUT | eBroadcastBitSTDERR | + eBroadcastBitProfileData); + + m_private_state_listener_sp->StartListeningForEvents(&m_private_state_broadcaster, + eBroadcastBitStateChanged | eBroadcastBitInterrupt); + + m_private_state_listener_sp->StartListeningForEvents( + &m_private_state_control_broadcaster, eBroadcastInternalStateControlStop | eBroadcastInternalStateControlPause | + eBroadcastInternalStateControlResume); // We need something valid here, even if just the default UnixSignalsSP. - assert (m_unix_signals_sp && "null m_unix_signals_sp after initialization"); + assert(m_unix_signals_sp && "null m_unix_signals_sp after initialization"); // Allow the platform to override the default cache line size - OptionValueSP value_sp = - m_collection_sp->GetPropertyAtIndex(nullptr, true, ePropertyMemCacheLineSize)->GetValue(); + OptionValueSP value_sp = m_collection_sp->GetPropertyAtIndex(nullptr, true, ePropertyMemCacheLineSize)->GetValue(); uint32_t platform_cache_line_size = target_sp->GetPlatform()->GetDefaultMemoryCacheLineSize(); - if (! value_sp->OptionWasSet() && platform_cache_line_size != 0) + if (!value_sp->OptionWasSet() && platform_cache_line_size != 0) value_sp->SetUInt64Value(platform_cache_line_size); } @@ -831,10 +829,14 @@ Process::~Process() const ProcessPropertiesSP & Process::GetGlobalProperties() { - static ProcessPropertiesSP g_settings_sp; - if (!g_settings_sp) - g_settings_sp.reset (new ProcessProperties (NULL)); - return g_settings_sp; + // NOTE: intentional leak so we don't crash if global destructor chain gets + // called as other threads still use the result of this function + static ProcessPropertiesSP *g_settings_sp_ptr = nullptr; + static std::once_flag g_once_flag; + std::call_once(g_once_flag, []() { + g_settings_sp_ptr = new ProcessPropertiesSP(new ProcessProperties(nullptr)); + }); + return *g_settings_sp_ptr; } void @@ -890,14 +892,14 @@ Process::Finalize() m_language_runtimes.clear(); m_instrumentation_runtimes.clear(); m_next_event_action_ap.reset(); - m_stop_info_override_callback = NULL; + m_stop_info_override_callback = nullptr; // Clear the last natural stop ID since it has a strong // reference to this process m_mod_id.SetStopEventForLastNaturalStopID(EventSP()); //#ifdef LLDB_CONFIGURATION_DEBUG // StreamFile s(stdout, false); // EventSP event_sp; -// while (m_private_state_listener.GetNextEvent(event_sp)) +// while (m_private_state_listener_sp->GetNextEvent(event_sp)) // { // event_sp->Dump (&s); // s.EOL(); @@ -906,7 +908,7 @@ Process::Finalize() // We have to be very careful here as the m_private_state_listener might // contain events that have ProcessSP values in them which can keep this // process around forever. These events need to be cleared out. - m_private_state_listener.Clear(); + m_private_state_listener_sp->Clear(); m_public_run_lock.TrySetRunning(); // This will do nothing if already locked m_public_run_lock.SetStopped(); m_private_run_lock.TrySetRunning(); // This will do nothing if already locked @@ -918,7 +920,7 @@ void Process::RegisterNotificationCallbacks (const Notifications& callbacks) { m_notifications.push_back(callbacks); - if (callbacks.initialize != NULL) + if (callbacks.initialize != nullptr) callbacks.initialize (callbacks.baton, this); } @@ -963,7 +965,7 @@ Process::GetNextEvent (EventSP &event_sp) { StateType state = eStateInvalid; - if (m_listener.GetNextEventForBroadcaster (this, event_sp) && event_sp) + if (m_listener_sp->GetNextEventForBroadcaster (this, event_sp) && event_sp) state = Process::ProcessEventData::GetStateFromEvent (event_sp.get()); return state; @@ -973,7 +975,7 @@ void Process::SyncIOHandler (uint32_t iohandler_id, uint64_t timeout_msec) { // don't sync (potentially context switch) in case where there is no process IO - if (! m_process_input_reader) + if (!m_process_input_reader) return; TimeValue timeout = TimeValue::Now(); @@ -990,7 +992,7 @@ StateType Process::WaitForProcessToStop (const TimeValue *timeout, EventSP *event_sp_ptr, bool wait_always, - Listener *hijack_listener, + ListenerSP hijack_listener_sp, Stream *stream, bool use_run_lock) { @@ -1019,7 +1021,7 @@ Process::WaitForProcessToStop (const TimeValue *timeout, __FUNCTION__); // We need to toggle the run lock as this won't get done in // SetPublicState() if the process is hijacked. - if (hijack_listener && use_run_lock) + if (hijack_listener_sp && use_run_lock) m_public_run_lock.SetStopped(); return state; } @@ -1027,11 +1029,11 @@ Process::WaitForProcessToStop (const TimeValue *timeout, while (state != eStateInvalid) { EventSP event_sp; - state = WaitForStateChangedEvents (timeout, event_sp, hijack_listener); + state = WaitForStateChangedEvents (timeout, event_sp, hijack_listener_sp); if (event_sp_ptr && event_sp) *event_sp_ptr = event_sp; - bool pop_process_io_handler = hijack_listener != NULL; + bool pop_process_io_handler = (hijack_listener_sp.get() != nullptr); Process::HandleProcessStateChangedEvent (event_sp, stream, pop_process_io_handler); switch (state) @@ -1042,7 +1044,7 @@ Process::WaitForProcessToStop (const TimeValue *timeout, case eStateUnloaded: // We need to toggle the run lock as this won't get done in // SetPublicState() if the process is hijacked. - if (hijack_listener && use_run_lock) + if (hijack_listener_sp && use_run_lock) m_public_run_lock.SetStopped(); return state; case eStateStopped: @@ -1052,7 +1054,7 @@ Process::WaitForProcessToStop (const TimeValue *timeout, { // We need to toggle the run lock as this won't get done in // SetPublicState() if the process is hijacked. - if (hijack_listener && use_run_lock) + if (hijack_listener_sp && use_run_lock) m_public_run_lock.SetStopped(); return state; } @@ -1068,7 +1070,7 @@ Process::HandleProcessStateChangedEvent (const EventSP &event_sp, Stream *stream, bool &pop_process_io_handler) { - const bool handle_pop = pop_process_io_handler == true; + const bool handle_pop = pop_process_io_handler; pop_process_io_handler = false; ProcessSP process_sp = Process::ProcessEventData::GetProcessFromEvent(event_sp.get()); @@ -1088,15 +1090,12 @@ Process::HandleProcessStateChangedEvent (const EventSP &event_sp, case eStateLaunching: case eStateStepping: case eStateDetached: - { - if (stream) - stream->Printf ("Process %" PRIu64 " %s\n", - process_sp->GetID(), - StateAsCString (event_state)); - - if (event_state == eStateDetached) - pop_process_io_handler = true; - } + if (stream) + stream->Printf("Process %" PRIu64 " %s\n", + process_sp->GetID(), + StateAsCString (event_state)); + if (event_state == eStateDetached) + pop_process_io_handler = true; break; case eStateConnected: @@ -1149,7 +1148,7 @@ Process::HandleProcessStateChangedEvent (const EventSP &event_sp, // Lock the thread list so it doesn't change on us, this is the scope for the locker: { ThreadList &thread_list = process_sp->GetThreadList(); - Mutex::Locker locker (thread_list.GetMutex()); + std::lock_guard<std::recursive_mutex> guard(thread_list.GetMutex()); ThreadSP curr_thread (thread_list.GetSelectedThread()); ThreadSP thread; @@ -1271,7 +1270,6 @@ Process::WaitForState(const TimeValue *timeout, const uint32_t num_match_states) { EventSP event_sp; - uint32_t i; StateType state = GetState(); while (state != eStateInvalid) { @@ -1280,9 +1278,9 @@ Process::WaitForState(const TimeValue *timeout, if (state == eStateDetached || state == eStateExited) return state; - state = WaitForStateChangedEvents (timeout, event_sp, NULL); + state = WaitForStateChangedEvents(timeout, event_sp, nullptr); - for (i=0; i<num_match_states; ++i) + for (uint32_t i = 0; i < num_match_states; ++i) { if (match_states[i] == state) return state; @@ -1292,11 +1290,11 @@ Process::WaitForState(const TimeValue *timeout, } bool -Process::HijackProcessEvents (Listener *listener) +Process::HijackProcessEvents (ListenerSP listener_sp) { - if (listener != NULL) + if (listener_sp) { - return HijackBroadcaster(listener, eBroadcastBitStateChanged | eBroadcastBitInterrupt); + return HijackBroadcaster(listener_sp, eBroadcastBitStateChanged | eBroadcastBitInterrupt); } else return false; @@ -1309,7 +1307,7 @@ Process::RestoreProcessEvents () } StateType -Process::WaitForStateChangedEvents (const TimeValue *timeout, EventSP &event_sp, Listener *hijack_listener) +Process::WaitForStateChangedEvents (const TimeValue *timeout, EventSP &event_sp, ListenerSP hijack_listener_sp) { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); @@ -1317,15 +1315,15 @@ Process::WaitForStateChangedEvents (const TimeValue *timeout, EventSP &event_sp, log->Printf ("Process::%s (timeout = %p, event_sp)...", __FUNCTION__, static_cast<const void*>(timeout)); - Listener *listener = hijack_listener; - if (listener == NULL) - listener = &m_listener; + ListenerSP listener_sp = hijack_listener_sp; + if (!listener_sp) + listener_sp = m_listener_sp; StateType state = eStateInvalid; - if (listener->WaitForEventForBroadcasterWithType (timeout, - this, - eBroadcastBitStateChanged | eBroadcastBitInterrupt, - event_sp)) + if (listener_sp->WaitForEventForBroadcasterWithType (timeout, + this, + eBroadcastBitStateChanged | eBroadcastBitInterrupt, + event_sp)) { if (event_sp && event_sp->GetType() == eBroadcastBitStateChanged) state = Process::ProcessEventData::GetStateFromEvent(event_sp.get()); @@ -1349,7 +1347,7 @@ Process::PeekAtStateChangedEvents () log->Printf ("Process::%s...", __FUNCTION__); Event *event_ptr; - event_ptr = m_listener.PeekAtNextEventForBroadcasterWithType (this, + event_ptr = m_listener_sp->PeekAtNextEventForBroadcasterWithType (this, eBroadcastBitStateChanged); if (log) { @@ -1378,7 +1376,7 @@ Process::WaitForStateChangedEventsPrivate (const TimeValue *timeout, EventSP &ev static_cast<const void*>(timeout)); StateType state = eStateInvalid; - if (m_private_state_listener.WaitForEventForBroadcasterWithType (timeout, + if (m_private_state_listener_sp->WaitForEventForBroadcasterWithType (timeout, &m_private_state_broadcaster, eBroadcastBitStateChanged | eBroadcastBitInterrupt, event_sp)) @@ -1405,9 +1403,9 @@ Process::WaitForEventsPrivate (const TimeValue *timeout, EventSP &event_sp, bool static_cast<const void*>(timeout)); if (control_only) - return m_private_state_listener.WaitForEventForBroadcaster(timeout, &m_private_state_control_broadcaster, event_sp); + return m_private_state_listener_sp->WaitForEventForBroadcaster(timeout, &m_private_state_control_broadcaster, event_sp); else - return m_private_state_listener.WaitForEvent(timeout, event_sp); + return m_private_state_listener_sp->WaitForEvent(timeout, event_sp); } bool @@ -1419,7 +1417,7 @@ Process::IsRunning () const int Process::GetExitStatus () { - Mutex::Locker locker (m_exit_status_mutex); + std::lock_guard<std::mutex> guard(m_exit_status_mutex); if (m_public_state.GetValue() == eStateExited) return m_exit_status; @@ -1429,18 +1427,18 @@ Process::GetExitStatus () const char * Process::GetExitDescription () { - Mutex::Locker locker (m_exit_status_mutex); + std::lock_guard<std::mutex> guard(m_exit_status_mutex); if (m_public_state.GetValue() == eStateExited && !m_exit_string.empty()) return m_exit_string.c_str(); - return NULL; + return nullptr; } bool Process::SetExitStatus (int status, const char *cstr) { // Use a mutex to protect setting the exit status. - Mutex::Locker locker (m_exit_status_mutex); + std::lock_guard<std::mutex> guard(m_exit_status_mutex); Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STATE | LIBLLDB_LOG_PROCESS)); if (log) @@ -1464,14 +1462,6 @@ Process::SetExitStatus (int status, const char *cstr) else m_exit_string.clear(); - // When we exit, we don't need the input reader anymore - if (m_process_input_reader) - { - m_process_input_reader->SetIsDone(true); - m_process_input_reader->Cancel(); - m_process_input_reader.reset(); - } - // Clear the last natural stop ID since it has a strong // reference to this process m_mod_id.SetStopEventForLastNaturalStopID(EventSP()); @@ -1489,12 +1479,6 @@ Process::IsAlive () { switch (m_private_state.GetValue()) { - case eStateInvalid: - case eStateUnloaded: - case eStateDetached: - case eStateExited: - return false; - case eStateConnected: case eStateAttaching: case eStateLaunching: @@ -1504,6 +1488,8 @@ Process::IsAlive () case eStateCrashed: case eStateSuspended: return true; + default: + return false; } } @@ -1512,21 +1498,15 @@ Process::IsAlive () // found in the global target list (we want to be completely sure that the // lldb_private::Process doesn't go away before we can deliver the signal. bool -Process::SetProcessExitStatus (void *callback_baton, - lldb::pid_t pid, - bool exited, - int signo, // Zero for no signal - int exit_status // Exit value of process if signal is zero -) +Process::SetProcessExitStatus(lldb::pid_t pid, bool exited, + int signo, // Zero for no signal + int exit_status // Exit value of process if signal is zero + ) { Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_PROCESS)); if (log) - log->Printf ("Process::SetProcessExitStatus (baton=%p, pid=%" PRIu64 ", exited=%i, signal=%i, exit_status=%i)\n", - callback_baton, - pid, - exited, - signo, - exit_status); + log->Printf("Process::SetProcessExitStatus (pid=%" PRIu64 ", exited=%i, signal=%i, exit_status=%i)\n", pid, + exited, signo, exit_status); if (exited) { @@ -1536,7 +1516,7 @@ Process::SetProcessExitStatus (void *callback_baton, ProcessSP process_sp (target_sp->GetProcessSP()); if (process_sp) { - const char *signal_cstr = NULL; + const char *signal_cstr = nullptr; if (signo) signal_cstr = process_sp->GetUnixSignals()->GetSignalAsCString(signo); @@ -1557,7 +1537,7 @@ Process::UpdateThreadListIfNeeded () const StateType state = GetPrivateState(); if (StateIsStoppedState (state, true)) { - Mutex::Locker locker (m_thread_list.GetMutex ()); + std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex()); // m_thread_list does have its own mutex, but we need to // hold onto the mutex between the call to UpdateThreadList(...) // and the os->UpdateThreadList(...) so it doesn't change on us @@ -1577,7 +1557,7 @@ Process::UpdateThreadListIfNeeded () // Clear any old backing threads where memory threads might have been // backed by actual threads from the lldb_private::Process subclass size_t num_old_threads = old_thread_list.GetSize(false); - for (size_t i=0; i<num_old_threads; ++i) + for (size_t i = 0; i < num_old_threads; ++i) old_thread_list.GetThreadAtIndex(i, false)->ClearBackingThread(); // Turn off dynamic types to ensure we don't run any expressions. Objective C @@ -1626,7 +1606,7 @@ Process::UpdateThreadListIfNeeded () void Process::UpdateQueueListIfNeeded () { - if (m_system_runtime_ap.get()) + if (m_system_runtime_ap) { if (m_queue_list.GetSize() == 0 || m_queue_list_stop_id != GetLastNaturalStopID()) { @@ -1691,7 +1671,8 @@ Process::StateChangedIsExternallyHijacked() { if (IsHijackedForEvent(eBroadcastBitStateChanged)) { - if (strcmp(m_hijacking_listeners.back()->GetName(), "lldb.Process.ResumeSynchronous.hijack")) + const char *hijacking_name = GetHijackingListenerName(); + if (hijacking_name && strcmp(hijacking_name, "lldb.Process.ResumeSynchronous.hijack")) return true; } return false; @@ -1764,13 +1745,13 @@ Process::ResumeSynchronous (Stream *stream) return error; } - ListenerSP listener_sp (new Listener("lldb.Process.ResumeSynchronous.hijack")); - HijackProcessEvents(listener_sp.get()); + ListenerSP listener_sp (Listener::MakeListener("lldb.Process.ResumeSynchronous.hijack")); + HijackProcessEvents(listener_sp); Error error = PrivateResume(); if (error.Success()) { - StateType state = WaitForProcessToStop (NULL, NULL, true, listener_sp.get(), stream); + StateType state = WaitForProcessToStop (NULL, NULL, true, listener_sp, stream); const bool must_be_alive = false; // eStateExited is ok, so this must be false if (!StateIsStoppedState(state, must_be_alive)) error.SetErrorStringWithFormat("process not in stopped state after synchronous resume: %s", StateAsCString(state)); @@ -1800,8 +1781,8 @@ Process::SetPrivateState (StateType new_state) if (log) log->Printf("Process::SetPrivateState (%s)", StateAsCString(new_state)); - Mutex::Locker thread_locker(m_thread_list.GetMutex()); - Mutex::Locker locker(m_private_state.GetMutex()); + std::lock_guard<std::recursive_mutex> thread_guard(m_thread_list.GetMutex()); + std::lock_guard<std::recursive_mutex> guard(m_private_state.GetMutex()); const StateType old_state = m_private_state.GetValueNoLock (); state_changed = old_state != new_state; @@ -1844,7 +1825,7 @@ Process::SetPrivateState (StateType new_state) } // Use our target to get a shared pointer to ourselves... - if (m_finalize_called && PrivateStateThreadIsValid() == false) + if (m_finalize_called && !PrivateStateThreadIsValid()) BroadcastEvent (event_sp); else m_private_state_broadcaster.BroadcastEvent (event_sp); @@ -1899,18 +1880,18 @@ CPPLanguageRuntime * Process::GetCPPLanguageRuntime (bool retry_if_null) { LanguageRuntime *runtime = GetLanguageRuntime(eLanguageTypeC_plus_plus, retry_if_null); - if (runtime != NULL && runtime->GetLanguageType() == eLanguageTypeC_plus_plus) + if (runtime != nullptr && runtime->GetLanguageType() == eLanguageTypeC_plus_plus) return static_cast<CPPLanguageRuntime *> (runtime); - return NULL; + return nullptr; } ObjCLanguageRuntime * Process::GetObjCLanguageRuntime (bool retry_if_null) { LanguageRuntime *runtime = GetLanguageRuntime(eLanguageTypeObjC, retry_if_null); - if (runtime != NULL && runtime->GetLanguageType() == eLanguageTypeObjC) + if (runtime != nullptr && runtime->GetLanguageType() == eLanguageTypeObjC) return static_cast<ObjCLanguageRuntime *> (runtime); - return NULL; + return nullptr; } bool @@ -2167,7 +2148,7 @@ Error Process::EnableSoftwareBreakpoint (BreakpointSite *bp_site) { Error error; - assert (bp_site != NULL); + assert(bp_site != nullptr); Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_BREAKPOINTS)); const addr_t bp_addr = bp_site->GetLoadAddress(); if (log) @@ -2196,7 +2177,7 @@ Process::EnableSoftwareBreakpoint (BreakpointSite *bp_site) { const uint8_t * const bp_opcode_bytes = bp_site->GetTrapOpcodeBytes(); - if (bp_opcode_bytes == NULL) + if (bp_opcode_bytes == nullptr) { error.SetErrorString ("BreakpointSite doesn't contain a valid breakpoint trap opcode."); return error; @@ -2244,7 +2225,7 @@ Error Process::DisableSoftwareBreakpoint (BreakpointSite *bp_site) { Error error; - assert (bp_site != NULL); + assert(bp_site != nullptr); Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_BREAKPOINTS)); addr_t bp_addr = bp_site->GetLoadAddress(); lldb::user_id_t breakID = bp_site->GetID(); @@ -2388,7 +2369,7 @@ Process::ReadCStringFromMemory (addr_t addr, std::string &out_str, Error &error) char buf[256]; out_str.clear(); addr_t curr_addr = addr; - while (1) + while (true) { size_t length = ReadCStringFromMemory (curr_addr, buf, sizeof(buf), error); if (length == 0) @@ -2436,7 +2417,7 @@ Process::ReadStringFromMemory (addr_t addr, char *dst, size_t max_bytes, Error & // Search for a null terminator of correct size and alignment in bytes_read size_t aligned_start = total_bytes_read - total_bytes_read % type_width; for (size_t i = aligned_start; i + type_width <= total_bytes_read + bytes_read; i += type_width) - if (::strncmp(&dst[i], terminator, type_width) == 0) + if (::memcmp(&dst[i], terminator, type_width) == 0) { error.Clear(); return i; @@ -2499,7 +2480,7 @@ Process::ReadCStringFromMemory (addr_t addr, char *dst, size_t dst_max_len, Erro } else { - if (dst == NULL) + if (dst == nullptr) result_error.SetErrorString("invalid arguments"); else result_error.Clear(); @@ -2510,7 +2491,7 @@ Process::ReadCStringFromMemory (addr_t addr, char *dst, size_t dst_max_len, Erro size_t Process::ReadMemoryFromInferior (addr_t addr, void *buf, size_t size, Error &error) { - if (buf == NULL || size == 0) + if (buf == nullptr || size == 0) return 0; size_t bytes_read = 0; @@ -2536,7 +2517,8 @@ Process::ReadMemoryFromInferior (addr_t addr, void *buf, size_t size, Error &err } uint64_t -Process::ReadUnsignedIntegerFromMemory (lldb::addr_t vm_addr, size_t integer_byte_size, uint64_t fail_value, Error &error) +Process::ReadUnsignedIntegerFromMemory(lldb::addr_t vm_addr, size_t integer_byte_size, uint64_t fail_value, + Error &error) { Scalar scalar; if (ReadScalarIntegerFromMemory(vm_addr, integer_byte_size, false, scalar, error)) @@ -2544,6 +2526,15 @@ Process::ReadUnsignedIntegerFromMemory (lldb::addr_t vm_addr, size_t integer_byt return fail_value; } +int64_t +Process::ReadSignedIntegerFromMemory(lldb::addr_t vm_addr, size_t integer_byte_size, int64_t fail_value, Error &error) +{ + Scalar scalar; + if (ReadScalarIntegerFromMemory(vm_addr, integer_byte_size, true, scalar, error)) + return scalar.SLongLong(fail_value); + return fail_value; +} + addr_t Process::ReadPointerFromMemory (lldb::addr_t vm_addr, Error &error) { @@ -2594,7 +2585,7 @@ Process::WriteMemory (addr_t addr, const void *buf, size_t size, Error &error) m_memory_cache.Flush (addr, size); #endif - if (buf == NULL || size == 0) + if (buf == nullptr || size == 0) return 0; m_mod_id.BumpMemoryID(); @@ -2905,7 +2896,7 @@ Process::WaitForProcessStopPrivate (const TimeValue *timeout, EventSP &event_sp) StateType state; // Now wait for the process to launch and return control to us, and then // call DidLaunch: - while (1) + while (true) { event_sp.reset(); state = WaitForStateChangedEventsPrivate (timeout, event_sp); @@ -2928,7 +2919,7 @@ Process::LoadOperatingSystemPlugin(bool flush) { if (flush) m_thread_list.Clear(); - m_os_ap.reset (OperatingSystem::FindPlugin (this, NULL)); + m_os_ap.reset(OperatingSystem::FindPlugin(this, nullptr)); if (flush) Flush(); } @@ -2943,7 +2934,7 @@ Process::Launch (ProcessLaunchInfo &launch_info) m_system_runtime_ap.reset(); m_os_ap.reset(); m_process_input_reader.reset(); - m_stop_info_override_callback = NULL; + m_stop_info_override_callback = nullptr; Module *exe_module = GetTarget().GetExecutableModulePointer(); if (exe_module) @@ -2988,7 +2979,7 @@ Process::Launch (ProcessLaunchInfo &launch_info) { SetID (LLDB_INVALID_PROCESS_ID); const char *error_string = error.AsCString(); - if (error_string == NULL) + if (error_string == nullptr) error_string = "launch failed"; SetExitStatus (-1, error_string); } @@ -3001,7 +2992,7 @@ Process::Launch (ProcessLaunchInfo &launch_info) timeout_time.OffsetWithSeconds(10); StateType state = WaitForProcessStopPrivate(&timeout_time, event_sp); - if (state == eStateInvalid || event_sp.get() == NULL) + if (state == eStateInvalid || !event_sp) { // We were able to launch the process, but we failed to // catch the initial stop. @@ -3066,8 +3057,8 @@ Process::LoadCore () Error error = DoLoadCore(); if (error.Success()) { - Listener listener ("lldb.process.load_core_listener"); - HijackProcessEvents(&listener); + ListenerSP listener_sp (Listener::MakeListener("lldb.process.load_core_listener")); + HijackProcessEvents(listener_sp); if (PrivateStateThreadIsValid ()) ResumePrivateStateThread (); @@ -3084,7 +3075,7 @@ Process::LoadCore () if (system_runtime) system_runtime->DidAttach(); - m_os_ap.reset (OperatingSystem::FindPlugin (this, NULL)); + m_os_ap.reset(OperatingSystem::FindPlugin(this, nullptr)); // We successfully loaded a core file, now pretend we stopped so we can // show all of the threads in the core file and explore the crashed // state. @@ -3092,7 +3083,7 @@ Process::LoadCore () // Wait indefinitely for a stopped event since we just posted one above... lldb::EventSP event_sp; - listener.WaitForEvent (NULL, event_sp); + listener_sp->WaitForEvent (nullptr, event_sp); StateType state = ProcessEventData::GetStateFromEvent(event_sp.get()); if (!StateIsStoppedState (state, false)) @@ -3110,8 +3101,8 @@ Process::LoadCore () DynamicLoader * Process::GetDynamicLoader () { - if (m_dyld_ap.get() == NULL) - m_dyld_ap.reset (DynamicLoader::FindPlugin(this, NULL)); + if (!m_dyld_ap) + m_dyld_ap.reset(DynamicLoader::FindPlugin(this, nullptr)); return m_dyld_ap.get(); } @@ -3135,8 +3126,8 @@ Process::GetJITLoaders () SystemRuntime * Process::GetSystemRuntime () { - if (m_system_runtime_ap.get() == NULL) - m_system_runtime_ap.reset (SystemRuntime::FindPlugin(this)); + if (!m_system_runtime_ap) + m_system_runtime_ap.reset(SystemRuntime::FindPlugin(this)); return m_system_runtime_ap.get(); } @@ -3169,31 +3160,29 @@ Process::AttachCompletionHandler::PerformAction (lldb::EventSP &event_sp) case eStateStopped: case eStateCrashed: + // During attach, prior to sending the eStateStopped event, + // lldb_private::Process subclasses must set the new process ID. + assert (m_process->GetID() != LLDB_INVALID_PROCESS_ID); + // We don't want these events to be reported, so go set the ShouldReportStop here: + m_process->GetThreadList().SetShouldReportStop (eVoteNo); + + if (m_exec_count > 0) { - // During attach, prior to sending the eStateStopped event, - // lldb_private::Process subclasses must set the new process ID. - assert (m_process->GetID() != LLDB_INVALID_PROCESS_ID); - // We don't want these events to be reported, so go set the ShouldReportStop here: - m_process->GetThreadList().SetShouldReportStop (eVoteNo); - - if (m_exec_count > 0) - { - --m_exec_count; + --m_exec_count; - if (log) - log->Printf ("Process::AttachCompletionHandler::%s state %s: reduced remaining exec count to %" PRIu32 ", requesting resume", __FUNCTION__, StateAsCString(state), m_exec_count); + if (log) + log->Printf ("Process::AttachCompletionHandler::%s state %s: reduced remaining exec count to %" PRIu32 ", requesting resume", __FUNCTION__, StateAsCString(state), m_exec_count); - RequestResume(); - return eEventActionRetry; - } - else - { - if (log) - log->Printf ("Process::AttachCompletionHandler::%s state %s: no more execs expected to start, continuing with attach", __FUNCTION__, StateAsCString(state)); + RequestResume(); + return eEventActionRetry; + } + else + { + if (log) + log->Printf ("Process::AttachCompletionHandler::%s state %s: no more execs expected to start, continuing with attach", __FUNCTION__, StateAsCString(state)); - m_process->CompleteAttach (); - return eEventActionSuccess; - } + m_process->CompleteAttach (); + return eEventActionSuccess; } break; @@ -3219,11 +3208,11 @@ Process::AttachCompletionHandler::GetExitString () return m_exit_string.c_str(); } -Listener & +ListenerSP ProcessAttachInfo::GetListenerForProcess (Debugger &debugger) { if (m_listener_sp) - return *m_listener_sp; + return m_listener_sp; else return debugger.GetListener(); } @@ -3237,7 +3226,7 @@ Process::Attach (ProcessAttachInfo &attach_info) m_jit_loaders_ap.reset(); m_system_runtime_ap.reset(); m_os_ap.reset(); - m_stop_info_override_callback = NULL; + m_stop_info_override_callback = nullptr; lldb::pid_t attach_pid = attach_info.GetProcessID(); Error error; @@ -3273,7 +3262,7 @@ Process::Attach (ProcessAttachInfo &attach_info) if (GetID() != LLDB_INVALID_PROCESS_ID) { SetID (LLDB_INVALID_PROCESS_ID); - if (error.AsCString() == NULL) + if (error.AsCString() == nullptr) error.SetErrorString("attach failed"); SetExitStatus(-1, error.AsCString()); @@ -3358,7 +3347,6 @@ Process::Attach (ProcessAttachInfo &attach_info) if (error.Success()) { - SetNextEventAction(new Process::AttachCompletionHandler(this, attach_info.GetResumeCount())); StartPrivateStateThread(); } @@ -3368,7 +3356,7 @@ Process::Attach (ProcessAttachInfo &attach_info) SetID (LLDB_INVALID_PROCESS_ID); const char *error_string = error.AsCString(); - if (error_string == NULL) + if (error_string == nullptr) error_string = "attach failed"; SetExitStatus(-1, error_string); @@ -3381,7 +3369,7 @@ Process::Attach (ProcessAttachInfo &attach_info) void Process::CompleteAttach () { - Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); + Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_TARGET)); if (log) log->Printf ("Process::%s()", __FUNCTION__); @@ -3405,11 +3393,11 @@ Process::CompleteAttach () // We just attached. If we have a platform, ask it for the process architecture, and if it isn't // the same as the one we've already set, switch architectures. PlatformSP platform_sp (GetTarget().GetPlatform ()); - assert (platform_sp.get()); + assert(platform_sp); if (platform_sp) { const ArchSpec &target_arch = GetTarget().GetArchitecture(); - if (target_arch.IsValid() && !platform_sp->IsCompatibleArchitecture (target_arch, false, NULL)) + if (target_arch.IsValid() && !platform_sp->IsCompatibleArchitecture(target_arch, false, nullptr)) { ArchSpec platform_arch; platform_sp = platform_sp->GetPlatformForArchitecture (target_arch, &platform_arch); @@ -3424,7 +3412,7 @@ Process::CompleteAttach () else if (!process_arch.IsValid()) { ProcessInstanceInfo process_info; - platform_sp->GetProcessInfo (GetID(), process_info); + GetProcessInfo(process_info); const ArchSpec &process_arch = process_info.GetArchitecture(); if (process_arch.IsValid() && !GetTarget().GetArchitecture().IsExactMatch(process_arch)) { @@ -3467,10 +3455,10 @@ Process::CompleteAttach () } } - m_os_ap.reset (OperatingSystem::FindPlugin (this, NULL)); + m_os_ap.reset(OperatingSystem::FindPlugin(this, nullptr)); // Figure out which one is the executable, and set that in our target: const ModuleList &target_modules = GetTarget().GetImages(); - Mutex::Locker modules_locker(target_modules.GetMutex()); + std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex()); size_t num_modules = target_modules.GetSize(); ModuleSP new_executable_module_sp; @@ -3514,7 +3502,7 @@ Process::ConnectRemote (Stream *strm, const char *remote_url) if (GetID() != LLDB_INVALID_PROCESS_ID) { EventSP event_sp; - StateType state = WaitForProcessStopPrivate(NULL, event_sp); + StateType state = WaitForProcessStopPrivate(nullptr, event_sp); if (state == eStateStopped || state == eStateCrashed) { @@ -3525,7 +3513,6 @@ Process::ConnectRemote (Stream *strm, const char *remote_url) // This delays passing the stopped event to listeners till // CompleteAttach gets a chance to complete... HandlePrivateEvent (event_sp); - } } @@ -3607,8 +3594,8 @@ Process::Halt (bool clear_thread_plans, bool use_run_lock) // own. m_clear_thread_plans_on_stop |= clear_thread_plans; - Listener halt_listener ("lldb.process.halt_listener"); - HijackProcessEvents(&halt_listener); + ListenerSP halt_listener_sp (Listener::MakeListener("lldb.process.halt_listener")); + HijackProcessEvents(halt_listener_sp); EventSP event_sp; @@ -3628,7 +3615,7 @@ Process::Halt (bool clear_thread_plans, bool use_run_lock) TimeValue timeout_time; timeout_time = TimeValue::Now(); timeout_time.OffsetWithSeconds(10); - StateType state = WaitForProcessToStop(&timeout_time, &event_sp, true, &halt_listener, + StateType state = WaitForProcessToStop(&timeout_time, &event_sp, true, halt_listener_sp, nullptr, use_run_lock); RestoreProcessEvents(); @@ -3653,8 +3640,8 @@ Process::StopForDestroyOrDetach(lldb::EventSP &exit_event_sp) if (log) log->Printf("Process::%s() About to stop.", __FUNCTION__); - ListenerSP listener_sp (new Listener("lldb.Process.StopForDestroyOrDetach.hijack")); - HijackProcessEvents(listener_sp.get()); + ListenerSP listener_sp (Listener::MakeListener("lldb.Process.StopForDestroyOrDetach.hijack")); + HijackProcessEvents(listener_sp); SendAsyncInterrupt(); @@ -3662,7 +3649,7 @@ Process::StopForDestroyOrDetach(lldb::EventSP &exit_event_sp) TimeValue timeout (TimeValue::Now()); timeout.OffsetWithSeconds(10); - StateType state = WaitForProcessToStop (&timeout, &exit_event_sp, true, listener_sp.get()); + StateType state = WaitForProcessToStop (&timeout, &exit_event_sp, true, listener_sp); RestoreProcessEvents(); @@ -3688,7 +3675,7 @@ Process::StopForDestroyOrDetach(lldb::EventSP &exit_event_sp) StateType private_state = m_private_state.GetValue(); if (private_state != eStateStopped) { - return error; + return Error("Attempt to stop the target in order to detach timed out. State = %s", StateAsCString(GetState())); } } } @@ -3888,7 +3875,7 @@ Process::ShouldBroadcastEvent (Event *event_ptr) m_stdio_communication.StopReadThread(); m_stdin_forward = false; - // fall-through + LLVM_FALLTHROUGH; case eStateConnected: case eStateAttaching: case eStateLaunching: @@ -3945,7 +3932,6 @@ Process::ShouldBroadcastEvent (Event *event_ptr) case eStateStopped: case eStateCrashed: case eStateSuspended: - { // We've stopped. First see if we're going to restart the target. // If we are going to stop, then we always broadcast the event. // If we aren't going to stop, let the thread plans decide if we're going to report this event. @@ -3974,7 +3960,7 @@ Process::ShouldBroadcastEvent (Event *event_ptr) // So in that case just report the event. if (!was_restarted) - should_resume = m_thread_list.ShouldStop (event_ptr) == false; + should_resume = !m_thread_list.ShouldStop(event_ptr); if (was_restarted || should_resume || m_resume_requested) { @@ -4011,8 +3997,7 @@ Process::ShouldBroadcastEvent (Event *event_ptr) SynchronouslyNotifyStateChanged (state); } } - } - break; + break; } // Forcing the next event delivery is a one shot deal. So reset it here. @@ -4069,8 +4054,8 @@ Process::StartPrivateStateThread (bool is_secondary_thread) } // Create the private state thread, and start it running. - PrivateStateThreadArgs args = {this, is_secondary_thread}; - m_private_state_thread = ThreadLauncher::LaunchThread(thread_name, Process::PrivateStateThread, (void *) &args, NULL, 8 * 1024 * 1024); + PrivateStateThreadArgs *args_ptr = new PrivateStateThreadArgs(this, is_secondary_thread); + m_private_state_thread = ThreadLauncher::LaunchThread(thread_name, Process::PrivateStateThread, (void *) args_ptr, nullptr, 8 * 1024 * 1024); if (m_private_state_thread.IsJoinable()) { ResumePrivateStateThread(); @@ -4095,7 +4080,7 @@ Process::ResumePrivateStateThread () void Process::StopPrivateStateThread () { - if (PrivateStateThreadIsValid ()) + if (m_private_state_thread.IsJoinable ()) ControlPrivateStateThread (eBroadcastInternalStateControlStop); else { @@ -4117,47 +4102,52 @@ Process::ControlPrivateStateThread (uint32_t signal) if (log) log->Printf ("Process::%s (signal = %d)", __FUNCTION__, signal); - // Signal the private state thread. First we should copy this is case the - // thread starts exiting since the private state thread will NULL this out - // when it exits - HostThread private_state_thread(m_private_state_thread); - if (private_state_thread.IsJoinable()) + // Signal the private state thread + if (m_private_state_thread.IsJoinable()) { - TimeValue timeout_time; - bool timed_out; - - m_private_state_control_broadcaster.BroadcastEvent (signal, NULL); - - timeout_time = TimeValue::Now(); - timeout_time.OffsetWithSeconds(2); + // Broadcast the event. + // It is important to do this outside of the if below, because + // it's possible that the thread state is invalid but that the + // thread is waiting on a control event instead of simply being + // on its way out (this should not happen, but it apparently can). if (log) log->Printf ("Sending control event of type: %d.", signal); - m_private_state_control_wait.WaitForValueEqualTo (true, &timeout_time, &timed_out); - m_private_state_control_wait.SetValue (false, eBroadcastNever); + std::shared_ptr<EventDataReceipt> event_receipt_sp(new EventDataReceipt()); + m_private_state_control_broadcaster.BroadcastEvent(signal, event_receipt_sp); - if (signal == eBroadcastInternalStateControlStop) + // Wait for the event receipt or for the private state thread to exit + bool receipt_received = false; + if (PrivateStateThreadIsValid()) { - if (timed_out) - { - Error error = private_state_thread.Cancel(); - if (log) - log->Printf ("Timed out responding to the control event, cancel got error: \"%s\".", error.AsCString()); - } - else + while (!receipt_received) { - if (log) - log->Printf ("The control event killed the private state thread without having to cancel."); + bool timed_out = false; + TimeValue timeout_time; + timeout_time = TimeValue::Now(); + timeout_time.OffsetWithSeconds(2); + // Check for a receipt for 2 seconds and then check if the private state + // thread is still around. + receipt_received = event_receipt_sp->WaitForEventReceived (&timeout_time, &timed_out); + if (!receipt_received) + { + // Check if the private state thread is still around. If it isn't then we are done waiting + if (!PrivateStateThreadIsValid()) + break; // Private state thread exited or is exiting, we are done + } } + } + if (signal == eBroadcastInternalStateControlStop) + { thread_result_t result = NULL; - private_state_thread.Join(&result); + m_private_state_thread.Join(&result); m_private_state_thread.Reset(); } } else { if (log) - log->Printf ("Private state thread already dead, no need to signal it to stop."); + log->Printf("Private state thread already dead, no need to signal it to stop."); } } @@ -4165,9 +4155,9 @@ void Process::SendAsyncInterrupt () { if (PrivateStateThreadIsValid()) - m_private_state_broadcaster.BroadcastEvent (Process::eBroadcastBitInterrupt, NULL); + m_private_state_broadcaster.BroadcastEvent(Process::eBroadcastBitInterrupt, nullptr); else - BroadcastEvent (Process::eBroadcastBitInterrupt, NULL); + BroadcastEvent(Process::eBroadcastBitInterrupt, nullptr); } void @@ -4179,7 +4169,7 @@ Process::HandlePrivateEvent (EventSP &event_sp) const StateType new_state = Process::ProcessEventData::GetStateFromEvent(event_sp.get()); // First check to see if anybody wants a shot at this event: - if (m_next_event_action_ap.get() != NULL) + if (m_next_event_action_ap) { NextEventAction::EventActionResult action_result = m_next_event_action_ap->PerformAction(event_sp); if (log) @@ -4188,7 +4178,7 @@ Process::HandlePrivateEvent (EventSP &event_sp) switch (action_result) { case NextEventAction::eEventActionSuccess: - SetNextEventAction(NULL); + SetNextEventAction(nullptr); break; case NextEventAction::eEventActionRetry: @@ -4202,10 +4192,10 @@ Process::HandlePrivateEvent (EventSP &event_sp) { // FIXME: should cons up an exited event, and discard this one. SetExitStatus(0, m_next_event_action_ap->GetExitString()); - SetNextEventAction(NULL); + SetNextEventAction(nullptr); return; } - SetNextEventAction(NULL); + SetNextEventAction(nullptr); break; } } @@ -4273,7 +4263,7 @@ Process::HandlePrivateEvent (EventSP &event_sp) // events) and we do need the IO handler to be pushed and popped // correctly. - if (is_hijacked || GetTarget().GetDebugger().IsHandlingEvents() == false) + if (is_hijacked || !GetTarget().GetDebugger().IsHandlingEvents()) PopProcessIOHandler (); } } @@ -4312,8 +4302,9 @@ Process::HaltPrivate() thread_result_t Process::PrivateStateThread (void *arg) { - PrivateStateThreadArgs *real_args = static_cast<PrivateStateThreadArgs *> (arg); - thread_result_t result = real_args->process->RunPrivateStateThread(real_args->is_secondary_thread); + PrivateStateThreadArgs real_args = *static_cast<PrivateStateThreadArgs *> (arg); + free (arg); + thread_result_t result = real_args.process->RunPrivateStateThread(real_args.is_secondary_thread); return result; } @@ -4321,7 +4312,6 @@ thread_result_t Process::RunPrivateStateThread (bool is_secondary_thread) { bool control_only = true; - m_private_state_control_wait.SetValue (false, eBroadcastNever); Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); if (log) @@ -4333,7 +4323,7 @@ Process::RunPrivateStateThread (bool is_secondary_thread) while (!exit_now) { EventSP event_sp; - WaitForEventsPrivate (NULL, event_sp, control_only); + WaitForEventsPrivate(nullptr, event_sp, control_only); if (event_sp->BroadcasterIs(&m_private_state_control_broadcaster)) { if (log) @@ -4356,7 +4346,6 @@ Process::RunPrivateStateThread (bool is_secondary_thread) break; } - m_private_state_control_wait.SetValue (true, eBroadcastAlways); continue; } else if (event_sp->GetType() == eBroadcastBitInterrupt) @@ -4367,7 +4356,7 @@ Process::RunPrivateStateThread (bool is_secondary_thread) log->Printf ("Process::%s (arg = %p, pid = %" PRIu64 ") woke up with an interrupt while attaching - forwarding interrupt.", __FUNCTION__, static_cast<void*>(this), GetID()); - BroadcastEvent (eBroadcastBitInterrupt, NULL); + BroadcastEvent(eBroadcastBitInterrupt, nullptr); } else if(StateIsRunningState(m_last_broadcast_state)) { @@ -4452,8 +4441,6 @@ Process::RunPrivateStateThread (bool is_secondary_thread) // try to change it on the way out. if (!is_secondary_thread) m_public_run_lock.SetStopped(); - m_private_state_control_wait.SetValue (true, eBroadcastAlways); - m_private_state_thread.Reset(); return NULL; } @@ -4610,7 +4597,7 @@ Process::ProcessEventData::DoOnRemoval (Event *event_ptr) this_thread_wants_to_stop = stop_info_sp->ShouldStop(event_ptr); } - if (still_should_stop == false) + if (!still_should_stop) still_should_stop = this_thread_wants_to_stop; } } @@ -4660,7 +4647,7 @@ Process::ProcessEventData::GetEventDataFromEvent (const Event *event_ptr) if (event_data && event_data->GetFlavor() == ProcessEventData::GetFlavorString()) return static_cast <const ProcessEventData *> (event_ptr->GetData()); } - return NULL; + return nullptr; } ProcessSP @@ -4677,7 +4664,7 @@ StateType Process::ProcessEventData::GetStateFromEvent (const Event *event_ptr) { const ProcessEventData *data = GetEventDataFromEvent (event_ptr); - if (data == NULL) + if (data == nullptr) return eStateInvalid; else return data->GetState(); @@ -4687,7 +4674,7 @@ bool Process::ProcessEventData::GetRestartedFromEvent (const Event *event_ptr) { const ProcessEventData *data = GetEventDataFromEvent (event_ptr); - if (data == NULL) + if (data == nullptr) return false; else return data->GetRestarted(); @@ -4697,7 +4684,7 @@ void Process::ProcessEventData::SetRestartedInEvent (Event *event_ptr, bool new_value) { ProcessEventData *data = const_cast<ProcessEventData *>(GetEventDataFromEvent (event_ptr)); - if (data != NULL) + if (data != nullptr) data->SetRestarted(new_value); } @@ -4705,7 +4692,7 @@ size_t Process::ProcessEventData::GetNumRestartedReasons(const Event *event_ptr) { ProcessEventData *data = const_cast<ProcessEventData *>(GetEventDataFromEvent (event_ptr)); - if (data != NULL) + if (data != nullptr) return data->GetNumRestartedReasons(); else return 0; @@ -4715,17 +4702,17 @@ const char * Process::ProcessEventData::GetRestartedReasonAtIndex(const Event *event_ptr, size_t idx) { ProcessEventData *data = const_cast<ProcessEventData *>(GetEventDataFromEvent (event_ptr)); - if (data != NULL) + if (data != nullptr) return data->GetRestartedReasonAtIndex(idx); else - return NULL; + return nullptr; } void Process::ProcessEventData::AddRestartedReason (Event *event_ptr, const char *reason) { ProcessEventData *data = const_cast<ProcessEventData *>(GetEventDataFromEvent (event_ptr)); - if (data != NULL) + if (data != nullptr) data->AddRestartedReason(reason); } @@ -4733,7 +4720,7 @@ bool Process::ProcessEventData::GetInterruptedFromEvent (const Event *event_ptr) { const ProcessEventData *data = GetEventDataFromEvent (event_ptr); - if (data == NULL) + if (data == nullptr) return false; else return data->GetInterrupted (); @@ -4743,7 +4730,7 @@ void Process::ProcessEventData::SetInterruptedInEvent (Event *event_ptr, bool new_value) { ProcessEventData *data = const_cast<ProcessEventData *>(GetEventDataFromEvent (event_ptr)); - if (data != NULL) + if (data != nullptr) data->SetInterrupted(new_value); } @@ -4770,8 +4757,8 @@ Process::CalculateExecutionContext (ExecutionContext &exe_ctx) { exe_ctx.SetTargetPtr (&GetTarget()); exe_ctx.SetProcessPtr (this); - exe_ctx.SetThreadPtr(NULL); - exe_ctx.SetFramePtr (NULL); + exe_ctx.SetThreadPtr(nullptr); + exe_ctx.SetFramePtr(nullptr); } //uint32_t @@ -4791,11 +4778,11 @@ Process::CalculateExecutionContext (ExecutionContext &exe_ctx) //{ // return Host::GetArchSpecForExistingProcess (process_name); //} -// + void Process::AppendSTDOUT (const char * s, size_t len) { - Mutex::Locker locker (m_stdio_communication_mutex); + std::lock_guard<std::recursive_mutex> guard(m_stdio_communication_mutex); m_stdout_data.append (s, len); BroadcastEventIfUnique (eBroadcastBitSTDOUT, new ProcessEventData (shared_from_this(), GetState())); } @@ -4803,7 +4790,7 @@ Process::AppendSTDOUT (const char * s, size_t len) void Process::AppendSTDERR (const char * s, size_t len) { - Mutex::Locker locker (m_stdio_communication_mutex); + std::lock_guard<std::recursive_mutex> guard(m_stdio_communication_mutex); m_stderr_data.append (s, len); BroadcastEventIfUnique (eBroadcastBitSTDERR, new ProcessEventData (shared_from_this(), GetState())); } @@ -4811,7 +4798,7 @@ Process::AppendSTDERR (const char * s, size_t len) void Process::BroadcastAsyncProfileData(const std::string &one_profile_data) { - Mutex::Locker locker (m_profile_data_comm_mutex); + std::lock_guard<std::recursive_mutex> guard(m_profile_data_comm_mutex); m_profile_data.push_back(one_profile_data); BroadcastEventIfUnique (eBroadcastBitProfileData, new ProcessEventData (shared_from_this(), GetState())); } @@ -4819,7 +4806,7 @@ Process::BroadcastAsyncProfileData(const std::string &one_profile_data) size_t Process::GetAsyncProfileData (char *buf, size_t buf_size, Error &error) { - Mutex::Locker locker(m_profile_data_comm_mutex); + std::lock_guard<std::recursive_mutex> guard(m_profile_data_comm_mutex); if (m_profile_data.empty()) return 0; @@ -4854,7 +4841,7 @@ Process::GetAsyncProfileData (char *buf, size_t buf_size, Error &error) size_t Process::GetSTDOUT (char *buf, size_t buf_size, Error &error) { - Mutex::Locker locker(m_stdio_communication_mutex); + std::lock_guard<std::recursive_mutex> guard(m_stdio_communication_mutex); size_t bytes_available = m_stdout_data.size(); if (bytes_available > 0) { @@ -4881,7 +4868,7 @@ Process::GetSTDOUT (char *buf, size_t buf_size, Error &error) size_t Process::GetSTDERR (char *buf, size_t buf_size, Error &error) { - Mutex::Locker locker(m_stdio_communication_mutex); + std::lock_guard<std::recursive_mutex> gaurd(m_stdio_communication_mutex); size_t bytes_available = m_stderr_data.size(); if (bytes_available > 0) { @@ -4952,6 +4939,7 @@ public: // FD_ZERO, FD_SET are not supported on windows #ifndef _WIN32 const int pipe_read_fd = m_pipe.GetReadFileDescriptor(); + m_is_running = true; while (!GetIsDone()) { fd_set read_fdset; @@ -4959,7 +4947,8 @@ public: FD_SET (read_fd, &read_fdset); FD_SET (pipe_read_fd, &read_fdset); const int nfds = std::max<int>(read_fd, pipe_read_fd) + 1; - int num_set_fds = select (nfds, &read_fdset, NULL, NULL, NULL); + int num_set_fds = select(nfds, &read_fdset, nullptr, nullptr, nullptr); + if (num_set_fds < 0) { const int select_errno = errno; @@ -5003,6 +4992,7 @@ public: } } } + m_is_running = false; #endif terminal_state.Restore(); } @@ -5010,9 +5000,24 @@ public: void Cancel () override { - char ch = 'q'; // Send 'q' for quit - size_t bytes_written = 0; - m_pipe.Write(&ch, 1, bytes_written); + SetIsDone(true); + // Only write to our pipe to cancel if we are in IOHandlerProcessSTDIO::Run(). + // We can end up with a python command that is being run from the command + // interpreter: + // + // (lldb) step_process_thousands_of_times + // + // In this case the command interpreter will be in the middle of handling + // the command and if the process pushes and pops the IOHandler thousands + // of times, we can end up writing to m_pipe without ever consuming the + // bytes from the pipe in IOHandlerProcessSTDIO::Run() and end up + // deadlocking when the pipe gets fed up and blocks until data is consumed. + if (m_is_running) + { + char ch = 'q'; // Send 'q' for quit + size_t bytes_written = 0; + m_pipe.Write(&ch, 1, bytes_written); + } } bool @@ -5059,6 +5064,7 @@ protected: File m_read_file; // Read from this file (usually actual STDIN for LLDB File m_write_file; // Write to this file (usually the master pty for getting io to debuggee) Pipe m_pipe; + std::atomic<bool> m_is_running; }; void @@ -5068,7 +5074,7 @@ Process::SetSTDIOFileDescriptor (int fd) std::unique_ptr<ConnectionFileDescriptor> conn_ap (new ConnectionFileDescriptor (fd, true)); - if (conn_ap.get()) + if (conn_ap) { m_stdio_communication.SetConnection (conn_ap.release()); if (m_stdio_communication.IsConnected()) @@ -5078,7 +5084,7 @@ Process::SetSTDIOFileDescriptor (int fd) // Now read thread is set up, set up input reader. - if (!m_process_input_reader.get()) + if (!m_process_input_reader) m_process_input_reader.reset (new IOHandlerProcessSTDIO (this, fd)); } } @@ -5180,41 +5186,41 @@ namespace } // anonymous namespace ExpressionResults -Process::RunThreadPlan (ExecutionContext &exe_ctx, - lldb::ThreadPlanSP &thread_plan_sp, - const EvaluateExpressionOptions &options, - Stream &errors) +Process::RunThreadPlan(ExecutionContext &exe_ctx, lldb::ThreadPlanSP &thread_plan_sp, + const EvaluateExpressionOptions &options, DiagnosticManager &diagnostic_manager) { ExpressionResults return_value = eExpressionSetupError; + + std::lock_guard<std::mutex> run_thread_plan_locker(m_run_thread_plan_lock); - if (thread_plan_sp.get() == NULL) + if (!thread_plan_sp) { - errors.Printf("RunThreadPlan called with empty thread plan."); + diagnostic_manager.PutCString(eDiagnosticSeverityError, "RunThreadPlan called with empty thread plan."); return eExpressionSetupError; } - if (!thread_plan_sp->ValidatePlan(NULL)) + if (!thread_plan_sp->ValidatePlan(nullptr)) { - errors.Printf ("RunThreadPlan called with an invalid thread plan."); + diagnostic_manager.PutCString(eDiagnosticSeverityError, "RunThreadPlan called with an invalid thread plan."); return eExpressionSetupError; } if (exe_ctx.GetProcessPtr() != this) { - errors.Printf("RunThreadPlan called on wrong process."); + diagnostic_manager.PutCString(eDiagnosticSeverityError, "RunThreadPlan called on wrong process."); return eExpressionSetupError; } Thread *thread = exe_ctx.GetThreadPtr(); - if (thread == NULL) + if (thread == nullptr) { - errors.Printf("RunThreadPlan called with invalid thread."); + diagnostic_manager.PutCString(eDiagnosticSeverityError, "RunThreadPlan called with invalid thread."); return eExpressionSetupError; } // We need to change some of the thread plan attributes for the thread plan runner. This will restore them // when we are done: - + RestorePlanState thread_plan_restorer(thread_plan_sp); // We rely on the thread plan we are running returning "PlanCompleted" if when it successfully completes. @@ -5231,7 +5237,8 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx, if (m_private_state.GetValue() != eStateStopped) { - errors.Printf ("RunThreadPlan called while the private state was not stopped."); + diagnostic_manager.PutCString(eDiagnosticSeverityError, + "RunThreadPlan called while the private state was not stopped."); return eExpressionSetupError; } @@ -5240,11 +5247,12 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx, StackFrameSP selected_frame_sp = thread->GetSelectedFrame(); if (!selected_frame_sp) { - thread->SetSelectedFrame(0); + thread->SetSelectedFrame(nullptr); selected_frame_sp = thread->GetSelectedFrame(); if (!selected_frame_sp) { - errors.Printf("RunThreadPlan called without a selected frame on thread %d", thread_idx_id); + diagnostic_manager.Printf(eDiagnosticSeverityError, + "RunThreadPlan called without a selected frame on thread %d", thread_idx_id); return eExpressionSetupError; } } @@ -5313,7 +5321,7 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx, return eExpressionStoppedForDebug; } - Listener listener("lldb.process.listener.run-thread-plan"); + ListenerSP listener_sp(Listener::MakeListener("lldb.process.listener.run-thread-plan")); lldb::EventSP event_to_broadcast_sp; @@ -5324,7 +5332,7 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx, // If the event needs to propagate beyond the hijacker (e.g., the process exits during execution), then the event // is put into event_to_broadcast_sp for rebroadcasting. - ProcessEventHijacker run_thread_plan_hijacker (*this, &listener); + ProcessEventHijacker run_thread_plan_hijacker (*this, listener_sp); if (log) { @@ -5340,7 +5348,7 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx, lldb::EventSP event_sp; lldb::StateType stop_state = lldb::eStateInvalid; - TimeValue* timeout_ptr = NULL; + TimeValue* timeout_ptr = nullptr; TimeValue real_timeout; bool before_first_timeout = true; // This is set to false the first time that we have to halt the target. @@ -5386,7 +5394,9 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx, { if (timeout_usec < option_one_thread_timeout) { - errors.Printf("RunThreadPlan called without one thread timeout greater than total timeout"); + diagnostic_manager.PutCString( + eDiagnosticSeverityError, + "RunThreadPlan called without one thread timeout greater than total timeout"); return eExpressionSetupError; } computed_one_thread_timeout = option_one_thread_timeout; @@ -5414,10 +5424,11 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx, // Are there cases where we might want to run the remaining events here, and then try to // call the function? That's probably being too tricky for our own good. - Event *other_events = listener.PeekAtNextEvent(); - if (other_events != NULL) + Event *other_events = listener_sp->PeekAtNextEvent(); + if (other_events != nullptr) { - errors.Printf("Calling RunThreadPlan with pending events on the queue."); + diagnostic_manager.PutCString(eDiagnosticSeverityError, + "RunThreadPlan called with pending events on the queue."); return eExpressionSetupError; } @@ -5441,7 +5452,7 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx, TimeValue one_thread_timeout; TimeValue final_timeout; - while (1) + while (true) { // We usually want to resume the process if we get to the top of the loop. // The only exception is if we get two running events with no intervening @@ -5459,12 +5470,12 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx, if (do_resume) { num_resumes++; - Error resume_error = PrivateResume (); + Error resume_error = PrivateResume(); if (!resume_error.Success()) { - errors.Printf("Error resuming inferior the %d time: \"%s\".\n", - num_resumes, - resume_error.AsCString()); + diagnostic_manager.Printf(eDiagnosticSeverityError, + "couldn't resume inferior the %d time: \"%s\".", num_resumes, + resume_error.AsCString()); return_value = eExpressionSetupError; break; } @@ -5473,14 +5484,15 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx, TimeValue resume_timeout = TimeValue::Now(); resume_timeout.OffsetWithMicroSeconds(500000); - got_event = listener.WaitForEvent(&resume_timeout, event_sp); + got_event = listener_sp->WaitForEvent(&resume_timeout, event_sp); if (!got_event) { if (log) - log->Printf ("Process::RunThreadPlan(): didn't get any event after resume %d, exiting.", - num_resumes); + log->Printf("Process::RunThreadPlan(): didn't get any event after resume %" PRIu32 ", exiting.", + num_resumes); - errors.Printf("Didn't get any event after resume %d, exiting.", num_resumes); + diagnostic_manager.Printf(eDiagnosticSeverityError, + "didn't get any event after resume %" PRIu32 ", exiting.", num_resumes); return_value = eExpressionSetupError; break; } @@ -5513,8 +5525,9 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx, Halt(clear_thread_plans, use_run_lock); } - errors.Printf("Didn't get running event after initial resume, got %s instead.", - StateAsCString(stop_state)); + diagnostic_manager.Printf(eDiagnosticSeverityError, + "didn't get running event after initial resume, got %s instead.", + StateAsCString(stop_state)); return_value = eExpressionSetupError; break; } @@ -5544,7 +5557,7 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx, else { if (timeout_usec == 0) - timeout_ptr = NULL; + timeout_ptr = nullptr; else { final_timeout = TimeValue::Now(); @@ -5556,7 +5569,7 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx, else { if (timeout_usec == 0) - timeout_ptr = NULL; + timeout_ptr = nullptr; else { final_timeout = TimeValue::Now(); @@ -5595,11 +5608,11 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx, } else #endif - got_event = listener.WaitForEvent (timeout_ptr, event_sp); + got_event = listener_sp->WaitForEvent (timeout_ptr, event_sp); if (got_event) { - if (event_sp.get()) + if (event_sp) { bool keep_going = false; if (event_sp->GetType() == eBroadcastBitInterrupt) @@ -5608,9 +5621,10 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx, const bool use_run_lock = false; Halt(clear_thread_plans, use_run_lock); return_value = eExpressionInterrupted; - errors.Printf ("Execution halted by user interrupt."); + diagnostic_manager.PutCString(eDiagnosticSeverityRemark, "execution halted by user interrupt."); if (log) - log->Printf ("Process::RunThreadPlan(): Got interrupted by eBroadcastBitInterrupted, exiting."); + log->Printf( + "Process::RunThreadPlan(): Got interrupted by eBroadcastBitInterrupted, exiting."); break; } else @@ -5713,7 +5727,8 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx, if (stop_state == eStateExited) event_to_broadcast_sp = event_sp; - errors.Printf ("Execution stopped with unexpected state.\n"); + diagnostic_manager.PutCString(eDiagnosticSeverityError, + "execution stopped with unexpected state."); return_value = eExpressionInterrupted; break; } @@ -5795,7 +5810,7 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx, real_timeout = TimeValue::Now(); real_timeout.OffsetWithMicroSeconds(500000); - got_event = listener.WaitForEvent(&real_timeout, event_sp); + got_event = listener_sp->WaitForEvent(&real_timeout, event_sp); if (got_event) { @@ -5943,7 +5958,7 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx, StreamString ts; - const char *event_explanation = NULL; + const char *event_explanation = nullptr; do { @@ -6091,7 +6106,7 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx, if (GetThreadList().SetSelectedThreadByIndexID (selected_tid) && selected_stack_id.IsValid()) { // We were able to restore the selected thread, now restore the frame: - Mutex::Locker lock(GetThreadList().GetMutex()); + std::lock_guard<std::recursive_mutex> guard(GetThreadList().GetMutex()); StackFrameSP old_frame_sp = GetThreadList().GetSelectedThread()->GetFrameWithStackID(selected_stack_id); if (old_frame_sp) GetThreadList().GetSelectedThread()->SetSelectedFrame(old_frame_sp.get()); @@ -6196,7 +6211,7 @@ Process::GetThreadStatus (Stream &strm, std::vector<lldb::tid_t> thread_id_array; //Scope for thread list locker; { - Mutex::Locker locker (GetThreadList().GetMutex()); + std::lock_guard<std::recursive_mutex> guard(GetThreadList().GetMutex()); ThreadList &curr_thread_list = GetThreadList(); num_threads = curr_thread_list.GetSize(); uint32_t idx; @@ -6213,7 +6228,7 @@ Process::GetThreadStatus (Stream &strm, if (only_threads_with_stop_reason) { StopInfoSP stop_info_sp = thread_sp->GetStopInfo(); - if (stop_info_sp.get() == NULL || !stop_info_sp->IsValid()) + if (!stop_info_sp || !stop_info_sp->IsValid()) continue; } thread_sp->GetStatus (strm, @@ -6259,7 +6274,7 @@ Process::RunPreResumeActions () struct PreResumeCallbackAndBaton action = m_pre_resume_actions.back(); m_pre_resume_actions.pop_back(); bool this_result = action.callback (action.baton); - if (result == true) + if (result) result = this_result; } return result; @@ -6312,7 +6327,7 @@ Process::DidExec () m_instrumentation_runtimes.clear(); m_thread_list.DiscardThreadPlans(); m_memory_cache.Clear(true); - m_stop_info_override_callback = NULL; + m_stop_info_override_callback = nullptr; DoDidExec(); CompleteAttach (); // Flush the process (threads and all stack frames) after running CompleteAttach() @@ -6389,14 +6404,17 @@ Process::ModulesDidLoad (ModuleList &module_list) for (const auto &pair: language_runtimes) { // We must check language_runtime_sp to make sure it is not - // NULL as we might cache the fact that we didn't have a + // nullptr as we might cache the fact that we didn't have a // language runtime for a language. LanguageRuntimeSP language_runtime_sp = pair.second; if (language_runtime_sp) language_runtime_sp->ModulesDidLoad(module_list); } - LoadOperatingSystemPlugin(false); + // If we don't have an operating system plug-in, try to load one since + // loading shared libraries might cause a new one to try and load + if (!m_os_ap) + LoadOperatingSystemPlugin(false); } void @@ -6405,10 +6423,10 @@ Process::PrintWarning (uint64_t warning_type, const void *repeat_key, const char bool print_warning = true; StreamSP stream_sp = GetTarget().GetDebugger().GetAsyncOutputStream(); - if (stream_sp.get() == nullptr) + if (!stream_sp) return; if (warning_type == eWarningsOptimization - && GetWarningsOptimization() == false) + && !GetWarningsOptimization()) { return; } @@ -6446,16 +6464,28 @@ Process::PrintWarning (uint64_t warning_type, const void *repeat_key, const char void Process::PrintWarningOptimization (const SymbolContext &sc) { - if (GetWarningsOptimization() == true - && sc.module_sp.get() - && sc.module_sp->GetFileSpec().GetFilename().IsEmpty() == false + if (GetWarningsOptimization() + && sc.module_sp + && !sc.module_sp->GetFileSpec().GetFilename().IsEmpty() && sc.function - && sc.function->GetIsOptimized() == true) + && sc.function->GetIsOptimized()) { PrintWarning (Process::Warnings::eWarningsOptimization, sc.module_sp.get(), "%s was compiled with optimization - stepping may behave oddly; variables may not be available.\n", sc.module_sp->GetFileSpec().GetFilename().GetCString()); } } +bool +Process::GetProcessInfo(ProcessInstanceInfo &info) +{ + info.Clear(); + + PlatformSP platform_sp = GetTarget().GetPlatform(); + if (! platform_sp) + return false; + + return platform_sp->GetProcessInfo(GetID(), info); +} + ThreadCollectionSP Process::GetHistoryThreads(lldb::addr_t addr) { @@ -6463,7 +6493,7 @@ Process::GetHistoryThreads(lldb::addr_t addr) const MemoryHistorySP &memory_history = MemoryHistory::FindPlugin(shared_from_this()); - if (! memory_history.get()) { + if (!memory_history) { return threads; } @@ -6521,13 +6551,13 @@ Process::AdvanceAddressToNextBranchInstruction (Address default_stop_addr, Addre { Target &target = GetTarget(); DisassemblerSP disassembler_sp; - InstructionList *insn_list = NULL; + InstructionList *insn_list = nullptr; Address retval = default_stop_addr; - if (target.GetUseFastStepping() == false) + if (!target.GetUseFastStepping()) return retval; - if (default_stop_addr.IsValid() == false) + if (!default_stop_addr.IsValid()) return retval; ExecutionContext exe_ctx (this); @@ -6540,10 +6570,10 @@ Process::AdvanceAddressToNextBranchInstruction (Address default_stop_addr, Addre exe_ctx, range_bounds, prefer_file_cache); - if (disassembler_sp.get()) + if (disassembler_sp) insn_list = &disassembler_sp->GetInstructionList(); - if (insn_list == NULL) + if (insn_list == nullptr) { return retval; } @@ -6569,11 +6599,38 @@ Process::AdvanceAddressToNextBranchInstruction (Address default_stop_addr, Addre } } - if (disassembler_sp.get()) + return retval; +} + +Error +Process::GetMemoryRegions (std::vector<lldb::MemoryRegionInfoSP>& region_list) +{ + + Error error; + + lldb::addr_t range_base = 0; + lldb::addr_t range_end = 0; + + region_list.clear(); + do { - // FIXME: The DisassemblerLLVMC has a reference cycle and won't go away if it has any active instructions. - disassembler_sp->GetInstructionList().Clear(); - } + lldb::MemoryRegionInfoSP region_info( new lldb_private::MemoryRegionInfo() ); + error = GetMemoryRegionInfo (range_end, *region_info); + // GetMemoryRegionInfo should only return an error if it is unimplemented. + if (error.Fail()) + { + region_list.clear(); + break; + } + + range_base = region_info->GetRange().GetRangeBase(); + range_end = region_info->GetRange().GetRangeEnd(); + if( region_info->GetMapped() == MemoryRegionInfo::eYes ) + { + region_list.push_back(region_info); + } + } while (range_end != LLDB_INVALID_ADDRESS); + + return error; - return retval; } diff --git a/source/Target/ProcessInfo.cpp b/source/Target/ProcessInfo.cpp index 22da2c6a2a29..214db9ed3d45 100644 --- a/source/Target/ProcessInfo.cpp +++ b/source/Target/ProcessInfo.cpp @@ -7,10 +7,15 @@ // //===----------------------------------------------------------------------===// +// C Includes +// C++ Includes +#include <climits> + +// Other libraries and framework includes +// Project includes #include "lldb/Target/ProcessInfo.h" -// C Includes -#include <limits.h> +#include "lldb/Core/Stream.h" using namespace lldb; using namespace lldb_private; @@ -62,6 +67,21 @@ ProcessInfo::GetNameLength() const } void +ProcessInfo::Dump (Stream &s, Platform *platform) const +{ + s << "Executable: " << GetName() << "\n"; + s << "Triple: "; + m_arch.DumpTriple(s); + s << "\n"; + + s << "Arguments:\n"; + m_arguments.Dump(s); + + s << "Environment:\n"; + m_environment.Dump(s, "env"); +} + +void ProcessInfo::SetExecutableFile (const FileSpec &exe_file, bool add_exe_file_as_first_arg) { if (exe_file) @@ -83,9 +103,7 @@ ProcessInfo::SetExecutableFile (const FileSpec &exe_file, bool add_exe_file_as_f const char * ProcessInfo::GetArg0 () const { - if (m_arg0.empty()) - return NULL; - return m_arg0.c_str(); + return (m_arg0.empty() ? nullptr : m_arg0.c_str()); } void @@ -116,6 +134,7 @@ ProcessInfo::SetArguments (char const **argv, bool first_arg_is_executable) } } } + void ProcessInfo::SetArguments (const Args& args, bool first_arg_is_executable) { diff --git a/source/Target/ProcessLaunchInfo.cpp b/source/Target/ProcessLaunchInfo.cpp index fc17fe614c5c..f132450ca359 100644 --- a/source/Target/ProcessLaunchInfo.cpp +++ b/source/Target/ProcessLaunchInfo.cpp @@ -7,15 +7,23 @@ // //===----------------------------------------------------------------------===// -#include "lldb/Host/Config.h" +// C Includes +// C++ Includes +#include <climits> +// Other libraries and framework includes +// Project includes #include "lldb/Core/Debugger.h" #include "lldb/Core/Log.h" +#include "lldb/Host/Config.h" #include "lldb/Host/FileSystem.h" -#include "lldb/Target/ProcessLaunchInfo.h" +#include "lldb/Host/HostInfo.h" #include "lldb/Target/FileAction.h" +#include "lldb/Target/ProcessLaunchInfo.h" #include "lldb/Target/Target.h" +#include "llvm/Support/ConvertUTF.h" + #if !defined(_WIN32) #include <limits.h> #endif @@ -27,19 +35,19 @@ using namespace lldb_private; // ProcessLaunchInfo member functions //---------------------------------------------------------------------------- -ProcessLaunchInfo::ProcessLaunchInfo () : +ProcessLaunchInfo::ProcessLaunchInfo() : ProcessInfo(), - m_working_dir (), - m_plugin_name (), - m_flags (0), - m_file_actions (), - m_pty (new lldb_utility::PseudoTerminal), - m_resume_count (0), - m_monitor_callback (NULL), - m_monitor_callback_baton (NULL), - m_monitor_signals (false), - m_listener_sp (), - m_hijack_listener_sp () + m_working_dir(), + m_plugin_name(), + m_flags(0), + m_file_actions(), + m_pty(new lldb_utility::PseudoTerminal), + m_resume_count(0), + m_monitor_callback(nullptr), + m_monitor_callback_baton(nullptr), + m_monitor_signals(false), + m_listener_sp(), + m_hijack_listener_sp() { } @@ -55,8 +63,8 @@ ProcessLaunchInfo::ProcessLaunchInfo(const FileSpec &stdin_file_spec, m_file_actions(), m_pty(new lldb_utility::PseudoTerminal), m_resume_count(0), - m_monitor_callback(NULL), - m_monitor_callback_baton(NULL), + m_monitor_callback(nullptr), + m_monitor_callback_baton(nullptr), m_monitor_signals(false), m_listener_sp (), m_hijack_listener_sp() @@ -143,7 +151,7 @@ ProcessLaunchInfo::GetFileActionAtIndex(size_t idx) const { if (idx < m_file_actions.size()) return &m_file_actions[idx]; - return NULL; + return nullptr; } const FileAction * @@ -154,7 +162,7 @@ ProcessLaunchInfo::GetFileActionForFD(int fd) const if (m_file_actions[idx].GetFD () == fd) return &m_file_actions[idx]; } - return NULL; + return nullptr; } const FileSpec & @@ -172,9 +180,7 @@ ProcessLaunchInfo::SetWorkingDirectory(const FileSpec &working_dir) const char * ProcessLaunchInfo::GetProcessPluginName () const { - if (m_plugin_name.empty()) - return NULL; - return m_plugin_name.c_str(); + return (m_plugin_name.empty() ? nullptr : m_plugin_name.c_str()); } void @@ -238,12 +244,9 @@ ProcessLaunchInfo::Clear () } void -ProcessLaunchInfo::SetMonitorProcessCallback (Host::MonitorChildProcessCallback callback, - void *baton, - bool monitor_signals) +ProcessLaunchInfo::SetMonitorProcessCallback(const Host::MonitorChildProcessCallback &callback, bool monitor_signals) { m_monitor_callback = callback; - m_monitor_callback_baton = baton; m_monitor_signals = monitor_signals; } @@ -253,7 +256,6 @@ ProcessLaunchInfo::MonitorProcess () const if (m_monitor_callback && ProcessIDIsValid()) { Host::StartMonitoringChildProcess (m_monitor_callback, - m_monitor_callback_baton, GetProcessID(), m_monitor_signals); return true; @@ -277,9 +279,9 @@ ProcessLaunchInfo::FinalizeFileActions (Target *target, bool default_to_use_pty) // If nothing for stdin or stdout or stderr was specified, then check the process for any default // settings that were set with "settings set" - if (GetFileActionForFD(STDIN_FILENO) == NULL || - GetFileActionForFD(STDOUT_FILENO) == NULL || - GetFileActionForFD(STDERR_FILENO) == NULL) + if (GetFileActionForFD(STDIN_FILENO) == nullptr || + GetFileActionForFD(STDOUT_FILENO) == nullptr || + GetFileActionForFD(STDERR_FILENO) == nullptr) { if (log) log->Printf ("ProcessLaunchInfo::%s at least one of stdin/stdout/stderr was not set, evaluating default handling", @@ -314,11 +316,11 @@ ProcessLaunchInfo::FinalizeFileActions (Target *target, bool default_to_use_pty) { // Only override with the target settings if we don't already have // an action for in, out or error - if (GetFileActionForFD(STDIN_FILENO) == NULL) + if (GetFileActionForFD(STDIN_FILENO) == nullptr) in_file_spec = target->GetStandardInputPath(); - if (GetFileActionForFD(STDOUT_FILENO) == NULL) + if (GetFileActionForFD(STDOUT_FILENO) == nullptr) out_file_spec = target->GetStandardOutputPath(); - if (GetFileActionForFD(STDERR_FILENO) == NULL) + if (GetFileActionForFD(STDERR_FILENO) == nullptr) err_file_spec = target->GetStandardErrorPath(); } @@ -366,27 +368,27 @@ ProcessLaunchInfo::FinalizeFileActions (Target *target, bool default_to_use_pty) // this will have to do for now. open_flags |= O_CLOEXEC; #endif - if (m_pty->OpenFirstAvailableMaster(open_flags, NULL, 0)) + if (m_pty->OpenFirstAvailableMaster(open_flags, nullptr, 0)) { - const FileSpec slave_file_spec{m_pty->GetSlaveName(NULL, 0), false}; + const FileSpec slave_file_spec{m_pty->GetSlaveName(nullptr, 0), false}; // Only use the slave tty if we don't have anything specified for // input and don't have an action for stdin - if (!in_file_spec && GetFileActionForFD(STDIN_FILENO) == NULL) + if (!in_file_spec && GetFileActionForFD(STDIN_FILENO) == nullptr) { AppendOpenFileAction(STDIN_FILENO, slave_file_spec, true, false); } // Only use the slave tty if we don't have anything specified for // output and don't have an action for stdout - if (!out_file_spec && GetFileActionForFD(STDOUT_FILENO) == NULL) + if (!out_file_spec && GetFileActionForFD(STDOUT_FILENO) == nullptr) { AppendOpenFileAction(STDOUT_FILENO, slave_file_spec, false, true); } // Only use the slave tty if we don't have anything specified for // error and don't have an action for stderr - if (!err_file_spec && GetFileActionForFD(STDERR_FILENO) == NULL) + if (!err_file_spec && GetFileActionForFD(STDERR_FILENO) == nullptr) { AppendOpenFileAction(STDERR_FILENO, slave_file_spec, false, true); } @@ -396,7 +398,6 @@ ProcessLaunchInfo::FinalizeFileActions (Target *target, bool default_to_use_pty) } } - bool ProcessLaunchInfo::ConvertArgumentsForLaunchingInShell (Error &error, bool localhost, @@ -413,7 +414,7 @@ ProcessLaunchInfo::ConvertArgumentsForLaunchingInShell (Error &error, std::string shell_executable = m_shell.GetPath(); const char **argv = GetArguments().GetConstArgumentVector (); - if (argv == NULL || argv[0] == NULL) + if (argv == nullptr || argv[0] == nullptr) return false; Args shell_arguments; std::string safe_arg; @@ -451,8 +452,8 @@ ProcessLaunchInfo::ConvertArgumentsForLaunchingInShell (Error &error, if (cwd && cwd[0]) new_path += cwd; } - const char *curr_path = getenv("PATH"); - if (curr_path) + std::string curr_path; + if (HostInfo::GetEnvironmentVar("PATH", curr_path)) { if (new_path.size() > empty_path_len) new_path += ':'; @@ -496,9 +497,11 @@ ProcessLaunchInfo::ConvertArgumentsForLaunchingInShell (Error &error, } else { - for (size_t i=0; argv[i] != NULL; ++i) + for (size_t i=0; argv[i] != nullptr; ++i) { - const char *arg = Args::GetShellSafeArgument (argv[i], safe_arg); + const char *arg = Args::GetShellSafeArgument (m_shell, + argv[i], + safe_arg); shell_command.Printf(" %s", arg); } } @@ -519,11 +522,11 @@ ProcessLaunchInfo::ConvertArgumentsForLaunchingInShell (Error &error, return false; } -Listener & +ListenerSP ProcessLaunchInfo::GetListenerForProcess (Debugger &debugger) { if (m_listener_sp) - return *m_listener_sp; + return m_listener_sp; else return debugger.GetListener(); } diff --git a/source/Target/Queue.cpp b/source/Target/Queue.cpp index 7cfa6fa5582f..9d4032a29e6f 100644 --- a/source/Target/Queue.cpp +++ b/source/Target/Queue.cpp @@ -7,6 +7,10 @@ // //===----------------------------------------------------------------------===// +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes #include "lldb/Target/Process.h" #include "lldb/Target/Queue.h" #include "lldb/Target/QueueList.h" @@ -32,9 +36,7 @@ Queue::Queue (ProcessSP process_sp, lldb::queue_id_t queue_id, const char *queue m_process_wp = process_sp; } -Queue::~Queue () -{ -} +Queue::~Queue() = default; queue_id_t Queue::GetID () @@ -45,10 +47,7 @@ Queue::GetID () const char * Queue::GetName () { - const char *result = NULL; - if (m_queue_name.size() > 0) - result = m_queue_name.c_str(); - return result; + return (m_queue_name.empty() ? nullptr : m_queue_name.c_str()); } uint32_t @@ -62,7 +61,7 @@ Queue::GetThreads () { std::vector<ThreadSP> result; ProcessSP process_sp = m_process_wp.lock(); - if (process_sp.get ()) + if (process_sp) { for (ThreadSP thread_sp : process_sp->Threads()) { @@ -87,7 +86,6 @@ Queue::GetNumRunningWorkItems () const return m_running_work_items_count; } - void Queue::SetNumPendingWorkItems (uint32_t count) { @@ -112,11 +110,10 @@ Queue::GetLibdispatchQueueAddress () const return m_dispatch_queue_t_addr; } - const std::vector<lldb::QueueItemSP> & Queue::GetPendingItems () { - if (m_pending_items.size() == 0) + if (m_pending_items.empty()) { ProcessSP process_sp = m_process_wp.lock(); if (process_sp && process_sp->GetSystemRuntime()) diff --git a/source/Target/QueueList.cpp b/source/Target/QueueList.cpp index 6134f5cc0b21..c63331db975a 100644 --- a/source/Target/QueueList.cpp +++ b/source/Target/QueueList.cpp @@ -14,11 +14,7 @@ using namespace lldb; using namespace lldb_private; -QueueList::QueueList (Process *process) : - m_process (process), - m_stop_id (0), - m_queues (), - m_mutex () +QueueList::QueueList(Process *process) : m_process(process), m_stop_id(0), m_queues(), m_mutex() { } @@ -30,14 +26,14 @@ QueueList::~QueueList () uint32_t QueueList::GetSize () { - Mutex::Locker locker (m_mutex); + std::lock_guard<std::mutex> guard(m_mutex); return m_queues.size(); } lldb::QueueSP QueueList::GetQueueAtIndex (uint32_t idx) { - Mutex::Locker locker (m_mutex); + std::lock_guard<std::mutex> guard(m_mutex); if (idx < m_queues.size()) { return m_queues[idx]; @@ -51,14 +47,14 @@ QueueList::GetQueueAtIndex (uint32_t idx) void QueueList::Clear () { - Mutex::Locker locker (m_mutex); + std::lock_guard<std::mutex> guard(m_mutex); m_queues.clear(); } void QueueList::AddQueue (QueueSP queue_sp) { - Mutex::Locker locker (m_mutex); + std::lock_guard<std::mutex> guard(m_mutex); if (queue_sp.get ()) { m_queues.push_back (queue_sp); @@ -95,8 +91,8 @@ QueueList::FindQueueByIndexID (uint32_t index_id) return ret; } -lldb_private::Mutex & -QueueList::GetMutex () +std::mutex & +QueueList::GetMutex() { return m_mutex; } diff --git a/source/Target/RegisterContext.cpp b/source/Target/RegisterContext.cpp index afc815ba4a4e..483c932719d6 100644 --- a/source/Target/RegisterContext.cpp +++ b/source/Target/RegisterContext.cpp @@ -32,12 +32,7 @@ RegisterContext::RegisterContext (Thread &thread, uint32_t concrete_frame_idx) : { } -//---------------------------------------------------------------------- -// Destructor -//---------------------------------------------------------------------- -RegisterContext::~RegisterContext() -{ -} +RegisterContext::~RegisterContext() = default; void RegisterContext::InvalidateIfNeeded (bool force) @@ -61,7 +56,6 @@ RegisterContext::InvalidateIfNeeded (bool force) } } - const RegisterInfo * RegisterContext::GetRegisterInfoByName (const char *reg_name, uint32_t start_idx) { @@ -72,14 +66,14 @@ RegisterContext::GetRegisterInfoByName (const char *reg_name, uint32_t start_idx { const RegisterInfo * reg_info = GetRegisterInfoAtIndex(reg); - if ((reg_info->name != NULL && ::strcasecmp (reg_info->name, reg_name) == 0) || - (reg_info->alt_name != NULL && ::strcasecmp (reg_info->alt_name, reg_name) == 0)) + if ((reg_info->name != nullptr && ::strcasecmp (reg_info->name, reg_name) == 0) || + (reg_info->alt_name != nullptr && ::strcasecmp (reg_info->alt_name, reg_name) == 0)) { return reg_info; } } } - return NULL; + return nullptr; } const RegisterInfo * @@ -87,7 +81,7 @@ RegisterContext::GetRegisterInfo (lldb::RegisterKind kind, uint32_t num) { const uint32_t reg_num = ConvertRegisterKindToRegisterNumber(kind, num); if (reg_num == LLDB_INVALID_REGNUM) - return NULL; + return nullptr; return GetRegisterInfoAtIndex (reg_num); } @@ -97,7 +91,7 @@ RegisterContext::GetRegisterName (uint32_t reg) const RegisterInfo * reg_info = GetRegisterInfoAtIndex(reg); if (reg_info) return reg_info->name; - return NULL; + return nullptr; } uint64_t @@ -191,7 +185,6 @@ RegisterContext::GetFlags (uint64_t fail_value) return ReadRegisterAsUnsigned (reg, fail_value); } - uint64_t RegisterContext::ReadRegisterAsUnsigned (uint32_t reg, uint64_t fail_value) { @@ -297,7 +290,6 @@ RegisterContext::ClearHardwareBreakpoint (uint32_t hw_idx) return false; } - uint32_t RegisterContext::NumSupportedHardwareWatchpoints () { @@ -329,13 +321,12 @@ RegisterContext::ReadRegisterValueFromMemory (const RegisterInfo *reg_info, RegisterValue ®_value) { Error error; - if (reg_info == NULL) + if (reg_info == nullptr) { error.SetErrorString ("invalid register info argument."); return error; } - // Moving from addr into a register // // Case 1: src_len == dst_len @@ -408,7 +399,6 @@ RegisterContext::WriteRegisterValueToMemory (const RegisterInfo *reg_info, uint32_t dst_len, const RegisterValue ®_value) { - uint8_t dst[RegisterValue::kMaxRegisterByteSize]; Error error; @@ -451,7 +441,6 @@ RegisterContext::WriteRegisterValueToMemory (const RegisterInfo *reg_info, error.SetErrorString("invalid process"); return error; - } bool @@ -472,7 +461,6 @@ RegisterContext::CalculateTarget () return m_thread.CalculateTarget(); } - ProcessSP RegisterContext::CalculateProcess () { @@ -500,7 +488,6 @@ RegisterContext::CalculateExecutionContext (ExecutionContext &exe_ctx) m_thread.CalculateExecutionContext (exe_ctx); } - bool RegisterContext::ConvertBetweenRegisterKinds (lldb::RegisterKind source_rk, uint32_t source_regnum, lldb::RegisterKind target_rk, uint32_t& target_regnum) { @@ -512,14 +499,7 @@ RegisterContext::ConvertBetweenRegisterKinds (lldb::RegisterKind source_rk, uint if (reg_info->kinds[source_rk] == source_regnum) { target_regnum = reg_info->kinds[target_rk]; - if (target_regnum == LLDB_INVALID_REGNUM) - { - return false; - } - else - { - return true; - } + return (target_regnum != LLDB_INVALID_REGNUM); } } return false; diff --git a/source/Target/SectionLoadHistory.cpp b/source/Target/SectionLoadHistory.cpp index 1e5c4175a2bf..196d5b07db20 100644 --- a/source/Target/SectionLoadHistory.cpp +++ b/source/Target/SectionLoadHistory.cpp @@ -23,21 +23,21 @@ using namespace lldb_private; bool SectionLoadHistory::IsEmpty() const { - Mutex::Locker locker(m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); return m_stop_id_to_section_load_list.empty(); } void SectionLoadHistory::Clear () { - Mutex::Locker locker(m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); m_stop_id_to_section_load_list.clear(); } uint32_t SectionLoadHistory::GetLastStopID() const { - Mutex::Locker locker(m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); if (m_stop_id_to_section_load_list.empty()) return 0; else @@ -108,7 +108,7 @@ SectionLoadList & SectionLoadHistory::GetCurrentSectionLoadList () { const bool read_only = true; - Mutex::Locker locker(m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); SectionLoadList *section_load_list = GetSectionLoadListForStopID (eStopIDNow, read_only); assert(section_load_list != NULL); return *section_load_list; @@ -117,7 +117,7 @@ SectionLoadHistory::GetCurrentSectionLoadList () addr_t SectionLoadHistory::GetSectionLoadAddress (uint32_t stop_id, const lldb::SectionSP §ion_sp) { - Mutex::Locker locker(m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); const bool read_only = true; SectionLoadList *section_load_list = GetSectionLoadListForStopID (stop_id, read_only); return section_load_list->GetSectionLoadAddress(section_sp); @@ -127,7 +127,7 @@ bool SectionLoadHistory::ResolveLoadAddress (uint32_t stop_id, addr_t load_addr, Address &so_addr) { // First find the top level section that this load address exists in - Mutex::Locker locker(m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); const bool read_only = true; SectionLoadList *section_load_list = GetSectionLoadListForStopID (stop_id, read_only); return section_load_list->ResolveLoadAddress (load_addr, so_addr); @@ -139,7 +139,7 @@ SectionLoadHistory::SetSectionLoadAddress (uint32_t stop_id, addr_t load_addr, bool warn_multiple) { - Mutex::Locker locker(m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); const bool read_only = false; SectionLoadList *section_load_list = GetSectionLoadListForStopID (stop_id, read_only); return section_load_list->SetSectionLoadAddress(section_sp, load_addr, warn_multiple); @@ -148,7 +148,7 @@ SectionLoadHistory::SetSectionLoadAddress (uint32_t stop_id, size_t SectionLoadHistory::SetSectionUnloaded (uint32_t stop_id, const lldb::SectionSP §ion_sp) { - Mutex::Locker locker(m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); const bool read_only = false; SectionLoadList *section_load_list = GetSectionLoadListForStopID (stop_id, read_only); return section_load_list->SetSectionUnloaded (section_sp); @@ -157,7 +157,7 @@ SectionLoadHistory::SetSectionUnloaded (uint32_t stop_id, const lldb::SectionSP bool SectionLoadHistory::SetSectionUnloaded (uint32_t stop_id, const lldb::SectionSP §ion_sp, addr_t load_addr) { - Mutex::Locker locker(m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); const bool read_only = false; SectionLoadList *section_load_list = GetSectionLoadListForStopID (stop_id, read_only); return section_load_list->SetSectionUnloaded (section_sp, load_addr); @@ -166,7 +166,7 @@ SectionLoadHistory::SetSectionUnloaded (uint32_t stop_id, const lldb::SectionSP void SectionLoadHistory::Dump (Stream &s, Target *target) { - Mutex::Locker locker(m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); StopIDToSectionLoadList::iterator pos, end = m_stop_id_to_section_load_list.end(); for (pos = m_stop_id_to_section_load_list.begin(); pos != end; ++pos) { diff --git a/source/Target/SectionLoadList.cpp b/source/Target/SectionLoadList.cpp index da3aea5034d1..1235a3795500 100644 --- a/source/Target/SectionLoadList.cpp +++ b/source/Target/SectionLoadList.cpp @@ -24,13 +24,9 @@ using namespace lldb; using namespace lldb_private; - -SectionLoadList::SectionLoadList (const SectionLoadList& rhs) : - m_addr_to_sect(), - m_sect_to_addr(), - m_mutex (Mutex::eMutexTypeRecursive) +SectionLoadList::SectionLoadList(const SectionLoadList &rhs) : m_addr_to_sect(), m_sect_to_addr(), m_mutex() { - Mutex::Locker locker(rhs.m_mutex); + std::lock_guard<std::recursive_mutex> guard(rhs.m_mutex); m_addr_to_sect = rhs.m_addr_to_sect; m_sect_to_addr = rhs.m_sect_to_addr; } @@ -38,8 +34,8 @@ SectionLoadList::SectionLoadList (const SectionLoadList& rhs) : void SectionLoadList::operator=(const SectionLoadList &rhs) { - Mutex::Locker lhs_locker (m_mutex); - Mutex::Locker rhs_locker (rhs.m_mutex); + std::lock_guard<std::recursive_mutex> lhs_guard(m_mutex); + std::lock_guard<std::recursive_mutex> rhs_guard(rhs.m_mutex); m_addr_to_sect = rhs.m_addr_to_sect; m_sect_to_addr = rhs.m_sect_to_addr; } @@ -47,14 +43,14 @@ SectionLoadList::operator=(const SectionLoadList &rhs) bool SectionLoadList::IsEmpty() const { - Mutex::Locker locker(m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); return m_addr_to_sect.empty(); } void SectionLoadList::Clear () { - Mutex::Locker locker(m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); m_addr_to_sect.clear(); m_sect_to_addr.clear(); } @@ -66,7 +62,7 @@ SectionLoadList::GetSectionLoadAddress (const lldb::SectionSP §ion) const addr_t section_load_addr = LLDB_INVALID_ADDRESS; if (section) { - Mutex::Locker locker(m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); sect_to_addr_collection::const_iterator pos = m_sect_to_addr.find (section.get()); if (pos != m_sect_to_addr.end()) @@ -98,7 +94,7 @@ SectionLoadList::SetSectionLoadAddress (const lldb::SectionSP §ion, addr_t l return false; // No change // Fill in the section -> load_addr map - Mutex::Locker locker(m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); sect_to_addr_collection::iterator sta_pos = m_sect_to_addr.find(section.get()); if (sta_pos != m_sect_to_addr.end()) { @@ -172,14 +168,20 @@ SectionLoadList::SetSectionUnloaded (const lldb::SectionSP §ion_sp) if (log) { - const FileSpec &module_file_spec (section_sp->GetModule()->GetFileSpec()); + ModuleSP module_sp = section_sp->GetModule(); + std::string module_name("<Unknown>"); + if (module_sp) + { + const FileSpec &module_file_spec (section_sp->GetModule()->GetFileSpec()); + module_name = module_file_spec.GetPath(); + } log->Printf ("SectionLoadList::%s (section = %p (%s.%s))", __FUNCTION__, static_cast<void*>(section_sp.get()), - module_file_spec.GetPath().c_str(), + module_name.c_str(), section_sp->GetName().AsCString()); } - Mutex::Locker locker(m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); sect_to_addr_collection::iterator sta_pos = m_sect_to_addr.find(section_sp.get()); if (sta_pos != m_sect_to_addr.end()) @@ -203,14 +205,20 @@ SectionLoadList::SetSectionUnloaded (const lldb::SectionSP §ion_sp, addr_t l if (log) { - const FileSpec &module_file_spec (section_sp->GetModule()->GetFileSpec()); + ModuleSP module_sp = section_sp->GetModule(); + std::string module_name("<Unknown>"); + if (module_sp) + { + const FileSpec &module_file_spec (section_sp->GetModule()->GetFileSpec()); + module_name = module_file_spec.GetPath(); + } log->Printf ("SectionLoadList::%s (section = %p (%s.%s), load_addr = 0x%16.16" PRIx64 ")", __FUNCTION__, static_cast<void*>(section_sp.get()), - module_file_spec.GetPath().c_str(), + module_name.c_str(), section_sp->GetName().AsCString(), load_addr); } bool erased = false; - Mutex::Locker locker(m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); sect_to_addr_collection::iterator sta_pos = m_sect_to_addr.find(section_sp.get()); if (sta_pos != m_sect_to_addr.end()) { @@ -232,8 +240,8 @@ SectionLoadList::SetSectionUnloaded (const lldb::SectionSP §ion_sp, addr_t l bool SectionLoadList::ResolveLoadAddress (addr_t load_addr, Address &so_addr) const { - // First find the top level section that this load address exists in - Mutex::Locker locker(m_mutex); + // First find the top level section that this load address exists in + std::lock_guard<std::recursive_mutex> guard(m_mutex); if (!m_addr_to_sect.empty()) { addr_to_sect_collection::const_iterator pos = m_addr_to_sect.lower_bound (load_addr); @@ -277,7 +285,7 @@ SectionLoadList::ResolveLoadAddress (addr_t load_addr, Address &so_addr) const void SectionLoadList::Dump (Stream &s, Target *target) { - Mutex::Locker locker(m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); addr_to_sect_collection::const_iterator pos, end; for (pos = m_addr_to_sect.begin(), end = m_addr_to_sect.end(); pos != end; ++pos) { diff --git a/source/Target/StackFrame.cpp b/source/Target/StackFrame.cpp index e835521e7884..8488377158df 100644 --- a/source/Target/StackFrame.cpp +++ b/source/Target/StackFrame.cpp @@ -7,16 +7,16 @@ // //===----------------------------------------------------------------------===// -#include "lldb/Target/StackFrame.h" - // C Includes // C++ Includes // Other libraries and framework includes // Project includes -#include "lldb/Core/Module.h" +#include "lldb/Target/StackFrame.h" #include "lldb/Core/Debugger.h" #include "lldb/Core/Disassembler.h" #include "lldb/Core/FormatEntity.h" +#include "lldb/Core/Mangled.h" +#include "lldb/Core/Module.h" #include "lldb/Core/Value.h" #include "lldb/Core/ValueObjectVariable.h" #include "lldb/Core/ValueObjectConstResult.h" @@ -44,135 +44,119 @@ using namespace lldb_private; #define RESOLVED_VARIABLES (GOT_FRAME_BASE << 1) #define RESOLVED_GLOBAL_VARIABLES (RESOLVED_VARIABLES << 1) -StackFrame::StackFrame (const ThreadSP &thread_sp, - user_id_t frame_idx, - user_id_t unwind_frame_index, - addr_t cfa, - bool cfa_is_valid, - addr_t pc, - uint32_t stop_id, - bool stop_id_is_valid, - bool is_history_frame, - const SymbolContext *sc_ptr) : - m_thread_wp (thread_sp), - m_frame_index (frame_idx), - m_concrete_frame_index (unwind_frame_index), - m_reg_context_sp (), - m_id (pc, cfa, NULL), - m_frame_code_addr (pc), - m_sc (), - m_flags (), - m_frame_base (), - m_frame_base_error (), - m_cfa_is_valid (cfa_is_valid), - m_stop_id (stop_id), - m_stop_id_is_valid (stop_id_is_valid), - m_is_history_frame (is_history_frame), - m_variable_list_sp (), - m_variable_list_value_objects (), - m_disassembly (), - m_mutex (Mutex::eMutexTypeRecursive) +StackFrame::StackFrame(const ThreadSP &thread_sp, user_id_t frame_idx, user_id_t unwind_frame_index, addr_t cfa, + bool cfa_is_valid, addr_t pc, uint32_t stop_id, bool stop_id_is_valid, bool is_history_frame, + const SymbolContext *sc_ptr) + : m_thread_wp(thread_sp), + m_frame_index(frame_idx), + m_concrete_frame_index(unwind_frame_index), + m_reg_context_sp(), + m_id(pc, cfa, nullptr), + m_frame_code_addr(pc), + m_sc(), + m_flags(), + m_frame_base(), + m_frame_base_error(), + m_cfa_is_valid(cfa_is_valid), + m_stop_id(stop_id), + m_stop_id_is_valid(stop_id_is_valid), + m_is_history_frame(is_history_frame), + m_variable_list_sp(), + m_variable_list_value_objects(), + m_disassembly(), + m_mutex() { // If we don't have a CFA value, use the frame index for our StackID so that recursive // functions properly aren't confused with one another on a history stack. - if (m_is_history_frame && m_cfa_is_valid == false) + if (m_is_history_frame && !m_cfa_is_valid) { - m_id.SetCFA (m_frame_index); + m_id.SetCFA(m_frame_index); } - if (sc_ptr != NULL) + if (sc_ptr != nullptr) { m_sc = *sc_ptr; - m_flags.Set(m_sc.GetResolvedMask ()); + m_flags.Set(m_sc.GetResolvedMask()); } } -StackFrame::StackFrame (const ThreadSP &thread_sp, - user_id_t frame_idx, - user_id_t unwind_frame_index, - const RegisterContextSP ®_context_sp, - addr_t cfa, - addr_t pc, - const SymbolContext *sc_ptr) : - m_thread_wp (thread_sp), - m_frame_index (frame_idx), - m_concrete_frame_index (unwind_frame_index), - m_reg_context_sp (reg_context_sp), - m_id (pc, cfa, NULL), - m_frame_code_addr (pc), - m_sc (), - m_flags (), - m_frame_base (), - m_frame_base_error (), - m_cfa_is_valid (true), - m_stop_id (0), - m_stop_id_is_valid (false), - m_is_history_frame (false), - m_variable_list_sp (), - m_variable_list_value_objects (), - m_disassembly (), - m_mutex (Mutex::eMutexTypeRecursive) +StackFrame::StackFrame(const ThreadSP &thread_sp, user_id_t frame_idx, user_id_t unwind_frame_index, + const RegisterContextSP ®_context_sp, addr_t cfa, addr_t pc, const SymbolContext *sc_ptr) + : m_thread_wp(thread_sp), + m_frame_index(frame_idx), + m_concrete_frame_index(unwind_frame_index), + m_reg_context_sp(reg_context_sp), + m_id(pc, cfa, nullptr), + m_frame_code_addr(pc), + m_sc(), + m_flags(), + m_frame_base(), + m_frame_base_error(), + m_cfa_is_valid(true), + m_stop_id(0), + m_stop_id_is_valid(false), + m_is_history_frame(false), + m_variable_list_sp(), + m_variable_list_value_objects(), + m_disassembly(), + m_mutex() { - if (sc_ptr != NULL) + if (sc_ptr != nullptr) { m_sc = *sc_ptr; - m_flags.Set(m_sc.GetResolvedMask ()); + m_flags.Set(m_sc.GetResolvedMask()); } - + if (reg_context_sp && !m_sc.target_sp) { m_sc.target_sp = reg_context_sp->CalculateTarget(); if (m_sc.target_sp) - m_flags.Set (eSymbolContextTarget); + m_flags.Set(eSymbolContextTarget); } } -StackFrame::StackFrame (const ThreadSP &thread_sp, - user_id_t frame_idx, - user_id_t unwind_frame_index, - const RegisterContextSP ®_context_sp, - addr_t cfa, - const Address& pc_addr, - const SymbolContext *sc_ptr) : - m_thread_wp (thread_sp), - m_frame_index (frame_idx), - m_concrete_frame_index (unwind_frame_index), - m_reg_context_sp (reg_context_sp), - m_id (pc_addr.GetLoadAddress (thread_sp->CalculateTarget().get()), cfa, NULL), - m_frame_code_addr (pc_addr), - m_sc (), - m_flags (), - m_frame_base (), - m_frame_base_error (), - m_cfa_is_valid (true), - m_stop_id (0), - m_stop_id_is_valid (false), - m_is_history_frame (false), - m_variable_list_sp (), - m_variable_list_value_objects (), - m_disassembly (), - m_mutex (Mutex::eMutexTypeRecursive) +StackFrame::StackFrame(const ThreadSP &thread_sp, user_id_t frame_idx, user_id_t unwind_frame_index, + const RegisterContextSP ®_context_sp, addr_t cfa, const Address &pc_addr, + const SymbolContext *sc_ptr) + : m_thread_wp(thread_sp), + m_frame_index(frame_idx), + m_concrete_frame_index(unwind_frame_index), + m_reg_context_sp(reg_context_sp), + m_id(pc_addr.GetLoadAddress(thread_sp->CalculateTarget().get()), cfa, nullptr), + m_frame_code_addr(pc_addr), + m_sc(), + m_flags(), + m_frame_base(), + m_frame_base_error(), + m_cfa_is_valid(true), + m_stop_id(0), + m_stop_id_is_valid(false), + m_is_history_frame(false), + m_variable_list_sp(), + m_variable_list_value_objects(), + m_disassembly(), + m_mutex() { - if (sc_ptr != NULL) + if (sc_ptr != nullptr) { m_sc = *sc_ptr; - m_flags.Set(m_sc.GetResolvedMask ()); + m_flags.Set(m_sc.GetResolvedMask()); } - - if (m_sc.target_sp.get() == NULL && reg_context_sp) + + if (!m_sc.target_sp && reg_context_sp) { m_sc.target_sp = reg_context_sp->CalculateTarget(); if (m_sc.target_sp) - m_flags.Set (eSymbolContextTarget); + m_flags.Set(eSymbolContextTarget); } - - ModuleSP pc_module_sp (pc_addr.GetModule()); + + ModuleSP pc_module_sp(pc_addr.GetModule()); if (!m_sc.module_sp || m_sc.module_sp != pc_module_sp) { if (pc_module_sp) { m_sc.module_sp = pc_module_sp; - m_flags.Set (eSymbolContextModule); + m_flags.Set(eSymbolContextModule); } else { @@ -181,18 +165,12 @@ StackFrame::StackFrame (const ThreadSP &thread_sp, } } - -//---------------------------------------------------------------------- -// Destructor -//---------------------------------------------------------------------- -StackFrame::~StackFrame() -{ -} +StackFrame::~StackFrame() = default; StackID& StackFrame::GetStackID() { - Mutex::Locker locker(m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); // Make sure we have resolved the StackID object's symbol context scope if // we already haven't looked it up. @@ -209,13 +187,13 @@ StackFrame::GetStackID() // Calculate the frame block and use this for the stack ID symbol // context scope if we have one. SymbolContextScope *scope = GetFrameBlock (); - if (scope == NULL) + if (scope == nullptr) { // We don't have a block, so use the symbol if (m_flags.IsClear (eSymbolContextSymbol)) GetSymbolContext (eSymbolContextSymbol); - // It is ok if m_sc.symbol is NULL here + // It is ok if m_sc.symbol is nullptr here scope = m_sc.symbol; } // Set the symbol context scope (the accessor will set the @@ -239,7 +217,7 @@ StackFrame::GetFrameIndex () const void StackFrame::SetSymbolContextScope (SymbolContextScope *symbol_scope) { - Mutex::Locker locker(m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); m_flags.Set (RESOLVED_FRAME_ID_SYMBOL_SCOPE); m_id.SetSymbolContextScope (symbol_scope); } @@ -247,7 +225,7 @@ StackFrame::SetSymbolContextScope (SymbolContextScope *symbol_scope) const Address& StackFrame::GetFrameCodeAddress() { - Mutex::Locker locker(m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); if (m_flags.IsClear(RESOLVED_FRAME_CODE_ADDR) && !m_frame_code_addr.IsSectionOffset()) { m_flags.Set (RESOLVED_FRAME_CODE_ADDR); @@ -278,7 +256,7 @@ StackFrame::GetFrameCodeAddress() bool StackFrame::ChangePC (addr_t pc) { - Mutex::Locker locker(m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); // We can't change the pc value of a history stack frame - it is immutable. if (m_is_history_frame) return false; @@ -294,15 +272,15 @@ StackFrame::ChangePC (addr_t pc) const char * StackFrame::Disassemble () { - Mutex::Locker locker(m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); if (m_disassembly.GetSize() == 0) { ExecutionContext exe_ctx (shared_from_this()); Target *target = exe_ctx.GetTargetPtr(); if (target) { - const char *plugin_name = NULL; - const char *flavor = NULL; + const char *plugin_name = nullptr; + const char *flavor = nullptr; Disassembler::Disassemble (target->GetDebugger(), target->GetArchitecture(), plugin_name, @@ -314,7 +292,7 @@ StackFrame::Disassemble () m_disassembly); } if (m_disassembly.GetSize() == 0) - return NULL; + return nullptr; } return m_disassembly.GetData(); } @@ -322,7 +300,7 @@ StackFrame::Disassemble () Block * StackFrame::GetFrameBlock () { - if (m_sc.block == NULL && m_flags.IsClear (eSymbolContextBlock)) + if (m_sc.block == nullptr && m_flags.IsClear(eSymbolContextBlock)) GetSymbolContext (eSymbolContextBlock); if (m_sc.block) @@ -342,7 +320,7 @@ StackFrame::GetFrameBlock () return &m_sc.function->GetBlock (false); } } - return NULL; + return nullptr; } //---------------------------------------------------------------------- @@ -354,7 +332,7 @@ StackFrame::GetFrameBlock () const SymbolContext& StackFrame::GetSymbolContext (uint32_t resolve_scope) { - Mutex::Locker locker(m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); // Copy our internal symbol context into "sc". if ((m_flags.Get() & resolve_scope) != resolve_scope) { @@ -368,7 +346,6 @@ StackFrame::GetSymbolContext (uint32_t resolve_scope) resolved |= eSymbolContextTarget; } - // Resolve our PC to section offset if we haven't already done so // and if we don't have a module. The resolved address section will // contain the module to which it belongs @@ -411,7 +388,6 @@ StackFrame::GetSymbolContext (uint32_t resolve_scope) } } - if (m_sc.module_sp) { // We have something in our stack frame symbol context, lets check @@ -487,25 +463,18 @@ StackFrame::GetSymbolContext (uint32_t resolve_scope) // Only replace what we didn't already have as we may have // information for an inlined function scope that won't match // what a standard lookup by address would match - if ((resolved & eSymbolContextCompUnit) && m_sc.comp_unit == NULL) + if ((resolved & eSymbolContextCompUnit) && m_sc.comp_unit == nullptr) m_sc.comp_unit = sc.comp_unit; - if ((resolved & eSymbolContextFunction) && m_sc.function == NULL) + if ((resolved & eSymbolContextFunction) && m_sc.function == nullptr) m_sc.function = sc.function; - if ((resolved & eSymbolContextBlock) && m_sc.block == NULL) + if ((resolved & eSymbolContextBlock) && m_sc.block == nullptr) m_sc.block = sc.block; - if ((resolved & eSymbolContextSymbol) && m_sc.symbol == NULL) + if ((resolved & eSymbolContextSymbol) && m_sc.symbol == nullptr) m_sc.symbol = sc.symbol; if ((resolved & eSymbolContextLineEntry) && !m_sc.line_entry.IsValid()) { m_sc.line_entry = sc.line_entry; - if (m_sc.target_sp) - { - // Be sure to apply and file remappings to our file and line - // entries when handing out a line entry - FileSpec new_file_spec; - if (m_sc.target_sp->GetSourcePathMap().FindFile (m_sc.line_entry.file, new_file_spec)) - m_sc.line_entry.file = new_file_spec; - } + m_sc.line_entry.ApplyFileMappings(m_sc.target_sp); } } } @@ -533,11 +502,10 @@ StackFrame::GetSymbolContext (uint32_t resolve_scope) return m_sc; } - VariableList * StackFrame::GetVariableList (bool get_file_globals) { - Mutex::Locker locker(m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); if (m_flags.IsClear(RESOLVED_VARIABLES)) { m_flags.Set(RESOLVED_VARIABLES); @@ -550,7 +518,11 @@ StackFrame::GetVariableList (bool get_file_globals) const bool can_create = true; const bool stop_if_child_block_is_inlined_function = true; m_variable_list_sp.reset(new VariableList()); - frame_block->AppendBlockVariables(can_create, get_child_variables, stop_if_child_block_is_inlined_function, m_variable_list_sp.get()); + frame_block->AppendBlockVariables(can_create, + get_child_variables, + stop_if_child_block_is_inlined_function, + [this](Variable* v) { return true; }, + m_variable_list_sp.get()); } } @@ -576,9 +548,9 @@ StackFrame::GetVariableList (bool get_file_globals) } VariableListSP -StackFrame::GetInScopeVariableList (bool get_file_globals) +StackFrame::GetInScopeVariableList (bool get_file_globals, bool must_have_valid_location) { - Mutex::Locker locker(m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); // We can't fetch variable information for a history stack frame. if (m_is_history_frame) return VariableListSP(); @@ -594,10 +566,14 @@ StackFrame::GetInScopeVariableList (bool get_file_globals) m_sc.block->AppendVariables (can_create, get_parent_variables, stop_if_block_is_inlined_function, + [this, must_have_valid_location](Variable* v) + { + return v->IsInScope(this) && (!must_have_valid_location || v->LocationIsValidForFrame(this)); + }, var_list_sp.get()); } - if (m_sc.comp_unit) + if (m_sc.comp_unit && get_file_globals) { VariableListSP global_variable_list_sp (m_sc.comp_unit->GetVariableList(true)); if (global_variable_list_sp) @@ -607,7 +583,6 @@ StackFrame::GetInScopeVariableList (bool get_file_globals) return var_list_sp; } - ValueObjectSP StackFrame::GetValueForVariableExpressionPath (const char *var_expr_cstr, DynamicValueType use_dynamic, @@ -736,7 +711,6 @@ StackFrame::GetValueForVariableExpressionPath (const char *var_expr_cstr, const char separator_type = var_path[0]; switch (separator_type) { - case '-': if (var_path.size() >= 2 && var_path[1] != '>') return ValueObjectSP(); @@ -745,7 +719,7 @@ StackFrame::GetValueForVariableExpressionPath (const char *var_expr_cstr, { // Make sure we aren't trying to deref an objective // C ivar if this is not allowed - const uint32_t pointer_type_flags = valobj_sp->GetCompilerType().GetTypeInfo (NULL); + const uint32_t pointer_type_flags = valobj_sp->GetCompilerType().GetTypeInfo(nullptr); if ((pointer_type_flags & eTypeIsObjC) && (pointer_type_flags & eTypeIsPointer)) { @@ -756,7 +730,7 @@ StackFrame::GetValueForVariableExpressionPath (const char *var_expr_cstr, } } var_path.erase (0, 1); // Remove the '-' - // Fall through + LLVM_FALLTHROUGH; case '.': { const bool expr_is_ptr = var_path[0] == '>'; @@ -800,7 +774,7 @@ StackFrame::GetValueForVariableExpressionPath (const char *var_expr_cstr, child_valobj_sp = valobj_sp->GetChildMemberWithName (child_name, true); if (!child_valobj_sp) { - if (no_synth_child == false) + if (!no_synth_child) { child_valobj_sp = valobj_sp->GetSyntheticValue(); if (child_valobj_sp) @@ -854,7 +828,7 @@ StackFrame::GetValueForVariableExpressionPath (const char *var_expr_cstr, // Array member access, or treating pointer as an array if (var_path.size() > 2) // Need at least two brackets and a number { - char *end = NULL; + char *end = nullptr; long child_index = ::strtol (&var_path[1], &end, 0); if (end && *end == ']' && *(end-1) != '[') // this code forces an error in the case of arr[]. as bitfield[] is not a good syntax we're good to go @@ -919,7 +893,7 @@ StackFrame::GetValueForVariableExpressionPath (const char *var_expr_cstr, { // dereferencing ObjC variables is not valid.. so let's try and recur to synthetic children ValueObjectSP synthetic = valobj_sp->GetSyntheticValue(); - if (synthetic.get() == NULL /* no synthetic */ + if (!synthetic /* no synthetic */ || synthetic == valobj_sp) /* synthetic is the same as the original object */ { valobj_sp->GetExpressionPath (var_expr_path_strm, false); @@ -961,12 +935,12 @@ StackFrame::GetValueForVariableExpressionPath (const char *var_expr_cstr, } } } - else if (valobj_sp->GetCompilerType().IsArrayType (NULL, NULL, &is_incomplete_array)) + else if (valobj_sp->GetCompilerType().IsArrayType(nullptr, nullptr, &is_incomplete_array)) { // Pass false to dynamic_value here so we can tell the difference between // no dynamic value and no member of this type... child_valobj_sp = valobj_sp->GetChildAtIndex (child_index, true); - if (!child_valobj_sp && (is_incomplete_array || no_synth_child == false)) + if (!child_valobj_sp && (is_incomplete_array || !no_synth_child)) child_valobj_sp = valobj_sp->GetSyntheticArrayMember (child_index, true); if (!child_valobj_sp) @@ -995,7 +969,7 @@ StackFrame::GetValueForVariableExpressionPath (const char *var_expr_cstr, { ValueObjectSP synthetic = valobj_sp->GetSyntheticValue(); if (no_synth_child /* synthetic is forbidden */ || - synthetic.get() == NULL /* no synthetic */ + !synthetic /* no synthetic */ || synthetic == valobj_sp) /* synthetic is the same as the original object */ { valobj_sp->GetExpressionPath (var_expr_path_strm, false); @@ -1048,7 +1022,7 @@ StackFrame::GetValueForVariableExpressionPath (const char *var_expr_cstr, else if (end && *end == '-') { // this is most probably a BitField, let's take a look - char *real_end = NULL; + char *real_end = nullptr; long final_index = ::strtol (end+1, &real_end, 0); bool expand_bitfield = true; if (real_end && *real_end == ']') @@ -1174,7 +1148,6 @@ StackFrame::GetValueForVariableExpressionPath (const char *var_expr_cstr, if (var_path.empty()) break; - } if (valobj_sp) { @@ -1208,8 +1181,8 @@ StackFrame::GetValueForVariableExpressionPath (const char *var_expr_cstr, bool StackFrame::GetFrameBaseValue (Scalar &frame_base, Error *error_ptr) { - Mutex::Locker locker(m_mutex); - if (m_cfa_is_valid == false) + std::lock_guard<std::recursive_mutex> guard(m_mutex); + if (!m_cfa_is_valid) { m_frame_base_error.SetErrorString("No frame base available for this historical stack frame."); return false; @@ -1229,7 +1202,15 @@ StackFrame::GetFrameBaseValue (Scalar &frame_base, Error *error_ptr) if (m_sc.function->GetFrameBaseExpression().IsLocationList()) loclist_base_addr = m_sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress (exe_ctx.GetTargetPtr()); - if (m_sc.function->GetFrameBaseExpression().Evaluate(&exe_ctx, NULL, NULL, NULL, loclist_base_addr, NULL, expr_value, &m_frame_base_error) == false) + if (m_sc.function->GetFrameBaseExpression().Evaluate(&exe_ctx, + nullptr, + nullptr, + nullptr, + loclist_base_addr, + nullptr, + nullptr, + expr_value, + &m_frame_base_error) == false) { // We should really have an error if evaluate returns, but in case // we don't, lets set the error to something at least. @@ -1258,7 +1239,7 @@ StackFrame::GetFrameBaseValue (Scalar &frame_base, Error *error_ptr) RegisterContextSP StackFrame::GetRegisterContext () { - Mutex::Locker locker(m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); if (!m_reg_context_sp) { ThreadSP thread_sp (GetThread()); @@ -1275,11 +1256,10 @@ StackFrame::HasDebugInformation () return m_sc.line_entry.IsValid(); } - ValueObjectSP StackFrame::GetValueObjectForFrameVariable (const VariableSP &variable_sp, DynamicValueType use_dynamic) { - Mutex::Locker locker(m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); ValueObjectSP valobj_sp; if (m_is_history_frame) { @@ -1294,7 +1274,7 @@ StackFrame::GetValueObjectForFrameVariable (const VariableSP &variable_sp, Dynam if (var_idx < num_variables) { valobj_sp = m_variable_list_value_objects.GetValueObjectAtIndex (var_idx); - if (valobj_sp.get() == NULL) + if (!valobj_sp) { if (m_variable_list_value_objects.GetSize() < num_variables) m_variable_list_value_objects.Resize(num_variables); @@ -1315,7 +1295,7 @@ StackFrame::GetValueObjectForFrameVariable (const VariableSP &variable_sp, Dynam ValueObjectSP StackFrame::TrackGlobalVariable (const VariableSP &variable_sp, DynamicValueType use_dynamic) { - Mutex::Locker locker(m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); if (m_is_history_frame) return ValueObjectSP(); @@ -1326,7 +1306,7 @@ StackFrame::TrackGlobalVariable (const VariableSP &variable_sp, DynamicValueType // We aren't already tracking this global VariableList *var_list = GetVariableList (true); // If this frame has no variables, create a new list - if (var_list == NULL) + if (var_list == nullptr) m_variable_list_sp.reset (new VariableList()); // Add the global/static variable to this frame @@ -1341,10 +1321,10 @@ StackFrame::TrackGlobalVariable (const VariableSP &variable_sp, DynamicValueType bool StackFrame::IsInlined () { - if (m_sc.block == NULL) + if (m_sc.block == nullptr) GetSymbolContext (eSymbolContextBlock); if (m_sc.block) - return m_sc.block->GetContainingInlinedBlock() != NULL; + return m_sc.block->GetContainingInlinedBlock() != nullptr; return false; } @@ -1357,6 +1337,23 @@ StackFrame::GetLanguage () return lldb::eLanguageTypeUnknown; } +lldb::LanguageType +StackFrame::GuessLanguage () +{ + LanguageType lang_type = GetLanguage(); + + if (lang_type == eLanguageTypeUnknown) + { + Function *f = GetSymbolContext(eSymbolContextFunction).function; + if (f) + { + lang_type = f->GetMangled().GuessLanguage(); + } + } + + return lang_type; +} + TargetSP StackFrame::CalculateTarget () { @@ -1393,7 +1390,6 @@ StackFrame::CalculateStackFrame () return shared_from_this(); } - void StackFrame::CalculateExecutionContext (ExecutionContext &exe_ctx) { @@ -1403,7 +1399,7 @@ StackFrame::CalculateExecutionContext (ExecutionContext &exe_ctx) void StackFrame::DumpUsingSettingsFormat (Stream *strm, const char *frame_marker) { - if (strm == NULL) + if (strm == nullptr) return; GetSymbolContext(eSymbolContextEverything); @@ -1413,11 +1409,11 @@ StackFrame::DumpUsingSettingsFormat (Stream *strm, const char *frame_marker) if (frame_marker) s.PutCString(frame_marker); - const FormatEntity::Entry *frame_format = NULL; + const FormatEntity::Entry *frame_format = nullptr; Target *target = exe_ctx.GetTargetPtr(); if (target) frame_format = target->GetDebugger().GetFrameFormat(); - if (frame_format && FormatEntity::Format(*frame_format, s, &m_sc, &exe_ctx, NULL, NULL, false, false)) + if (frame_format && FormatEntity::Format(*frame_format, s, &m_sc, &exe_ctx, nullptr, nullptr, false, false)) { strm->Write(s.GetData(), s.GetSize()); } @@ -1431,7 +1427,7 @@ StackFrame::DumpUsingSettingsFormat (Stream *strm, const char *frame_marker) void StackFrame::Dump (Stream *strm, bool show_frame_index, bool show_fullpaths) { - if (strm == NULL) + if (strm == nullptr) return; if (show_frame_index) @@ -1459,19 +1455,18 @@ StackFrame::Dump (Stream *strm, bool show_frame_index, bool show_fullpaths) void StackFrame::UpdateCurrentFrameFromPreviousFrame (StackFrame &prev_frame) { - Mutex::Locker locker(m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); assert (GetStackID() == prev_frame.GetStackID()); // TODO: remove this after some testing m_variable_list_sp = prev_frame.m_variable_list_sp; m_variable_list_value_objects.Swap (prev_frame.m_variable_list_value_objects); if (!m_disassembly.GetString().empty()) m_disassembly.GetString().swap (m_disassembly.GetString()); } - void StackFrame::UpdatePreviousFrameFromCurrentFrame (StackFrame &curr_frame) { - Mutex::Locker locker(m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); assert (GetStackID() == curr_frame.GetStackID()); // TODO: remove this after some testing m_id.SetPC (curr_frame.m_id.GetPC()); // Update the Stack ID PC value assert (GetThread() == curr_frame.GetThread()); @@ -1479,10 +1474,10 @@ StackFrame::UpdatePreviousFrameFromCurrentFrame (StackFrame &curr_frame) m_concrete_frame_index = curr_frame.m_concrete_frame_index; m_reg_context_sp = curr_frame.m_reg_context_sp; m_frame_code_addr = curr_frame.m_frame_code_addr; - assert (m_sc.target_sp.get() == NULL || curr_frame.m_sc.target_sp.get() == NULL || m_sc.target_sp.get() == curr_frame.m_sc.target_sp.get()); - assert (m_sc.module_sp.get() == NULL || curr_frame.m_sc.module_sp.get() == NULL || m_sc.module_sp.get() == curr_frame.m_sc.module_sp.get()); - assert (m_sc.comp_unit == NULL || curr_frame.m_sc.comp_unit == NULL || m_sc.comp_unit == curr_frame.m_sc.comp_unit); - assert (m_sc.function == NULL || curr_frame.m_sc.function == NULL || m_sc.function == curr_frame.m_sc.function); + assert (!m_sc.target_sp || !curr_frame.m_sc.target_sp || m_sc.target_sp.get() == curr_frame.m_sc.target_sp.get()); + assert (!m_sc.module_sp || !curr_frame.m_sc.module_sp || m_sc.module_sp.get() == curr_frame.m_sc.module_sp.get()); + assert (m_sc.comp_unit == nullptr || curr_frame.m_sc.comp_unit == nullptr || m_sc.comp_unit == curr_frame.m_sc.comp_unit); + assert (m_sc.function == nullptr || curr_frame.m_sc.function == nullptr || m_sc.function == curr_frame.m_sc.function); m_sc = curr_frame.m_sc; m_flags.Clear(GOT_FRAME_BASE | eSymbolContextEverything); m_flags.Set (m_sc.GetResolvedMask()); @@ -1490,11 +1485,10 @@ StackFrame::UpdatePreviousFrameFromCurrentFrame (StackFrame &curr_frame) m_frame_base_error.Clear(); } - bool StackFrame::HasCachedData () const { - if (m_variable_list_sp.get()) + if (m_variable_list_sp) return true; if (m_variable_list_value_objects.GetSize() > 0) return true; @@ -1554,12 +1548,12 @@ StackFrame::GetStatus (Stream& strm, case Debugger::eStopDisassemblyTypeNoDebugInfo: if (have_debuginfo) break; - // Fall through to next case + LLVM_FALLTHROUGH; case Debugger::eStopDisassemblyTypeNoSource: if (have_source) break; - // Fall through to next case + LLVM_FALLTHROUGH; case Debugger::eStopDisassemblyTypeAlways: if (target) @@ -1571,8 +1565,8 @@ StackFrame::GetStatus (Stream& strm, AddressRange pc_range; pc_range.GetBaseAddress() = GetFrameCodeAddress(); pc_range.SetByteSize(disasm_lines * target_arch.GetMaximumOpcodeByteSize()); - const char *plugin_name = NULL; - const char *flavor = NULL; + const char *plugin_name = nullptr; + const char *flavor = nullptr; Disassembler::Disassemble (target->GetDebugger(), target_arch, plugin_name, @@ -1591,4 +1585,3 @@ StackFrame::GetStatus (Stream& strm, } return true; } - diff --git a/source/Target/StackFrameList.cpp b/source/Target/StackFrameList.cpp index f2f3cad471fe..8304caf5710f 100644 --- a/source/Target/StackFrameList.cpp +++ b/source/Target/StackFrameList.cpp @@ -7,12 +7,11 @@ // //===----------------------------------------------------------------------===// -#include "lldb/Target/StackFrameList.h" - // C Includes // C++ Includes // Other libraries and framework includes // Project includes +#include "lldb/Target/StackFrameList.h" #include "lldb/Breakpoint/BreakpointLocation.h" #include "lldb/Breakpoint/Breakpoint.h" #include "lldb/Core/Log.h" @@ -37,32 +36,24 @@ using namespace lldb_private; //---------------------------------------------------------------------- // StackFrameList constructor //---------------------------------------------------------------------- -StackFrameList::StackFrameList -( - Thread &thread, - const lldb::StackFrameListSP &prev_frames_sp, - bool show_inline_frames -) : - m_thread (thread), - m_prev_frames_sp (prev_frames_sp), - m_mutex (Mutex::eMutexTypeRecursive), - m_frames (), - m_selected_frame_idx (0), - m_concrete_frames_fetched (0), - m_current_inlined_depth (UINT32_MAX), - m_current_inlined_pc (LLDB_INVALID_ADDRESS), - m_show_inlined_frames (show_inline_frames) +StackFrameList::StackFrameList(Thread &thread, const lldb::StackFrameListSP &prev_frames_sp, bool show_inline_frames) + : m_thread(thread), + m_prev_frames_sp(prev_frames_sp), + m_mutex(), + m_frames(), + m_selected_frame_idx(0), + m_concrete_frames_fetched(0), + m_current_inlined_depth(UINT32_MAX), + m_current_inlined_pc(LLDB_INVALID_ADDRESS), + m_show_inlined_frames(show_inline_frames) { if (prev_frames_sp) { m_current_inlined_depth = prev_frames_sp->m_current_inlined_depth; - m_current_inlined_pc = prev_frames_sp->m_current_inlined_pc; + m_current_inlined_pc = prev_frames_sp->m_current_inlined_pc; } } -//---------------------------------------------------------------------- -// Destructor -//---------------------------------------------------------------------- StackFrameList::~StackFrameList() { // Call clear since this takes a lock and clears the stack frame list @@ -105,12 +96,12 @@ StackFrameList::GetCurrentInlinedDepth () void StackFrameList::ResetCurrentInlinedDepth () { - Mutex::Locker locker (m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); if (m_show_inlined_frames) { GetFramesUpTo(0); - if (m_frames.size() == 0) + if (m_frames.empty()) return; if (!m_frames[0]->IsInlined()) { @@ -191,6 +182,7 @@ StackFrameList::ResetCurrentInlinedDepth () break; } } + LLVM_FALLTHROUGH; default: { // Otherwise, we should set ourselves at the container of the inlining, so that the @@ -199,7 +191,7 @@ StackFrameList::ResetCurrentInlinedDepth () int num_inlined_functions = 0; for (Block *container_ptr = block_ptr->GetInlinedParent(); - container_ptr != NULL; + container_ptr != nullptr; container_ptr = container_ptr->GetInlinedParent()) { if (!container_ptr->GetRangeContainingAddress(pc_as_address, containing_range)) @@ -258,7 +250,7 @@ void StackFrameList::GetFramesUpTo(uint32_t end_idx) { // this makes sure we do not fetch frames for an invalid thread - if (m_thread.IsValid() == false) + if (!m_thread.IsValid()) return; // We've already gotten more frames than asked for, or we've already finished unwinding, return. @@ -304,7 +296,6 @@ StackFrameList::GetFramesUpTo(uint32_t end_idx) if (reg_ctx_sp) { - const bool success = unwinder && unwinder->GetFrameInfoAtIndex(idx, cfa, pc); // There shouldn't be any way not to get the frame info for frame 0. // But if the unwinder can't make one, lets make one by hand with the @@ -315,13 +306,13 @@ StackFrameList::GetFramesUpTo(uint32_t end_idx) pc = reg_ctx_sp->GetPC(); } - unwind_frame_sp.reset (new StackFrame (m_thread.shared_from_this(), - m_frames.size(), - idx, - reg_ctx_sp, - cfa, - pc, - NULL)); + unwind_frame_sp.reset(new StackFrame(m_thread.shared_from_this(), + m_frames.size(), + idx, + reg_ctx_sp, + cfa, + pc, + nullptr)); m_frames.push_back (unwind_frame_sp); } } @@ -343,7 +334,8 @@ StackFrameList::GetFramesUpTo(uint32_t end_idx) const bool cfa_is_valid = true; const bool stop_id_is_valid = false; const bool is_history_frame = false; - unwind_frame_sp.reset (new StackFrame (m_thread.shared_from_this(), m_frames.size(), idx, cfa, cfa_is_valid, pc, 0, stop_id_is_valid, is_history_frame, NULL)); + unwind_frame_sp.reset(new StackFrame(m_thread.shared_from_this(), m_frames.size(), idx, cfa, cfa_is_valid, pc, + 0, stop_id_is_valid, is_history_frame, nullptr)); m_frames.push_back (unwind_frame_sp); } @@ -353,6 +345,7 @@ StackFrameList::GetFramesUpTo(uint32_t end_idx) if (unwind_block) { Address curr_frame_address (unwind_frame_sp->GetFrameCodeAddress()); + TargetSP target_sp = m_thread.CalculateTarget(); // Be sure to adjust the frame address to match the address // that was used to lookup the symbol context above. If we are // in the first concrete frame, then we lookup using the current @@ -365,9 +358,8 @@ StackFrameList::GetFramesUpTo(uint32_t end_idx) // If curr_frame_address points to the first address in a section then after // adjustment it will point to an other section. In that case resolve the // address again to the correct section plus offset form. - TargetSP target = m_thread.CalculateTarget(); - addr_t load_addr = curr_frame_address.GetOpcodeLoadAddress(target.get(), eAddressClassCode); - curr_frame_address.SetOpcodeLoadAddress(load_addr - 1, target.get(), eAddressClassCode); + addr_t load_addr = curr_frame_address.GetOpcodeLoadAddress(target_sp.get(), eAddressClassCode); + curr_frame_address.SetOpcodeLoadAddress(load_addr - 1, target_sp.get(), eAddressClassCode); } else { @@ -380,17 +372,18 @@ StackFrameList::GetFramesUpTo(uint32_t end_idx) while (unwind_sc.GetParentOfInlinedScope(curr_frame_address, next_frame_sc, next_frame_address)) { - StackFrameSP frame_sp(new StackFrame (m_thread.shared_from_this(), - m_frames.size(), - idx, - unwind_frame_sp->GetRegisterContextSP (), - cfa, - next_frame_address, - &next_frame_sc)); - - m_frames.push_back (frame_sp); - unwind_sc = next_frame_sc; - curr_frame_address = next_frame_address; + next_frame_sc.line_entry.ApplyFileMappings(target_sp);
+ StackFrameSP frame_sp(new StackFrame(m_thread.shared_from_this(), + m_frames.size(), + idx, + unwind_frame_sp->GetRegisterContextSP (), + cfa, + next_frame_address, + &next_frame_sc)); + + m_frames.push_back (frame_sp); + unwind_sc = next_frame_sc; + curr_frame_address = next_frame_address; } } } while (m_frames.size() - 1 < end_idx); @@ -439,7 +432,7 @@ StackFrameList::GetFramesUpTo(uint32_t end_idx) StackFrame *curr_frame = curr_frame_sp.get(); StackFrame *prev_frame = prev_frame_sp.get(); - if (curr_frame == NULL || prev_frame == NULL) + if (curr_frame == nullptr || prev_frame == nullptr) break; // Check the stack ID to make sure they are equal @@ -487,7 +480,7 @@ StackFrameList::GetFramesUpTo(uint32_t end_idx) uint32_t StackFrameList::GetNumFrames (bool can_create) { - Mutex::Locker locker (m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); if (can_create) GetFramesUpTo (UINT32_MAX); @@ -502,9 +495,10 @@ StackFrameList::GetNumFrames (bool can_create) void StackFrameList::Dump (Stream *s) { - if (s == NULL) + if (s == nullptr) return; - Mutex::Locker locker (m_mutex); + + std::lock_guard<std::recursive_mutex> guard(m_mutex); const_iterator pos, begin = m_frames.begin(), end = m_frames.end(); for (pos = begin; pos != end; ++pos) @@ -527,7 +521,7 @@ StackFrameSP StackFrameList::GetFrameAtIndex (uint32_t idx) { StackFrameSP frame_sp; - Mutex::Locker locker (m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); uint32_t original_idx = idx; uint32_t inlined_depth = GetCurrentInlinedDepth(); @@ -562,7 +556,8 @@ StackFrameList::GetFrameAtIndex (uint32_t idx) const bool cfa_is_valid = true; const bool stop_id_is_valid = false; const bool is_history_frame = false; - frame_sp.reset (new StackFrame (m_thread.shared_from_this(), idx, idx, cfa, cfa_is_valid, pc, 0, stop_id_is_valid, is_history_frame, NULL)); + frame_sp.reset(new StackFrame(m_thread.shared_from_this(), idx, idx, cfa, cfa_is_valid, pc, 0, + stop_id_is_valid, is_history_frame, nullptr)); Function *function = frame_sp->GetSymbolContext (eSymbolContextFunction).function; if (function) @@ -573,7 +568,7 @@ StackFrameList::GetFrameAtIndex (uint32_t idx) } else { - // Set the symbol scope from the symbol regardless if it is NULL or valid. + // Set the symbol scope from the symbol regardless if it is nullptr or valid. frame_sp->SetSymbolContextScope (frame_sp->GetSymbolContext (eSymbolContextSymbol).symbol); } SetFrameAtIndex(idx, frame_sp); @@ -586,17 +581,16 @@ StackFrameList::GetFrameAtIndex (uint32_t idx) // There should ALWAYS be a frame at index 0. If something went wrong with the CurrentInlinedDepth such that // there weren't as many frames as we thought taking that into account, then reset the current inlined depth // and return the real zeroth frame. - if (m_frames.size() > 0) - { - ResetCurrentInlinedDepth(); - frame_sp = m_frames[original_idx]; - } - else + if (m_frames.empty()) { // Why do we have a thread with zero frames, that should not ever happen... if (m_thread.IsValid()) assert ("A valid thread has no frames."); - + } + else + { + ResetCurrentInlinedDepth(); + frame_sp = m_frames[original_idx]; } } @@ -636,7 +630,7 @@ StackFrameList::GetFrameWithStackID (const StackID &stack_id) if (stack_id.IsValid()) { - Mutex::Locker locker (m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); uint32_t frame_idx = 0; // Do a binary search in case the stack frame is already in our cache collection::const_iterator begin = m_frames.begin(); @@ -682,15 +676,14 @@ StackFrameList::SetFrameAtIndex (uint32_t idx, StackFrameSP &frame_sp) uint32_t StackFrameList::GetSelectedFrameIndex () const { - Mutex::Locker locker (m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); return m_selected_frame_idx; } - uint32_t StackFrameList::SetSelectedFrame (lldb_private::StackFrame *frame) { - Mutex::Locker locker (m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); const_iterator pos; const_iterator begin = m_frames.begin(); const_iterator end = m_frames.end(); @@ -714,7 +707,7 @@ StackFrameList::SetSelectedFrame (lldb_private::StackFrame *frame) bool StackFrameList::SetSelectedFrameByIndex (uint32_t idx) { - Mutex::Locker locker (m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); StackFrameSP frame_sp (GetFrameAtIndex (idx)); if (frame_sp) { @@ -746,7 +739,7 @@ StackFrameList::SetDefaultFileAndLineToSelectedFrame() void StackFrameList::Clear () { - Mutex::Locker locker (m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); m_frames.clear(); m_concrete_frames_fetched = 0; } @@ -754,7 +747,7 @@ StackFrameList::Clear () void StackFrameList::InvalidateFrames (uint32_t start_idx) { - Mutex::Locker locker (m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); if (m_show_inlined_frames) { Clear(); @@ -773,25 +766,28 @@ StackFrameList::InvalidateFrames (uint32_t start_idx) void StackFrameList::Merge (std::unique_ptr<StackFrameList>& curr_ap, lldb::StackFrameListSP& prev_sp) { - Mutex::Locker curr_locker (curr_ap.get() ? &curr_ap->m_mutex : NULL); - Mutex::Locker prev_locker (prev_sp.get() ? &prev_sp->m_mutex : NULL); + std::unique_lock<std::recursive_mutex> current_lock, previous_lock; + if (curr_ap) + current_lock = std::unique_lock<std::recursive_mutex>(curr_ap->m_mutex); + if (prev_sp) + previous_lock = std::unique_lock<std::recursive_mutex>(prev_sp->m_mutex); #if defined (DEBUG_STACK_FRAMES) StreamFile s(stdout, false); s.PutCString("\n\nStackFrameList::Merge():\nPrev:\n"); - if (prev_sp.get()) + if (prev_sp) prev_sp->Dump (&s); else s.PutCString ("NULL"); s.PutCString("\nCurr:\n"); - if (curr_ap.get()) + if (curr_ap) curr_ap->Dump (&s); else s.PutCString ("NULL"); s.EOL(); #endif - if (curr_ap.get() == NULL || curr_ap->GetNumFrames (false) == 0) + if (!curr_ap || curr_ap->GetNumFrames(false) == 0) { #if defined (DEBUG_STACK_FRAMES) s.PutCString("No current frames, leave previous frames alone...\n"); @@ -800,7 +796,7 @@ StackFrameList::Merge (std::unique_ptr<StackFrameList>& curr_ap, lldb::StackFram return; } - if (prev_sp.get() == NULL || prev_sp->GetNumFrames (false) == 0) + if (!prev_sp || prev_sp->GetNumFrames(false) == 0) { #if defined (DEBUG_STACK_FRAMES) s.PutCString("No previous frames, so use current frames...\n"); @@ -866,8 +862,6 @@ StackFrameList::Merge (std::unique_ptr<StackFrameList>& curr_ap, lldb::StackFram s.PutCString("\nMerged:\n"); prev_sp->Dump (&s); #endif - - } lldb::StackFrameSP @@ -913,7 +907,7 @@ StackFrameList::GetStatus (Stream& strm, last_frame = first_frame + num_frames; StackFrameSP selected_frame_sp = m_thread.GetSelectedFrame(); - const char *unselected_marker = NULL; + const char *unselected_marker = nullptr; std::string buffer; if (selected_frame_marker) { @@ -921,15 +915,15 @@ StackFrameList::GetStatus (Stream& strm, buffer.insert(buffer.begin(), len, ' '); unselected_marker = buffer.c_str(); } - const char *marker = NULL; + const char *marker = nullptr; for (frame_idx = first_frame; frame_idx < last_frame; ++frame_idx) { frame_sp = GetFrameAtIndex(frame_idx); - if (frame_sp.get() == NULL) + if (!frame_sp) break; - if (selected_frame_marker != NULL) + if (selected_frame_marker != nullptr) { if (frame_sp == selected_frame_sp) marker = selected_frame_marker; @@ -947,4 +941,3 @@ StackFrameList::GetStatus (Stream& strm, strm.IndentLess(); return num_frames_displayed; } - diff --git a/source/Target/StackID.cpp b/source/Target/StackID.cpp index ca337f914406..222b2d3f2aa8 100644 --- a/source/Target/StackID.cpp +++ b/source/Target/StackID.cpp @@ -7,12 +7,11 @@ // //===----------------------------------------------------------------------===// -#include "lldb/Target/StackID.h" - // C Includes // C++ Includes // Other libraries and framework includes // Project includes +#include "lldb/Target/StackID.h" #include "lldb/Core/Stream.h" #include "lldb/Symbol/Block.h" #include "lldb/Symbol/Symbol.h" @@ -20,7 +19,6 @@ using namespace lldb_private; - void StackID::Dump (Stream *s) { @@ -48,8 +46,8 @@ lldb_private::operator== (const StackID& lhs, const StackID& rhs) SymbolContextScope *lhs_scope = lhs.GetSymbolContextScope(); SymbolContextScope *rhs_scope = rhs.GetSymbolContextScope(); - // Only compare the PC values if both symbol context scopes are NULL - if (lhs_scope == NULL && rhs_scope == NULL) + // Only compare the PC values if both symbol context scopes are nullptr + if (lhs_scope == nullptr && rhs_scope == nullptr) return lhs.GetPC() == rhs.GetPC(); return lhs_scope == rhs_scope; @@ -64,7 +62,7 @@ lldb_private::operator!= (const StackID& lhs, const StackID& rhs) SymbolContextScope *lhs_scope = lhs.GetSymbolContextScope(); SymbolContextScope *rhs_scope = rhs.GetSymbolContextScope(); - if (lhs_scope == NULL && rhs_scope == NULL) + if (lhs_scope == nullptr && rhs_scope == nullptr) return lhs.GetPC() != rhs.GetPC(); return lhs_scope != rhs_scope; @@ -88,7 +86,7 @@ lldb_private::operator< (const StackID& lhs, const StackID& rhs) SymbolContextScope *lhs_scope = lhs.GetSymbolContextScope(); SymbolContextScope *rhs_scope = rhs.GetSymbolContextScope(); - if (lhs_scope != NULL && rhs_scope != NULL) + if (lhs_scope != nullptr && rhs_scope != nullptr) { // Same exact scope, lhs is not less than (younger than rhs) if (lhs_scope == rhs_scope) @@ -101,8 +99,8 @@ lldb_private::operator< (const StackID& lhs, const StackID& rhs) // Items with the same function can only be compared if (lhs_sc.function == rhs_sc.function && - lhs_sc.function != NULL && lhs_sc.block != NULL && - rhs_sc.function != NULL && rhs_sc.block != NULL) + lhs_sc.function != nullptr && lhs_sc.block != nullptr && + rhs_sc.function != nullptr && rhs_sc.block != nullptr) { return rhs_sc.block->Contains (lhs_sc.block); } diff --git a/source/Target/StopInfo.cpp b/source/Target/StopInfo.cpp index e88b6467f7c6..7c244363ffd2 100644 --- a/source/Target/StopInfo.cpp +++ b/source/Target/StopInfo.cpp @@ -228,7 +228,7 @@ public: break; } } - return all_internal == false; + return !all_internal; } } return true; @@ -254,7 +254,7 @@ public: for (size_t idx = 0; idx < num_owners; idx++) { const char *kind = bp_site_sp->GetOwnerAtIndex(idx)->GetBreakpoint().GetBreakpointKind(); - if (kind != NULL) + if (kind != nullptr) { m_description.assign (kind); return kind; @@ -371,6 +371,10 @@ protected: // running all the callbacks. m_should_stop = false; + + // We don't select threads as we go through them testing breakpoint conditions and running commands. + // So we need to set the thread for expression evaluation here: + ThreadList::ExpressionExecutionThreadPusher thread_pusher(thread_sp); ExecutionContext exe_ctx (thread_sp->GetStackFrameAtIndex(0)); Process *process = exe_ctx.GetProcessPtr(); @@ -467,7 +471,7 @@ protected: // Next run the condition for the breakpoint. If that says we should stop, then we'll run // the callback for the breakpoint. If the callback says we shouldn't stop that will win. - if (bp_loc_sp->GetConditionText() != NULL) + if (bp_loc_sp->GetConditionText() != nullptr) { Error condition_error; bool condition_says_stop = bp_loc_sp->ConditionSaysStop(exe_ctx, condition_error); @@ -544,7 +548,6 @@ protected: } // We've figured out what this stop wants to do, so mark it as valid so we don't compute it again. m_should_stop_is_valid = true; - } else { @@ -733,7 +736,7 @@ protected: new_plan_sp->SetOkayToDiscard (false); new_plan_sp->SetPrivate (true); process->GetThreadList().SetSelectedThreadByID (thread_sp->GetID()); - process->ResumeSynchronous(NULL); + process->ResumeSynchronous(nullptr); process->GetThreadList().SetSelectedThreadByID (thread_sp->GetID()); thread_sp->SetStopInfo(stored_stop_info_sp); } @@ -769,7 +772,7 @@ protected: if (wp_sp->GetHitCount() <= wp_sp->GetIgnoreCount()) m_should_stop = false; - if (m_should_stop && wp_sp->GetConditionText() != NULL) + if (m_should_stop && wp_sp->GetConditionText() != nullptr) { // We need to make sure the user sees any parse errors in their condition, so we'll hook the // constructor errors up to the debugger's Async I/O. @@ -779,12 +782,12 @@ protected: expr_options.SetIgnoreBreakpoints(true); ValueObjectSP result_value_sp; Error error; - result_code = UserExpression::Evaluate (exe_ctx, - expr_options, - wp_sp->GetConditionText(), - NULL, - result_value_sp, - error); + result_code = UserExpression::Evaluate(exe_ctx, + expr_options, + wp_sp->GetConditionText(), + nullptr, + result_value_sp, + error); if (result_code == eExpressionCompleted) { @@ -951,7 +954,7 @@ public: ThreadSP thread_sp (m_thread_wp.lock()); if (thread_sp) { - if (thread_sp->GetProcess()->GetUnixSignals()->GetShouldSuppress(m_value) == false) + if (!thread_sp->GetProcess()->GetUnixSignals()->GetShouldSuppress(m_value)) thread_sp->SetResumeSignal(m_value); } } diff --git a/source/Target/SystemRuntime.cpp b/source/Target/SystemRuntime.cpp index c3fb9c8091fd..522b535039ff 100644 --- a/source/Target/SystemRuntime.cpp +++ b/source/Target/SystemRuntime.cpp @@ -7,6 +7,10 @@ // //===----------------------------------------------------------------------===// +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes #include "lldb/lldb-private.h" #include "lldb/Target/SystemRuntime.h" #include "lldb/Target/Process.h" @@ -18,17 +22,16 @@ using namespace lldb_private; SystemRuntime* SystemRuntime::FindPlugin (Process *process) { - SystemRuntimeCreateInstance create_callback = NULL; - for (uint32_t idx = 0; (create_callback = PluginManager::GetSystemRuntimeCreateCallbackAtIndex(idx)) != NULL; ++idx) + SystemRuntimeCreateInstance create_callback = nullptr; + for (uint32_t idx = 0; (create_callback = PluginManager::GetSystemRuntimeCreateCallbackAtIndex(idx)) != nullptr; ++idx) { std::unique_ptr<SystemRuntime> instance_ap(create_callback(process)); - if (instance_ap.get()) + if (instance_ap) return instance_ap.release(); } - return NULL; + return nullptr; } - //---------------------------------------------------------------------- // SystemRuntime constructor //---------------------------------------------------------------------- @@ -38,12 +41,7 @@ SystemRuntime::SystemRuntime(Process *process) : { } -//---------------------------------------------------------------------- -// Destructor -//---------------------------------------------------------------------- -SystemRuntime::~SystemRuntime() -{ -} +SystemRuntime::~SystemRuntime() = default; void SystemRuntime::DidAttach () diff --git a/source/Target/Target.cpp b/source/Target/Target.cpp index 21e42916bae9..9ef56f01c659 100644 --- a/source/Target/Target.cpp +++ b/source/Target/Target.cpp @@ -9,6 +9,7 @@ // C Includes // C++ Includes +#include <mutex> // Other libraries and framework includes // Project includes #include "lldb/Target/Target.h" @@ -67,45 +68,47 @@ Target::GetStaticBroadcasterClass () return class_name; } -Target::Target(Debugger &debugger, const ArchSpec &target_arch, const lldb::PlatformSP &platform_sp, bool is_dummy_target) : - TargetProperties (this), - Broadcaster (&debugger, Target::GetStaticBroadcasterClass().AsCString()), - ExecutionContextScope (), - m_debugger (debugger), - m_platform_sp (platform_sp), - m_mutex (Mutex::eMutexTypeRecursive), - m_arch (target_arch), - m_images (this), - m_section_load_history (), - m_breakpoint_list (false), - m_internal_breakpoint_list (true), - m_watchpoint_list (), - m_process_sp (), - m_search_filter_sp (), - m_image_search_paths (ImageSearchPathsChanged, this), - m_ast_importer_sp (), - m_source_manager_ap(), - m_stop_hooks (), - m_stop_hook_next_id (0), - m_valid (true), - m_suppress_stop_hooks (false), - m_is_dummy_target(is_dummy_target) - -{ - SetEventName (eBroadcastBitBreakpointChanged, "breakpoint-changed"); - SetEventName (eBroadcastBitModulesLoaded, "modules-loaded"); - SetEventName (eBroadcastBitModulesUnloaded, "modules-unloaded"); - SetEventName (eBroadcastBitWatchpointChanged, "watchpoint-changed"); - SetEventName (eBroadcastBitSymbolsLoaded, "symbols-loaded"); +Target::Target(Debugger &debugger, const ArchSpec &target_arch, const lldb::PlatformSP &platform_sp, + bool is_dummy_target) + : TargetProperties(this), + Broadcaster(debugger.GetBroadcasterManager(), Target::GetStaticBroadcasterClass().AsCString()), + ExecutionContextScope(), + m_debugger(debugger), + m_platform_sp(platform_sp), + m_mutex(), + m_arch(target_arch), + m_images(this), + m_section_load_history(), + m_breakpoint_list(false), + m_internal_breakpoint_list(true), + m_watchpoint_list(), + m_process_sp(), + m_search_filter_sp(), + m_image_search_paths(ImageSearchPathsChanged, this), + m_ast_importer_sp(), + m_source_manager_ap(), + m_stop_hooks(), + m_stop_hook_next_id(0), + m_valid(true), + m_suppress_stop_hooks(false), + m_is_dummy_target(is_dummy_target) + +{ + SetEventName(eBroadcastBitBreakpointChanged, "breakpoint-changed"); + SetEventName(eBroadcastBitModulesLoaded, "modules-loaded"); + SetEventName(eBroadcastBitModulesUnloaded, "modules-unloaded"); + SetEventName(eBroadcastBitWatchpointChanged, "watchpoint-changed"); + SetEventName(eBroadcastBitSymbolsLoaded, "symbols-loaded"); CheckInWithManager(); - Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT)); + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT)); if (log) - log->Printf ("%p Target::Target()", static_cast<void*>(this)); + log->Printf("%p Target::Target()", static_cast<void *>(this)); if (m_arch.IsValid()) { - LogIfAnyCategoriesSet(LIBLLDB_LOG_TARGET, "Target::Target created with architecture %s (%s)", m_arch.GetArchitectureName(), m_arch.GetTriple().getTriple().c_str()); + LogIfAnyCategoriesSet(LIBLLDB_LOG_TARGET, "Target::Target created with architecture %s (%s)", + m_arch.GetArchitectureName(), m_arch.GetTriple().getTriple().c_str()); } } @@ -168,8 +171,8 @@ Target::CleanupProcess () m_breakpoint_list.ClearAllBreakpointSites(); m_internal_breakpoint_list.ClearAllBreakpointSites(); // Disable watchpoints just on the debugger side. - Mutex::Locker locker; - this->GetWatchpointList().GetListMutex(locker); + std::unique_lock<std::recursive_mutex> lock; + this->GetWatchpointList().GetListMutex(lock); DisableAllWatchpoints(false); ClearAllWatchpointHitCounts(); ClearAllWatchpointHistoricValues(); @@ -193,10 +196,10 @@ Target::DeleteCurrentProcess () } const lldb::ProcessSP & -Target::CreateProcess (Listener &listener, const char *plugin_name, const FileSpec *crash_file) +Target::CreateProcess (ListenerSP listener_sp, const char *plugin_name, const FileSpec *crash_file) { DeleteCurrentProcess (); - m_process_sp = Process::FindPlugin(shared_from_this(), plugin_name, listener, crash_file); + m_process_sp = Process::FindPlugin(shared_from_this(), plugin_name, listener_sp, crash_file); return m_process_sp; } @@ -221,7 +224,7 @@ Target::GetREPL (Error &err, lldb::LanguageType language, const char *repl_optio } else if (repl_languages.size() == 0) { - err.SetErrorStringWithFormat("LLDB isn't configured with support support for any REPLs."); + err.SetErrorStringWithFormat("LLDB isn't configured with REPL support for any languages."); return REPLSP(); } else @@ -272,7 +275,7 @@ Target::SetREPL (lldb::LanguageType language, lldb::REPLSP repl_sp) void Target::Destroy() { - Mutex::Locker locker (m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); m_valid = false; DeleteCurrentProcess (); m_platform_sp.reset(); @@ -325,6 +328,7 @@ Target::GetBreakpointByID (break_id_t break_id) BreakpointSP Target::CreateSourceRegexBreakpoint (const FileSpecList *containingModules, const FileSpecList *source_file_spec_list, + const std::unordered_set<std::string> &function_names, RegularExpression &source_regex, bool internal, bool hardware, @@ -333,7 +337,11 @@ Target::CreateSourceRegexBreakpoint (const FileSpecList *containingModules, SearchFilterSP filter_sp(GetSearchFilterForModuleAndCUList (containingModules, source_file_spec_list)); if (move_to_nearest_code == eLazyBoolCalculate) move_to_nearest_code = GetMoveToNearestCode() ? eLazyBoolYes : eLazyBoolNo; - BreakpointResolverSP resolver_sp(new BreakpointResolverFileRegex(nullptr, source_regex, !static_cast<bool>(move_to_nearest_code))); + BreakpointResolverSP resolver_sp(new BreakpointResolverFileRegex(nullptr, + source_regex, + function_names, + !static_cast<bool>(move_to_nearest_code))); + return CreateBreakpoint (filter_sp, resolver_sp, internal, hardware, true); } @@ -341,12 +349,20 @@ BreakpointSP Target::CreateBreakpoint (const FileSpecList *containingModules, const FileSpec &file, uint32_t line_no, + lldb::addr_t offset, LazyBool check_inlines, LazyBool skip_prologue, bool internal, bool hardware, LazyBool move_to_nearest_code) { + FileSpec remapped_file; + ConstString remapped_path; + if (GetSourcePathMap().ReverseRemapPath(ConstString(file.GetPath().c_str()), remapped_path)) + remapped_file.SetFile(remapped_path.AsCString(), true); + else + remapped_file = file; + if (check_inlines == eLazyBoolCalculate) { const InlineStrategy inline_strategy = GetInlineStrategy(); @@ -357,7 +373,7 @@ Target::CreateBreakpoint (const FileSpecList *containingModules, break; case eInlineBreakpointsHeaders: - if (file.IsSourceImplementationFile()) + if (remapped_file.IsSourceImplementationFile()) check_inlines = eLazyBoolNo; else check_inlines = eLazyBoolYes; @@ -373,7 +389,7 @@ Target::CreateBreakpoint (const FileSpecList *containingModules, { // Not checking for inlines, we are looking only for matching compile units FileSpecList compile_unit_list; - compile_unit_list.Append (file); + compile_unit_list.Append (remapped_file); filter_sp = GetSearchFilterForModuleAndCUList (containingModules, &compile_unit_list); } else @@ -385,12 +401,13 @@ Target::CreateBreakpoint (const FileSpecList *containingModules, if (move_to_nearest_code == eLazyBoolCalculate) move_to_nearest_code = GetMoveToNearestCode() ? eLazyBoolYes : eLazyBoolNo; - BreakpointResolverSP resolver_sp(new BreakpointResolverFileLine(nullptr, - file, - line_no, - check_inlines, - skip_prologue, - !static_cast<bool>(move_to_nearest_code))); + BreakpointResolverSP resolver_sp(new BreakpointResolverFileLine (nullptr, + remapped_file, + line_no, + offset, + check_inlines, + skip_prologue, + !static_cast<bool>(move_to_nearest_code))); return CreateBreakpoint (filter_sp, resolver_sp, internal, hardware, true); } @@ -439,8 +456,9 @@ BreakpointSP Target::CreateBreakpoint (const FileSpecList *containingModules, const FileSpecList *containingSourceFiles, const char *func_name, - uint32_t func_name_type_mask, + uint32_t func_name_type_mask, LanguageType language, + lldb::addr_t offset, LazyBool skip_prologue, bool internal, bool hardware) @@ -455,12 +473,13 @@ Target::CreateBreakpoint (const FileSpecList *containingModules, if (language == lldb::eLanguageTypeUnknown) language = GetLanguage(); - BreakpointResolverSP resolver_sp(new BreakpointResolverName(nullptr, - func_name, - func_name_type_mask, - language, - Breakpoint::Exact, - skip_prologue)); + BreakpointResolverSP resolver_sp (new BreakpointResolverName (nullptr, + func_name, + func_name_type_mask, + language, + Breakpoint::Exact, + offset, + skip_prologue)); bp_sp = CreateBreakpoint (filter_sp, resolver_sp, internal, hardware, true); } return bp_sp; @@ -472,6 +491,7 @@ Target::CreateBreakpoint (const FileSpecList *containingModules, const std::vector<std::string> &func_names, uint32_t func_name_type_mask, LanguageType language, + lldb::addr_t offset, LazyBool skip_prologue, bool internal, bool hardware) @@ -487,11 +507,13 @@ Target::CreateBreakpoint (const FileSpecList *containingModules, if (language == lldb::eLanguageTypeUnknown) language = GetLanguage(); - BreakpointResolverSP resolver_sp(new BreakpointResolverName(nullptr, - func_names, - func_name_type_mask, - language, - skip_prologue)); + + BreakpointResolverSP resolver_sp (new BreakpointResolverName (nullptr, + func_names, + func_name_type_mask, + language, + offset, + skip_prologue)); bp_sp = CreateBreakpoint (filter_sp, resolver_sp, internal, hardware, true); } return bp_sp; @@ -502,8 +524,9 @@ Target::CreateBreakpoint (const FileSpecList *containingModules, const FileSpecList *containingSourceFiles, const char *func_names[], size_t num_names, - uint32_t func_name_type_mask, + uint32_t func_name_type_mask, LanguageType language, + lldb::addr_t offset, LazyBool skip_prologue, bool internal, bool hardware) @@ -514,16 +537,23 @@ Target::CreateBreakpoint (const FileSpecList *containingModules, SearchFilterSP filter_sp(GetSearchFilterForModuleAndCUList (containingModules, containingSourceFiles)); if (skip_prologue == eLazyBoolCalculate) - skip_prologue = GetSkipPrologue() ? eLazyBoolYes : eLazyBoolNo; + { + if (offset == 0) + skip_prologue = GetSkipPrologue() ? eLazyBoolYes : eLazyBoolNo; + else + skip_prologue = eLazyBoolNo; + } if (language == lldb::eLanguageTypeUnknown) language = GetLanguage(); - BreakpointResolverSP resolver_sp(new BreakpointResolverName(nullptr, - func_names, - num_names, - func_name_type_mask, - language, - skip_prologue)); + BreakpointResolverSP resolver_sp (new BreakpointResolverName (nullptr, + func_names, + num_names, + func_name_type_mask, + language, + offset, + skip_prologue)); + resolver_sp->SetOffset(offset); bp_sp = CreateBreakpoint (filter_sp, resolver_sp, internal, hardware, true); } return bp_sp; @@ -602,10 +632,11 @@ Target::CreateFuncRegexBreakpoint (const FileSpecList *containingModules, bool skip = (skip_prologue == eLazyBoolCalculate) ? GetSkipPrologue() : static_cast<bool>(skip_prologue); - BreakpointResolverSP resolver_sp(new BreakpointResolverName(nullptr, - func_regex, - requested_language, - skip)); + BreakpointResolverSP resolver_sp(new BreakpointResolverName (nullptr, + func_regex, + requested_language, + 0, + skip)); return CreateBreakpoint (filter_sp, resolver_sp, internal, hardware, true); } @@ -678,14 +709,13 @@ CheckIfWatchpointsExhausted(Target *target, Error &error) { uint32_t num_supported_hardware_watchpoints; Error rc = target->GetProcessSP()->GetWatchpointSupportInfo(num_supported_hardware_watchpoints); - if (rc.Success()) + if (num_supported_hardware_watchpoints == 0) { - uint32_t num_current_watchpoints = target->GetWatchpointList().GetSize(); - if (num_current_watchpoints >= num_supported_hardware_watchpoints) - error.SetErrorStringWithFormat("number of supported hardware watchpoints (%u) has been reached", - num_supported_hardware_watchpoints); + error.SetErrorStringWithFormat ("Target supports (%u) hardware watchpoint slots.\n", + num_supported_hardware_watchpoints); + return false; } - return false; + return true; } // See also Watchpoint::SetWatchpointType(uint32_t type) and @@ -719,13 +749,16 @@ Target::CreateWatchpoint(lldb::addr_t addr, size_t size, const CompilerType *typ error.SetErrorStringWithFormat ("invalid watchpoint type: %d", kind); } + if (!CheckIfWatchpointsExhausted (this, error)) + return wp_sp; + // Currently we only support one watchpoint per address, with total number // of watchpoints limited by the hardware which the inferior is running on. // Grab the list mutex while doing operations. const bool notify = false; // Don't notify about all the state changes we do on creating the watchpoint. - Mutex::Locker locker; - this->GetWatchpointList().GetListMutex(locker); + std::unique_lock<std::recursive_mutex> lock; + this->GetWatchpointList().GetListMutex(lock); WatchpointSP matched_sp = m_watchpoint_list.FindByAddress(addr); if (matched_sp) { @@ -767,11 +800,9 @@ Target::CreateWatchpoint(lldb::addr_t addr, size_t size, const CompilerType *typ // Remove the said watchpoint from the list maintained by the target instance. m_watchpoint_list.Remove (wp_sp->GetID(), true); // See if we could provide more helpful error message. - if (!CheckIfWatchpointsExhausted(this, error)) - { - if (!OptionGroupWatchpoint::IsWatchSizeSupported(size)) - error.SetErrorStringWithFormat("watch size of %" PRIu64 " is not supported", (uint64_t)size); - } + if (!OptionGroupWatchpoint::IsWatchSizeSupported(size)) + error.SetErrorStringWithFormat("watch size of %" PRIu64 " is not supported", (uint64_t)size); + wp_sp.reset(); } else @@ -1277,7 +1308,7 @@ Target::SetArchitecture (const ArchSpec &arch_spec) os_ver_changed, env_changed); - if (!arch_changed && !vendor_changed && !os_changed) + if (!arch_changed && !vendor_changed && !os_changed && !env_changed) replace_local_arch = false; } } @@ -1941,7 +1972,7 @@ Target::CalculateTarget () ProcessSP Target::CalculateProcess () { - return ProcessSP(); + return m_process_sp; } ThreadSP @@ -2210,7 +2241,8 @@ ExpressionResults Target::EvaluateExpression(const char *expr_cstr, ExecutionContextScope *exe_scope, lldb::ValueObjectSP &result_valobj_sp, - const EvaluateExpressionOptions& options) + const EvaluateExpressionOptions& options, + std::string *fixed_expression) { result_valobj_sp.reset(); @@ -2260,7 +2292,9 @@ Target::EvaluateExpression(const char *expr_cstr, expr_cstr, prefix, result_valobj_sp, - error); + error, + 0, // Line Number + fixed_expression); } m_suppress_stop_hooks = old_suppress_value; @@ -2579,11 +2613,11 @@ Target::GetSourceManager () ClangModulesDeclVendor * Target::GetClangModulesDeclVendor () { - static Mutex s_clang_modules_decl_vendor_mutex; // If this is contended we can make it per-target - + static std::mutex s_clang_modules_decl_vendor_mutex; // If this is contended we can make it per-target + { - Mutex::Locker clang_modules_decl_vendor_locker(s_clang_modules_decl_vendor_mutex); - + std::lock_guard<std::mutex> guard(s_clang_modules_decl_vendor_mutex); + if (!m_clang_modules_decl_vendor_ap) { m_clang_modules_decl_vendor_ap.reset(ClangModulesDeclVendor::Create(*this)); @@ -2777,12 +2811,14 @@ Target::RunStopHooks () const TargetPropertiesSP & Target::GetGlobalProperties() { - static TargetPropertiesSP g_settings_sp; - if (!g_settings_sp) - { - g_settings_sp.reset(new TargetProperties(nullptr)); - } - return g_settings_sp; + // NOTE: intentional leak so we don't crash if global destructor chain gets + // called as other threads still use the result of this function + static TargetPropertiesSP *g_settings_sp_ptr = nullptr; + static std::once_flag g_once_flag; + std::call_once(g_once_flag, []() { + g_settings_sp_ptr = new TargetPropertiesSP(new TargetProperties(nullptr)); + }); + return *g_settings_sp_ptr; } Error @@ -2802,10 +2838,10 @@ Target::Install (ProcessLaunchInfo *launch_info) const size_t num_images = modules.GetSize(); for (size_t idx = 0; idx < num_images; ++idx) { - const bool is_main_executable = idx == 0; ModuleSP module_sp(modules.GetModuleAtIndex(idx)); if (module_sp) { + const bool is_main_executable = module_sp == GetExecutableModule(); FileSpec local_file (module_sp->GetFileSpec()); if (local_file) { @@ -3062,12 +3098,12 @@ Target::Launch (ProcessLaunchInfo &launch_info, Stream *stream) ListenerSP hijack_listener_sp (launch_info.GetHijackListener()); if (!hijack_listener_sp) { - hijack_listener_sp.reset(new Listener("lldb.Target.Launch.hijack")); + hijack_listener_sp = Listener::MakeListener("lldb.Target.Launch.hijack"); launch_info.SetHijackListener(hijack_listener_sp); - m_process_sp->HijackProcessEvents(hijack_listener_sp.get()); + m_process_sp->HijackProcessEvents(hijack_listener_sp); } - StateType state = m_process_sp->WaitForProcessToStop(nullptr, nullptr, false, hijack_listener_sp.get(), nullptr); + StateType state = m_process_sp->WaitForProcessToStop(nullptr, nullptr, false, hijack_listener_sp, nullptr); if (state == eStateStopped) { @@ -3078,7 +3114,7 @@ Target::Launch (ProcessLaunchInfo &launch_info, Stream *stream) error = m_process_sp->PrivateResume(); if (error.Success()) { - state = m_process_sp->WaitForProcessToStop(nullptr, nullptr, true, hijack_listener_sp.get(), stream); + state = m_process_sp->WaitForProcessToStop(nullptr, nullptr, true, hijack_listener_sp, stream); const bool must_be_alive = false; // eStateExited is ok, so this must be false if (!StateIsStoppedState(state, must_be_alive)) { @@ -3172,7 +3208,7 @@ Target::Attach (ProcessAttachInfo &attach_info, Stream *stream) const bool async = attach_info.GetAsync(); if (!async) { - hijack_listener_sp.reset (new Listener ("lldb.Target.Attach.attach.hijack")); + hijack_listener_sp = Listener::MakeListener("lldb.Target.Attach.attach.hijack"); attach_info.SetHijackListener (hijack_listener_sp); } @@ -3195,7 +3231,7 @@ Target::Attach (ProcessAttachInfo &attach_info, Stream *stream) } } if (hijack_listener_sp) - process_sp->HijackProcessEvents (hijack_listener_sp.get ()); + process_sp->HijackProcessEvents (hijack_listener_sp); error = process_sp->Attach (attach_info); } @@ -3207,7 +3243,7 @@ Target::Attach (ProcessAttachInfo &attach_info, Stream *stream) } else { - state = process_sp->WaitForProcessToStop (nullptr, nullptr, false, attach_info.GetHijackListener ().get (), stream); + state = process_sp->WaitForProcessToStop (nullptr, nullptr, false, attach_info.GetHijackListener(), stream); process_sp->RestoreProcessEvents (); if (state != eStateStopped) @@ -3363,6 +3399,15 @@ g_load_script_from_sym_file_values[] = }; static OptionEnumValueElement +g_load_current_working_dir_lldbinit_values[] = +{ + { eLoadCWDlldbinitTrue, "true", "Load .lldbinit files from current directory"}, + { eLoadCWDlldbinitFalse, "false", "Do not load .lldbinit files from current directory"}, + { eLoadCWDlldbinitWarn, "warn", "Warn about loading .lldbinit files from current directory"}, + { 0, nullptr, nullptr } +}; + +static OptionEnumValueElement g_memory_module_load_level_values[] = { { eMemoryModuleLoadLevelMinimal, "minimal" , "Load minimal information when loading modules from memory. Currently this setting loads sections only."}, @@ -3389,7 +3434,9 @@ g_properties[] = { "exec-search-paths" , OptionValue::eTypeFileSpecList, false, 0 , nullptr, nullptr, "Executable search paths to use when locating executable files whose paths don't match the local file system." }, { "debug-file-search-paths" , OptionValue::eTypeFileSpecList, false, 0 , nullptr, nullptr, "List of directories to be searched when locating debug symbol files." }, { "clang-module-search-paths" , OptionValue::eTypeFileSpecList, false, 0 , nullptr, nullptr, "List of directories to be searched when locating modules for Clang." }, - { "auto-import-clang-modules" , OptionValue::eTypeBoolean , false, false , nullptr, nullptr, "Automatically load Clang modules referred to by the program." }, + { "auto-import-clang-modules" , OptionValue::eTypeBoolean , false, true , nullptr, nullptr, "Automatically load Clang modules referred to by the program." }, + { "auto-apply-fixits" , OptionValue::eTypeBoolean , false, true , nullptr, nullptr, "Automatically apply fix-it hints to expressions." }, + { "notify-about-fixits" , OptionValue::eTypeBoolean , false, true , nullptr, nullptr, "Print the fixed expression text." }, { "max-children-count" , OptionValue::eTypeSInt64 , false, 256 , nullptr, nullptr, "Maximum number of children to expand in any level of depth." }, { "max-string-summary-length" , OptionValue::eTypeSInt64 , false, 1024 , nullptr, nullptr, "Maximum number of characters to show when using %s in summary strings." }, { "max-memory-read-size" , OptionValue::eTypeSInt64 , false, 1024 , nullptr, nullptr, "Maximum number of bytes that 'memory read' will fetch before --force must be specified." }, @@ -3418,6 +3465,7 @@ g_properties[] = { "hex-immediate-style" , OptionValue::eTypeEnum , false, Disassembler::eHexStyleC, nullptr, g_hex_immediate_style_values, "Which style to use for printing hexadecimal disassembly values." }, { "use-fast-stepping" , OptionValue::eTypeBoolean , false, true, nullptr, nullptr, "Use a fast stepping algorithm based on running from branch to branch rather than instruction single-stepping." }, { "load-script-from-symbol-file" , OptionValue::eTypeEnum , false, eLoadScriptFromSymFileWarn, nullptr, g_load_script_from_sym_file_values, "Allow LLDB to load scripting resources embedded in symbol files when available." }, + { "load-cwd-lldbinit" , OptionValue::eTypeEnum , false, eLoadCWDlldbinitWarn, nullptr, g_load_current_working_dir_lldbinit_values, "Allow LLDB to .lldbinit files from the current directory automatically." }, { "memory-module-load-level" , OptionValue::eTypeEnum , false, eMemoryModuleLoadLevelComplete, nullptr, g_memory_module_load_level_values, "Loading modules from memory can be slow as reading the symbol tables and other data can take a long time depending on your connection to the debug target. " "This setting helps users control how much information gets loaded when loading modules from memory." @@ -3445,6 +3493,8 @@ enum ePropertyDebugFileSearchPaths, ePropertyClangModuleSearchPaths, ePropertyAutoImportClangModules, + ePropertyAutoApplyFixIts, + ePropertyNotifyAboutFixIts, ePropertyMaxChildrenCount, ePropertyMaxSummaryLength, ePropertyMaxMemReadSize, @@ -3465,11 +3515,13 @@ enum ePropertyHexImmediateStyle, ePropertyUseFastStepping, ePropertyLoadScriptFromSymbolFile, + ePropertyLoadCWDlldbinitFile, ePropertyMemoryModuleLoadLevel, ePropertyDisplayExpressionsInCrashlogs, ePropertyTrapHandlerNames, ePropertyDisplayRuntimeSupportValues, - ePropertyNonStopModeEnabled + ePropertyNonStopModeEnabled, + ePropertyExperimental }; class TargetOptionValueProperties : public OptionValueProperties @@ -3580,6 +3632,38 @@ protected: //---------------------------------------------------------------------- // TargetProperties //---------------------------------------------------------------------- +static PropertyDefinition +g_experimental_properties[] +{ +{ "inject-local-vars", OptionValue::eTypeBoolean , true, true, nullptr, nullptr, "If true, inject local variables explicitly into the expression text. " + "This will fix symbol resolution when there are name collisions between ivars and local variables. " + "But it can make expressions run much more slowly." }, +{ nullptr, OptionValue::eTypeInvalid , true, 0 , nullptr, nullptr, nullptr } +}; + +enum +{ + ePropertyInjectLocalVars = 0 +}; + +class TargetExperimentalOptionValueProperties : public OptionValueProperties +{ +public: + TargetExperimentalOptionValueProperties () : + OptionValueProperties (ConstString(Properties::GetExperimentalSettingsName())) + { + } +}; + +TargetExperimentalProperties::TargetExperimentalProperties() : + Properties(OptionValuePropertiesSP(new TargetExperimentalOptionValueProperties())) +{ + m_collection_sp->Initialize(g_experimental_properties); +} + +//---------------------------------------------------------------------- +// TargetProperties +//---------------------------------------------------------------------- TargetProperties::TargetProperties (Target *target) : Properties (), m_launch_info () @@ -3598,7 +3682,13 @@ TargetProperties::TargetProperties (Target *target) : m_collection_sp->SetValueChangedCallback(ePropertyDetachOnError, TargetProperties::DetachOnErrorValueChangedCallback, this); m_collection_sp->SetValueChangedCallback(ePropertyDisableASLR, TargetProperties::DisableASLRValueChangedCallback, this); m_collection_sp->SetValueChangedCallback(ePropertyDisableSTDIO, TargetProperties::DisableSTDIOValueChangedCallback, this); - + + m_experimental_properties_up.reset(new TargetExperimentalProperties()); + m_collection_sp->AppendProperty (ConstString(Properties::GetExperimentalSettingsName()), + ConstString("Experimental settings - setting these won't produce errors if the setting is not present."), + true, + m_experimental_properties_up->GetValueProperties()); + // Update m_launch_info once it was created Arg0ValueChangedCallback(this, nullptr); RunArgsValueChangedCallback(this, nullptr); @@ -3614,8 +3704,13 @@ TargetProperties::TargetProperties (Target *target) : { m_collection_sp.reset (new TargetOptionValueProperties(ConstString("target"))); m_collection_sp->Initialize(g_properties); + m_experimental_properties_up.reset(new TargetExperimentalProperties()); + m_collection_sp->AppendProperty (ConstString(Properties::GetExperimentalSettingsName()), + ConstString("Experimental settings - setting these won't produce errors if the setting is not present."), + true, + m_experimental_properties_up->GetValueProperties()); m_collection_sp->AppendProperty(ConstString("process"), - ConstString("Settings specify to processes."), + ConstString("Settings specific to processes."), true, Process::GetGlobalProperties()->GetValueProperties()); } @@ -3623,6 +3718,26 @@ TargetProperties::TargetProperties (Target *target) : TargetProperties::~TargetProperties() = default; +bool +TargetProperties::GetInjectLocalVariables(ExecutionContext *exe_ctx) const +{ + const Property *exp_property = m_collection_sp->GetPropertyAtIndex(exe_ctx, false, ePropertyExperimental); + OptionValueProperties *exp_values = exp_property->GetValue()->GetAsProperties(); + if (exp_values) + return exp_values->GetPropertyAtIndexAsBoolean(exe_ctx, ePropertyInjectLocalVars, true); + else + return true; +} + +void +TargetProperties::SetInjectLocalVariables(ExecutionContext *exe_ctx, bool b) +{ + const Property *exp_property = m_collection_sp->GetPropertyAtIndex(exe_ctx, true, ePropertyExperimental); + OptionValueProperties *exp_values = exp_property->GetValue()->GetAsProperties(); + if (exp_values) + exp_values->SetPropertyAtIndexAsBoolean(exe_ctx, ePropertyInjectLocalVars, true); +} + ArchSpec TargetProperties::GetDefaultArchitecture () const { @@ -3817,6 +3932,20 @@ TargetProperties::GetEnableAutoImportClangModules() const } bool +TargetProperties::GetEnableAutoApplyFixIts() const +{ + const uint32_t idx = ePropertyAutoApplyFixIts; + return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, g_properties[idx].default_uint_value != 0); +} + +bool +TargetProperties::GetEnableNotifyAboutFixIts() const +{ + const uint32_t idx = ePropertyNotifyAboutFixIts; + return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, g_properties[idx].default_uint_value != 0); +} + +bool TargetProperties::GetEnableSyntheticValue () const { const uint32_t idx = ePropertyEnableSynthetic; @@ -3945,6 +4074,13 @@ TargetProperties::GetLoadScriptFromSymbolFile () const return (LoadScriptFromSymFile)m_collection_sp->GetPropertyAtIndexAsEnumeration(nullptr, idx, g_properties[idx].default_uint_value); } +LoadCWDlldbinitFile +TargetProperties::GetLoadCWDlldbinitFile () const +{ + const uint32_t idx = ePropertyLoadCWDlldbinitFile; + return (LoadCWDlldbinitFile) m_collection_sp->GetPropertyAtIndexAsEnumeration(nullptr, idx, g_properties[idx].default_uint_value); +} + Disassembler::HexImmediateStyle TargetProperties::GetHexImmediateStyle () const { @@ -4147,6 +4283,12 @@ Target::TargetEventData::GetFlavorString () void Target::TargetEventData::Dump (Stream *s) const { + for (size_t i = 0; i < m_module_list.GetSize(); ++i) + { + if (i != 0) + *s << ", "; + m_module_list.GetModuleAtIndex(i)->GetDescription(s, lldb::eDescriptionLevelBrief); + } } const Target::TargetEventData * diff --git a/source/Target/TargetList.cpp b/source/Target/TargetList.cpp index ffec758ac215..349544676919 100644 --- a/source/Target/TargetList.cpp +++ b/source/Target/TargetList.cpp @@ -42,11 +42,11 @@ TargetList::GetStaticBroadcasterClass () //---------------------------------------------------------------------- // TargetList constructor //---------------------------------------------------------------------- -TargetList::TargetList(Debugger &debugger) : - Broadcaster(&debugger, TargetList::GetStaticBroadcasterClass().AsCString()), - m_target_list(), - m_target_list_mutex (Mutex::eMutexTypeRecursive), - m_selected_target_idx (0) +TargetList::TargetList(Debugger &debugger) + : Broadcaster(debugger.GetBroadcasterManager(), TargetList::GetStaticBroadcasterClass().AsCString()), + m_target_list(), + m_target_list_mutex(), + m_selected_target_idx(0) { CheckInWithManager(); } @@ -56,7 +56,7 @@ TargetList::TargetList(Debugger &debugger) : //---------------------------------------------------------------------- TargetList::~TargetList() { - Mutex::Locker locker(m_target_list_mutex); + std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); m_target_list.clear(); } @@ -515,7 +515,7 @@ TargetList::CreateTargetInternal (Debugger &debugger, // Don't put the dummy target in the target list, it's held separately. if (!is_dummy_target) { - Mutex::Locker locker(m_target_list_mutex); + std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); m_selected_target_idx = m_target_list.size(); m_target_list.push_back(target_sp); // Now prime this from the dummy target: @@ -533,7 +533,7 @@ TargetList::CreateTargetInternal (Debugger &debugger, bool TargetList::DeleteTarget (TargetSP &target_sp) { - Mutex::Locker locker(m_target_list_mutex); + std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); collection::iterator pos, end = m_target_list.end(); for (pos = m_target_list.begin(); pos != end; ++pos) @@ -551,7 +551,7 @@ TargetSP TargetList::FindTargetWithExecutableAndArchitecture(const FileSpec &exe_file_spec, const ArchSpec *exe_arch_ptr) const { - Mutex::Locker locker (m_target_list_mutex); + std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); TargetSP target_sp; bool full_match = (bool)exe_file_spec.GetDirectory(); @@ -580,7 +580,7 @@ TargetList::FindTargetWithExecutableAndArchitecture(const FileSpec &exe_file_spe TargetSP TargetList::FindTargetWithProcessID (lldb::pid_t pid) const { - Mutex::Locker locker(m_target_list_mutex); + std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); TargetSP target_sp; collection::const_iterator pos, end = m_target_list.end(); for (pos = m_target_list.begin(); pos != end; ++pos) @@ -601,7 +601,7 @@ TargetList::FindTargetWithProcess (Process *process) const TargetSP target_sp; if (process) { - Mutex::Locker locker(m_target_list_mutex); + std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); collection::const_iterator pos, end = m_target_list.end(); for (pos = m_target_list.begin(); pos != end; ++pos) { @@ -621,7 +621,7 @@ TargetList::GetTargetSP (Target *target) const TargetSP target_sp; if (target) { - Mutex::Locker locker(m_target_list_mutex); + std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); collection::const_iterator pos, end = m_target_list.end(); for (pos = m_target_list.begin(); pos != end; ++pos) { @@ -671,7 +671,7 @@ TargetList::SignalIfRunning (lldb::pid_t pid, int signo) if (pid == LLDB_INVALID_PROCESS_ID) { // Signal all processes with signal - Mutex::Locker locker(m_target_list_mutex); + std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); collection::iterator pos, end = m_target_list.end(); for (pos = m_target_list.begin(); pos != end; ++pos) { @@ -709,7 +709,7 @@ TargetList::SignalIfRunning (lldb::pid_t pid, int signo) int TargetList::GetNumTargets () const { - Mutex::Locker locker (m_target_list_mutex); + std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); return m_target_list.size(); } @@ -717,7 +717,7 @@ lldb::TargetSP TargetList::GetTargetAtIndex (uint32_t idx) const { TargetSP target_sp; - Mutex::Locker locker (m_target_list_mutex); + std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); if (idx < m_target_list.size()) target_sp = m_target_list[idx]; return target_sp; @@ -726,7 +726,7 @@ TargetList::GetTargetAtIndex (uint32_t idx) const uint32_t TargetList::GetIndexOfTarget (lldb::TargetSP target_sp) const { - Mutex::Locker locker (m_target_list_mutex); + std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); size_t num_targets = m_target_list.size(); for (size_t idx = 0; idx < num_targets; idx++) { @@ -739,7 +739,7 @@ TargetList::GetIndexOfTarget (lldb::TargetSP target_sp) const uint32_t TargetList::SetSelectedTarget (Target* target) { - Mutex::Locker locker (m_target_list_mutex); + std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); collection::const_iterator pos, begin = m_target_list.begin(), end = m_target_list.end(); @@ -758,7 +758,7 @@ TargetList::SetSelectedTarget (Target* target) lldb::TargetSP TargetList::GetSelectedTarget () { - Mutex::Locker locker (m_target_list_mutex); + std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); if (m_selected_target_idx >= m_target_list.size()) m_selected_target_idx = 0; return GetTargetAtIndex (m_selected_target_idx); diff --git a/source/Target/Thread.cpp b/source/Target/Thread.cpp index 551e48000936..40c137c4d521 100644 --- a/source/Target/Thread.cpp +++ b/source/Target/Thread.cpp @@ -58,10 +58,14 @@ using namespace lldb_private; const ThreadPropertiesSP & Thread::GetGlobalProperties() { - static ThreadPropertiesSP g_settings_sp; - if (!g_settings_sp) - g_settings_sp.reset (new ThreadProperties (true)); - return g_settings_sp; + // NOTE: intentional leak so we don't crash if global destructor chain gets + // called as other threads still use the result of this function + static ThreadPropertiesSP *g_settings_sp_ptr = nullptr; + static std::once_flag g_once_flag; + std::call_once(g_once_flag, []() { + g_settings_sp_ptr = new ThreadPropertiesSP(new ThreadProperties (true)); + }); + return *g_settings_sp_ptr; } static PropertyDefinition @@ -266,36 +270,36 @@ Thread::GetStaticBroadcasterClass () return class_name; } -Thread::Thread (Process &process, lldb::tid_t tid, bool use_invalid_index_id) : - ThreadProperties (false), - UserID (tid), - Broadcaster(&process.GetTarget().GetDebugger(), Thread::GetStaticBroadcasterClass().AsCString()), - m_process_wp (process.shared_from_this()), - m_stop_info_sp (), - m_stop_info_stop_id (0), - m_stop_info_override_stop_id (0), - m_index_id (use_invalid_index_id ? LLDB_INVALID_INDEX32 : process.GetNextThreadIndexID(tid)), - m_reg_context_sp (), - m_state (eStateUnloaded), - m_state_mutex (Mutex::eMutexTypeRecursive), - m_plan_stack (), - m_completed_plan_stack(), - m_frame_mutex (Mutex::eMutexTypeRecursive), - m_curr_frames_sp (), - m_prev_frames_sp (), - m_resume_signal (LLDB_INVALID_SIGNAL_NUMBER), - m_resume_state (eStateRunning), - m_temporary_resume_state (eStateRunning), - m_unwinder_ap (), - m_destroy_called (false), - m_override_should_notify (eLazyBoolCalculate), - m_extended_info_fetched (false), - m_extended_info () -{ - Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT)); +Thread::Thread(Process &process, lldb::tid_t tid, bool use_invalid_index_id) + : ThreadProperties(false), + UserID(tid), + Broadcaster(process.GetTarget().GetDebugger().GetBroadcasterManager(), + Thread::GetStaticBroadcasterClass().AsCString()), + m_process_wp(process.shared_from_this()), + m_stop_info_sp(), + m_stop_info_stop_id(0), + m_stop_info_override_stop_id(0), + m_index_id(use_invalid_index_id ? LLDB_INVALID_INDEX32 : process.GetNextThreadIndexID(tid)), + m_reg_context_sp(), + m_state(eStateUnloaded), + m_state_mutex(), + m_plan_stack(), + m_completed_plan_stack(), + m_frame_mutex(), + m_curr_frames_sp(), + m_prev_frames_sp(), + m_resume_signal(LLDB_INVALID_SIGNAL_NUMBER), + m_resume_state(eStateRunning), + m_temporary_resume_state(eStateRunning), + m_unwinder_ap(), + m_destroy_called(false), + m_override_should_notify(eLazyBoolCalculate), + m_extended_info_fetched(false), + m_extended_info() +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT)); if (log) - log->Printf ("%p Thread::Thread(tid = 0x%4.4" PRIx64 ")", - static_cast<void*>(this), GetID()); + log->Printf("%p Thread::Thread(tid = 0x%4.4" PRIx64 ")", static_cast<void *>(this), GetID()); CheckInWithManager(); QueueFundamentalPlan(true); @@ -340,7 +344,7 @@ Thread::DestroyThread () m_stop_info_sp.reset(); m_reg_context_sp.reset(); m_unwinder_ap.reset(); - Mutex::Locker locker(m_frame_mutex); + std::lock_guard<std::recursive_mutex> guard(m_frame_mutex); m_curr_frames_sp.reset(); m_prev_frames_sp.reset(); } @@ -640,14 +644,14 @@ StateType Thread::GetState() const { // If any other threads access this we will need a mutex for it - Mutex::Locker locker(m_state_mutex); + std::lock_guard<std::recursive_mutex> guard(m_state_mutex); return m_state; } void Thread::SetState(StateType state) { - Mutex::Locker locker(m_state_mutex); + std::lock_guard<std::recursive_mutex> guard(m_state_mutex); m_state = state; } @@ -701,7 +705,6 @@ Thread::SetupForResume () ThreadPlanSP step_bp_plan_sp (new ThreadPlanStepOverBreakpoint (*this)); if (step_bp_plan_sp) { - ; step_bp_plan_sp->SetPrivate (true); if (GetCurrentPlan()->RunState() != eStateStepping) @@ -1819,7 +1822,7 @@ StackFrameListSP Thread::GetStackFrameList () { StackFrameListSP frame_list_sp; - Mutex::Locker locker(m_frame_mutex); + std::lock_guard<std::recursive_mutex> guard(m_frame_mutex); if (m_curr_frames_sp) { frame_list_sp = m_curr_frames_sp; @@ -1835,7 +1838,7 @@ Thread::GetStackFrameList () void Thread::ClearStackFrames () { - Mutex::Locker locker(m_frame_mutex); + std::lock_guard<std::recursive_mutex> guard(m_frame_mutex); Unwind *unwinder = GetUnwinder (); if (unwinder) @@ -2087,13 +2090,13 @@ Thread::GetThreadPointer () } addr_t -Thread::GetThreadLocalData (const ModuleSP module) +Thread::GetThreadLocalData(const ModuleSP module, lldb::addr_t tls_file_addr) { // The default implementation is to ask the dynamic loader for it. // This can be overridden for specific platforms. DynamicLoader *loader = GetProcess()->GetDynamicLoader(); if (loader) - return loader->GetThreadLocalData (module, shared_from_this()); + return loader->GetThreadLocalData(module, shared_from_this(), tls_file_addr); else return LLDB_INVALID_ADDRESS; } @@ -2336,6 +2339,7 @@ Thread::GetUnwinder () case llvm::Triple::mips64el: case llvm::Triple::ppc: case llvm::Triple::ppc64: + case llvm::Triple::systemz: case llvm::Triple::hexagon: m_unwinder_ap.reset (new UnwindLLDB (*this)); break; diff --git a/source/Target/ThreadCollection.cpp b/source/Target/ThreadCollection.cpp index dc1e38e02420..d8d622e9387a 100644 --- a/source/Target/ThreadCollection.cpp +++ b/source/Target/ThreadCollection.cpp @@ -9,8 +9,10 @@ #include <stdlib.h> #include <algorithm> +#include <mutex> #include "lldb/Target/ThreadCollection.h" +#include "lldb/Target/Thread.h" using namespace lldb; using namespace lldb_private; @@ -30,14 +32,32 @@ ThreadCollection::ThreadCollection(collection threads) : void ThreadCollection::AddThread (const ThreadSP &thread_sp) { - Mutex::Locker locker(GetMutex()); + std::lock_guard<std::recursive_mutex> guard(GetMutex()); m_threads.push_back (thread_sp); } void +ThreadCollection::AddThreadSortedByIndexID (const ThreadSP &thread_sp) +{ + std::lock_guard<std::recursive_mutex> guard(GetMutex()); + // Make sure we always keep the threads sorted by thread index ID + const uint32_t thread_index_id = thread_sp->GetIndexID(); + if (m_threads.empty() || m_threads.back()->GetIndexID() < thread_index_id) + m_threads.push_back (thread_sp); + else + { + m_threads.insert(std::upper_bound(m_threads.begin(), m_threads.end(), thread_sp, + [] (const ThreadSP &lhs, const ThreadSP &rhs) -> bool + { + return lhs->GetIndexID() < rhs->GetIndexID(); + }), thread_sp); + } +} + +void ThreadCollection::InsertThread (const lldb::ThreadSP &thread_sp, uint32_t idx) { - Mutex::Locker locker(GetMutex()); + std::lock_guard<std::recursive_mutex> guard(GetMutex()); if (idx < m_threads.size()) m_threads.insert(m_threads.begin() + idx, thread_sp); else @@ -47,14 +67,14 @@ ThreadCollection::InsertThread (const lldb::ThreadSP &thread_sp, uint32_t idx) uint32_t ThreadCollection::GetSize () { - Mutex::Locker locker(GetMutex()); + std::lock_guard<std::recursive_mutex> guard(GetMutex()); return m_threads.size(); } ThreadSP ThreadCollection::GetThreadAtIndex (uint32_t idx) { - Mutex::Locker locker(GetMutex()); + std::lock_guard<std::recursive_mutex> guard(GetMutex()); ThreadSP thread_sp; if (idx < m_threads.size()) thread_sp = m_threads[idx]; diff --git a/source/Target/ThreadList.cpp b/source/Target/ThreadList.cpp index a34cb0fa143a..23e9f7807321 100644 --- a/source/Target/ThreadList.cpp +++ b/source/Target/ThreadList.cpp @@ -53,7 +53,8 @@ ThreadList::operator = (const ThreadList& rhs) { // Lock both mutexes to make sure neither side changes anyone on us // while the assignment occurs - Mutex::Locker locker(GetMutex()); + std::lock_guard<std::recursive_mutex> guard(GetMutex()); + m_process = rhs.m_process; m_stop_id = rhs.m_stop_id; m_threads = rhs.m_threads; @@ -71,6 +72,30 @@ ThreadList::~ThreadList() Clear(); } +lldb::ThreadSP +ThreadList::GetExpressionExecutionThread() +{ + if (m_expression_tid_stack.empty()) + return GetSelectedThread(); + ThreadSP expr_thread_sp = FindThreadByID(m_expression_tid_stack.back()); + if (expr_thread_sp) + return expr_thread_sp; + else + return GetSelectedThread(); +} + +void +ThreadList::PushExpressionExecutionThread(lldb::tid_t tid) +{ + m_expression_tid_stack.push_back(tid); +} + +void +ThreadList::PopExpressionExecutionThread(lldb::tid_t tid) +{ + assert(m_expression_tid_stack.back() == tid); + m_expression_tid_stack.pop_back(); +} uint32_t ThreadList::GetStopID () const @@ -87,7 +112,8 @@ ThreadList::SetStopID (uint32_t stop_id) uint32_t ThreadList::GetSize (bool can_update) { - Mutex::Locker locker(GetMutex()); + std::lock_guard<std::recursive_mutex> guard(GetMutex()); + if (can_update) m_process->UpdateThreadListIfNeeded(); return m_threads.size(); @@ -96,7 +122,8 @@ ThreadList::GetSize (bool can_update) ThreadSP ThreadList::GetThreadAtIndex (uint32_t idx, bool can_update) { - Mutex::Locker locker(GetMutex()); + std::lock_guard<std::recursive_mutex> guard(GetMutex()); + if (can_update) m_process->UpdateThreadListIfNeeded(); @@ -109,7 +136,7 @@ ThreadList::GetThreadAtIndex (uint32_t idx, bool can_update) ThreadSP ThreadList::FindThreadByID (lldb::tid_t tid, bool can_update) { - Mutex::Locker locker(GetMutex()); + std::lock_guard<std::recursive_mutex> guard(GetMutex()); if (can_update) m_process->UpdateThreadListIfNeeded(); @@ -131,8 +158,8 @@ ThreadList::FindThreadByID (lldb::tid_t tid, bool can_update) ThreadSP ThreadList::FindThreadByProtocolID (lldb::tid_t tid, bool can_update) { - Mutex::Locker locker(GetMutex()); - + std::lock_guard<std::recursive_mutex> guard(GetMutex()); + if (can_update) m_process->UpdateThreadListIfNeeded(); @@ -154,8 +181,8 @@ ThreadList::FindThreadByProtocolID (lldb::tid_t tid, bool can_update) ThreadSP ThreadList::RemoveThreadByID (lldb::tid_t tid, bool can_update) { - Mutex::Locker locker(GetMutex()); - + std::lock_guard<std::recursive_mutex> guard(GetMutex()); + if (can_update) m_process->UpdateThreadListIfNeeded(); @@ -177,8 +204,8 @@ ThreadList::RemoveThreadByID (lldb::tid_t tid, bool can_update) ThreadSP ThreadList::RemoveThreadByProtocolID (lldb::tid_t tid, bool can_update) { - Mutex::Locker locker(GetMutex()); - + std::lock_guard<std::recursive_mutex> guard(GetMutex()); + if (can_update) m_process->UpdateThreadListIfNeeded(); @@ -203,7 +230,7 @@ ThreadList::GetThreadSPForThreadPtr (Thread *thread_ptr) ThreadSP thread_sp; if (thread_ptr) { - Mutex::Locker locker(GetMutex()); + std::lock_guard<std::recursive_mutex> guard(GetMutex()); uint32_t idx = 0; const uint32_t num_threads = m_threads.size(); @@ -224,7 +251,7 @@ ThreadList::GetThreadSPForThreadPtr (Thread *thread_ptr) ThreadSP ThreadList::FindThreadByIndexID (uint32_t index_id, bool can_update) { - Mutex::Locker locker(GetMutex()); + std::lock_guard<std::recursive_mutex> guard(GetMutex()); if (can_update) m_process->UpdateThreadListIfNeeded(); @@ -260,7 +287,7 @@ ThreadList::ShouldStop (Event *event_ptr) collection threads_copy; { // Scope for locker - Mutex::Locker locker(GetMutex()); + std::lock_guard<std::recursive_mutex> guard(GetMutex()); m_process->UpdateThreadListIfNeeded(); for (lldb::ThreadSP thread_sp : m_threads) @@ -371,7 +398,7 @@ ThreadList::ShouldStop (Event *event_ptr) Vote ThreadList::ShouldReportStop (Event *event_ptr) { - Mutex::Locker locker(GetMutex()); + std::lock_guard<std::recursive_mutex> guard(GetMutex()); Vote result = eVoteNoOpinion; m_process->UpdateThreadListIfNeeded(); @@ -422,7 +449,8 @@ ThreadList::ShouldReportStop (Event *event_ptr) void ThreadList::SetShouldReportStop (Vote vote) { - Mutex::Locker locker(GetMutex()); + std::lock_guard<std::recursive_mutex> guard(GetMutex()); + m_process->UpdateThreadListIfNeeded(); collection::iterator pos, end = m_threads.end(); for (pos = m_threads.begin(); pos != end; ++pos) @@ -436,7 +464,7 @@ Vote ThreadList::ShouldReportRun (Event *event_ptr) { - Mutex::Locker locker(GetMutex()); + std::lock_guard<std::recursive_mutex> guard(GetMutex()); Vote result = eVoteNoOpinion; m_process->UpdateThreadListIfNeeded(); @@ -475,7 +503,7 @@ ThreadList::ShouldReportRun (Event *event_ptr) void ThreadList::Clear() { - Mutex::Locker locker(GetMutex()); + std::lock_guard<std::recursive_mutex> guard(GetMutex()); m_stop_id = 0; m_threads.clear(); m_selected_tid = LLDB_INVALID_THREAD_ID; @@ -484,7 +512,7 @@ ThreadList::Clear() void ThreadList::Destroy() { - Mutex::Locker locker(GetMutex()); + std::lock_guard<std::recursive_mutex> guard(GetMutex()); const uint32_t num_threads = m_threads.size(); for (uint32_t idx = 0; idx < num_threads; ++idx) { @@ -495,7 +523,7 @@ ThreadList::Destroy() void ThreadList::RefreshStateAfterStop () { - Mutex::Locker locker(GetMutex()); + std::lock_guard<std::recursive_mutex> guard(GetMutex()); m_process->UpdateThreadListIfNeeded(); @@ -513,7 +541,7 @@ ThreadList::DiscardThreadPlans () { // You don't need to update the thread list here, because only threads // that you currently know about have any thread plans. - Mutex::Locker locker(GetMutex()); + std::lock_guard<std::recursive_mutex> guard(GetMutex()); collection::iterator pos, end = m_threads.end(); for (pos = m_threads.begin(); pos != end; ++pos) @@ -528,7 +556,7 @@ ThreadList::WillResume () // But we only do this for threads that are running, user suspended // threads stay where they are. - Mutex::Locker locker(GetMutex()); + std::lock_guard<std::recursive_mutex> guard(GetMutex()); m_process->UpdateThreadListIfNeeded(); collection::iterator pos, end = m_threads.end(); @@ -676,7 +704,7 @@ ThreadList::WillResume () void ThreadList::DidResume () { - Mutex::Locker locker(GetMutex()); + std::lock_guard<std::recursive_mutex> guard(GetMutex()); collection::iterator pos, end = m_threads.end(); for (pos = m_threads.begin(); pos != end; ++pos) { @@ -691,7 +719,7 @@ ThreadList::DidResume () void ThreadList::DidStop () { - Mutex::Locker locker(GetMutex()); + std::lock_guard<std::recursive_mutex> guard(GetMutex()); collection::iterator pos, end = m_threads.end(); for (pos = m_threads.begin(); pos != end; ++pos) { @@ -712,7 +740,7 @@ ThreadList::DidStop () ThreadSP ThreadList::GetSelectedThread () { - Mutex::Locker locker(GetMutex()); + std::lock_guard<std::recursive_mutex> guard(GetMutex()); ThreadSP thread_sp = FindThreadByID(m_selected_tid); if (!thread_sp.get()) { @@ -727,7 +755,7 @@ ThreadList::GetSelectedThread () bool ThreadList::SetSelectedThreadByID (lldb::tid_t tid, bool notify) { - Mutex::Locker locker(GetMutex()); + std::lock_guard<std::recursive_mutex> guard(GetMutex()); ThreadSP selected_thread_sp(FindThreadByID(tid)); if (selected_thread_sp) { @@ -746,7 +774,7 @@ ThreadList::SetSelectedThreadByID (lldb::tid_t tid, bool notify) bool ThreadList::SetSelectedThreadByIndexID (uint32_t index_id, bool notify) { - Mutex::Locker locker(GetMutex()); + std::lock_guard<std::recursive_mutex> guard(GetMutex()); ThreadSP selected_thread_sp (FindThreadByIndexID(index_id)); if (selected_thread_sp.get()) { @@ -778,7 +806,8 @@ ThreadList::Update (ThreadList &rhs) { // Lock both mutexes to make sure neither side changes anyone on us // while the assignment occurs - Mutex::Locker locker(GetMutex()); + std::lock_guard<std::recursive_mutex> guard(GetMutex()); + m_process = rhs.m_process; m_stop_id = rhs.m_stop_id; m_threads.swap(rhs.m_threads); @@ -816,15 +845,28 @@ ThreadList::Update (ThreadList &rhs) void ThreadList::Flush () { - Mutex::Locker locker(GetMutex()); + std::lock_guard<std::recursive_mutex> guard(GetMutex()); collection::iterator pos, end = m_threads.end(); for (pos = m_threads.begin(); pos != end; ++pos) (*pos)->Flush (); } -Mutex & -ThreadList::GetMutex () +std::recursive_mutex & +ThreadList::GetMutex() { return m_process->m_thread_mutex; } +ThreadList::ExpressionExecutionThreadPusher::ExpressionExecutionThreadPusher (lldb::ThreadSP thread_sp) : + m_thread_list(nullptr), + m_tid(LLDB_INVALID_THREAD_ID) +{ + if (thread_sp) + { + m_tid = thread_sp->GetID(); + m_thread_list = &thread_sp->GetProcess()->GetThreadList(); + m_thread_list->PushExpressionExecutionThread(m_tid); + } +} + + diff --git a/source/Target/ThreadPlan.cpp b/source/Target/ThreadPlan.cpp index 24323337accb..bf9a05497c74 100644 --- a/source/Target/ThreadPlan.cpp +++ b/source/Target/ThreadPlan.cpp @@ -27,21 +27,21 @@ using namespace lldb_private; //---------------------------------------------------------------------- // ThreadPlan constructor //---------------------------------------------------------------------- -ThreadPlan::ThreadPlan(ThreadPlanKind kind, const char *name, Thread &thread, Vote stop_vote, Vote run_vote) : - m_thread (thread), - m_stop_vote (stop_vote), - m_run_vote (run_vote), - m_kind (kind), - m_name (name), - m_plan_complete_mutex (Mutex::eMutexTypeRecursive), - m_cached_plan_explains_stop (eLazyBoolCalculate), - m_plan_complete (false), - m_plan_private (false), - m_okay_to_discard (true), - m_is_master_plan (false), - m_plan_succeeded(true) +ThreadPlan::ThreadPlan(ThreadPlanKind kind, const char *name, Thread &thread, Vote stop_vote, Vote run_vote) + : m_thread(thread), + m_stop_vote(stop_vote), + m_run_vote(run_vote), + m_kind(kind), + m_name(name), + m_plan_complete_mutex(), + m_cached_plan_explains_stop(eLazyBoolCalculate), + m_plan_complete(false), + m_plan_private(false), + m_okay_to_discard(true), + m_is_master_plan(false), + m_plan_succeeded(true) { - SetID (GetNextID()); + SetID(GetNextID()); } //---------------------------------------------------------------------- @@ -67,14 +67,14 @@ ThreadPlan::PlanExplainsStop (Event *event_ptr) bool ThreadPlan::IsPlanComplete () { - Mutex::Locker locker(m_plan_complete_mutex); + std::lock_guard<std::recursive_mutex> guard(m_plan_complete_mutex); return m_plan_complete; } void ThreadPlan::SetPlanComplete (bool success) { - Mutex::Locker locker(m_plan_complete_mutex); + std::lock_guard<std::recursive_mutex> guard(m_plan_complete_mutex); m_plan_complete = true; m_plan_succeeded = success; } @@ -82,7 +82,7 @@ ThreadPlan::SetPlanComplete (bool success) bool ThreadPlan::MischiefManaged () { - Mutex::Locker locker(m_plan_complete_mutex); + std::lock_guard<std::recursive_mutex> guard(m_plan_complete_mutex); // Mark the plan is complete, but don't override the success flag. m_plan_complete = true; return true; diff --git a/source/Target/ThreadPlanCallUserExpression.cpp b/source/Target/ThreadPlanCallUserExpression.cpp index b24f74b10dfa..d4259ed18d34 100644 --- a/source/Target/ThreadPlanCallUserExpression.cpp +++ b/source/Target/ThreadPlanCallUserExpression.cpp @@ -19,8 +19,9 @@ #include "lldb/Core/Address.h" #include "lldb/Core/Log.h" #include "lldb/Core/Stream.h" -#include "lldb/Expression/UserExpression.h" +#include "lldb/Expression/DiagnosticManager.h" #include "lldb/Expression/IRDynamicChecks.h" +#include "lldb/Expression/UserExpression.h" #include "lldb/Host/HostInfo.h" #include "lldb/Target/LanguageRuntime.h" #include "lldb/Target/Process.h" @@ -90,15 +91,16 @@ ThreadPlanCallUserExpression::MischiefManaged () function_stack_bottom = function_stack_pointer - HostInfo::GetPageSize(); function_stack_top = function_stack_pointer; - - StreamString error_stream; - + + DiagnosticManager diagnostics; + ExecutionContext exe_ctx(GetThread()); - m_user_expression_sp->FinalizeJITExecution(error_stream, exe_ctx, m_result_var_sp, function_stack_bottom, function_stack_top); + m_user_expression_sp->FinalizeJITExecution(diagnostics, exe_ctx, m_result_var_sp, function_stack_bottom, + function_stack_top); } - - ThreadPlan::MischiefManaged (); + + ThreadPlan::MischiefManaged(); return true; } else diff --git a/source/Target/ThreadPlanShouldStopHere.cpp b/source/Target/ThreadPlanShouldStopHere.cpp index 55aaaf00b569..fcbc7f01c901 100644 --- a/source/Target/ThreadPlanShouldStopHere.cpp +++ b/source/Target/ThreadPlanShouldStopHere.cpp @@ -11,10 +11,11 @@ // C++ Includes // Other libraries and framework includes // Project includes +#include "lldb/Core/Log.h" +#include "lldb/Symbol/Symbol.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Target/Thread.h" #include "lldb/Target/ThreadPlanShouldStopHere.h" -#include "lldb/Core/Log.h" using namespace lldb; using namespace lldb_private; @@ -113,19 +114,45 @@ ThreadPlanShouldStopHere::DefaultStepFromHereCallback (ThreadPlan *current_plan, ThreadPlanSP return_plan_sp; // If we are stepping through code at line number 0, then we need to step over this range. Otherwise // we will step out. + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); + StackFrame *frame = current_plan->GetThread().GetStackFrameAtIndex(0).get(); if (!frame) return return_plan_sp; SymbolContext sc; - sc = frame->GetSymbolContext (eSymbolContextLineEntry); + sc = frame->GetSymbolContext (eSymbolContextLineEntry|eSymbolContextSymbol); + if (sc.line_entry.line == 0) { AddressRange range = sc.line_entry.range; - return_plan_sp = current_plan->GetThread().QueueThreadPlanForStepOverRange(false, - range, - sc, - eOnlyDuringStepping, - eLazyBoolNo); + + // If the whole function is marked line 0 just step out, that's easier & faster than continuing + // to step through it. + bool just_step_out = false; + if (sc.symbol && sc.symbol->ValueIsAddress()) + { + Address symbol_end = sc.symbol->GetAddress(); + symbol_end.Slide(sc.symbol->GetByteSize() - 1); + if (range.ContainsFileAddress(sc.symbol->GetAddress()) && range.ContainsFileAddress(symbol_end)) + { + if (log) + log->Printf("Stopped in a function with only line 0 lines, just stepping out."); + just_step_out = true; + } + } + if (!just_step_out) + { + if (log) + log->Printf ("ThreadPlanShouldStopHere::DefaultStepFromHereCallback Queueing StepInRange plan to step through line 0 code."); + + return_plan_sp = current_plan->GetThread().QueueThreadPlanForStepInRange(false, + range, + sc, + NULL, + eOnlyDuringStepping, + eLazyBoolCalculate, + eLazyBoolNo); + } } if (!return_plan_sp) diff --git a/source/Target/ThreadPlanStepInstruction.cpp b/source/Target/ThreadPlanStepInstruction.cpp index 9d7d52167ffc..ccfd52e00e10 100644 --- a/source/Target/ThreadPlanStepInstruction.cpp +++ b/source/Target/ThreadPlanStepInstruction.cpp @@ -239,7 +239,8 @@ ThreadPlanStepInstruction::ShouldStop (Event *event_ptr) } else { - if (m_thread.GetRegisterContext()->GetPC(0) != m_instruction_addr) + lldb::addr_t pc_addr = m_thread.GetRegisterContext()->GetPC(0); + if (pc_addr != m_instruction_addr) { if (--m_iteration_count <= 0) { diff --git a/source/Target/ThreadPlanStepOverRange.cpp b/source/Target/ThreadPlanStepOverRange.cpp index 2e731a845788..95dc2205bbf6 100644 --- a/source/Target/ThreadPlanStepOverRange.cpp +++ b/source/Target/ThreadPlanStepOverRange.cpp @@ -232,7 +232,7 @@ ThreadPlanStepOverRange::ShouldStop (Event *event_ptr) sc = frame_sp->GetSymbolContext (eSymbolContextEverything); if (sc.line_entry.IsValid()) { - if (sc.line_entry.file != m_addr_context.line_entry.file + if (sc.line_entry.original_file != m_addr_context.line_entry.original_file && sc.comp_unit == m_addr_context.comp_unit && sc.function == m_addr_context.function) { @@ -256,7 +256,7 @@ ThreadPlanStepOverRange::ShouldStop (Event *event_ptr) // some code fragment by using #include <source-fragment.c> directly. LineEntry prev_line_entry; if (line_table->GetLineEntryAtIndex(entry_idx - 1, prev_line_entry) - && prev_line_entry.file == line_entry.file) + && prev_line_entry.original_file == line_entry.original_file) { SymbolContext prev_sc; Address prev_address = prev_line_entry.range.GetBaseAddress(); @@ -289,7 +289,7 @@ ThreadPlanStepOverRange::ShouldStop (Event *event_ptr) if (next_line_function != m_addr_context.function) break; - if (next_line_entry.file == m_addr_context.line_entry.file) + if (next_line_entry.original_file == m_addr_context.line_entry.original_file) { const bool abort_other_plans = false; const RunMode stop_other_threads = RunMode::eAllThreads; diff --git a/source/Target/ThreadPlanStepRange.cpp b/source/Target/ThreadPlanStepRange.cpp index 02667f8236ea..32e225c4af70 100644 --- a/source/Target/ThreadPlanStepRange.cpp +++ b/source/Target/ThreadPlanStepRange.cpp @@ -64,16 +64,6 @@ ThreadPlanStepRange::ThreadPlanStepRange (ThreadPlanKind kind, ThreadPlanStepRange::~ThreadPlanStepRange () { ClearNextBranchBreakpoint(); - - size_t num_instruction_ranges = m_instruction_ranges.size(); - - // FIXME: The DisassemblerLLVMC has a reference cycle and won't go away if it has any active instructions. - // I'll fix that but for now, just clear the list and it will go away nicely. - for (size_t i = 0; i < num_instruction_ranges; i++) - { - if (m_instruction_ranges[i]) - m_instruction_ranges[i]->GetInstructionList().Clear(); - } } void @@ -155,7 +145,7 @@ ThreadPlanStepRange::InRange () SymbolContext new_context(frame->GetSymbolContext(eSymbolContextEverything)); if (m_addr_context.line_entry.IsValid() && new_context.line_entry.IsValid()) { - if (m_addr_context.line_entry.file == new_context.line_entry.file) + if (m_addr_context.line_entry.original_file == new_context.line_entry.original_file) { if (m_addr_context.line_entry.line == new_context.line_entry.line) { diff --git a/source/Target/ThreadPlanStepThrough.cpp b/source/Target/ThreadPlanStepThrough.cpp index a5346a4cddee..c345b6a7d4ac 100644 --- a/source/Target/ThreadPlanStepThrough.cpp +++ b/source/Target/ThreadPlanStepThrough.cpp @@ -124,7 +124,7 @@ ThreadPlanStepThrough::GetDescription (Stream *s, lldb::DescriptionLevel level) s->Address(m_start_address, sizeof (addr_t)); if (m_backstop_bkpt_id != LLDB_INVALID_BREAK_ID) { - s->Printf (" with backstop breakpoint id: %d at address: ", m_backstop_bkpt_id); + s->Printf(" with backstop breakpoint ID: %d at address: ", m_backstop_bkpt_id); s->Address (m_backstop_addr, sizeof (addr_t)); } else diff --git a/source/Target/UnixSignals.cpp b/source/Target/UnixSignals.cpp index 8a98c21560d7..cf244ba8f7d3 100644 --- a/source/Target/UnixSignals.cpp +++ b/source/Target/UnixSignals.cpp @@ -7,15 +7,14 @@ // //===----------------------------------------------------------------------===// -#include "lldb/Target/UnixSignals.h" // C Includes // C++ Includes // Other libraries and framework includes // Project includes +#include "lldb/Target/UnixSignals.h" #include "lldb/Core/ArchSpec.h" #include "lldb/Host/StringConvert.h" - #include "Plugins/Process/Utility/FreeBSDSignals.h" #include "Plugins/Process/Utility/LinuxSignals.h" #include "Plugins/Process/Utility/MipsLinuxSignals.h" @@ -23,15 +22,12 @@ using namespace lldb_private; -UnixSignals::Signal::Signal -( - const char *name, - bool default_suppress, - bool default_stop, - bool default_notify, - const char *description, - const char *alias -) : +UnixSignals::Signal::Signal(const char *name, + bool default_suppress, + bool default_stop, + bool default_notify, + const char *description, + const char *alias) : m_name (name), m_alias (alias), m_description (), @@ -85,12 +81,7 @@ UnixSignals::UnixSignals(const UnixSignals &rhs) { } -//---------------------------------------------------------------------- -// Destructor -//---------------------------------------------------------------------- -UnixSignals::~UnixSignals () -{ -} +UnixSignals::~UnixSignals() = default; void UnixSignals::Reset () @@ -135,16 +126,13 @@ UnixSignals::Reset () } void -UnixSignals::AddSignal -( - int signo, - const char *name, - bool default_suppress, - bool default_stop, - bool default_notify, - const char *description, - const char *alias -) +UnixSignals::AddSignal(int signo, + const char *name, + bool default_suppress, + bool default_stop, + bool default_notify, + const char *description, + const char *alias) { Signal new_signal (name, default_suppress, default_stop, default_notify, description, alias); m_signals.insert (std::make_pair(signo, new_signal)); @@ -163,12 +151,11 @@ UnixSignals::GetSignalAsCString (int signo) const { collection::const_iterator pos = m_signals.find (signo); if (pos == m_signals.end()) - return NULL; + return nullptr; else return pos->second.m_name.GetCString (); } - bool UnixSignals::SignalIsValid (int32_t signo) const { @@ -180,7 +167,7 @@ UnixSignals::GetShortName(ConstString name) const { if (name) { - char* signame = (char*)(name.AsCString()); + const char* signame = name.AsCString(); return ConstString(signame + 3); // Remove "SIG" from name } return name; @@ -232,17 +219,14 @@ UnixSignals::GetNextSignalNumber (int32_t current_signal) const } const char * -UnixSignals::GetSignalInfo -( - int32_t signo, - bool &should_suppress, - bool &should_stop, - bool &should_notify -) const +UnixSignals::GetSignalInfo(int32_t signo, + bool &should_suppress, + bool &should_stop, + bool &should_notify) const { collection::const_iterator pos = m_signals.find (signo); if (pos == m_signals.end()) - return NULL; + return nullptr; else { const Signal &signal = pos->second; diff --git a/source/Target/UnwindAssembly.cpp b/source/Target/UnwindAssembly.cpp index af7f86fe492a..3dc443599016 100644 --- a/source/Target/UnwindAssembly.cpp +++ b/source/Target/UnwindAssembly.cpp @@ -1,4 +1,4 @@ -//===-- UnwindAssembly.cpp ------------------------------*- C++ -*-===// +//===-- UnwindAssembly.cpp --------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,6 +7,10 @@ // //===----------------------------------------------------------------------===// +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes #include "lldb/lldb-private.h" #include "lldb/Core/PluginManager.h" #include "lldb/Core/PluginInterface.h" @@ -21,14 +25,14 @@ UnwindAssembly::FindPlugin (const ArchSpec &arch) UnwindAssemblyCreateInstance create_callback; for (uint32_t idx = 0; - (create_callback = PluginManager::GetUnwindAssemblyCreateCallbackAtIndex(idx)) != NULL; + (create_callback = PluginManager::GetUnwindAssemblyCreateCallbackAtIndex(idx)) != nullptr; ++idx) { UnwindAssemblySP assembly_profiler_ap (create_callback (arch)); - if (assembly_profiler_ap.get ()) + if (assembly_profiler_ap) return assembly_profiler_ap; } - return NULL; + return nullptr; } UnwindAssembly::UnwindAssembly (const ArchSpec &arch) : @@ -36,6 +40,4 @@ UnwindAssembly::UnwindAssembly (const ArchSpec &arch) : { } -UnwindAssembly::~UnwindAssembly () -{ -} +UnwindAssembly::~UnwindAssembly() = default; |