diff --git a/lldb/include/lldb/API/SBFrame.h b/lldb/include/lldb/API/SBFrame.h index 04cd2d70776a..5af12ff6737e 100644 --- a/lldb/include/lldb/API/SBFrame.h +++ b/lldb/include/lldb/API/SBFrame.h @@ -19,7 +19,6 @@ namespace lldb { class SBFrame { public: - typedef STD_SHARED_PTR(lldb_private::StackFrameImpl) StackFrameImplSP; SBFrame (); SBFrame (const lldb::SBFrame &rhs); @@ -224,7 +223,7 @@ protected: void SetFrameSP (const lldb::StackFrameSP &lldb_object_sp); - StackFrameImplSP m_opaque_sp; + lldb::ExecutionContextRefSP m_opaque_sp; }; } // namespace lldb diff --git a/lldb/include/lldb/API/SBThread.h b/lldb/include/lldb/API/SBThread.h index dc502ac922b7..327a3be662ec 100644 --- a/lldb/include/lldb/API/SBThread.h +++ b/lldb/include/lldb/API/SBThread.h @@ -173,11 +173,7 @@ protected: SetThread (const lldb::ThreadSP& lldb_object_sp); private: - //------------------------------------------------------------------ - // Classes that inherit from Thread can see and modify these - //------------------------------------------------------------------ - - lldb::ThreadWP m_opaque_wp; + lldb::ExecutionContextRefSP m_opaque_sp; }; } // namespace lldb diff --git a/lldb/include/lldb/Host/ReadWriteLock.h b/lldb/include/lldb/Host/ReadWriteLock.h new file mode 100644 index 000000000000..4b7bfd284eb2 --- /dev/null +++ b/lldb/include/lldb/Host/ReadWriteLock.h @@ -0,0 +1,208 @@ +//===-- ReadWriteLock.h -----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_ReadWriteLock_h_ +#define liblldb_ReadWriteLock_h_ +#if defined(__cplusplus) + +#include "lldb/Host/Mutex.h" +#include "lldb/Host/Condition.h" +#include +#include +#include + +//---------------------------------------------------------------------- +/// Enumerations for broadcasting. +//---------------------------------------------------------------------- +namespace lldb_private { + +//---------------------------------------------------------------------- +/// @class ReadWriteLock ReadWriteLock.h "lldb/Host/ReadWriteLock.h" +/// @brief A C++ wrapper class for providing threaded access to a value +/// of type T. +/// +/// A templatized class that provides multi-threaded access to a value +/// of type T. Threads can efficiently wait for bits within T to be set +/// or reset, or wait for T to be set to be equal/not equal to a +/// specified values. +//---------------------------------------------------------------------- + +class ReadWriteLock +{ +public: + ReadWriteLock () : + m_rwlock() + { + int err = ::pthread_rwlock_init(&m_rwlock, NULL); +#if LLDB_CONFIGURATION_DEBUG + assert(err == 0); +#endif + } + + ~ReadWriteLock () + { + int err = ::pthread_rwlock_destroy (&m_rwlock); +#if LLDB_CONFIGURATION_DEBUG + assert(err == 0); +#endif + } + + bool + ReadLock () + { + return ::pthread_rwlock_rdlock (&m_rwlock) == 0; + } + + bool + ReadTryLock () + { + return ::pthread_rwlock_tryrdlock (&m_rwlock) == 0; + } + + bool + ReadUnlock () + { + return ::pthread_rwlock_unlock (&m_rwlock) == 0; + } + + bool + WriteLock() + { + return ::pthread_rwlock_wrlock (&m_rwlock) == 0; + } + + bool + WriteUnlock () + { + return ::pthread_rwlock_unlock (&m_rwlock) == 0; + } + + class ReadLocker + { + public: + ReadLocker () : + m_lock (NULL) + { + } + + ReadLocker (ReadWriteLock *lock) : + m_lock (NULL) + { + Lock(lock); + } + + ~ReadLocker() + { + Unlock(); + } + + void + Lock (ReadWriteLock *lock) + { + if (m_lock) + { + if (m_lock == lock) + return; // We already have this lock locked + else + Unlock(); + } + if (lock) + { + lock->ReadLock(); + m_lock = lock; + } + } + + // Try to lock the read lock, but only do so if there are no writers. + bool + TryLock (ReadWriteLock *lock) + { + if (m_lock) + { + if (m_lock == lock) + return true; // We already have this lock locked + else + Unlock(); + } + if (lock) + { + if (lock->ReadTryLock()) + { + m_lock = lock; + return true; + } + } + return false; + } + + void + Unlock () + { + if (m_lock) + { + m_lock->ReadUnlock(); + m_lock = NULL; + } + } + + protected: + ReadWriteLock *m_lock; + private: + DISALLOW_COPY_AND_ASSIGN(ReadLocker); + }; + + class WriteLocker + { + public: + WriteLocker () : + m_lock (NULL) + { + } + + WriteLocker (ReadWriteLock *lock) : + m_lock (lock) + { + Lock(); + } + + ~WriteLocker() + { + Unlock(); + } + + void + Lock () + { + if (m_lock) + m_lock->WriteLock(); + } + + void + Unlock () + { + if (m_lock) + m_lock->WriteUnlock(); + } + + protected: + ReadWriteLock *m_lock; + private: + DISALLOW_COPY_AND_ASSIGN(WriteLocker); + }; + +protected: + pthread_rwlock_t m_rwlock; +private: + DISALLOW_COPY_AND_ASSIGN(ReadWriteLock); +}; + +} // namespace lldb_private + +#endif // #if defined(__cplusplus) +#endif // #ifndef liblldb_ReadWriteLock_h_ diff --git a/lldb/include/lldb/Target/ExecutionContext.h b/lldb/include/lldb/Target/ExecutionContext.h index 644044f88a94..7f3e77e49d6c 100644 --- a/lldb/include/lldb/Target/ExecutionContext.h +++ b/lldb/include/lldb/Target/ExecutionContext.h @@ -329,6 +329,20 @@ public: return m_stack_id.IsValid(); } + void + ClearThread () + { + m_thread_wp.reset(); + m_tid = LLDB_INVALID_THREAD_ID; + } + + void + ClearFrame () + { + m_stack_id.Clear(); + m_frame_wp.reset(); + } + protected: //------------------------------------------------------------------ // Member variables diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h index 23e87d95d3ed..dddc23380b20 100644 --- a/lldb/include/lldb/Target/Process.h +++ b/lldb/include/lldb/Target/Process.h @@ -37,6 +37,7 @@ #include "lldb/Expression/IRDynamicChecks.h" #include "lldb/Host/FileSpec.h" #include "lldb/Host/Host.h" +#include "lldb/Host/ReadWriteLock.h" #include "lldb/Interpreter/Args.h" #include "lldb/Interpreter/Options.h" #include "lldb/Target/ExecutionContextScope.h" @@ -922,13 +923,13 @@ class ProcessInstanceInfoMatch public: ProcessInstanceInfoMatch () : m_match_info (), - m_name_match_type (lldb_private::eNameMatchIgnore), + m_name_match_type (eNameMatchIgnore), m_match_all_users (false) { } ProcessInstanceInfoMatch (const char *process_name, - lldb_private::NameMatchType process_name_match_type) : + NameMatchType process_name_match_type) : m_match_info (), m_name_match_type (process_name_match_type), m_match_all_users (false) @@ -960,14 +961,14 @@ public: m_match_all_users = b; } - lldb_private::NameMatchType + NameMatchType GetNameMatchType () const { return m_name_match_type; } void - SetNameMatchType (lldb_private::NameMatchType name_match_type) + SetNameMatchType (NameMatchType name_match_type) { m_name_match_type = name_match_type; } @@ -985,7 +986,7 @@ public: protected: ProcessInstanceInfo m_match_info; - lldb_private::NameMatchType m_name_match_type; + NameMatchType m_name_match_type; bool m_match_all_users; }; @@ -1295,6 +1296,15 @@ public: }; typedef Range LoadRange; + // We use a read/write lock to allow on or more clients to + // access the process state while the process is stopped (reader). + // We lock the write lock to control access to the process + // while it is running (readers, or clients that want the process + // stopped can block waiting for the process to stop, or just + // try to lock it to see if they can immediately access the stopped + // process. If the try read lock fails, then the process is running. + typedef ReadWriteLock::ReadLocker StopLocker; + typedef ReadWriteLock::WriteLocker RunLocker; // These two functions fill out the Broadcaster interface: @@ -3133,7 +3143,13 @@ public: //------------------------------------------------------------------ bool RemoveInvalidMemoryRange (const LoadRange ®ion); - + + ReadWriteLock & + GetRunLock () + { + return m_run_lock; + } + protected: //------------------------------------------------------------------ // NextEventAction provides a way to register an action on the next @@ -3214,6 +3230,11 @@ protected: return m_private_state_thread != LLDB_INVALID_HOST_THREAD; } + //------------------------------------------------------------------ + // Type definitions + //------------------------------------------------------------------ + typedef std::map LanguageRuntimeCollection; + //------------------------------------------------------------------ // Member variables //------------------------------------------------------------------ @@ -3225,7 +3246,7 @@ protected: Listener m_private_state_listener; // This is the listener for the private state thread. Predicate m_private_state_control_wait; /// This Predicate is used to signal that a control operation is complete. lldb::thread_t m_private_state_thread; // Thread ID for the thread that watches interal state events - ProcessModID m_mod_id; ///< Tracks the state of the process over stops and other alterations. + ProcessModID m_mod_id; ///< Tracks the state of the process over stops and other alterations. uint32_t m_thread_index_id; ///< Each thread is created with a 1 based index that won't get re-used. int m_exit_status; ///< The exit status of the process, or -1 if not set. std::string m_exit_string; ///< A textual description of why a process exited. @@ -3233,25 +3254,23 @@ protected: std::vector m_notifications; ///< The list of notifications that this process can deliver. std::vector m_image_tokens; Listener &m_listener; - BreakpointSiteList m_breakpoint_site_list; ///< This is the list of breakpoint locations we intend - ///< to insert in the target. + BreakpointSiteList m_breakpoint_site_list; ///< This is the list of breakpoint locations we intend to insert in the target. std::auto_ptr m_dyld_ap; - std::auto_ptr m_dynamic_checkers_ap; ///< The functions used by the expression parser to validate data that expressions use. - std::auto_ptr m_os_ap; + std::auto_ptr m_dynamic_checkers_ap; ///< The functions used by the expression parser to validate data that expressions use. + std::auto_ptr m_os_ap; UnixSignals m_unix_signals; /// This is the current signal set for this process. lldb::ABISP m_abi_sp; lldb::InputReaderSP m_process_input_reader; - lldb_private::Communication m_stdio_communication; - lldb_private::Mutex m_stdio_communication_mutex; + Communication m_stdio_communication; + Mutex m_stdio_communication_mutex; std::string m_stdout_data; std::string m_stderr_data; MemoryCache m_memory_cache; AllocatedMemoryCache m_allocated_memory_cache; bool m_should_detach; /// Should we detach if the process object goes away with an explicit call to Kill or Detach? - - typedef std::map LanguageRuntimeCollection; - LanguageRuntimeCollection m_language_runtimes; + LanguageRuntimeCollection m_language_runtimes; std::auto_ptr m_next_event_action_ap; + ReadWriteLock m_run_lock; enum { eCanJITDontKnow= 0, diff --git a/lldb/include/lldb/lldb-forward.h b/lldb/include/lldb/lldb-forward.h index 3842cde905fc..08143dc39731 100644 --- a/lldb/include/lldb/lldb-forward.h +++ b/lldb/include/lldb/lldb-forward.h @@ -267,6 +267,7 @@ namespace lldb { typedef STD_SHARED_PTR(lldb_private::Disassembler) DisassemblerSP; typedef STD_SHARED_PTR(lldb_private::DynamicLoader) DynamicLoaderSP; typedef STD_SHARED_PTR(lldb_private::Event) EventSP; + typedef STD_SHARED_PTR(lldb_private::ExecutionContextRef) ExecutionContextRefSP; typedef STD_SHARED_PTR(lldb_private::TypeCategoryImpl) TypeCategoryImplSP; typedef STD_SHARED_PTR(lldb_private::Function) FunctionSP; typedef STD_SHARED_PTR(lldb_private::InlineFunctionInfo) InlineFunctionInfoSP; diff --git a/lldb/lldb.xcodeproj/project.pbxproj b/lldb/lldb.xcodeproj/project.pbxproj index e414ad6ad332..a7f45acdaf9f 100644 --- a/lldb/lldb.xcodeproj/project.pbxproj +++ b/lldb/lldb.xcodeproj/project.pbxproj @@ -70,6 +70,7 @@ 265205AA13D3E3F700132FE2 /* RegisterContextKDP_i386.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 265205A413D3E3F700132FE2 /* RegisterContextKDP_i386.cpp */; }; 265205AC13D3E3F700132FE2 /* RegisterContextKDP_x86_64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 265205A613D3E3F700132FE2 /* RegisterContextKDP_x86_64.cpp */; }; 2660AAB914622483003A9694 /* LLDBWrapPython.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26A4EEB511682AAC007A372A /* LLDBWrapPython.cpp */; }; + 2663E379152BD1890091EC22 /* ReadWriteLock.h in Headers */ = {isa = PBXBuildFile; fileRef = 2663E378152BD1890091EC22 /* ReadWriteLock.h */; }; 26651A18133BF9E0005B64B7 /* Opcode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26651A17133BF9DF005B64B7 /* Opcode.cpp */; }; 266603CA1345B5A8004DA8B6 /* ConnectionSharedMemory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 266603C91345B5A8004DA8B6 /* ConnectionSharedMemory.cpp */; }; 2668020E115FD12C008E1FE4 /* lldb-defines.h in Headers */ = {isa = PBXBuildFile; fileRef = 26BC7C2510F1B3BC00F91463 /* lldb-defines.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -827,6 +828,7 @@ 2660D9F611922A1300958FBD /* StringExtractor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = StringExtractor.cpp; path = source/Utility/StringExtractor.cpp; sourceTree = ""; }; 2660D9F711922A1300958FBD /* StringExtractor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StringExtractor.h; path = source/Utility/StringExtractor.h; sourceTree = ""; }; 2660D9FE11922A7F00958FBD /* ThreadPlanStepUntil.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ThreadPlanStepUntil.cpp; path = source/Target/ThreadPlanStepUntil.cpp; sourceTree = ""; }; + 2663E378152BD1890091EC22 /* ReadWriteLock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ReadWriteLock.h; path = include/lldb/Host/ReadWriteLock.h; sourceTree = ""; }; 26651A14133BEC76005B64B7 /* lldb-public.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "lldb-public.h"; path = "include/lldb/lldb-public.h"; sourceTree = ""; }; 26651A15133BF9CC005B64B7 /* Opcode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Opcode.h; path = include/lldb/Core/Opcode.h; sourceTree = ""; }; 26651A17133BF9DF005B64B7 /* Opcode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Opcode.cpp; path = source/Core/Opcode.cpp; sourceTree = ""; }; @@ -2680,6 +2682,7 @@ 26BC7DD410F1B7D500F91463 /* Host.h */, 26BC7DD510F1B7D500F91463 /* Mutex.h */, 26BC7DD610F1B7D500F91463 /* Predicate.h */, + 2663E378152BD1890091EC22 /* ReadWriteLock.h */, 26D7E45B13D5E2F9007FD12B /* SocketAddress.h */, 26D7E45C13D5E30A007FD12B /* SocketAddress.cpp */, 2689B0A4113EE3CD00A4AEDB /* Symbols.h */, @@ -3191,6 +3194,7 @@ 26FFC19E14FC072100087D58 /* DynamicLoaderPOSIXDYLD.h in Headers */, 2694E99E14FC0BB30076DE67 /* PlatformFreeBSD.h in Headers */, 2694E9A514FC0BBD0076DE67 /* PlatformLinux.h in Headers */, + 2663E379152BD1890091EC22 /* ReadWriteLock.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/lldb/source/API/SBFrame.cpp b/lldb/source/API/SBFrame.cpp index 9f4709fac9e5..c84ac13597c6 100644 --- a/lldb/source/API/SBFrame.cpp +++ b/lldb/source/API/SBFrame.cpp @@ -42,91 +42,17 @@ #include "lldb/API/SBSymbolContext.h" #include "lldb/API/SBThread.h" -namespace lldb_private { - - class StackFrameImpl - { - public: - StackFrameImpl (const lldb::StackFrameSP &frame_sp) : - m_frame_wp (frame_sp), - m_thread_wp (), - m_stack_id () - { - if (frame_sp) - { - m_thread_wp = frame_sp->GetThread(); - m_stack_id = frame_sp->GetStackID(); - } - } - - ~StackFrameImpl() - { - } - - lldb::StackFrameSP - GetFrameSP () - { - lldb::StackFrameSP frame_sp; - // We have a weak pointer to our thread, which might - // be NULL'ed out if the thread went away, so first - // make sure our thread is still alive. - lldb::ThreadSP thread_sp (m_thread_wp.lock()); - if (thread_sp) - { - // Our thread is still here, check if our frame - // is still alive as well. - frame_sp = m_frame_wp.lock(); - if (frame_sp) - { - // Our frame is still alive, make sure that our thread - // still has this exact frame... - lldb::StackFrameSP tmp_frame_sp (thread_sp->GetStackFrameAtIndex (frame_sp->GetFrameIndex())); - if (tmp_frame_sp == frame_sp) - return frame_sp; - } - // The original stack frame might have gone away, - // we need to check for the frame by stack ID - frame_sp = thread_sp->GetFrameWithStackID (m_stack_id); - m_frame_wp = frame_sp; - } - return frame_sp; - } - - void - SetFrameSP (const lldb::StackFrameSP &frame_sp) - { - if (frame_sp) - { - m_frame_wp = frame_sp; - m_thread_wp = frame_sp->GetThread(); - m_stack_id = frame_sp->GetStackID(); - } - else - { - m_frame_wp.reset(); - m_thread_wp.reset(); - m_stack_id.Clear(); - } - } - - protected: - lldb::StackFrameWP m_frame_wp; - lldb::ThreadWP m_thread_wp; - StackID m_stack_id; - }; -} // namespace lldb_private - using namespace lldb; using namespace lldb_private; SBFrame::SBFrame () : - m_opaque_sp () + m_opaque_sp (new ExecutionContextRef()) { } SBFrame::SBFrame (const StackFrameSP &lldb_object_sp) : - m_opaque_sp (new StackFrameImpl (lldb_object_sp)) + m_opaque_sp (new ExecutionContextRef (lldb_object_sp)) { LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); @@ -141,7 +67,7 @@ SBFrame::SBFrame (const StackFrameSP &lldb_object_sp) : } SBFrame::SBFrame(const SBFrame &rhs) : - m_opaque_sp (rhs.m_opaque_sp) + m_opaque_sp (new ExecutionContextRef (*rhs.m_opaque_sp)) { } @@ -149,7 +75,7 @@ const SBFrame & SBFrame::operator = (const SBFrame &rhs) { if (this != &rhs) - m_opaque_sp = rhs.m_opaque_sp; + *m_opaque_sp = *rhs.m_opaque_sp; return *this; } @@ -160,42 +86,19 @@ SBFrame::~SBFrame() StackFrameSP SBFrame::GetFrameSP() const { - StackFrameImplSP impl_sp (m_opaque_sp); - StackFrameSP frame_sp; - if (impl_sp) - frame_sp = impl_sp->GetFrameSP(); - return frame_sp; + return m_opaque_sp->GetFrameSP(); } void SBFrame::SetFrameSP (const StackFrameSP &lldb_object_sp) { - if (lldb_object_sp) - { - if (m_opaque_sp) - { - StackFrameImplSP impl_sp (m_opaque_sp); - if (impl_sp) - impl_sp->SetFrameSP (lldb_object_sp); - } - else - { - m_opaque_sp = StackFrameImplSP (new StackFrameImpl(lldb_object_sp)); - } - } - else - { - m_opaque_sp.reset(); - } + return m_opaque_sp->SetFrameSP(lldb_object_sp); } bool SBFrame::IsValid() const { - StackFrameImplSP impl_sp (m_opaque_sp); - if (impl_sp) - return (impl_sp->GetFrameSP().get() != NULL); - return false; + return GetFrameSP().get() != NULL; } SBSymbolContext @@ -203,13 +106,17 @@ SBFrame::GetSymbolContext (uint32_t resolve_scope) const { SBSymbolContext sb_sym_ctx; - ExecutionContext exe_ctx(GetFrameSP()); + ExecutionContext exe_ctx(m_opaque_sp.get()); StackFrame *frame = exe_ctx.GetFramePtr(); Target *target = exe_ctx.GetTargetPtr(); if (frame && target) { - Mutex::Locker api_locker (target->GetAPIMutex()); - sb_sym_ctx.SetSymbolContext(&frame->GetSymbolContext (resolve_scope)); + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) + { + Mutex::Locker api_locker (target->GetAPIMutex()); + sb_sym_ctx.SetSymbolContext(&frame->GetSymbolContext (resolve_scope)); + } } LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); @@ -225,14 +132,18 @@ SBFrame::GetModule () const { SBModule sb_module; ModuleSP module_sp; - ExecutionContext exe_ctx(GetFrameSP()); + ExecutionContext exe_ctx(m_opaque_sp.get()); StackFrame *frame = exe_ctx.GetFramePtr(); Target *target = exe_ctx.GetTargetPtr(); if (frame && target) { - Mutex::Locker api_locker (target->GetAPIMutex()); - module_sp = frame->GetSymbolContext (eSymbolContextModule).module_sp; - sb_module.SetSP (module_sp); + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) + { + Mutex::Locker api_locker (target->GetAPIMutex()); + module_sp = frame->GetSymbolContext (eSymbolContextModule).module_sp; + sb_module.SetSP (module_sp); + } } LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); @@ -247,13 +158,17 @@ SBCompileUnit SBFrame::GetCompileUnit () const { SBCompileUnit sb_comp_unit; - ExecutionContext exe_ctx(GetFrameSP()); + ExecutionContext exe_ctx(m_opaque_sp.get()); StackFrame *frame = exe_ctx.GetFramePtr(); Target *target = exe_ctx.GetTargetPtr(); if (frame && target) { - Mutex::Locker api_locker (target->GetAPIMutex()); - sb_comp_unit.reset (frame->GetSymbolContext (eSymbolContextCompUnit).comp_unit); + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) + { + Mutex::Locker api_locker (target->GetAPIMutex()); + sb_comp_unit.reset (frame->GetSymbolContext (eSymbolContextCompUnit).comp_unit); + } } LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) @@ -267,13 +182,17 @@ SBFunction SBFrame::GetFunction () const { SBFunction sb_function; - ExecutionContext exe_ctx(GetFrameSP()); + ExecutionContext exe_ctx(m_opaque_sp.get()); StackFrame *frame = exe_ctx.GetFramePtr(); Target *target = exe_ctx.GetTargetPtr(); if (frame && target) { - Mutex::Locker api_locker (target->GetAPIMutex()); - sb_function.reset(frame->GetSymbolContext (eSymbolContextFunction).function); + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) + { + Mutex::Locker api_locker (target->GetAPIMutex()); + sb_function.reset(frame->GetSymbolContext (eSymbolContextFunction).function); + } } LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) @@ -287,13 +206,17 @@ SBSymbol SBFrame::GetSymbol () const { SBSymbol sb_symbol; - ExecutionContext exe_ctx(GetFrameSP()); + ExecutionContext exe_ctx(m_opaque_sp.get()); StackFrame *frame = exe_ctx.GetFramePtr(); Target *target = exe_ctx.GetTargetPtr(); if (frame && target) { - Mutex::Locker api_locker (target->GetAPIMutex()); - sb_symbol.reset(frame->GetSymbolContext (eSymbolContextSymbol).symbol); + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) + { + Mutex::Locker api_locker (target->GetAPIMutex()); + sb_symbol.reset(frame->GetSymbolContext (eSymbolContextSymbol).symbol); + } } LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) @@ -306,13 +229,17 @@ SBBlock SBFrame::GetBlock () const { SBBlock sb_block; - ExecutionContext exe_ctx(GetFrameSP()); + ExecutionContext exe_ctx(m_opaque_sp.get()); StackFrame *frame = exe_ctx.GetFramePtr(); Target *target = exe_ctx.GetTargetPtr(); if (frame && target) { - Mutex::Locker api_locker (target->GetAPIMutex()); - sb_block.SetPtr (frame->GetSymbolContext (eSymbolContextBlock).block); + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) + { + Mutex::Locker api_locker (target->GetAPIMutex()); + sb_block.SetPtr (frame->GetSymbolContext (eSymbolContextBlock).block); + } } LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) @@ -325,13 +252,17 @@ SBBlock SBFrame::GetFrameBlock () const { SBBlock sb_block; - ExecutionContext exe_ctx(GetFrameSP()); + ExecutionContext exe_ctx(m_opaque_sp.get()); StackFrame *frame = exe_ctx.GetFramePtr(); Target *target = exe_ctx.GetTargetPtr(); if (frame && target) { - Mutex::Locker api_locker (target->GetAPIMutex()); - sb_block.SetPtr(frame->GetFrameBlock ()); + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) + { + Mutex::Locker api_locker (target->GetAPIMutex()); + sb_block.SetPtr(frame->GetFrameBlock ()); + } } LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) @@ -344,13 +275,17 @@ SBLineEntry SBFrame::GetLineEntry () const { SBLineEntry sb_line_entry; - ExecutionContext exe_ctx(GetFrameSP()); + ExecutionContext exe_ctx(m_opaque_sp.get()); StackFrame *frame = exe_ctx.GetFramePtr(); Target *target = exe_ctx.GetTargetPtr(); if (frame && target) { - Mutex::Locker api_locker (target->GetAPIMutex()); - sb_line_entry.SetLineEntry (frame->GetSymbolContext (eSymbolContextLineEntry).line_entry); + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) + { + Mutex::Locker api_locker (target->GetAPIMutex()); + sb_line_entry.SetLineEntry (frame->GetSymbolContext (eSymbolContextLineEntry).line_entry); + } } LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) @@ -364,11 +299,9 @@ SBFrame::GetFrameID () const { uint32_t frame_idx = UINT32_MAX; - - ExecutionContext exe_ctx(GetFrameSP()); + ExecutionContext exe_ctx(m_opaque_sp.get()); StackFrame *frame = exe_ctx.GetFramePtr(); - Target *target = exe_ctx.GetTargetPtr(); - if (frame && target) + if (frame) frame_idx = frame->GetFrameIndex (); LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); @@ -382,13 +315,17 @@ addr_t SBFrame::GetPC () const { addr_t addr = LLDB_INVALID_ADDRESS; - ExecutionContext exe_ctx(GetFrameSP()); + ExecutionContext exe_ctx(m_opaque_sp.get()); StackFrame *frame = exe_ctx.GetFramePtr(); Target *target = exe_ctx.GetTargetPtr(); if (frame && target) { - Mutex::Locker api_locker (target->GetAPIMutex()); - addr = frame->GetFrameCodeAddress().GetOpcodeLoadAddress (target); + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) + { + Mutex::Locker api_locker (target->GetAPIMutex()); + addr = frame->GetFrameCodeAddress().GetOpcodeLoadAddress (target); + } } LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); @@ -402,13 +339,17 @@ bool SBFrame::SetPC (addr_t new_pc) { bool ret_val = false; - ExecutionContext exe_ctx(GetFrameSP()); + ExecutionContext exe_ctx(m_opaque_sp.get()); StackFrame *frame = exe_ctx.GetFramePtr(); Target *target = exe_ctx.GetTargetPtr(); if (frame && target) { - Mutex::Locker api_locker (target->GetAPIMutex()); - ret_val = frame->GetRegisterContext()->SetPC (new_pc); + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) + { + Mutex::Locker api_locker (target->GetAPIMutex()); + ret_val = frame->GetRegisterContext()->SetPC (new_pc); + } } LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); @@ -423,13 +364,17 @@ addr_t SBFrame::GetSP () const { addr_t addr = LLDB_INVALID_ADDRESS; - ExecutionContext exe_ctx(GetFrameSP()); + ExecutionContext exe_ctx(m_opaque_sp.get()); StackFrame *frame = exe_ctx.GetFramePtr(); Target *target = exe_ctx.GetTargetPtr(); if (frame && target) { - Mutex::Locker api_locker (target->GetAPIMutex()); - addr = frame->GetRegisterContext()->GetSP(); + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) + { + Mutex::Locker api_locker (target->GetAPIMutex()); + addr = frame->GetRegisterContext()->GetSP(); + } } LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) @@ -443,13 +388,17 @@ addr_t SBFrame::GetFP () const { addr_t addr = LLDB_INVALID_ADDRESS; - ExecutionContext exe_ctx(GetFrameSP()); + ExecutionContext exe_ctx(m_opaque_sp.get()); StackFrame *frame = exe_ctx.GetFramePtr(); Target *target = exe_ctx.GetTargetPtr(); if (frame && target) { - Mutex::Locker api_locker (target->GetAPIMutex()); - addr = frame->GetRegisterContext()->GetFP(); + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) + { + Mutex::Locker api_locker (target->GetAPIMutex()); + addr = frame->GetRegisterContext()->GetFP(); + } } LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); @@ -463,13 +412,17 @@ SBAddress SBFrame::GetPCAddress () const { SBAddress sb_addr; - ExecutionContext exe_ctx(GetFrameSP()); + ExecutionContext exe_ctx(m_opaque_sp.get()); StackFrame *frame = exe_ctx.GetFramePtr(); Target *target = exe_ctx.GetTargetPtr(); if (frame && target) { - Mutex::Locker api_locker (target->GetAPIMutex()); - sb_addr.SetAddress (&frame->GetFrameCodeAddress()); + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) + { + Mutex::Locker api_locker (target->GetAPIMutex()); + sb_addr.SetAddress (&frame->GetFrameCodeAddress()); + } } LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) @@ -487,13 +440,17 @@ lldb::SBValue SBFrame::GetValueForVariablePath (const char *var_path) { SBValue sb_value; - ExecutionContext exe_ctx(GetFrameSP()); + ExecutionContext exe_ctx(m_opaque_sp.get()); StackFrame *frame = exe_ctx.GetFramePtr(); Target *target = exe_ctx.GetTargetPtr(); if (frame && target) { - lldb::DynamicValueType use_dynamic = frame->CalculateTarget()->GetPreferDynamicValue(); - sb_value = GetValueForVariablePath (var_path, use_dynamic); + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) + { + lldb::DynamicValueType use_dynamic = frame->CalculateTarget()->GetPreferDynamicValue(); + sb_value = GetValueForVariablePath (var_path, use_dynamic); + } } return sb_value; } @@ -502,20 +459,24 @@ lldb::SBValue SBFrame::GetValueForVariablePath (const char *var_path, DynamicValueType use_dynamic) { SBValue sb_value; - ExecutionContext exe_ctx(GetFrameSP()); + ExecutionContext exe_ctx(m_opaque_sp.get()); StackFrame *frame = exe_ctx.GetFramePtr(); Target *target = exe_ctx.GetTargetPtr(); if (frame && target && var_path && var_path[0]) { - Mutex::Locker api_locker (target->GetAPIMutex()); - VariableSP var_sp; - Error error; - ValueObjectSP value_sp (frame->GetValueForVariableExpressionPath (var_path, - use_dynamic, - StackFrame::eExpressionPathOptionCheckPtrVsMember, - var_sp, - error)); - sb_value.SetSP(value_sp); + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) + { + Mutex::Locker api_locker (target->GetAPIMutex()); + VariableSP var_sp; + Error error; + ValueObjectSP value_sp (frame->GetValueForVariableExpressionPath (var_path, + use_dynamic, + StackFrame::eExpressionPathOptionCheckPtrVsMember, + var_sp, + error)); + sb_value.SetSP(value_sp); + } } return sb_value; } @@ -524,7 +485,7 @@ SBValue SBFrame::FindVariable (const char *name) { SBValue value; - ExecutionContext exe_ctx(GetFrameSP()); + ExecutionContext exe_ctx(m_opaque_sp.get()); StackFrame *frame = exe_ctx.GetFramePtr(); Target *target = exe_ctx.GetTargetPtr(); if (frame && target) @@ -542,36 +503,39 @@ SBFrame::FindVariable (const char *name, lldb::DynamicValueType use_dynamic) VariableSP var_sp; SBValue sb_value; ValueObjectSP value_sp; - ExecutionContext exe_ctx(GetFrameSP()); + ExecutionContext exe_ctx(m_opaque_sp.get()); StackFrame *frame = exe_ctx.GetFramePtr(); Target *target = exe_ctx.GetTargetPtr(); if (frame && target && name && name[0]) { - VariableList variable_list; - Mutex::Locker api_locker (target->GetAPIMutex()); - SymbolContext sc (frame->GetSymbolContext (eSymbolContextBlock)); - - if (sc.block) + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { - const bool can_create = true; - const bool get_parent_variables = true; - const bool stop_if_block_is_inlined_function = true; - - if (sc.block->AppendVariables (can_create, - get_parent_variables, - stop_if_block_is_inlined_function, - &variable_list)) + VariableList variable_list; + Mutex::Locker api_locker (target->GetAPIMutex()); + SymbolContext sc (frame->GetSymbolContext (eSymbolContextBlock)); + + if (sc.block) { - var_sp = variable_list.FindVariable (ConstString(name)); + const bool can_create = true; + const bool get_parent_variables = true; + const bool stop_if_block_is_inlined_function = true; + + if (sc.block->AppendVariables (can_create, + get_parent_variables, + stop_if_block_is_inlined_function, + &variable_list)) + { + var_sp = variable_list.FindVariable (ConstString(name)); + } + } + + if (var_sp) + { + value_sp = frame->GetValueObjectForFrameVariable(var_sp, use_dynamic); + sb_value.SetSP(value_sp); } } - - if (var_sp) - { - value_sp = frame->GetValueObjectForFrameVariable(var_sp, use_dynamic); - sb_value.SetSP(value_sp); - } - } LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); @@ -586,7 +550,7 @@ SBValue SBFrame::FindValue (const char *name, ValueType value_type) { SBValue value; - ExecutionContext exe_ctx(GetFrameSP()); + ExecutionContext exe_ctx(m_opaque_sp.get()); StackFrame *frame = exe_ctx.GetFramePtr(); Target *target = exe_ctx.GetTargetPtr(); if (frame && target) @@ -602,109 +566,113 @@ SBFrame::FindValue (const char *name, ValueType value_type, lldb::DynamicValueTy { SBValue sb_value; ValueObjectSP value_sp; - ExecutionContext exe_ctx(GetFrameSP()); + ExecutionContext exe_ctx(m_opaque_sp.get()); StackFrame *frame = exe_ctx.GetFramePtr(); Target *target = exe_ctx.GetTargetPtr(); if (frame && target && name && name[0]) { - Mutex::Locker api_locker (target->GetAPIMutex()); - - switch (value_type) + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { - case eValueTypeVariableGlobal: // global variable - case eValueTypeVariableStatic: // static variable - case eValueTypeVariableArgument: // function argument variables - case eValueTypeVariableLocal: // function local variables + Mutex::Locker api_locker (target->GetAPIMutex()); + + switch (value_type) { - VariableList *variable_list = frame->GetVariableList(true); + case eValueTypeVariableGlobal: // global variable + case eValueTypeVariableStatic: // static variable + case eValueTypeVariableArgument: // function argument variables + case eValueTypeVariableLocal: // function local variables + { + VariableList *variable_list = frame->GetVariableList(true); - SymbolContext sc (frame->GetSymbolContext (eSymbolContextBlock)); + SymbolContext sc (frame->GetSymbolContext (eSymbolContextBlock)); - const bool can_create = true; - const bool get_parent_variables = true; - const bool stop_if_block_is_inlined_function = true; + const bool can_create = true; + const bool get_parent_variables = true; + const bool stop_if_block_is_inlined_function = true; - if (sc.block && sc.block->AppendVariables (can_create, - get_parent_variables, - stop_if_block_is_inlined_function, - variable_list)) + if (sc.block && sc.block->AppendVariables (can_create, + get_parent_variables, + stop_if_block_is_inlined_function, + variable_list)) + { + ConstString const_name(name); + const uint32_t num_variables = variable_list->GetSize(); + for (uint32_t i = 0; i < num_variables; ++i) + { + VariableSP variable_sp (variable_list->GetVariableAtIndex(i)); + if (variable_sp && + variable_sp->GetScope() == value_type && + variable_sp->GetName() == const_name) + { + value_sp = frame->GetValueObjectForFrameVariable (variable_sp, use_dynamic); + sb_value.SetSP (value_sp); + break; + } + } + } + } + break; + + case eValueTypeRegister: // stack frame register value + { + RegisterContextSP reg_ctx (frame->GetRegisterContext()); + if (reg_ctx) + { + const uint32_t num_regs = reg_ctx->GetRegisterCount(); + for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx) + { + const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex (reg_idx); + if (reg_info && + ((reg_info->name && strcasecmp (reg_info->name, name) == 0) || + (reg_info->alt_name && strcasecmp (reg_info->alt_name, name) == 0))) + { + value_sp = ValueObjectRegister::Create (frame, reg_ctx, reg_idx); + sb_value.SetSP (value_sp); + break; + } + } + } + } + break; + + case eValueTypeRegisterSet: // A collection of stack frame register values + { + RegisterContextSP reg_ctx (frame->GetRegisterContext()); + if (reg_ctx) + { + const uint32_t num_sets = reg_ctx->GetRegisterSetCount(); + for (uint32_t set_idx = 0; set_idx < num_sets; ++set_idx) + { + const RegisterSet *reg_set = reg_ctx->GetRegisterSet (set_idx); + if (reg_set && + ((reg_set->name && strcasecmp (reg_set->name, name) == 0) || + (reg_set->short_name && strcasecmp (reg_set->short_name, name) == 0))) + { + value_sp = ValueObjectRegisterSet::Create (frame, reg_ctx, set_idx); + sb_value.SetSP (value_sp); + break; + } + } + } + } + break; + + case eValueTypeConstResult: // constant result variables { ConstString const_name(name); - const uint32_t num_variables = variable_list->GetSize(); - for (uint32_t i = 0; i < num_variables; ++i) + ClangExpressionVariableSP expr_var_sp (target->GetPersistentVariables().GetVariable (const_name)); + if (expr_var_sp) { - VariableSP variable_sp (variable_list->GetVariableAtIndex(i)); - if (variable_sp && - variable_sp->GetScope() == value_type && - variable_sp->GetName() == const_name) - { - value_sp = frame->GetValueObjectForFrameVariable (variable_sp, use_dynamic); - sb_value.SetSP (value_sp); - break; - } + value_sp = expr_var_sp->GetValueObject(); + sb_value.SetSP (value_sp); } } - } - break; + break; - case eValueTypeRegister: // stack frame register value - { - RegisterContextSP reg_ctx (frame->GetRegisterContext()); - if (reg_ctx) - { - const uint32_t num_regs = reg_ctx->GetRegisterCount(); - for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx) - { - const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex (reg_idx); - if (reg_info && - ((reg_info->name && strcasecmp (reg_info->name, name) == 0) || - (reg_info->alt_name && strcasecmp (reg_info->alt_name, name) == 0))) - { - value_sp = ValueObjectRegister::Create (frame, reg_ctx, reg_idx); - sb_value.SetSP (value_sp); - break; - } - } - } + default: + break; } - break; - - case eValueTypeRegisterSet: // A collection of stack frame register values - { - RegisterContextSP reg_ctx (frame->GetRegisterContext()); - if (reg_ctx) - { - const uint32_t num_sets = reg_ctx->GetRegisterSetCount(); - for (uint32_t set_idx = 0; set_idx < num_sets; ++set_idx) - { - const RegisterSet *reg_set = reg_ctx->GetRegisterSet (set_idx); - if (reg_set && - ((reg_set->name && strcasecmp (reg_set->name, name) == 0) || - (reg_set->short_name && strcasecmp (reg_set->short_name, name) == 0))) - { - value_sp = ValueObjectRegisterSet::Create (frame, reg_ctx, set_idx); - sb_value.SetSP (value_sp); - break; - } - } - } - } - break; - - case eValueTypeConstResult: // constant result variables - { - ConstString const_name(name); - ClangExpressionVariableSP expr_var_sp (target->GetPersistentVariables().GetVariable (const_name)); - if (expr_var_sp) - { - value_sp = expr_var_sp->GetValueObject(); - sb_value.SetSP (value_sp); - } - } - break; - - default: - break; } } @@ -742,7 +710,7 @@ SBFrame::GetThread () const { LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); - ExecutionContext exe_ctx(GetFrameSP()); + ExecutionContext exe_ctx(m_opaque_sp.get()); ThreadSP thread_sp (exe_ctx.GetThreadSP()); SBThread sb_thread (thread_sp); @@ -763,13 +731,17 @@ const char * SBFrame::Disassemble () const { const char *disassembly = NULL; - ExecutionContext exe_ctx(GetFrameSP()); + ExecutionContext exe_ctx(m_opaque_sp.get()); StackFrame *frame = exe_ctx.GetFramePtr(); Target *target = exe_ctx.GetTargetPtr(); if (frame && target) { - Mutex::Locker api_locker (target->GetAPIMutex()); - disassembly = frame->Disassemble(); + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) + { + Mutex::Locker api_locker (target->GetAPIMutex()); + disassembly = frame->Disassemble(); + } } LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); @@ -787,7 +759,7 @@ SBFrame::GetVariables (bool arguments, bool in_scope_only) { SBValueList value_list; - ExecutionContext exe_ctx(GetFrameSP()); + ExecutionContext exe_ctx(m_opaque_sp.get()); StackFrame *frame = exe_ctx.GetFramePtr(); Target *target = exe_ctx.GetTargetPtr(); if (frame && target) @@ -808,7 +780,7 @@ SBFrame::GetVariables (bool arguments, LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); SBValueList value_list; - ExecutionContext exe_ctx(GetFrameSP()); + ExecutionContext exe_ctx(m_opaque_sp.get()); StackFrame *frame = exe_ctx.GetFramePtr(); Target *target = exe_ctx.GetTargetPtr(); @@ -822,54 +794,58 @@ SBFrame::GetVariables (bool arguments, if (frame && target) { + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) + { - size_t i; - VariableList *variable_list = NULL; - // Scope for locker - { - Mutex::Locker api_locker (target->GetAPIMutex()); - variable_list = frame->GetVariableList(true); - } - if (variable_list) - { - const size_t num_variables = variable_list->GetSize(); - if (num_variables) + size_t i; + VariableList *variable_list = NULL; + // Scope for locker { - for (i = 0; i < num_variables; ++i) + Mutex::Locker api_locker (target->GetAPIMutex()); + variable_list = frame->GetVariableList(true); + } + if (variable_list) + { + const size_t num_variables = variable_list->GetSize(); + if (num_variables) { - VariableSP variable_sp (variable_list->GetVariableAtIndex(i)); - if (variable_sp) + for (i = 0; i < num_variables; ++i) { - bool add_variable = false; - switch (variable_sp->GetScope()) + VariableSP variable_sp (variable_list->GetVariableAtIndex(i)); + if (variable_sp) { - case eValueTypeVariableGlobal: - case eValueTypeVariableStatic: - add_variable = statics; - break; + bool add_variable = false; + switch (variable_sp->GetScope()) + { + case eValueTypeVariableGlobal: + case eValueTypeVariableStatic: + add_variable = statics; + break; - case eValueTypeVariableArgument: - add_variable = arguments; - break; + case eValueTypeVariableArgument: + add_variable = arguments; + break; - case eValueTypeVariableLocal: - add_variable = locals; - break; + case eValueTypeVariableLocal: + add_variable = locals; + break; - default: - break; - } - if (add_variable) - { - if (in_scope_only && !variable_sp->IsInScope(frame)) - continue; + default: + break; + } + if (add_variable) + { + if (in_scope_only && !variable_sp->IsInScope(frame)) + continue; - value_list.Append(frame->GetValueObjectForFrameVariable (variable_sp, use_dynamic)); + value_list.Append(frame->GetValueObjectForFrameVariable (variable_sp, use_dynamic)); + } } } } } - } + } } if (log) @@ -887,19 +863,23 @@ SBFrame::GetRegisters () LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); SBValueList value_list; - ExecutionContext exe_ctx(GetFrameSP()); + ExecutionContext exe_ctx(m_opaque_sp.get()); StackFrame *frame = exe_ctx.GetFramePtr(); Target *target = exe_ctx.GetTargetPtr(); if (frame && target) { - Mutex::Locker api_locker (target->GetAPIMutex()); - RegisterContextSP reg_ctx (frame->GetRegisterContext()); - if (reg_ctx) + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { - const uint32_t num_sets = reg_ctx->GetRegisterSetCount(); - for (uint32_t set_idx = 0; set_idx < num_sets; ++set_idx) + Mutex::Locker api_locker (target->GetAPIMutex()); + RegisterContextSP reg_ctx (frame->GetRegisterContext()); + if (reg_ctx) { - value_list.Append(ValueObjectRegisterSet::Create (frame, reg_ctx, set_idx)); + const uint32_t num_sets = reg_ctx->GetRegisterSetCount(); + for (uint32_t set_idx = 0; set_idx < num_sets; ++set_idx) + { + value_list.Append(ValueObjectRegisterSet::Create (frame, reg_ctx, set_idx)); + } } } } @@ -915,13 +895,17 @@ SBFrame::GetDescription (SBStream &description) { Stream &strm = description.ref(); - ExecutionContext exe_ctx(GetFrameSP()); + ExecutionContext exe_ctx(m_opaque_sp.get()); StackFrame *frame = exe_ctx.GetFramePtr(); Target *target = exe_ctx.GetTargetPtr(); if (frame && target) { - Mutex::Locker api_locker (target->GetAPIMutex()); - frame->DumpUsingSettingsFormat (&strm); + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) + { + Mutex::Locker api_locker (target->GetAPIMutex()); + frame->DumpUsingSettingsFormat (&strm); + } } else strm.PutCString ("No value"); @@ -933,7 +917,7 @@ SBValue SBFrame::EvaluateExpression (const char *expr) { SBValue result; - ExecutionContext exe_ctx(GetFrameSP()); + ExecutionContext exe_ctx(m_opaque_sp.get()); StackFrame *frame = exe_ctx.GetFramePtr(); Target *target = exe_ctx.GetTargetPtr(); if (frame && target) @@ -955,7 +939,7 @@ SBFrame::EvaluateExpression (const char *expr, lldb::DynamicValueType fetch_dyna SBValue expr_result; ValueObjectSP expr_value_sp; - ExecutionContext exe_ctx(GetFrameSP()); + ExecutionContext exe_ctx(m_opaque_sp.get()); StackFrame *frame = exe_ctx.GetFramePtr(); Target *target = exe_ctx.GetTargetPtr(); if (log) @@ -963,29 +947,34 @@ SBFrame::EvaluateExpression (const char *expr, lldb::DynamicValueType fetch_dyna if (frame && target) { - Mutex::Locker api_locker (target->GetAPIMutex()); - - - StreamString frame_description; - frame->DumpUsingSettingsFormat (&frame_description); + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) + { - Host::SetCrashDescriptionWithFormat ("SBFrame::EvaluateExpression (expr = \"%s\", fetch_dynamic_value = %u) %s", - expr, fetch_dynamic_value, frame_description.GetString().c_str()); + Mutex::Locker api_locker (target->GetAPIMutex()); + + + StreamString frame_description; + frame->DumpUsingSettingsFormat (&frame_description); - const bool coerce_to_id = false; - const bool unwind_on_error = true; - const bool keep_in_memory = false; + Host::SetCrashDescriptionWithFormat ("SBFrame::EvaluateExpression (expr = \"%s\", fetch_dynamic_value = %u) %s", + expr, fetch_dynamic_value, frame_description.GetString().c_str()); - exe_results = target->EvaluateExpression (expr, - frame, - eExecutionPolicyOnlyWhenNeeded, - coerce_to_id, - unwind_on_error, - keep_in_memory, - fetch_dynamic_value, - expr_value_sp); - expr_result.SetSP(expr_value_sp); - Host::SetCrashDescription (NULL); + const bool coerce_to_id = false; + const bool unwind_on_error = true; + const bool keep_in_memory = false; + + exe_results = target->EvaluateExpression (expr, + frame, + eExecutionPolicyOnlyWhenNeeded, + coerce_to_id, + unwind_on_error, + keep_in_memory, + fetch_dynamic_value, + expr_value_sp); + expr_result.SetSP(expr_value_sp); + Host::SetCrashDescription (NULL); + } } #ifndef LLDB_DISABLE_PYTHON @@ -1008,14 +997,19 @@ SBFrame::EvaluateExpression (const char *expr, lldb::DynamicValueType fetch_dyna bool SBFrame::IsInlined() { - ExecutionContext exe_ctx(GetFrameSP()); + ExecutionContext exe_ctx(m_opaque_sp.get()); StackFrame *frame = exe_ctx.GetFramePtr(); Target *target = exe_ctx.GetTargetPtr(); if (frame && target) { - Block *block = frame->GetSymbolContext(eSymbolContextBlock).block; - if (block) - return block->GetContainingInlinedBlock () != NULL; + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) + { + + Block *block = frame->GetSymbolContext(eSymbolContextBlock).block; + if (block) + return block->GetContainingInlinedBlock () != NULL; + } } return false; } @@ -1024,32 +1018,36 @@ const char * SBFrame::GetFunctionName() { const char *name = NULL; - ExecutionContext exe_ctx(GetFrameSP()); + ExecutionContext exe_ctx(m_opaque_sp.get()); StackFrame *frame = exe_ctx.GetFramePtr(); Target *target = exe_ctx.GetTargetPtr(); if (frame && target) { - SymbolContext sc (frame->GetSymbolContext(eSymbolContextFunction | eSymbolContextBlock | eSymbolContextSymbol)); - if (sc.block) + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { - Block *inlined_block = sc.block->GetContainingInlinedBlock (); - if (inlined_block) + SymbolContext sc (frame->GetSymbolContext(eSymbolContextFunction | eSymbolContextBlock | eSymbolContextSymbol)); + if (sc.block) { - const InlineFunctionInfo* inlined_info = inlined_block->GetInlinedFunctionInfo(); - name = inlined_info->GetName().AsCString(); + Block *inlined_block = sc.block->GetContainingInlinedBlock (); + if (inlined_block) + { + const InlineFunctionInfo* inlined_info = inlined_block->GetInlinedFunctionInfo(); + name = inlined_info->GetName().AsCString(); + } + } + + if (name == NULL) + { + if (sc.function) + name = sc.function->GetName().GetCString(); } - } - - if (name == NULL) - { - if (sc.function) - name = sc.function->GetName().GetCString(); - } - if (name == NULL) - { - if (sc.symbol) - name = sc.symbol->GetName().GetCString(); + if (name == NULL) + { + if (sc.symbol) + name = sc.symbol->GetName().GetCString(); + } } } return name; diff --git a/lldb/source/API/SBProcess.cpp b/lldb/source/API/SBProcess.cpp index ae7f4de66583..ee87924a9a9c 100644 --- a/lldb/source/API/SBProcess.cpp +++ b/lldb/source/API/SBProcess.cpp @@ -134,28 +134,37 @@ SBProcess::RemoteLaunch (char const **argv, ProcessSP process_sp(GetSP()); if (process_sp) { - Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); - if (process_sp->GetState() == eStateConnected) + Process::StopLocker stop_locker; + + if (stop_locker.TryLock(&process_sp->GetRunLock())) { - if (stop_at_entry) - launch_flags |= eLaunchFlagStopAtEntry; - ProcessLaunchInfo launch_info (stdin_path, - stdout_path, - stderr_path, - working_directory, - launch_flags); - Module *exe_module = process_sp->GetTarget().GetExecutableModulePointer(); - if (exe_module) - launch_info.SetExecutableFile(exe_module->GetFileSpec(), true); - if (argv) - launch_info.GetArguments().AppendArguments (argv); - if (envp) - launch_info.GetEnvironmentEntries ().SetArguments (envp); - error.SetError (process_sp->Launch (launch_info)); + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + if (process_sp->GetState() == eStateConnected) + { + if (stop_at_entry) + launch_flags |= eLaunchFlagStopAtEntry; + ProcessLaunchInfo launch_info (stdin_path, + stdout_path, + stderr_path, + working_directory, + launch_flags); + Module *exe_module = process_sp->GetTarget().GetExecutableModulePointer(); + if (exe_module) + launch_info.SetExecutableFile(exe_module->GetFileSpec(), true); + if (argv) + launch_info.GetArguments().AppendArguments (argv); + if (envp) + launch_info.GetEnvironmentEntries ().SetArguments (envp); + error.SetError (process_sp->Launch (launch_info)); + } + else + { + error.SetErrorString ("must be in eStateConnected to call RemoteLaunch"); + } } else { - error.SetErrorString ("must be in eStateConnected to call RemoteLaunch"); + error.SetErrorString ("process is running"); } } else @@ -178,16 +187,25 @@ SBProcess::RemoteAttachToProcessWithID (lldb::pid_t pid, lldb::SBError& error) ProcessSP process_sp(GetSP()); if (process_sp) { - Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); - if (process_sp->GetState() == eStateConnected) + Process::StopLocker stop_locker; + + if (stop_locker.TryLock(&process_sp->GetRunLock())) { - ProcessAttachInfo attach_info; - attach_info.SetProcessID (pid); - error.SetError (process_sp->Attach (attach_info)); + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + if (process_sp->GetState() == eStateConnected) + { + ProcessAttachInfo attach_info; + attach_info.SetProcessID (pid); + error.SetError (process_sp->Attach (attach_info)); + } + else + { + error.SetErrorString ("must be in eStateConnected to call RemoteAttachToProcessWithID"); + } } else { - error.SetErrorString ("must be in eStateConnected to call RemoteAttachToProcessWithID"); + error.SetErrorString ("process is running"); } } else @@ -215,8 +233,10 @@ SBProcess::GetNumThreads () ProcessSP process_sp(GetSP()); if (process_sp) { + Process::StopLocker stop_locker; + + const bool can_update = stop_locker.TryLock(&process_sp->GetRunLock()); Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); - const bool can_update = true; num_threads = process_sp->GetThreadList().GetSize(can_update); } @@ -413,8 +433,10 @@ SBProcess::GetThreadAtIndex (size_t index) ProcessSP process_sp(GetSP()); if (process_sp) { + Process::StopLocker stop_locker; + const bool can_update = stop_locker.TryLock(&process_sp->GetRunLock()); Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); - thread_sp = process_sp->GetThreadList().GetThreadAtIndex(index); + thread_sp = process_sp->GetThreadList().GetThreadAtIndex(index, can_update); sb_thread.SetThread (thread_sp); } @@ -703,7 +725,9 @@ SBProcess::GetThreadByID (tid_t tid) if (process_sp) { Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); - thread_sp = process_sp->GetThreadList().FindThreadByID (tid); + Process::StopLocker stop_locker; + const bool can_update = stop_locker.TryLock(&process_sp->GetRunLock()); + thread_sp = process_sp->GetThreadList().FindThreadByID (tid, can_update); sb_thread.SetThread (thread_sp); } @@ -795,10 +819,16 @@ SBProcess::ReadMemory (addr_t addr, void *dst, size_t dst_len, SBError &sb_error if (process_sp) { - Error error; - Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); - bytes_read = process_sp->ReadMemory (addr, dst, dst_len, error); - sb_error.SetError (error); + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&process_sp->GetRunLock())) + { + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + bytes_read = process_sp->ReadMemory (addr, dst, dst_len, sb_error.ref()); + } + else + { + sb_error.SetErrorString("process is running"); + } } else { @@ -829,10 +859,16 @@ SBProcess::ReadCStringFromMemory (addr_t addr, void *buf, size_t size, lldb::SBE ProcessSP process_sp(GetSP()); if (process_sp) { - Error error; - Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); - bytes_read = process_sp->ReadCStringFromMemory (addr, (char *)buf, size, error); - sb_error.SetError (error); + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&process_sp->GetRunLock())) + { + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + bytes_read = process_sp->ReadCStringFromMemory (addr, (char *)buf, size, sb_error.ref()); + } + else + { + sb_error.SetErrorString("process is running"); + } } else { @@ -844,20 +880,26 @@ SBProcess::ReadCStringFromMemory (addr_t addr, void *buf, size_t size, lldb::SBE uint64_t SBProcess::ReadUnsignedFromMemory (addr_t addr, uint32_t byte_size, lldb::SBError &sb_error) { + uint64_t value = 0; ProcessSP process_sp(GetSP()); if (process_sp) { - Error error; - Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); - uint64_t value = process_sp->ReadUnsignedIntegerFromMemory (addr, byte_size, 0, error); - sb_error.SetError (error); - return value; + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&process_sp->GetRunLock())) + { + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + value = process_sp->ReadUnsignedIntegerFromMemory (addr, byte_size, 0, sb_error.ref()); + } + else + { + sb_error.SetErrorString("process is running"); + } } else { sb_error.SetErrorString ("SBProcess is invalid"); } - return 0; + return value; } lldb::addr_t @@ -867,10 +909,16 @@ SBProcess::ReadPointerFromMemory (addr_t addr, lldb::SBError &sb_error) ProcessSP process_sp(GetSP()); if (process_sp) { - Error error; - Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); - ptr = process_sp->ReadPointerFromMemory (addr, error); - sb_error.SetError (error); + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&process_sp->GetRunLock())) + { + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + ptr = process_sp->ReadPointerFromMemory (addr, sb_error.ref()); + } + else + { + sb_error.SetErrorString("process is running"); + } } else { @@ -900,10 +948,16 @@ SBProcess::WriteMemory (addr_t addr, const void *src, size_t src_len, SBError &s if (process_sp) { - Error error; - Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); - bytes_written = process_sp->WriteMemory (addr, src, src_len, error); - sb_error.SetError (error); + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&process_sp->GetRunLock())) + { + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + bytes_written = process_sp->WriteMemory (addr, src, src_len, sb_error.ref()); + } + else + { + sb_error.SetErrorString("process is running"); + } } if (log) @@ -957,8 +1011,16 @@ SBProcess::LoadImage (lldb::SBFileSpec &sb_image_spec, lldb::SBError &sb_error) ProcessSP process_sp(GetSP()); if (process_sp) { - Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); - return process_sp->LoadImage (*sb_image_spec, sb_error.ref()); + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&process_sp->GetRunLock())) + { + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + return process_sp->LoadImage (*sb_image_spec, sb_error.ref()); + } + else + { + sb_error.SetErrorString("process is running"); + } } return LLDB_INVALID_IMAGE_TOKEN; } @@ -970,8 +1032,16 @@ SBProcess::UnloadImage (uint32_t image_token) ProcessSP process_sp(GetSP()); if (process_sp) { - Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); - sb_error.SetError (process_sp->UnloadImage (image_token)); + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&process_sp->GetRunLock())) + { + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + sb_error.SetError (process_sp->UnloadImage (image_token)); + } + else + { + sb_error.SetErrorString("process is running"); + } } else sb_error.SetErrorString("invalid process"); diff --git a/lldb/source/API/SBThread.cpp b/lldb/source/API/SBThread.cpp index ff2a68ca1355..510f7420a494 100644 --- a/lldb/source/API/SBThread.cpp +++ b/lldb/source/API/SBThread.cpp @@ -43,18 +43,19 @@ using namespace lldb_private; // Constructors //---------------------------------------------------------------------- SBThread::SBThread () : - m_opaque_wp () + m_opaque_sp (new ExecutionContextRef()) { } SBThread::SBThread (const ThreadSP& lldb_object_sp) : - m_opaque_wp (lldb_object_sp) + m_opaque_sp (new ExecutionContextRef(lldb_object_sp)) { } SBThread::SBThread (const SBThread &rhs) : - m_opaque_wp (rhs.m_opaque_wp) + m_opaque_sp (new ExecutionContextRef(*rhs.m_opaque_sp)) { + } //---------------------------------------------------------------------- @@ -65,7 +66,7 @@ const lldb::SBThread & SBThread::operator = (const SBThread &rhs) { if (this != &rhs) - m_opaque_wp = rhs.m_opaque_wp; + *m_opaque_sp = *rhs.m_opaque_sp; return *this; } @@ -79,13 +80,13 @@ SBThread::~SBThread() bool SBThread::IsValid() const { - return !m_opaque_wp.expired(); + return m_opaque_sp->GetThreadSP().get() != NULL; } void SBThread::Clear () { - m_opaque_wp.reset(); + m_opaque_sp->Clear(); } @@ -95,13 +96,17 @@ SBThread::GetStopReason() LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); StopReason reason = eStopReasonInvalid; - ExecutionContext exe_ctx (m_opaque_wp); + ExecutionContext exe_ctx (m_opaque_sp.get()); if (exe_ctx.HasThreadScope()) { - Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex()); - StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo (); - if (stop_info_sp) - reason = stop_info_sp->GetStopReason(); + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) + { + Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex()); + StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo (); + if (stop_info_sp) + reason = stop_info_sp->GetStopReason(); + } } if (log) @@ -114,42 +119,46 @@ SBThread::GetStopReason() size_t SBThread::GetStopReasonDataCount () { - ExecutionContext exe_ctx (m_opaque_wp); + ExecutionContext exe_ctx (m_opaque_sp.get()); if (exe_ctx.HasThreadScope()) { - Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex()); - StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo (); - if (stop_info_sp) + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { - StopReason reason = stop_info_sp->GetStopReason(); - switch (reason) + Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex()); + StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo (); + if (stop_info_sp) { - case eStopReasonInvalid: - case eStopReasonNone: - case eStopReasonTrace: - case eStopReasonPlanComplete: - // There is no data for these stop reasons. - return 0; - - case eStopReasonBreakpoint: + StopReason reason = stop_info_sp->GetStopReason(); + switch (reason) { - break_id_t site_id = stop_info_sp->GetValue(); - lldb::BreakpointSiteSP bp_site_sp (exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID (site_id)); - if (bp_site_sp) - return bp_site_sp->GetNumberOfOwners () * 2; - else - return 0; // Breakpoint must have cleared itself... + case eStopReasonInvalid: + case eStopReasonNone: + case eStopReasonTrace: + case eStopReasonPlanComplete: + // There is no data for these stop reasons. + return 0; + + case eStopReasonBreakpoint: + { + break_id_t site_id = stop_info_sp->GetValue(); + lldb::BreakpointSiteSP bp_site_sp (exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID (site_id)); + if (bp_site_sp) + return bp_site_sp->GetNumberOfOwners () * 2; + else + return 0; // Breakpoint must have cleared itself... + } + break; + + case eStopReasonWatchpoint: + return 1; + + case eStopReasonSignal: + return 1; + + case eStopReasonException: + return 1; } - break; - - case eStopReasonWatchpoint: - return 1; - - case eStopReasonSignal: - return 1; - - case eStopReasonException: - return 1; } } } @@ -159,58 +168,63 @@ SBThread::GetStopReasonDataCount () uint64_t SBThread::GetStopReasonDataAtIndex (uint32_t idx) { - ExecutionContext exe_ctx (m_opaque_wp); + ExecutionContext exe_ctx (m_opaque_sp.get()); if (exe_ctx.HasThreadScope()) { - Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex()); - Thread *thread = exe_ctx.GetThreadPtr(); - StopInfoSP stop_info_sp = thread->GetStopInfo (); - if (stop_info_sp) + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { - StopReason reason = stop_info_sp->GetStopReason(); - switch (reason) - { - case eStopReasonInvalid: - case eStopReasonNone: - case eStopReasonTrace: - case eStopReasonPlanComplete: - // There is no data for these stop reasons. - return 0; - case eStopReasonBreakpoint: + Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex()); + Thread *thread = exe_ctx.GetThreadPtr(); + StopInfoSP stop_info_sp = thread->GetStopInfo (); + if (stop_info_sp) + { + StopReason reason = stop_info_sp->GetStopReason(); + switch (reason) { - break_id_t site_id = stop_info_sp->GetValue(); - lldb::BreakpointSiteSP bp_site_sp (exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID (site_id)); - if (bp_site_sp) + case eStopReasonInvalid: + case eStopReasonNone: + case eStopReasonTrace: + case eStopReasonPlanComplete: + // There is no data for these stop reasons. + return 0; + + case eStopReasonBreakpoint: { - uint32_t bp_index = idx / 2; - BreakpointLocationSP bp_loc_sp (bp_site_sp->GetOwnerAtIndex (bp_index)); - if (bp_loc_sp) + break_id_t site_id = stop_info_sp->GetValue(); + lldb::BreakpointSiteSP bp_site_sp (exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID (site_id)); + if (bp_site_sp) { - if (bp_index & 1) + uint32_t bp_index = idx / 2; + BreakpointLocationSP bp_loc_sp (bp_site_sp->GetOwnerAtIndex (bp_index)); + if (bp_loc_sp) { - // Odd idx, return the breakpoint location ID - return bp_loc_sp->GetID(); - } - else - { - // Even idx, return the breakpoint ID - return bp_loc_sp->GetBreakpoint().GetID(); + if (bp_index & 1) + { + // Odd idx, return the breakpoint location ID + return bp_loc_sp->GetID(); + } + else + { + // Even idx, return the breakpoint ID + return bp_loc_sp->GetBreakpoint().GetID(); + } } } + return LLDB_INVALID_BREAK_ID; } - return LLDB_INVALID_BREAK_ID; + break; + + case eStopReasonWatchpoint: + return stop_info_sp->GetValue(); + + case eStopReasonSignal: + return stop_info_sp->GetValue(); + + case eStopReasonException: + return stop_info_sp->GetValue(); } - break; - - case eStopReasonWatchpoint: - return stop_info_sp->GetValue(); - - case eStopReasonSignal: - return stop_info_sp->GetValue(); - - case eStopReasonException: - return stop_info_sp->GetValue(); } } } @@ -222,94 +236,99 @@ SBThread::GetStopDescription (char *dst, size_t dst_len) { LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); - ExecutionContext exe_ctx (m_opaque_wp); + ExecutionContext exe_ctx (m_opaque_sp.get()); if (exe_ctx.HasThreadScope()) { - Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex()); - StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo (); - if (stop_info_sp) + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { - const char *stop_desc = stop_info_sp->GetDescription(); - if (stop_desc) + + Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex()); + StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo (); + if (stop_info_sp) { - if (log) - log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => \"%s\"", - exe_ctx.GetThreadPtr(), stop_desc); - if (dst) - return ::snprintf (dst, dst_len, "%s", stop_desc); - else - { - // NULL dst passed in, return the length needed to contain the description - return ::strlen (stop_desc) + 1; // Include the NULL byte for size - } - } - else - { - size_t stop_desc_len = 0; - switch (stop_info_sp->GetStopReason()) - { - case eStopReasonTrace: - case eStopReasonPlanComplete: - { - static char trace_desc[] = "step"; - stop_desc = trace_desc; - stop_desc_len = sizeof(trace_desc); // Include the NULL byte for size - } - break; - - case eStopReasonBreakpoint: - { - static char bp_desc[] = "breakpoint hit"; - stop_desc = bp_desc; - stop_desc_len = sizeof(bp_desc); // Include the NULL byte for size - } - break; - - case eStopReasonWatchpoint: - { - static char wp_desc[] = "watchpoint hit"; - stop_desc = wp_desc; - stop_desc_len = sizeof(wp_desc); // Include the NULL byte for size - } - break; - - case eStopReasonSignal: - { - stop_desc = exe_ctx.GetProcessPtr()->GetUnixSignals ().GetSignalAsCString (stop_info_sp->GetValue()); - if (stop_desc == NULL || stop_desc[0] == '\0') - { - static char signal_desc[] = "signal"; - stop_desc = signal_desc; - stop_desc_len = sizeof(signal_desc); // Include the NULL byte for size - } - } - break; - - case eStopReasonException: - { - char exc_desc[] = "exception"; - stop_desc = exc_desc; - stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size - } - break; - - default: - break; - } - - if (stop_desc && stop_desc[0]) + const char *stop_desc = stop_info_sp->GetDescription(); + if (stop_desc) { if (log) - log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => '%s'", + log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => \"%s\"", exe_ctx.GetThreadPtr(), stop_desc); - if (dst) - return ::snprintf (dst, dst_len, "%s", stop_desc) + 1; // Include the NULL byte + return ::snprintf (dst, dst_len, "%s", stop_desc); + else + { + // NULL dst passed in, return the length needed to contain the description + return ::strlen (stop_desc) + 1; // Include the NULL byte for size + } + } + else + { + size_t stop_desc_len = 0; + switch (stop_info_sp->GetStopReason()) + { + case eStopReasonTrace: + case eStopReasonPlanComplete: + { + static char trace_desc[] = "step"; + stop_desc = trace_desc; + stop_desc_len = sizeof(trace_desc); // Include the NULL byte for size + } + break; - if (stop_desc_len == 0) - stop_desc_len = ::strlen (stop_desc) + 1; // Include the NULL byte - - return stop_desc_len; + case eStopReasonBreakpoint: + { + static char bp_desc[] = "breakpoint hit"; + stop_desc = bp_desc; + stop_desc_len = sizeof(bp_desc); // Include the NULL byte for size + } + break; + + case eStopReasonWatchpoint: + { + static char wp_desc[] = "watchpoint hit"; + stop_desc = wp_desc; + stop_desc_len = sizeof(wp_desc); // Include the NULL byte for size + } + break; + + case eStopReasonSignal: + { + stop_desc = exe_ctx.GetProcessPtr()->GetUnixSignals ().GetSignalAsCString (stop_info_sp->GetValue()); + if (stop_desc == NULL || stop_desc[0] == '\0') + { + static char signal_desc[] = "signal"; + stop_desc = signal_desc; + stop_desc_len = sizeof(signal_desc); // Include the NULL byte for size + } + } + break; + + case eStopReasonException: + { + char exc_desc[] = "exception"; + stop_desc = exc_desc; + stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size + } + break; + + default: + break; + } + + if (stop_desc && stop_desc[0]) + { + if (log) + log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => '%s'", + exe_ctx.GetThreadPtr(), stop_desc); + + if (dst) + return ::snprintf (dst, dst_len, "%s", stop_desc) + 1; // Include the NULL byte + + if (stop_desc_len == 0) + stop_desc_len = ::strlen (stop_desc) + 1; // Include the NULL byte + + return stop_desc_len; + } } } } @@ -323,14 +342,18 @@ SBValue SBThread::GetStopReturnValue () { ValueObjectSP return_valobj_sp; - ExecutionContext exe_ctx (m_opaque_wp); + ExecutionContext exe_ctx (m_opaque_sp.get()); if (exe_ctx.HasThreadScope()) { - Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex()); - StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo (); - if (stop_info_sp) + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { - return_valobj_sp = StopInfo::GetReturnValueObject (stop_info_sp); + Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex()); + StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo (); + if (stop_info_sp) + { + return_valobj_sp = StopInfo::GetReturnValueObject (stop_info_sp); + } } } @@ -347,14 +370,14 @@ SBThread::GetStopReturnValue () void SBThread::SetThread (const ThreadSP& lldb_object_sp) { - m_opaque_wp = lldb_object_sp; + m_opaque_sp->SetThreadSP (lldb_object_sp); } lldb::tid_t SBThread::GetThreadID () const { - ThreadSP thread_sp(m_opaque_wp.lock()); + ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); if (thread_sp) return thread_sp->GetID(); return LLDB_INVALID_THREAD_ID; @@ -363,7 +386,7 @@ SBThread::GetThreadID () const uint32_t SBThread::GetIndexID () const { - ThreadSP thread_sp(m_opaque_wp.lock()); + ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); if (thread_sp) return thread_sp->GetIndexID(); return LLDB_INVALID_INDEX32; @@ -373,11 +396,15 @@ const char * SBThread::GetName () const { const char *name = NULL; - ExecutionContext exe_ctx (m_opaque_wp); + ExecutionContext exe_ctx (m_opaque_sp.get()); if (exe_ctx.HasThreadScope()) { - Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex()); - name = exe_ctx.GetThreadPtr()->GetName(); + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) + { + Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex()); + name = exe_ctx.GetThreadPtr()->GetName(); + } } LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); @@ -391,11 +418,15 @@ const char * SBThread::GetQueueName () const { const char *name = NULL; - ExecutionContext exe_ctx (m_opaque_wp); + ExecutionContext exe_ctx (m_opaque_sp.get()); if (exe_ctx.HasThreadScope()) { - Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex()); - name = exe_ctx.GetThreadPtr()->GetQueueName(); + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) + { + Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex()); + name = exe_ctx.GetThreadPtr()->GetQueueName(); + } } LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); @@ -411,7 +442,7 @@ SBThread::StepOver (lldb::RunMode stop_other_threads) { LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); - ExecutionContext exe_ctx (m_opaque_wp); + ExecutionContext exe_ctx (m_opaque_sp.get()); if (log) log->Printf ("SBThread(%p)::StepOver (stop_other_threads='%s')", exe_ctx.GetThreadPtr(), @@ -464,7 +495,7 @@ SBThread::StepInto (lldb::RunMode stop_other_threads) { LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); - ExecutionContext exe_ctx (m_opaque_wp); + ExecutionContext exe_ctx (m_opaque_sp.get()); if (log) log->Printf ("SBThread(%p)::StepInto (stop_other_threads='%s')", exe_ctx.GetThreadPtr(), @@ -514,7 +545,7 @@ SBThread::StepOut () { LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); - ExecutionContext exe_ctx (m_opaque_wp); + ExecutionContext exe_ctx (m_opaque_sp.get()); if (log) log->Printf ("SBThread(%p)::StepOut ()", exe_ctx.GetThreadPtr()); @@ -553,7 +584,7 @@ SBThread::StepOutOfFrame (lldb::SBFrame &sb_frame) { LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); - ExecutionContext exe_ctx (m_opaque_wp); + ExecutionContext exe_ctx (m_opaque_sp.get()); StackFrameSP frame_sp (sb_frame.GetFrameSP()); if (log) { @@ -595,7 +626,7 @@ SBThread::StepInstruction (bool step_over) { LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); - ExecutionContext exe_ctx (m_opaque_wp); + ExecutionContext exe_ctx (m_opaque_sp.get()); if (log) @@ -624,7 +655,7 @@ SBThread::RunToAddress (lldb::addr_t addr) { LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); - ExecutionContext exe_ctx (m_opaque_wp); + ExecutionContext exe_ctx (m_opaque_sp.get()); if (log) log->Printf ("SBThread(%p)::RunToAddress (addr=0x%llx)", exe_ctx.GetThreadPtr(), addr); @@ -662,7 +693,7 @@ SBThread::StepOverUntil (lldb::SBFrame &sb_frame, LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); char path[PATH_MAX]; - ExecutionContext exe_ctx (m_opaque_wp); + ExecutionContext exe_ctx (m_opaque_sp.get()); StackFrameSP frame_sp (sb_frame.GetFrameSP()); if (log) @@ -815,7 +846,7 @@ SBThread::StepOverUntil (lldb::SBFrame &sb_frame, bool SBThread::Suspend() { - ExecutionContext exe_ctx (m_opaque_wp); + ExecutionContext exe_ctx (m_opaque_sp.get()); if (exe_ctx.HasThreadScope()) { exe_ctx.GetThreadPtr()->SetResumeState (eStateSuspended); @@ -827,7 +858,7 @@ SBThread::Suspend() bool SBThread::Resume () { - ExecutionContext exe_ctx (m_opaque_wp); + ExecutionContext exe_ctx (m_opaque_sp.get()); if (exe_ctx.HasThreadScope()) { exe_ctx.GetThreadPtr()->SetResumeState (eStateRunning); @@ -839,7 +870,7 @@ SBThread::Resume () bool SBThread::IsSuspended() { - ExecutionContext exe_ctx (m_opaque_wp); + ExecutionContext exe_ctx (m_opaque_sp.get()); if (exe_ctx.HasThreadScope()) return exe_ctx.GetThreadPtr()->GetResumeState () == eStateSuspended; return false; @@ -851,7 +882,7 @@ SBThread::GetProcess () SBProcess sb_process; ProcessSP process_sp; - ExecutionContext exe_ctx (m_opaque_wp); + ExecutionContext exe_ctx (m_opaque_sp.get()); if (exe_ctx.HasThreadScope()) { // Have to go up to the target so we can get a shared pointer to our process... @@ -876,11 +907,15 @@ SBThread::GetNumFrames () LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); uint32_t num_frames = 0; - ExecutionContext exe_ctx (m_opaque_wp); + ExecutionContext exe_ctx (m_opaque_sp.get()); if (exe_ctx.HasThreadScope()) { - Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex()); - num_frames = exe_ctx.GetThreadPtr()->GetStackFrameCount(); + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) + { + Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex()); + num_frames = exe_ctx.GetThreadPtr()->GetStackFrameCount(); + } } if (log) @@ -896,12 +931,16 @@ SBThread::GetFrameAtIndex (uint32_t idx) SBFrame sb_frame; StackFrameSP frame_sp; - ExecutionContext exe_ctx (m_opaque_wp); + ExecutionContext exe_ctx (m_opaque_sp.get()); if (exe_ctx.HasThreadScope()) { - Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex()); - frame_sp = exe_ctx.GetThreadPtr()->GetStackFrameAtIndex (idx); - sb_frame.SetFrameSP (frame_sp); + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) + { + Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex()); + frame_sp = exe_ctx.GetThreadPtr()->GetStackFrameAtIndex (idx); + sb_frame.SetFrameSP (frame_sp); + } } if (log) @@ -922,12 +961,16 @@ SBThread::GetSelectedFrame () SBFrame sb_frame; StackFrameSP frame_sp; - ExecutionContext exe_ctx (m_opaque_wp); + ExecutionContext exe_ctx (m_opaque_sp.get()); if (exe_ctx.HasThreadScope()) { - Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex()); - frame_sp = exe_ctx.GetThreadPtr()->GetSelectedFrame (); - sb_frame.SetFrameSP (frame_sp); + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) + { + Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex()); + frame_sp = exe_ctx.GetThreadPtr()->GetSelectedFrame (); + sb_frame.SetFrameSP (frame_sp); + } } if (log) @@ -948,16 +991,20 @@ SBThread::SetSelectedFrame (uint32_t idx) SBFrame sb_frame; StackFrameSP frame_sp; - ExecutionContext exe_ctx (m_opaque_wp); + ExecutionContext exe_ctx (m_opaque_sp.get()); if (exe_ctx.HasThreadScope()) { - Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex()); - Thread *thread = exe_ctx.GetThreadPtr(); - frame_sp = thread->GetStackFrameAtIndex (idx); - if (frame_sp) + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { - thread->SetSelectedFrame (frame_sp.get()); - sb_frame.SetFrameSP (frame_sp); + Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex()); + Thread *thread = exe_ctx.GetThreadPtr(); + frame_sp = thread->GetStackFrameAtIndex (idx); + if (frame_sp) + { + thread->SetSelectedFrame (frame_sp.get()); + sb_frame.SetFrameSP (frame_sp); + } } } @@ -975,13 +1022,13 @@ SBThread::SetSelectedFrame (uint32_t idx) bool SBThread::operator == (const SBThread &rhs) const { - return m_opaque_wp.lock().get() == rhs.m_opaque_wp.lock().get(); + return m_opaque_sp->GetThreadSP().get() == rhs.m_opaque_sp->GetThreadSP().get(); } bool SBThread::operator != (const SBThread &rhs) const { - return m_opaque_wp.lock().get() != rhs.m_opaque_wp.lock().get(); + return m_opaque_sp->GetThreadSP().get() != rhs.m_opaque_sp->GetThreadSP().get(); } bool @@ -989,7 +1036,7 @@ SBThread::GetDescription (SBStream &description) const { Stream &strm = description.ref(); - ExecutionContext exe_ctx (m_opaque_wp); + ExecutionContext exe_ctx (m_opaque_sp.get()); if (exe_ctx.HasThreadScope()) { strm.Printf("SBThread: tid = 0x%4.4llx", exe_ctx.GetThreadPtr()->GetID()); diff --git a/lldb/source/Target/ExecutionContext.cpp b/lldb/source/Target/ExecutionContext.cpp index 2adfff0e86bd..9bddb6190cfd 100644 --- a/lldb/source/Target/ExecutionContext.cpp +++ b/lldb/source/Target/ExecutionContext.cpp @@ -534,10 +534,20 @@ ExecutionContextRef::operator =(const ExecutionContextRef &rhs) ExecutionContextRef & ExecutionContextRef::operator =(const ExecutionContext &exe_ctx) { - m_target_wp = exe_ctx.GetTargetSP(); + m_target_wp = exe_ctx.GetTargetSP(); m_process_wp = exe_ctx.GetProcessSP(); - SetThreadSP (exe_ctx.GetThreadSP()); - SetFrameSP (exe_ctx.GetFrameSP()); + lldb::ThreadSP thread_sp (exe_ctx.GetThreadSP()); + m_thread_wp = thread_sp; + if (thread_sp) + m_tid = thread_sp->GetID(); + else + m_tid = LLDB_INVALID_THREAD_ID; + lldb::StackFrameSP frame_sp (exe_ctx.GetFrameSP()); + m_frame_wp = frame_sp; + if (frame_sp) + m_stack_id = frame_sp->GetStackID(); + else + m_stack_id.Clear(); return *this; } @@ -546,10 +556,8 @@ ExecutionContextRef::Clear() { m_target_wp.reset(); m_process_wp.reset(); - m_thread_wp.reset(); - m_frame_wp.reset(); - m_tid = LLDB_INVALID_THREAD_ID; - m_stack_id.Clear(); + ClearThread(); + ClearFrame(); } ExecutionContextRef::~ExecutionContextRef() @@ -565,27 +573,52 @@ ExecutionContextRef::SetTargetSP (const lldb::TargetSP &target_sp) void ExecutionContextRef::SetProcessSP (const lldb::ProcessSP &process_sp) { - m_process_wp = process_sp; + if (process_sp) + { + m_process_wp = process_sp; + SetTargetSP (process_sp->GetTarget().shared_from_this()); + } + else + { + m_process_wp.reset(); + m_target_wp.reset(); + } } void ExecutionContextRef::SetThreadSP (const lldb::ThreadSP &thread_sp) { - m_thread_wp = thread_sp; if (thread_sp) + { + m_thread_wp = thread_sp; m_tid = thread_sp->GetID(); + SetProcessSP (thread_sp->GetProcess()); + } else - m_tid = LLDB_INVALID_THREAD_ID; + { + ClearThread(); + m_process_wp.reset(); + m_target_wp.reset(); + } } void ExecutionContextRef::SetFrameSP (const lldb::StackFrameSP &frame_sp) { - m_frame_wp = frame_sp; if (frame_sp) + { + m_frame_wp = frame_sp; m_stack_id = frame_sp->GetStackID(); + SetThreadSP (frame_sp->GetThread()); + } else - m_stack_id.Clear(); + { + ClearFrame(); + ClearThread(); + m_process_wp.reset(); + m_target_wp.reset(); + } + } void @@ -630,27 +663,38 @@ void ExecutionContextRef::SetProcessPtr (Process *process) { if (process) - m_process_wp = process->shared_from_this(); + { + SetProcessSP(process->shared_from_this()); + } else + { m_process_wp.reset(); + m_target_wp.reset(); + } } void ExecutionContextRef::SetThreadPtr (Thread *thread) { if (thread) - m_thread_wp = thread->shared_from_this(); + { + SetThreadSP (thread->shared_from_this()); + } else - m_thread_wp.reset(); + { + ClearThread(); + m_process_wp.reset(); + m_target_wp.reset(); + } } void ExecutionContextRef::SetFramePtr (StackFrame *frame) { if (frame) - m_frame_wp = frame->shared_from_this(); + SetFrameSP (frame->shared_from_this()); else - m_frame_wp.reset(); + Clear(); } diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp index 973fc54d7600..8fdfaf96c883 100644 --- a/lldb/source/Target/Process.cpp +++ b/lldb/source/Target/Process.cpp @@ -788,7 +788,8 @@ Process::Process(Target &target, Listener &listener) : m_allocated_memory_cache (*this), m_should_detach (false), m_next_event_action_ap(), - m_can_jit(eCanJITDontKnow) + m_can_jit(eCanJITDontKnow), + m_run_lock () { UpdateInstanceName(); @@ -1265,7 +1266,28 @@ Process::SetPublicState (StateType new_state) LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STATE | LIBLLDB_LOG_PROCESS)); if (log) log->Printf("Process::SetPublicState (%s)", StateAsCString(new_state)); + const StateType old_state = m_public_state.GetValue(); m_public_state.SetValue (new_state); + if (!IsHijackedForEvent(eBroadcastBitStateChanged)) + { + const bool old_state_is_stopped = StateIsStoppedState(old_state, false); + const bool new_state_is_stopped = StateIsStoppedState(new_state, false); + if (old_state_is_stopped != new_state_is_stopped) + { + if (new_state_is_stopped) + { + if (log) + log->Printf("Process::SetPublicState (%s) -- unlocking run lock", StateAsCString(new_state)); + m_run_lock.WriteUnlock(); + } + else + { + if (log) + log->Printf("Process::SetPublicState (%s) -- locking run lock", StateAsCString(new_state)); + m_run_lock.WriteLock(); + } + } + } } StateType @@ -1287,6 +1309,20 @@ Process::SetPrivateState (StateType new_state) const StateType old_state = m_private_state.GetValueNoLock (); state_changed = old_state != new_state; + // This code is left commented out in case we ever need to control + // the private process state with another run lock. Right now it doesn't + // seem like we need to do this, but if we ever do, we can uncomment and + // use this code. +// const bool old_state_is_stopped = StateIsStoppedState(old_state, false); +// const bool new_state_is_stopped = StateIsStoppedState(new_state, false); +// if (old_state_is_stopped != new_state_is_stopped) +// { +// if (new_state_is_stopped) +// m_private_run_lock.WriteUnlock(); +// else +// m_private_run_lock.WriteLock(); +// } + if (state_changed) { m_private_state.SetValueNoLock (new_state); diff --git a/lldb/test/python_api/frame/TestFrames.py b/lldb/test/python_api/frame/TestFrames.py index 554755ff18eb..0318cee8e16d 100644 --- a/lldb/test/python_api/frame/TestFrames.py +++ b/lldb/test/python_api/frame/TestFrames.py @@ -212,7 +212,7 @@ class FrameAPITestCase(TestBase): self.assertTrue(frameOutOfC) # The latest two frames should not be equal. - self.assertFalse(frameEntered.IsEqual(frameNow)) + self.assertFalse(frameOutOfC.IsEqual(frameNow)) if __name__ == '__main__': diff --git a/lldb/test/python_api/lldbutil/frame/TestFrameUtils.py b/lldb/test/python_api/lldbutil/frame/TestFrameUtils.py index 04d398bc5fa1..070fe7988427 100644 --- a/lldb/test/python_api/lldbutil/frame/TestFrameUtils.py +++ b/lldb/test/python_api/lldbutil/frame/TestFrameUtils.py @@ -43,8 +43,11 @@ class FrameUtilsTestCase(TestBase): import lldbutil thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint) + self.assertTrue (thread) frame0 = thread.GetFrameAtIndex(0) + self.assertTrue (frame0) frame1 = thread.GetFrameAtIndex(1) + self.assertTrue (frame1) parent = lldbutil.get_parent_frame(frame0) self.assertTrue(parent and parent.GetFrameID() == frame1.GetFrameID()) frame0_args = lldbutil.get_args_as_string(frame0)