[Lldb-commits] [lldb] r180886 - <rdar://problem/13700260>

Greg Clayton gclayton at apple.com
Wed May 1 14:54:05 PDT 2013


Author: gclayton
Date: Wed May  1 16:54:04 2013
New Revision: 180886

URL: http://llvm.org/viewvc/llvm-project?rev=180886&view=rev
Log:
<rdar://problem/13700260>
<rdar://problem/13723772>

Modified the lldb_private::Thread to work much better with the OperatingSystem plug-ins. Operating system plug-ins can now return have a "core" key/value pair in each thread dictionary for the OperatingSystemPython plug-ins which allows the core threads to be contained with memory threads. It also allows these memory threads to be stepped, resumed, and controlled just as if they were the actual backing threads themselves.

A few things are introduced:
- lldb_private::Thread now has a GetProtocolID() method which returns the thread protocol ID for a given thread. The protocol ID (Thread::GetProtocolID()) is usually the same as the thread id (Thread::GetID()), but it can differ when a memory thread has its own id, but is backed by an actual API thread.
- Cleaned up the Thread::WillResume() code to do the mandatory parts in Thread::ShouldResume(), and let the thread subclasses override the Thread::WillResume() which is now just a notification.
- Cleaned up ClearStackFrames() implementations so that fewer thread subclasses needed to override them
- Changed the POSIXThread class a bit since it overrode Thread::WillResume(). It is doing the wrong thing by calling "Thread::SetResumeState()" on its own, this shouldn't be done by thread subclasses, but the current code might rely on it so I left it in with a TODO comment with an explanation.


Added:
    lldb/trunk/source/Plugins/Process/Utility/RegisterContextThreadMemory.cpp
    lldb/trunk/source/Plugins/Process/Utility/RegisterContextThreadMemory.h
Modified:
    lldb/trunk/include/lldb/Target/OperatingSystem.h
    lldb/trunk/include/lldb/Target/RegisterContext.h
    lldb/trunk/include/lldb/Target/StopInfo.h
    lldb/trunk/include/lldb/Target/Thread.h
    lldb/trunk/include/lldb/Target/ThreadList.h
    lldb/trunk/lldb.xcodeproj/project.pbxproj
    lldb/trunk/source/Core/Debugger.cpp
    lldb/trunk/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp
    lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp
    lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.h
    lldb/trunk/source/Plugins/Process/POSIX/POSIXThread.cpp
    lldb/trunk/source/Plugins/Process/POSIX/POSIXThread.h
    lldb/trunk/source/Plugins/Process/Utility/ThreadMemory.cpp
    lldb/trunk/source/Plugins/Process/Utility/ThreadMemory.h
    lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
    lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
    lldb/trunk/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
    lldb/trunk/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h
    lldb/trunk/source/Plugins/Process/mach-core/ThreadMachCore.cpp
    lldb/trunk/source/Plugins/Process/mach-core/ThreadMachCore.h
    lldb/trunk/source/Target/OperatingSystem.cpp
    lldb/trunk/source/Target/Thread.cpp
    lldb/trunk/source/Target/ThreadList.cpp

Modified: lldb/trunk/include/lldb/Target/OperatingSystem.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/OperatingSystem.h?rev=180886&r1=180885&r2=180886&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/OperatingSystem.h (original)
+++ lldb/trunk/include/lldb/Target/OperatingSystem.h Wed May  1 16:54:04 2013
@@ -81,6 +81,10 @@ public:
     {
         return lldb::ThreadSP();
     }
+    
+    virtual bool
+    IsOperatingSystemPluginThread (const lldb::ThreadSP &thread_sp);
+
 protected:
     //------------------------------------------------------------------
     // Member variables.

Modified: lldb/trunk/include/lldb/Target/RegisterContext.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/RegisterContext.h?rev=180886&r1=180885&r2=180886&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/RegisterContext.h (original)
+++ lldb/trunk/include/lldb/Target/RegisterContext.h Wed May  1 16:54:04 2013
@@ -111,10 +111,10 @@ public:
     //------------------------------------------------------------------
     // Subclasses should not override these
     //------------------------------------------------------------------
-    lldb::tid_t
+    virtual lldb::tid_t
     GetThreadID() const;
 
-    Thread &
+    virtual Thread &
     GetThread ()
     {
         return m_thread;

Modified: lldb/trunk/include/lldb/Target/StopInfo.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/StopInfo.h?rev=180886&r1=180885&r2=180886&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/StopInfo.h (original)
+++ lldb/trunk/include/lldb/Target/StopInfo.h Wed May  1 16:54:04 2013
@@ -40,6 +40,12 @@ public:
     bool
     IsValid () const;
 
+    void
+    SetThread (const lldb::ThreadSP &thread_sp)
+    {
+        m_thread_wp = thread_sp;
+    }
+
     lldb::ThreadSP
     GetThread() const
     {

Modified: lldb/trunk/include/lldb/Target/Thread.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Thread.h?rev=180886&r1=180885&r2=180886&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/Thread.h (original)
+++ lldb/trunk/include/lldb/Target/Thread.h Wed May  1 16:54:04 2013
@@ -255,17 +255,22 @@ public:
         m_resume_state = state;
     }
 
-    // This function is called on all the threads before "WillResume" in case
-    // a thread needs to change its state before the ThreadList polls all the
-    // threads to figure out which ones actually will get to run and how.
+    // This function is called on all the threads before "ShouldResume" and
+    // "WillResume" in case a thread needs to change its state before the
+    // ThreadList polls all the threads to figure out which ones actually
+    // will get to run and how.
     void
     SetupForResume ();
     
-    // Override this to do platform specific tasks before resume, but always
-    // call the Thread::WillResume at the end of your work.
+    // Do not override this function, it is for thread plan logic only
+    bool
+    ShouldResume (lldb::StateType resume_state);
 
-    virtual bool
-    WillResume (lldb::StateType resume_state);
+    // Override this to do platform specific tasks before resume.
+    virtual void
+    WillResume (lldb::StateType resume_state)
+    {
+    }
 
     // This clears generic thread state after a resume.  If you subclass this,
     // be sure to call it.
@@ -820,13 +825,34 @@ public:
     void
     SetTracer (lldb::ThreadPlanTracerSP &tracer_sp);
     
-    // Get the thread index ID. The index ID that is guaranteed to not be
-    // re-used by a process. They start at 1 and increase with each new thread.
-    // This allows easy command line access by a unique ID that is easier to
-    // type than the actual system thread ID.
+    //------------------------------------------------------------------
+    // Get the thread index ID. The index ID that is guaranteed to not
+    // be re-used by a process. They start at 1 and increase with each
+    // new thread. This allows easy command line access by a unique ID
+    // that is easier to type than the actual system thread ID.
+    //------------------------------------------------------------------
     uint32_t
     GetIndexID () const;
     
+    
+    //------------------------------------------------------------------
+    // The API ID is often the same as the Thread::GetID(), but not in
+    // all cases. Thread::GetID() is the user visible thread ID that
+    // clients would want to see. The API thread ID is the thread ID
+    // that is used when sending data to/from the debugging protocol.
+    //------------------------------------------------------------------
+    virtual lldb::user_id_t
+    GetProtocolID () const
+    {
+        return m_protocol_tid.GetID();
+    }
+
+    virtual void
+    SetProtocolID (lldb::user_id_t api_tid)
+    {
+        return m_protocol_tid.SetID(api_tid);
+    }
+
     //------------------------------------------------------------------
     // lldb::ExecutionContextScope pure virtual functions
     //------------------------------------------------------------------
@@ -881,7 +907,7 @@ public:
     // Gets the temporary resume state for a thread.
     //
     // This value gets set in each thread by complex debugger logic in
-    // Thread::WillResume() and an appropriate thread resume state will get
+    // Thread::ShouldResume() and an appropriate thread resume state will get
     // set in each thread every time the process is resumed prior to calling
     // Process::DoResume(). The lldb_private::Process subclass should adhere
     // to the thread resume state request which will be one of:
@@ -898,6 +924,9 @@ public:
         return m_temporary_resume_state;
     }
 
+    void
+    SetStopInfo (const lldb::StopInfoSP &stop_info_sp);
+
 protected:
 
     friend class ThreadPlan;
@@ -905,6 +934,7 @@ protected:
     friend class ThreadEventData;
     friend class StackFrameList;
     friend class StackFrame;
+    friend class OperatingSystem;
     
     // This is necessary to make sure thread assets get destroyed while the thread is still in good shape
     // to call virtual thread methods.  This must be called by classes that derive from Thread in their destructor.
@@ -923,9 +953,6 @@ protected:
 
     typedef std::vector<lldb::ThreadPlanSP> plan_stack;
 
-    void
-    SetStopInfo (const lldb::StopInfoSP &stop_info_sp);
-
     virtual bool
     SaveFrameZeroState (RegisterCheckpoint &checkpoint);
 
@@ -943,6 +970,17 @@ protected:
     virtual bool
     IsStillAtLastBreakpointHit();
 
+    // Some threads are threads that are made up by OperatingSystem plugins that
+    // are threads that exist and are context switched out into memory. The
+    // OperatingSystem plug-in need a ways to know if a thread is "real" or made
+    // up.
+    virtual bool
+    IsOperatingSystemPluginThread () const
+    {
+        return false;
+    }
+    
+
     lldb::StackFrameListSP
     GetStackFrameList ();
     
@@ -959,6 +997,7 @@ protected:
     lldb::ProcessWP     m_process_wp;           ///< The process that owns this thread.
     lldb::StopInfoSP    m_actual_stop_info_sp;  ///< The private stop reason for this thread
     const uint32_t      m_index_id;             ///< A unique 1 based index assigned to each thread for easy UI/command line access.
+    UserID              m_protocol_tid;         ///< The thread ID used in the system level debugging or protocol functions calls. This is usually the same as the Thread::GetID(), but not always.
     lldb::RegisterContextSP m_reg_context_sp;   ///< The register context for this thread's current register state.
     lldb::StateType     m_state;                ///< The state of our process.
     mutable Mutex       m_state_mutex;          ///< Multithreaded protection for m_state.
@@ -971,7 +1010,7 @@ protected:
     int                 m_resume_signal;        ///< The signal that should be used when continuing this thread.
     lldb::StateType     m_resume_state;         ///< This state is used to force a thread to be suspended from outside the ThreadPlan logic.
     lldb::StateType     m_temporary_resume_state; ///< This state records what the thread was told to do by the thread plan logic for the current resume.
-                                                  /// It gets set in Thread::WillResume.
+                                                  /// It gets set in Thread::ShoudResume.
     std::unique_ptr<lldb_private::Unwind> m_unwinder_ap;
     bool                m_destroy_called;       // This is used internally to make sure derived Thread classes call DestroyThread.
     uint32_t m_thread_stop_reason_stop_id;      // This is the stop id for which the StopInfo is valid.  Can use this so you know that

Modified: lldb/trunk/include/lldb/Target/ThreadList.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/ThreadList.h?rev=180886&r1=180885&r2=180886&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/ThreadList.h (original)
+++ lldb/trunk/include/lldb/Target/ThreadList.h Wed May  1 16:54:04 2013
@@ -73,9 +73,15 @@ public:
 
     lldb::ThreadSP
     FindThreadByID (lldb::tid_t tid, bool can_update = true);
+    
+    lldb::ThreadSP
+    FindThreadByProtocolID (lldb::tid_t tid, bool can_update = true);
 
     lldb::ThreadSP
     RemoveThreadByID (lldb::tid_t tid, bool can_update = true);
+    
+    lldb::ThreadSP
+    RemoveThreadByProtocolID (lldb::tid_t tid, bool can_update = true);
 
     lldb::ThreadSP
     FindThreadByIndexID (uint32_t index_id, bool can_update = true);

Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=180886&r1=180885&r2=180886&view=diff
==============================================================================
--- lldb/trunk/lldb.xcodeproj/project.pbxproj (original)
+++ lldb/trunk/lldb.xcodeproj/project.pbxproj Wed May  1 16:54:04 2013
@@ -440,6 +440,8 @@
 		26BD407F135D2AE000237D80 /* FileLineResolver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BD407E135D2ADF00237D80 /* FileLineResolver.cpp */; };
 		26C72C94124322890068DC16 /* SBStream.h in Headers */ = {isa = PBXBuildFile; fileRef = 26C72C93124322890068DC16 /* SBStream.h */; settings = {ATTRIBUTES = (Public, ); }; };
 		26C72C961243229A0068DC16 /* SBStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C72C951243229A0068DC16 /* SBStream.cpp */; };
+		26CA97A1172B1FD5005DC71B /* RegisterContextThreadMemory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26CA979F172B1FD5005DC71B /* RegisterContextThreadMemory.cpp */; };
+		26CA97A2172B1FD5005DC71B /* RegisterContextThreadMemory.h in Headers */ = {isa = PBXBuildFile; fileRef = 26CA97A0172B1FD5005DC71B /* RegisterContextThreadMemory.h */; };
 		26D1803E16CEBFD300EDFB5B /* KQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26D1803C16CEBFD300EDFB5B /* KQueue.cpp */; };
 		26D1804216CEDF0700EDFB5B /* TimeSpecTimeout.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26D1804016CEDF0700EDFB5B /* TimeSpecTimeout.cpp */; };
 		26D1804516CEE12500EDFB5B /* KQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 26D1804416CEE12500EDFB5B /* KQueue.h */; };
@@ -1333,6 +1335,8 @@
 		26C72C951243229A0068DC16 /* SBStream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBStream.cpp; path = source/API/SBStream.cpp; sourceTree = "<group>"; };
 		26C81CA411335651004BDC5A /* UUID.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = UUID.h; path = include/lldb/Core/UUID.h; sourceTree = "<group>"; };
 		26C81CA511335651004BDC5A /* UUID.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = UUID.cpp; path = source/Core/UUID.cpp; sourceTree = "<group>"; };
+		26CA979F172B1FD5005DC71B /* RegisterContextThreadMemory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RegisterContextThreadMemory.cpp; path = Utility/RegisterContextThreadMemory.cpp; sourceTree = "<group>"; };
+		26CA97A0172B1FD5005DC71B /* RegisterContextThreadMemory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RegisterContextThreadMemory.h; path = Utility/RegisterContextThreadMemory.h; sourceTree = "<group>"; };
 		26CF992414428766001E4138 /* AnsiTerminal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AnsiTerminal.h; path = include/lldb/Utility/AnsiTerminal.h; sourceTree = "<group>"; };
 		26D0DD5010FE554D00271C65 /* BreakpointResolverAddress.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BreakpointResolverAddress.h; path = include/lldb/Breakpoint/BreakpointResolverAddress.h; sourceTree = "<group>"; };
 		26D0DD5110FE554D00271C65 /* BreakpointResolverFileLine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BreakpointResolverFileLine.h; path = include/lldb/Breakpoint/BreakpointResolverFileLine.h; sourceTree = "<group>"; };
@@ -2523,6 +2527,8 @@
 				262D24E513FB8710002D1960 /* RegisterContextMemory.h */,
 				26E3EEF811A994E800FBADB6 /* RegisterContextMacOSXFrameBackchain.h */,
 				26E3EEF711A994E800FBADB6 /* RegisterContextMacOSXFrameBackchain.cpp */,
+				26CA979F172B1FD5005DC71B /* RegisterContextThreadMemory.cpp */,
+				26CA97A0172B1FD5005DC71B /* RegisterContextThreadMemory.h */,
 				2615DBC91208B5FC0021781D /* StopInfoMachException.h */,
 				2615DBC81208B5FC0021781D /* StopInfoMachException.cpp */,
 				26F4A21A13FBA31A0064B613 /* ThreadMemory.cpp */,
@@ -3574,6 +3580,7 @@
 				4C6649A014EEE7F100B0316F /* StreamCallback.h in Headers */,
 				26B7564F14F89356008D9CB3 /* PlatformiOSSimulator.h in Headers */,
 				26FFC19A14FC072100087D58 /* AuxVector.h in Headers */,
+				26CA97A2172B1FD5005DC71B /* RegisterContextThreadMemory.h in Headers */,
 				26FFC19C14FC072100087D58 /* DYLDRendezvous.h in Headers */,
 				26FFC19E14FC072100087D58 /* DynamicLoaderPOSIXDYLD.h in Headers */,
 				AF254E32170CCC33007AE5C9 /* PlatformDarwinKernel.h in Headers */,
@@ -4214,6 +4221,7 @@
 				2689010713353E6F00698AC0 /* ThreadPlanStepThrough.cpp in Sources */,
 				2689010813353E6F00698AC0 /* ThreadPlanStepUntil.cpp in Sources */,
 				2689010A13353E6F00698AC0 /* ThreadPlanTracer.cpp in Sources */,
+				26CA97A1172B1FD5005DC71B /* RegisterContextThreadMemory.cpp in Sources */,
 				2689010B13353E6F00698AC0 /* ThreadSpec.cpp in Sources */,
 				2689010C13353E6F00698AC0 /* UnixSignals.cpp in Sources */,
 				2689011013353E8200698AC0 /* SharingPtr.cpp in Sources */,

Modified: lldb/trunk/source/Core/Debugger.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Debugger.cpp?rev=180886&r1=180885&r2=180886&view=diff
==============================================================================
--- lldb/trunk/source/Core/Debugger.cpp (original)
+++ lldb/trunk/source/Core/Debugger.cpp Wed May  1 16:54:04 2013
@@ -1964,6 +1964,11 @@ Debugger::FormatPrompt
                                             s.Printf("0x%4.4" PRIx64, thread->GetID());
                                             var_success = true;
                                         }
+                                        else if (::strncmp (var_name_begin, "protocol_id}", strlen("protocol_id}")) == 0)
+                                        {
+                                            s.Printf("0x%4.4" PRIx64, thread->GetProtocolID());
+                                            var_success = true;
+                                        }
                                         else if (::strncmp (var_name_begin, "index}", strlen("index}")) == 0)
                                         {
                                             s.Printf("%u", thread->GetIndexID());

Modified: lldb/trunk/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp?rev=180886&r1=180885&r2=180886&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp (original)
+++ lldb/trunk/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp Wed May  1 16:54:04 2013
@@ -247,8 +247,8 @@ OperatingSystemPython::CreateThreadFromT
             PythonString core_pystr("core");
             PythonString name_pystr("name");
             PythonString queue_pystr("queue");
-            PythonString state_pystr("state");
-            PythonString stop_reason_pystr("stop_reason");
+            //PythonString state_pystr("state");
+            //PythonString stop_reason_pystr("stop_reason");
             PythonString reg_data_addr_pystr ("register_data_addr");
             
             const uint32_t core_number = thread_dict.GetItemForKeyAsInteger (core_pystr, UINT32_MAX);
@@ -258,7 +258,21 @@ OperatingSystemPython::CreateThreadFromT
             //const char *state = thread_dict.GetItemForKeyAsString (state_pystr);
             //const char *stop_reason = thread_dict.GetItemForKeyAsString (stop_reason_pystr);
             
+            // See if a thread already exists for "tid"
             thread_sp = old_thread_list.FindThreadByID (tid, false);
+            if (thread_sp)
+            {
+                // A thread already does exist for "tid", make sure it was an operating system
+                // plug-in generated thread.
+                if (!IsOperatingSystemPluginThread(thread_sp))
+                {
+                    // We have thread ID overlap between the protocol threads and the
+                    // operating system threads, clear the thread so we create an
+                    // operating system thread for this.
+                    thread_sp.reset();
+                }
+            }
+    
             if (!thread_sp)
             {
                 if (did_create_ptr)
@@ -273,7 +287,19 @@ OperatingSystemPython::CreateThreadFromT
             
             if (core_number < core_thread_list.GetSize(false))
             {
-                thread_sp->SetBackingThread(core_thread_list.GetThreadAtIndex(core_number, false));
+                ThreadSP core_thread_sp (core_thread_list.GetThreadAtIndex(core_number, false));
+                if (core_thread_sp)
+                {
+                    ThreadSP backing_core_thread_sp (core_thread_sp->GetBackingThread());
+                    if (backing_core_thread_sp)
+                    {
+                        thread_sp->SetBackingThread(backing_core_thread_sp);
+                    }
+                    else
+                    {
+                        thread_sp->SetBackingThread(core_thread_sp);
+                    }
+                }
             }
         }
     }
@@ -292,7 +318,10 @@ OperatingSystemPython::CreateRegisterCon
 {
     RegisterContextSP reg_ctx_sp;
     if (!m_interpreter || !m_python_object_sp || !thread)
-        return RegisterContextSP();
+        return reg_ctx_sp;
+
+    if (!IsOperatingSystemPluginThread(thread->shared_from_this()))
+        return reg_ctx_sp;
     
     // First thing we have to do is get the API lock, and the run lock.  We're going to change the thread
     // content of the process, and we're going to use python, which requires the API lock to do it.
@@ -308,7 +337,10 @@ OperatingSystemPython::CreateRegisterCon
         // The registers data is in contiguous memory, just create the register
         // context using the address provided
         if (log)
-            log->Printf ("OperatingSystemPython::CreateRegisterContextForThread (tid = 0x%" PRIx64 ", reg_data_addr = 0x%" PRIx64 ") creating memory register context", thread->GetID(), reg_data_addr);
+            log->Printf ("OperatingSystemPython::CreateRegisterContextForThread (tid = 0x%" PRIx64 ", 0x%" PRIx64 ", reg_data_addr = 0x%" PRIx64 ") creating memory register context",
+                         thread->GetID(),
+                         thread->GetProtocolID(),
+                         reg_data_addr);
         reg_ctx_sp.reset (new RegisterContextMemory (*thread, 0, *GetDynamicRegisterInfo (), reg_data_addr));
     }
     else
@@ -316,7 +348,9 @@ OperatingSystemPython::CreateRegisterCon
         // No register data address is provided, query the python plug-in to let
         // it make up the data as it sees fit
         if (log)
-            log->Printf ("OperatingSystemPython::CreateRegisterContextForThread (tid = 0x%" PRIx64 ") fetching register data from python", thread->GetID());
+            log->Printf ("OperatingSystemPython::CreateRegisterContextForThread (tid = 0x%" PRIx64 ", 0x%" PRIx64 ") fetching register data from python",
+                         thread->GetID(),
+                         thread->GetProtocolID());
 
         PythonString reg_context_data(m_interpreter->OSPlugin_RegisterContextData (m_python_object_sp, thread->GetID()));
         if (reg_context_data)

Modified: lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp?rev=180886&r1=180885&r2=180886&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp (original)
+++ lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp Wed May  1 16:54:04 2013
@@ -66,23 +66,6 @@ ThreadKDP::GetQueueName ()
     return NULL;
 }
 
-bool
-ThreadKDP::WillResume (StateType resume_state)
-{
-    // Call the Thread::WillResume first. If we stop at a signal, the stop info
-    // class for signal will set the resume signal that we need below. The signal
-    // stuff obeys the Process::UnixSignal defaults. 
-    Thread::WillResume(resume_state);
-
-    ClearStackFrames();
-
-    Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP));
-    if (log)
-        log->Printf ("Resuming thread: %4.4" PRIx64 " with state: %s.", GetID(), StateAsCString(resume_state));
-
-    return true;
-}
-
 void
 ThreadKDP::RefreshStateAfterStop()
 {
@@ -100,16 +83,6 @@ ThreadKDP::RefreshStateAfterStop()
         reg_ctx_sp->InvalidateIfNeeded (force);
 }
 
-void
-ThreadKDP::ClearStackFrames ()
-{
-    Unwind *unwinder = GetUnwinder ();
-    if (unwinder)
-        unwinder->Clear();
-    Thread::ClearStackFrames();
-}
-
-
 bool
 ThreadKDP::ThreadIDIsValid (lldb::tid_t thread)
 {

Modified: lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.h?rev=180886&r1=180885&r2=180886&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.h (original)
+++ lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.h Wed May  1 16:54:04 2013
@@ -26,9 +26,6 @@ public:
     virtual
     ~ThreadKDP ();
 
-    virtual bool
-    WillResume (lldb::StateType resume_state);
-
     virtual void
     RefreshStateAfterStop();
 
@@ -44,9 +41,6 @@ public:
     virtual lldb::RegisterContextSP
     CreateRegisterContextForFrame (lldb_private::StackFrame *frame);
 
-    virtual void
-    ClearStackFrames ();
-
     void
     Dump (lldb_private::Log *log, uint32_t index);
 

Modified: lldb/trunk/source/Plugins/Process/POSIX/POSIXThread.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/POSIX/POSIXThread.cpp?rev=180886&r1=180885&r2=180886&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/POSIX/POSIXThread.cpp (original)
+++ lldb/trunk/source/Plugins/Process/POSIX/POSIXThread.cpp Wed May  1 16:54:04 2013
@@ -150,19 +150,12 @@ POSIXThread::GetUnwinder()
     return m_unwinder_ap.get();
 }
 
-bool
+void
 POSIXThread::WillResume(lldb::StateType resume_state)
 {
+	// TODO: the line below shouldn't really be done, but
+    // the POSIXThread might rely on this so I will leave this in for now
     SetResumeState(resume_state);
-
-    if (!Thread::WillResume(resume_state))
-        return false;
-
-    if (m_unwinder_ap.get())
-        m_unwinder_ap->Clear();
-    Thread::ClearStackFrames();
-
-    return true;
 }
 
 bool

Modified: lldb/trunk/source/Plugins/Process/POSIX/POSIXThread.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/POSIX/POSIXThread.h?rev=180886&r1=180885&r2=180886&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/POSIX/POSIXThread.h (original)
+++ lldb/trunk/source/Plugins/Process/POSIX/POSIXThread.h Wed May  1 16:54:04 2013
@@ -36,7 +36,7 @@ public:
     void
     RefreshStateAfterStop();
 
-    bool
+    virtual void
     WillResume(lldb::StateType resume_state);
 
     const char *

Added: lldb/trunk/source/Plugins/Process/Utility/RegisterContextThreadMemory.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/RegisterContextThreadMemory.cpp?rev=180886&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/RegisterContextThreadMemory.cpp (added)
+++ lldb/trunk/source/Plugins/Process/Utility/RegisterContextThreadMemory.cpp Wed May  1 16:54:04 2013
@@ -0,0 +1,256 @@
+//===-- RegisterContextThreadMemory.cpp -------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/lldb-private.h"
+#include "lldb/Core/Error.h"
+#include "lldb/Target/OperatingSystem.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/Thread.h"
+
+#include "RegisterContextThreadMemory.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+RegisterContextThreadMemory::RegisterContextThreadMemory (Thread &thread,
+                                                          lldb::addr_t register_data_addr) :
+    RegisterContext (thread, 0),
+    m_thread_wp (thread.shared_from_this()),
+    m_reg_ctx_sp (),
+    m_register_data_addr (register_data_addr),
+    m_stop_id(0)
+{
+}
+
+RegisterContextThreadMemory::~RegisterContextThreadMemory()
+{
+}
+
+void
+RegisterContextThreadMemory::UpdateRegisterContext ()
+{
+    ThreadSP thread_sp (m_thread_wp.lock());
+    if (thread_sp)
+    {
+        ProcessSP process_sp (thread_sp->GetProcess());
+
+        if (process_sp)
+        {
+            const uint32_t stop_id = process_sp->GetModID().GetStopID();
+            if (m_stop_id != stop_id)
+            {
+                m_stop_id = stop_id;
+                m_reg_ctx_sp.reset();
+            }
+            if (!m_reg_ctx_sp)
+            {
+                OperatingSystem *os = process_sp->GetOperatingSystem ();
+                if (os->IsOperatingSystemPluginThread (thread_sp))
+                    m_reg_ctx_sp = os->CreateRegisterContextForThread (thread_sp.get(), LLDB_INVALID_ADDRESS);
+                else
+                {
+
+                    ThreadSP backing_thread_sp (thread_sp->GetBackingThread());
+                    if (backing_thread_sp)
+                        m_reg_ctx_sp = backing_thread_sp->GetRegisterContext();
+                }
+            }
+        }
+    }
+    else
+    {
+        m_reg_ctx_sp.reset();
+    }
+}
+
+//------------------------------------------------------------------
+// Subclasses must override these functions
+//------------------------------------------------------------------
+void
+RegisterContextThreadMemory::InvalidateAllRegisters ()
+{
+    UpdateRegisterContext ();
+    if (m_reg_ctx_sp)
+        m_reg_ctx_sp->InvalidateAllRegisters();
+}
+
+size_t
+RegisterContextThreadMemory::GetRegisterCount ()
+{
+    UpdateRegisterContext ();
+    if (m_reg_ctx_sp)
+        return m_reg_ctx_sp->GetRegisterCount();
+    return 0;
+}
+
+const RegisterInfo *
+RegisterContextThreadMemory::GetRegisterInfoAtIndex (size_t reg)
+{
+    UpdateRegisterContext ();
+    if (m_reg_ctx_sp)
+        return m_reg_ctx_sp->GetRegisterInfoAtIndex(reg);
+    return NULL;
+}
+
+size_t
+RegisterContextThreadMemory::GetRegisterSetCount ()
+{
+    UpdateRegisterContext ();
+    if (m_reg_ctx_sp)
+        return m_reg_ctx_sp->GetRegisterSetCount();
+    return 0;
+}
+
+const RegisterSet *
+RegisterContextThreadMemory::GetRegisterSet (size_t reg_set)
+{
+    UpdateRegisterContext ();
+    if (m_reg_ctx_sp)
+        return m_reg_ctx_sp->GetRegisterSet(reg_set);
+    return NULL;
+}
+
+bool
+RegisterContextThreadMemory::ReadRegister (const RegisterInfo *reg_info, RegisterValue &reg_value)
+{
+    UpdateRegisterContext ();
+    if (m_reg_ctx_sp)
+        return m_reg_ctx_sp->ReadRegister(reg_info, reg_value);
+    return false;
+}
+
+bool
+RegisterContextThreadMemory::WriteRegister (const RegisterInfo *reg_info, const RegisterValue &reg_value)
+{
+    UpdateRegisterContext ();
+    if (m_reg_ctx_sp)
+        return m_reg_ctx_sp->WriteRegister (reg_info, reg_value);
+    return false;
+}
+
+bool
+RegisterContextThreadMemory::ReadAllRegisterValues (lldb::DataBufferSP &data_sp)
+{
+    UpdateRegisterContext ();
+    if (m_reg_ctx_sp)
+        return m_reg_ctx_sp->ReadAllRegisterValues(data_sp);
+    return false;
+}
+
+bool
+RegisterContextThreadMemory::WriteAllRegisterValues (const lldb::DataBufferSP &data_sp)
+{
+    UpdateRegisterContext ();
+    if (m_reg_ctx_sp)
+        return m_reg_ctx_sp->WriteAllRegisterValues (data_sp);
+    return false;
+}
+
+bool
+RegisterContextThreadMemory::CopyFromRegisterContext (lldb::RegisterContextSP reg_ctx_sp)
+{
+    UpdateRegisterContext ();
+    if (m_reg_ctx_sp)
+        return m_reg_ctx_sp->CopyFromRegisterContext(reg_ctx_sp);
+    return false;
+}
+
+uint32_t
+RegisterContextThreadMemory::ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num)
+{
+    UpdateRegisterContext ();
+    if (m_reg_ctx_sp)
+        return m_reg_ctx_sp->ConvertRegisterKindToRegisterNumber(kind, num);
+    return false;
+}
+
+uint32_t
+RegisterContextThreadMemory::NumSupportedHardwareBreakpoints ()
+{
+    UpdateRegisterContext ();
+    if (m_reg_ctx_sp)
+        return m_reg_ctx_sp->NumSupportedHardwareBreakpoints();
+    return false;
+}
+
+uint32_t
+RegisterContextThreadMemory::SetHardwareBreakpoint (lldb::addr_t addr, size_t size)
+{
+    UpdateRegisterContext ();
+    if (m_reg_ctx_sp)
+        return m_reg_ctx_sp->SetHardwareBreakpoint(addr, size);
+    return 0;
+}
+
+bool
+RegisterContextThreadMemory::ClearHardwareBreakpoint (uint32_t hw_idx)
+{
+    UpdateRegisterContext ();
+    if (m_reg_ctx_sp)
+        return m_reg_ctx_sp->ClearHardwareBreakpoint (hw_idx);
+    return false;
+}
+
+uint32_t
+RegisterContextThreadMemory::NumSupportedHardwareWatchpoints ()
+{
+    UpdateRegisterContext ();
+    if (m_reg_ctx_sp)
+        return m_reg_ctx_sp->NumSupportedHardwareWatchpoints();
+    return 0;
+}
+
+uint32_t
+RegisterContextThreadMemory::SetHardwareWatchpoint (lldb::addr_t addr, size_t size, bool read, bool write)
+{
+    UpdateRegisterContext ();
+    if (m_reg_ctx_sp)
+        return m_reg_ctx_sp->SetHardwareWatchpoint(addr, size, read, write);
+    return 0;
+}
+
+bool
+RegisterContextThreadMemory::ClearHardwareWatchpoint (uint32_t hw_index)
+{
+    UpdateRegisterContext ();
+    if (m_reg_ctx_sp)
+        return m_reg_ctx_sp->ClearHardwareWatchpoint(hw_index);
+    return false;
+}
+
+bool
+RegisterContextThreadMemory::HardwareSingleStep (bool enable)
+{
+    UpdateRegisterContext ();
+    if (m_reg_ctx_sp)
+        return m_reg_ctx_sp->HardwareSingleStep(enable);
+    return false;
+}
+
+Error
+RegisterContextThreadMemory::ReadRegisterValueFromMemory (const lldb_private::RegisterInfo *reg_info, lldb::addr_t src_addr, uint32_t src_len, RegisterValue &reg_value)
+{
+    UpdateRegisterContext ();
+    if (m_reg_ctx_sp)
+        return m_reg_ctx_sp->ReadRegisterValueFromMemory (reg_info, src_addr, src_len, reg_value);
+    Error error;
+    error.SetErrorString("invalid register context");
+    return error;
+}
+
+Error
+RegisterContextThreadMemory::WriteRegisterValueToMemory (const lldb_private::RegisterInfo *reg_info, lldb::addr_t dst_addr, uint32_t dst_len, const RegisterValue &reg_value)
+{
+    UpdateRegisterContext ();
+    if (m_reg_ctx_sp)
+        return m_reg_ctx_sp->WriteRegisterValueToMemory (reg_info, dst_addr, dst_len, reg_value);
+    Error error;
+    error.SetErrorString("invalid register context");
+    return error;
+}

Added: lldb/trunk/source/Plugins/Process/Utility/RegisterContextThreadMemory.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/RegisterContextThreadMemory.h?rev=180886&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/RegisterContextThreadMemory.h (added)
+++ lldb/trunk/source/Plugins/Process/Utility/RegisterContextThreadMemory.h Wed May  1 16:54:04 2013
@@ -0,0 +1,114 @@
+//===-- RegisterContextThreadMemory.h ---------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef lldb_RegisterContextThreadMemory_h_
+#define lldb_RegisterContextThreadMemory_h_
+
+#include <vector>
+
+#include "lldb/lldb-private.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/Symbol/SymbolContext.h"
+
+namespace lldb_private {
+    
+class RegisterContextThreadMemory : public lldb_private::RegisterContext
+{
+public:
+    RegisterContextThreadMemory (Thread &thread,
+                                 lldb::addr_t register_data_addr);
+    
+    virtual ~RegisterContextThreadMemory();
+    //------------------------------------------------------------------
+    // Subclasses must override these functions
+    //------------------------------------------------------------------
+    virtual void
+    InvalidateAllRegisters ();
+    
+    virtual size_t
+    GetRegisterCount ();
+    
+    virtual const RegisterInfo *
+    GetRegisterInfoAtIndex (size_t reg);
+    
+    virtual size_t
+    GetRegisterSetCount ();
+    
+    virtual const RegisterSet *
+    GetRegisterSet (size_t reg_set);
+    
+    virtual bool
+    ReadRegister (const RegisterInfo *reg_info, RegisterValue &reg_value);
+    
+    virtual bool
+    WriteRegister (const RegisterInfo *reg_info, const RegisterValue &reg_value);
+    
+    // These two functions are used to implement "push" and "pop" of register states.  They are used primarily
+    // for expression evaluation, where we need to push a new state (storing the old one in data_sp) and then
+    // restoring the original state by passing the data_sp we got from ReadAllRegisters to WriteAllRegisterValues.
+    // ReadAllRegisters will do what is necessary to return a coherent set of register values for this thread, which
+    // may mean e.g. interrupting a thread that is sitting in a kernel trap.  That is a somewhat disruptive operation,
+    // so these API's should only be used when this behavior is needed.
+    
+    virtual bool
+    ReadAllRegisterValues (lldb::DataBufferSP &data_sp);
+    
+    virtual bool
+    WriteAllRegisterValues (const lldb::DataBufferSP &data_sp);
+    
+    bool
+    CopyFromRegisterContext (lldb::RegisterContextSP context);
+    
+    virtual uint32_t
+    ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num);
+    
+    //------------------------------------------------------------------
+    // Subclasses can override these functions if desired
+    //------------------------------------------------------------------
+    virtual uint32_t
+    NumSupportedHardwareBreakpoints ();
+    
+    virtual uint32_t
+    SetHardwareBreakpoint (lldb::addr_t addr, size_t size);
+    
+    virtual bool
+    ClearHardwareBreakpoint (uint32_t hw_idx);
+    
+    virtual uint32_t
+    NumSupportedHardwareWatchpoints ();
+    
+    virtual uint32_t
+    SetHardwareWatchpoint (lldb::addr_t addr, size_t size, bool read, bool write);
+    
+    virtual bool
+    ClearHardwareWatchpoint (uint32_t hw_index);
+    
+    virtual bool
+    HardwareSingleStep (bool enable);
+    
+    virtual Error
+    ReadRegisterValueFromMemory (const lldb_private::RegisterInfo *reg_info, lldb::addr_t src_addr, uint32_t src_len, RegisterValue &reg_value);
+    
+    virtual Error
+    WriteRegisterValueToMemory (const lldb_private::RegisterInfo *reg_info, lldb::addr_t dst_addr, uint32_t dst_len, const RegisterValue &reg_value);
+    
+protected:
+    void
+    UpdateRegisterContext ();
+    
+    lldb::ThreadWP m_thread_wp;
+    lldb::RegisterContextSP m_reg_ctx_sp;
+    lldb::addr_t m_register_data_addr;
+    uint32_t m_stop_id;
+private:
+    DISALLOW_COPY_AND_ASSIGN (RegisterContextThreadMemory);
+};
+} // namespace lldb_private
+
+#endif  // lldb_RegisterContextThreadMemory_h_

Modified: lldb/trunk/source/Plugins/Process/Utility/ThreadMemory.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/ThreadMemory.cpp?rev=180886&r1=180885&r2=180886&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/ThreadMemory.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Utility/ThreadMemory.cpp Wed May  1 16:54:04 2013
@@ -13,6 +13,7 @@
 #include "lldb/Target/Process.h"
 #include "lldb/Target/StopInfo.h"
 #include "lldb/Target/Unwind.h"
+#include "Plugins/Process/Utility/RegisterContextThreadMemory.h"
 
 using namespace lldb;
 using namespace lldb_private;
@@ -53,42 +54,32 @@ ThreadMemory::~ThreadMemory()
     DestroyThread();
 }
 
-bool
+void
 ThreadMemory::WillResume (StateType resume_state)
 {
-    ClearStackFrames();
-    Thread::WillResume(resume_state);
+    if (m_backing_thread_sp)
+        m_backing_thread_sp->WillResume(resume_state);
+}
 
+void
+ThreadMemory::ClearStackFrames ()
+{
     if (m_backing_thread_sp)
-        return m_backing_thread_sp->WillResume(resume_state);
-    return true;
+        m_backing_thread_sp->ClearStackFrames();
+    Thread::ClearStackFrames();
 }
 
 RegisterContextSP
 ThreadMemory::GetRegisterContext ()
 {
-    if (m_backing_thread_sp)
-        return m_backing_thread_sp->GetRegisterContext();
-
     if (!m_reg_context_sp)
-    {
-        ProcessSP process_sp (GetProcess());
-        if (process_sp)
-        {
-            OperatingSystem *os = process_sp->GetOperatingSystem ();
-            if (os)
-                m_reg_context_sp = os->CreateRegisterContextForThread (this, m_register_data_addr);
-        }
-    }
+        m_reg_context_sp.reset (new RegisterContextThreadMemory (*this, m_register_data_addr));
     return m_reg_context_sp;
 }
 
 RegisterContextSP
 ThreadMemory::CreateRegisterContextForFrame (StackFrame *frame)
 {
-    if (m_backing_thread_sp)
-        return m_backing_thread_sp->CreateRegisterContextForFrame(frame);
-
     RegisterContextSP reg_ctx_sp;
     uint32_t concrete_frame_idx = 0;
     
@@ -108,11 +99,179 @@ ThreadMemory::CreateRegisterContextForFr
     return reg_ctx_sp;
 }
 
+
+//class StopInfoThreadMemory : public StopInfo
+//{
+//public:
+//    //------------------------------------------------------------------
+//    // Constructors and Destructors
+//    //------------------------------------------------------------------
+//    StopInfoThreadMemory (Thread &thread,
+//                          uint64_t value,
+//                          StopInfoSP &backing_stop_info_sp) :
+//    StopInfo (thread, value),
+//    m_backing_stop_info_sp (backing_stop_info_sp)
+//    {
+//    }
+//    
+//    virtual
+//    ~StopInfoThreadMemory()
+//    {
+//    }
+//    
+//    virtual bool
+//    IsValid () const
+//    {
+//        ThreadSP backing_thread_sp (m_thread.GetBackingThread());
+//        if (backing_thread_sp)
+//            return backing_thread_sp->IsValid();
+//        return StopInfo::IsValid();
+//    }
+//    
+//    virtual Thread &
+//    GetThread()
+//    {
+//        return m_thread;
+//    }
+//    
+//    virtual const Thread &
+//    GetThread() const
+//    {
+//        return m_thread;
+//    }
+//    
+//    virtual uint64_t
+//    GetValue() const
+//    {
+//        if (m_backing_stop_info_sp)
+//            return m_backing_stop_info_sp->GetValue();
+//        return StopInfo::GetValue();
+//    }
+//    
+//    virtual lldb::StopReason
+//    GetStopReason () const
+//    {
+//        if (m_backing_stop_info_sp)
+//            return m_backing_stop_info_sp->GetStopReason();
+//        return eStopReasonNone;
+//    }
+//    
+//    // ShouldStopSynchronous will get called before any thread plans are consulted, and if it says we should
+//    // resume the target, then we will just immediately resume.  This should not run any code in or resume the
+//    // target.
+//    
+//    virtual bool
+//    ShouldStopSynchronous (Event *event_ptr)
+//    {
+//        if (m_backing_stop_info_sp)
+//            return m_backing_stop_info_sp->ShouldStopSynchronous(event_ptr);
+//        return StopInfo::ShouldStopSynchronous (event_ptr);
+//    }
+//    
+//    // If should stop returns false, check if we should notify of this event
+//    virtual bool
+//    ShouldNotify (Event *event_ptr)
+//    {
+//        if (m_backing_stop_info_sp)
+//            return m_backing_stop_info_sp->ShouldNotify(event_ptr);
+//        return StopInfo::ShouldNotify (event_ptr);
+//    }
+//    
+//    virtual void
+//    WillResume (lldb::StateType resume_state)
+//    {
+//        if (m_backing_stop_info_sp)
+//            return m_backing_stop_info_sp->WillResume(resume_state);
+//        return StopInfo::WillResume (resume_state);
+//    }
+//    
+//    virtual const char *
+//    GetDescription ()
+//    {
+//        if (m_backing_stop_info_sp)
+//            return m_backing_stop_info_sp->GetDescription();
+//        return StopInfo::GetDescription();
+//    }
+//    
+//    virtual void
+//    SetDescription (const char *desc_cstr)
+//    {
+//        if (m_backing_stop_info_sp)
+//            m_backing_stop_info_sp->SetDescription(desc_cstr);
+//        StopInfo::SetDescription(desc_cstr);
+//    }
+//    
+//    // Sometimes the thread plan logic will know that it wants a given stop to stop or not,
+//    // regardless of what the ordinary logic for that StopInfo would dictate.  The main example
+//    // of this is the ThreadPlanCallFunction, which for instance knows - based on how that particular
+//    // expression was executed - whether it wants all breakpoints to auto-continue or not.
+//    // Use OverrideShouldStop on the StopInfo to implement this.
+//    
+//    virtual void
+//    OverrideShouldStop (bool override_value)
+//    {
+//        if (m_backing_stop_info_sp)
+//            m_backing_stop_info_sp->OverrideShouldStop(override_value);
+//        StopInfo::OverrideShouldStop (override_value);
+//    }
+//    
+//    virtual bool
+//    GetOverrideShouldStop()
+//    {
+//        if (m_backing_stop_info_sp)
+//            return m_backing_stop_info_sp->GetOverrideShouldStop();
+//        return StopInfo::GetOverrideShouldStop();
+//    }
+//    
+//    virtual bool
+//    GetOverriddenShouldStopValue ()
+//    {
+//        if (m_backing_stop_info_sp)
+//            return m_backing_stop_info_sp->GetOverriddenShouldStopValue();
+//        return StopInfo::GetOverriddenShouldStopValue();
+//    }
+//    
+//    virtual void
+//    PerformAction (Event *event_ptr)
+//    {
+//        if (m_backing_stop_info_sp)
+//            return m_backing_stop_info_sp->PerformAction(event_ptr);
+//        return StopInfo::PerformAction(event_ptr);
+//    }
+//    
+//    virtual bool
+//    ShouldStop (Event *event_ptr)
+//    {
+//        if (m_backing_stop_info_sp)
+//            return m_backing_stop_info_sp->ShouldStop(event_ptr);
+//        return StopInfo::ShouldStop(event_ptr);
+//    }
+//    
+//    
+//protected:
+//    StopInfoSP m_backing_stop_info_sp;
+//    
+//private:
+//    DISALLOW_COPY_AND_ASSIGN (StopInfoThreadMemory);
+//};
+
+
 lldb::StopInfoSP
 ThreadMemory::GetPrivateStopReason ()
 {
+    if (m_actual_stop_info_sp)
+        return m_actual_stop_info_sp;
+
     if (m_backing_thread_sp)
-        return m_backing_thread_sp->GetPrivateStopReason();
+    {
+        lldb::StopInfoSP backing_stop_info_sp (m_backing_thread_sp->GetPrivateStopReason());
+        if (backing_stop_info_sp)
+        {
+            m_actual_stop_info_sp = backing_stop_info_sp;
+            m_actual_stop_info_sp->SetThread (shared_from_this());
+            return m_actual_stop_info_sp;
+        }
+    }
 
     ProcessSP process_sp (GetProcess());
 
@@ -150,15 +309,4 @@ ThreadMemory::RefreshStateAfterStop()
 {
     if (m_backing_thread_sp)
         return m_backing_thread_sp->RefreshStateAfterStop();
-    
-
-    // Don't fetch the registers by calling Thread::GetRegisterContext() below.
-    // We might not have fetched any registers yet and we don't want to fetch
-    // the registers just to call invalidate on them...
-    RegisterContextSP reg_ctx_sp(m_reg_context_sp);
-    if (reg_ctx_sp)
-    {
-        const bool force = true;
-        reg_ctx_sp->InvalidateIfNeeded (force);
-    }
 }

Modified: lldb/trunk/source/Plugins/Process/Utility/ThreadMemory.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/ThreadMemory.h?rev=180886&r1=180885&r2=180886&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/ThreadMemory.h (original)
+++ lldb/trunk/source/Plugins/Process/Utility/ThreadMemory.h Wed May  1 16:54:04 2013
@@ -70,7 +70,7 @@ public:
         return NULL;
     }
 
-    virtual bool
+    virtual void
     WillResume (lldb::StateType resume_state);
 
     virtual void
@@ -79,6 +79,14 @@ public:
         if (m_backing_thread_sp)
             m_backing_thread_sp->DidResume();
     }
+    
+    virtual lldb::user_id_t
+    GetProtocolID () const
+    {
+        if (m_backing_thread_sp)
+            return m_backing_thread_sp->GetProtocolID();
+        return Thread::GetProtocolID();
+    }
 
     virtual void
     RefreshStateAfterStop();
@@ -90,6 +98,9 @@ public:
     }
     
     virtual void
+    ClearStackFrames ();
+
+    virtual void
     ClearBackingThread ()
     {
         m_backing_thread_sp.reset();
@@ -98,6 +109,7 @@ public:
     virtual bool
     SetBackingThread (const lldb::ThreadSP &thread_sp)
     {
+        //printf ("Thread 0x%llx is being backed by thread 0x%llx\n", GetID(), thread_sp->GetID());
         m_backing_thread_sp = thread_sp;
         return (bool)thread_sp;
     }
@@ -109,6 +121,14 @@ public:
     }
 
 protected:
+    
+    virtual bool
+    IsOperatingSystemPluginThread () const
+    {
+        return true;
+    }
+    
+
     //------------------------------------------------------------------
     // For ThreadMemory and subclasses
     //------------------------------------------------------------------

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp?rev=180886&r1=180885&r2=180886&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp Wed May  1 16:54:04 2013
@@ -155,7 +155,7 @@ GDBRemoteRegisterContext::GetPrimordialR
     int packet_len = 0;
     const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
     if (gdb_comm.GetThreadSuffixSupported())
-        packet_len = ::snprintf (packet, sizeof(packet), "p%x;thread:%4.4" PRIx64 ";", reg, m_thread.GetID());
+        packet_len = ::snprintf (packet, sizeof(packet), "p%x;thread:%4.4" PRIx64 ";", reg, m_thread.GetProtocolID());
     else
         packet_len = ::snprintf (packet, sizeof(packet), "p%x", reg);
     assert (packet_len < (sizeof(packet) - 1));
@@ -187,7 +187,7 @@ GDBRemoteRegisterContext::ReadRegisterBy
         {
             const bool thread_suffix_supported = gdb_comm.GetThreadSuffixSupported();
             ProcessSP process_sp (m_thread.GetProcess());
-            if (thread_suffix_supported || static_cast<ProcessGDBRemote *>(process_sp.get())->GetGDBRemote().SetCurrentThread(m_thread.GetID()))
+            if (thread_suffix_supported || static_cast<ProcessGDBRemote *>(process_sp.get())->GetGDBRemote().SetCurrentThread(m_thread.GetProtocolID()))
             {
                 char packet[64];
                 StringExtractorGDBRemote response;
@@ -196,7 +196,7 @@ GDBRemoteRegisterContext::ReadRegisterBy
                 {
                     // Get all registers in one packet
                     if (thread_suffix_supported)
-                        packet_len = ::snprintf (packet, sizeof(packet), "g;thread:%4.4" PRIx64 ";", m_thread.GetID());
+                        packet_len = ::snprintf (packet, sizeof(packet), "g;thread:%4.4" PRIx64 ";", m_thread.GetProtocolID());
                     else
                         packet_len = ::snprintf (packet, sizeof(packet), "g");
                     assert (packet_len < (sizeof(packet) - 1));
@@ -314,7 +314,7 @@ GDBRemoteRegisterContext::SetPrimordialR
                               lldb::endian::InlHostByteOrder());
 
     if (gdb_comm.GetThreadSuffixSupported())
-        packet.Printf (";thread:%4.4" PRIx64 ";", m_thread.GetID());
+        packet.Printf (";thread:%4.4" PRIx64 ";", m_thread.GetProtocolID());
 
     // Invalidate just this register
     SetRegisterIsValid(reg, false);
@@ -340,7 +340,7 @@ GDBRemoteRegisterContext::SyncThreadStat
 
     StreamString packet;
     StringExtractorGDBRemote response;
-    packet.Printf ("QSyncThreadState:%4.4" PRIx64 ";", m_thread.GetID());
+    packet.Printf ("QSyncThreadState:%4.4" PRIx64 ";", m_thread.GetProtocolID());
     if (gdb_comm.SendPacketAndWaitForResponse(packet.GetString().c_str(),
                                               packet.GetString().size(),
                                               response,
@@ -386,7 +386,7 @@ GDBRemoteRegisterContext::WriteRegisterB
         {
             const bool thread_suffix_supported = gdb_comm.GetThreadSuffixSupported();
             ProcessSP process_sp (m_thread.GetProcess());
-            if (thread_suffix_supported || static_cast<ProcessGDBRemote *>(process_sp.get())->GetGDBRemote().SetCurrentThread(m_thread.GetID()))
+            if (thread_suffix_supported || static_cast<ProcessGDBRemote *>(process_sp.get())->GetGDBRemote().SetCurrentThread(m_thread.GetProtocolID()))
             {
                 StreamString packet;
                 StringExtractorGDBRemote response;
@@ -401,7 +401,7 @@ GDBRemoteRegisterContext::WriteRegisterB
                                               lldb::endian::InlHostByteOrder());
 
                     if (thread_suffix_supported)
-                        packet.Printf (";thread:%4.4" PRIx64 ";", m_thread.GetID());
+                        packet.Printf (";thread:%4.4" PRIx64 ";", m_thread.GetProtocolID());
 
                     // Invalidate all register values
                     InvalidateIfNeeded (true);
@@ -508,11 +508,11 @@ GDBRemoteRegisterContext::ReadAllRegiste
         char packet[32];
         const bool thread_suffix_supported = gdb_comm.GetThreadSuffixSupported();
         ProcessSP process_sp (m_thread.GetProcess());
-        if (thread_suffix_supported || static_cast<ProcessGDBRemote *>(process_sp.get())->GetGDBRemote().SetCurrentThread(m_thread.GetID()))
+        if (thread_suffix_supported || static_cast<ProcessGDBRemote *>(process_sp.get())->GetGDBRemote().SetCurrentThread(m_thread.GetProtocolID()))
         {
             int packet_len = 0;
             if (thread_suffix_supported)
-                packet_len = ::snprintf (packet, sizeof(packet), "g;thread:%4.4" PRIx64, m_thread.GetID());
+                packet_len = ::snprintf (packet, sizeof(packet), "g;thread:%4.4" PRIx64, m_thread.GetProtocolID());
             else
                 packet_len = ::snprintf (packet, sizeof(packet), "g");
             assert (packet_len < (sizeof(packet) - 1));
@@ -529,7 +529,7 @@ GDBRemoteRegisterContext::ReadAllRegiste
                     if (thread_suffix_supported)
                     {
                         char thread_id_cstr[64];
-                        ::snprintf (thread_id_cstr, sizeof(thread_id_cstr), ";thread:%4.4" PRIx64 ";", m_thread.GetID());
+                        ::snprintf (thread_id_cstr, sizeof(thread_id_cstr), ";thread:%4.4" PRIx64 ";", m_thread.GetProtocolID());
                         response_str.append (thread_id_cstr);
                     }
                     data_sp.reset (new DataBufferHeap (response_str.c_str(), response_str.size()));
@@ -579,7 +579,7 @@ GDBRemoteRegisterContext::WriteAllRegist
     {
         const bool thread_suffix_supported = gdb_comm.GetThreadSuffixSupported();
         ProcessSP process_sp (m_thread.GetProcess());
-        if (thread_suffix_supported || static_cast<ProcessGDBRemote *>(process_sp.get())->GetGDBRemote().SetCurrentThread(m_thread.GetID()))
+        if (thread_suffix_supported || static_cast<ProcessGDBRemote *>(process_sp.get())->GetGDBRemote().SetCurrentThread(m_thread.GetProtocolID()))
         {
             // The data_sp contains the entire G response packet including the
             // G, and if the thread suffix is supported, it has the thread suffix
@@ -652,7 +652,7 @@ GDBRemoteRegisterContext::WriteAllRegist
                                                           lldb::endian::InlHostByteOrder());
 
                                 if (thread_suffix_supported)
-                                    packet.Printf (";thread:%4.4" PRIx64 ";", m_thread.GetID());
+                                    packet.Printf (";thread:%4.4" PRIx64 ";", m_thread.GetProtocolID());
 
                                 SetRegisterIsValid(reg, false);
                                 if (gdb_comm.SendPacketAndWaitForResponse(packet.GetString().c_str(),

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp?rev=180886&r1=180885&r2=180886&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp Wed May  1 16:54:04 2013
@@ -1322,7 +1322,13 @@ ProcessGDBRemote::UpdateThreadList (Thre
         for (size_t i=0; i<num_thread_ids; ++i)
         {
             tid_t tid = m_thread_ids[i];
-            ThreadSP thread_sp (old_thread_list_copy.RemoveThreadByID (tid, false));
+            ThreadSP thread_sp (old_thread_list_copy.RemoveThreadByProtocolID(tid, false));
+            if (thread_sp)
+            {
+                ThreadSP backing_thread_sp (thread_sp->GetBackingThread());
+                if (backing_thread_sp && backing_thread_sp->GetProtocolID() == tid)
+                    thread_sp = backing_thread_sp;
+            }
             if (!thread_sp)
                 thread_sp.reset (new ThreadGDBRemote (*this, tid));
             new_thread_list.AddThread(thread_sp);
@@ -1337,7 +1343,7 @@ ProcessGDBRemote::UpdateThreadList (Thre
         ThreadSP old_thread_sp(old_thread_list_copy.GetThreadAtIndex (i, false));
         if (old_thread_sp)
         {
-            lldb::tid_t old_thread_id = old_thread_sp->GetID();
+            lldb::tid_t old_thread_id = old_thread_sp->GetProtocolID();
             m_thread_id_to_index_id_map.erase(old_thread_id);
         }
     }
@@ -1379,6 +1385,8 @@ ProcessGDBRemote::SetThreadStopInfo (Str
             std::vector<addr_t> exc_data;
             addr_t thread_dispatch_qaddr = LLDB_INVALID_ADDRESS;
             ThreadSP thread_sp;
+            ThreadSP backing_thread_sp;
+            ThreadGDBRemote *gdb_thread = NULL;
 
             while (stop_packet.GetNameColonValue(name, value))
             {
@@ -1400,34 +1408,21 @@ ProcessGDBRemote::SetThreadStopInfo (Str
                     // hold onto the mutex between the call to m_thread_list.FindThreadByID(...)
                     // and the m_thread_list.AddThread(...) so it doesn't change on us
                     Mutex::Locker locker (m_thread_list.GetMutex ());
-                    thread_sp = m_thread_list.FindThreadByID(tid, false);
-                    if (!thread_sp)
+                    thread_sp = m_thread_list.FindThreadByProtocolID(tid, false);
+
+                    if (thread_sp)
                     {
-                        // If there is an operating system plug-in it might hiding the actual API
-                        // thread inside a ThreadMemory...
-                        if (GetOperatingSystem())
-                        {
-                            bool found_backing_thread = false;
-                            const uint32_t num_threads = m_thread_list.GetSize();
-                            for (uint32_t thread_idx = 0; thread_idx < num_threads; ++thread_idx)
-                            {
-                                thread_sp = m_thread_list.GetThreadAtIndex(thread_idx)->GetBackingThread();
-                                if (thread_sp && thread_sp->GetID() == tid)
-                                {
-                                    found_backing_thread = true;
-                                    break;
-                                }
-                            }
-                            
-                            if (!found_backing_thread)
-                                thread_sp.reset();
-                        }
+                        backing_thread_sp = thread_sp->GetBackingThread();
+                        if (backing_thread_sp)
+                            gdb_thread = static_cast<ThreadGDBRemote *> (backing_thread_sp.get());
+                        else
+                            gdb_thread = static_cast<ThreadGDBRemote *> (thread_sp.get());
                     }
-                    
-                    if (!thread_sp)
+                    else
                     {
                         // Create the thread if we need to
                         thread_sp.reset (new ThreadGDBRemote (*this, tid));
+                        gdb_thread = static_cast<ThreadGDBRemote *> (thread_sp.get());
                         m_thread_list.AddThread(thread_sp);
                     }
                 }
@@ -1488,7 +1483,7 @@ ProcessGDBRemote::SetThreadStopInfo (Str
                     // We have a register number that contains an expedited
                     // register value. Lets supply this register to our thread
                     // so it won't have to go and read it.
-                    if (thread_sp)
+                    if (gdb_thread)
                     {
                         uint32_t reg = Args::StringToUInt32 (name.c_str(), UINT32_MAX, 16);
 
@@ -1497,7 +1492,7 @@ ProcessGDBRemote::SetThreadStopInfo (Str
                             StringExtractor reg_value_extractor;
                             // Swap "value" over into "reg_value_extractor"
                             reg_value_extractor.GetStringRef().swap(value);
-                            if (!static_cast<ThreadGDBRemote *> (thread_sp.get())->PrivateSetRegisterValue (reg, reg_value_extractor))
+                            if (!gdb_thread->PrivateSetRegisterValue (reg, reg_value_extractor))
                             {
                                 Host::SetCrashDescriptionWithFormat("Setting thread register '%s' (decoded to %u (0x%x)) with value '%s' for stop packet: '%s'", 
                                                                     name.c_str(), 
@@ -1513,20 +1508,18 @@ ProcessGDBRemote::SetThreadStopInfo (Str
 
             if (thread_sp)
             {
-                ThreadGDBRemote *gdb_thread = static_cast<ThreadGDBRemote *> (thread_sp.get());
-
                 gdb_thread->SetThreadDispatchQAddr (thread_dispatch_qaddr);
                 gdb_thread->SetName (thread_name.empty() ? NULL : thread_name.c_str());
                 if (exc_type != 0)
                 {
                     const size_t exc_data_size = exc_data.size();
 
-                    gdb_thread->SetStopInfo (StopInfoMachException::CreateStopReasonWithMachException (*thread_sp,
-                                                                                                       exc_type, 
-                                                                                                       exc_data_size,
-                                                                                                       exc_data_size >= 1 ? exc_data[0] : 0,
-                                                                                                       exc_data_size >= 2 ? exc_data[1] : 0,
-                                                                                                       exc_data_size >= 3 ? exc_data[2] : 0));
+                    thread_sp->SetStopInfo (StopInfoMachException::CreateStopReasonWithMachException (*thread_sp,
+                                                                                                      exc_type,
+                                                                                                      exc_data_size,
+                                                                                                      exc_data_size >= 1 ? exc_data[0] : 0,
+                                                                                                      exc_data_size >= 2 ? exc_data[1] : 0,
+                                                                                                      exc_data_size >= 3 ? exc_data[2] : 0));
                 }
                 else
                 {
@@ -1535,27 +1528,27 @@ ProcessGDBRemote::SetThreadStopInfo (Str
                     {
                         if (reason.compare("trace") == 0)
                         {
-                            gdb_thread->SetStopInfo (StopInfo::CreateStopReasonToTrace (*thread_sp));
+                            thread_sp->SetStopInfo (StopInfo::CreateStopReasonToTrace (*thread_sp));
                             handled = true;
                         }
                         else if (reason.compare("breakpoint") == 0)
                         {
-                            addr_t pc = gdb_thread->GetRegisterContext()->GetPC();
-                            lldb::BreakpointSiteSP bp_site_sp = gdb_thread->GetProcess()->GetBreakpointSiteList().FindByAddress(pc);
+                            addr_t pc = thread_sp->GetRegisterContext()->GetPC();
+                            lldb::BreakpointSiteSP bp_site_sp = thread_sp->GetProcess()->GetBreakpointSiteList().FindByAddress(pc);
                             if (bp_site_sp)
                             {
                                 // If the breakpoint is for this thread, then we'll report the hit, but if it is for another thread,
                                 // we can just report no reason.  We don't need to worry about stepping over the breakpoint here, that
                                 // will be taken care of when the thread resumes and notices that there's a breakpoint under the pc.
                                 handled = true;
-                                if (bp_site_sp->ValidForThisThread (gdb_thread))
+                                if (bp_site_sp->ValidForThisThread (thread_sp.get()))
                                 {
-                                    gdb_thread->SetStopInfo (StopInfo::CreateStopReasonWithBreakpointSiteID (*thread_sp, bp_site_sp->GetID()));
+                                    thread_sp->SetStopInfo (StopInfo::CreateStopReasonWithBreakpointSiteID (*thread_sp, bp_site_sp->GetID()));
                                 }
                                 else
                                 {
                                     StopInfoSP invalid_stop_info_sp;
-                                    gdb_thread->SetStopInfo (invalid_stop_info_sp);
+                                    thread_sp->SetStopInfo (invalid_stop_info_sp);
                                 }
                             }
                             
@@ -1568,12 +1561,12 @@ ProcessGDBRemote::SetThreadStopInfo (Str
                         {
                             break_id_t watch_id = LLDB_INVALID_WATCH_ID;
                             // TODO: locate the watchpoint somehow...
-                            gdb_thread->SetStopInfo (StopInfo::CreateStopReasonWithWatchpointID (*thread_sp, watch_id));
+                            thread_sp->SetStopInfo (StopInfo::CreateStopReasonWithWatchpointID (*thread_sp, watch_id));
                             handled = true;
                         }
                         else if (reason.compare("exception") == 0)
                         {
-                            gdb_thread->SetStopInfo (StopInfo::CreateStopReasonWithException(*thread_sp, description.c_str()));
+                            thread_sp->SetStopInfo (StopInfo::CreateStopReasonWithException(*thread_sp, description.c_str()));
                             handled = true;
                         }
                     }
@@ -1585,22 +1578,22 @@ ProcessGDBRemote::SetThreadStopInfo (Str
                             // Currently we are going to assume SIGTRAP means we are either
                             // hitting a breakpoint or hardware single stepping. 
                             handled = true;
-                            addr_t pc = gdb_thread->GetRegisterContext()->GetPC();
-                            lldb::BreakpointSiteSP bp_site_sp = gdb_thread->GetProcess()->GetBreakpointSiteList().FindByAddress(pc);
+                            addr_t pc = thread_sp->GetRegisterContext()->GetPC();
+                            lldb::BreakpointSiteSP bp_site_sp = thread_sp->GetProcess()->GetBreakpointSiteList().FindByAddress(pc);
                             
                             if (bp_site_sp)
                             {
                                 // If the breakpoint is for this thread, then we'll report the hit, but if it is for another thread,
                                 // we can just report no reason.  We don't need to worry about stepping over the breakpoint here, that
                                 // will be taken care of when the thread resumes and notices that there's a breakpoint under the pc.
-                                if (bp_site_sp->ValidForThisThread (gdb_thread))
+                                if (bp_site_sp->ValidForThisThread (thread_sp.get()))
                                 {
-                                    gdb_thread->SetStopInfo (StopInfo::CreateStopReasonWithBreakpointSiteID (*thread_sp, bp_site_sp->GetID()));
+                                    thread_sp->SetStopInfo (StopInfo::CreateStopReasonWithBreakpointSiteID (*thread_sp, bp_site_sp->GetID()));
                                 }
                                 else
                                 {
                                     StopInfoSP invalid_stop_info_sp;
-                                    gdb_thread->SetStopInfo (invalid_stop_info_sp);
+                                    thread_sp->SetStopInfo (invalid_stop_info_sp);
                                 }
                             }
                             else
@@ -1608,31 +1601,31 @@ ProcessGDBRemote::SetThreadStopInfo (Str
                                 // If we were stepping then assume the stop was the result of the trace.  If we were
                                 // not stepping then report the SIGTRAP.
                                 // FIXME: We are still missing the case where we single step over a trap instruction.
-                                if (gdb_thread->GetTemporaryResumeState() == eStateStepping)
-                                    gdb_thread->SetStopInfo (StopInfo::CreateStopReasonToTrace (*thread_sp));
+                                if (thread_sp->GetTemporaryResumeState() == eStateStepping)
+                                    thread_sp->SetStopInfo (StopInfo::CreateStopReasonToTrace (*thread_sp));
                                 else
-                                    gdb_thread->SetStopInfo (StopInfo::CreateStopReasonWithSignal(*thread_sp, signo));
+                                    thread_sp->SetStopInfo (StopInfo::CreateStopReasonWithSignal(*thread_sp, signo));
                             }
                         }
                         if (!handled)
-                            gdb_thread->SetStopInfo (StopInfo::CreateStopReasonWithSignal (*thread_sp, signo));
+                            thread_sp->SetStopInfo (StopInfo::CreateStopReasonWithSignal (*thread_sp, signo));
                     }
                     else
                     {
                         StopInfoSP invalid_stop_info_sp;
-                        gdb_thread->SetStopInfo (invalid_stop_info_sp);
+                        thread_sp->SetStopInfo (invalid_stop_info_sp);
                     }
                     
                     if (!description.empty())
                     {
-                        lldb::StopInfoSP stop_info_sp (gdb_thread->GetStopInfo ());
+                        lldb::StopInfoSP stop_info_sp (thread_sp->GetStopInfo ());
                         if (stop_info_sp)
                         {
                             stop_info_sp->SetDescription (description.c_str());
                         }
                         else
                         {
-                            gdb_thread->SetStopInfo (StopInfo::CreateStopReasonWithException (*thread_sp, description.c_str()));
+                            thread_sp->SetStopInfo (StopInfo::CreateStopReasonWithException (*thread_sp, description.c_str()));
                         }
                     }
                 }
@@ -1797,8 +1790,8 @@ ProcessGDBRemote::DoDestroy ()
                             || reason == eStopReasonException)
                         {
                             if (log)
-                                log->Printf ("ProcessGDBRemote::DoDestroy() - thread: %" PRId64 " stopped with reason: %s.",
-                                             thread_sp->GetID(),
+                                log->Printf ("ProcessGDBRemote::DoDestroy() - thread: 0x%4.4" PRIx64 " stopped with reason: %s.",
+                                             thread_sp->GetProtocolID(),
                                              stop_info_sp->GetDescription());
                             stop_looks_like_crash = true;
                             break;
@@ -1832,8 +1825,8 @@ ProcessGDBRemote::DoDestroy ()
                                 && reason != eStopReasonException)
                             {
                                 if (log)
-                                    log->Printf ("ProcessGDBRemote::DoDestroy() - Suspending thread: %" PRId64 " before running.",
-                                                 thread_sp->GetID());
+                                    log->Printf ("ProcessGDBRemote::DoDestroy() - Suspending thread: 0x%4.4" PRIx64 " before running.",
+                                                 thread_sp->GetProtocolID());
                                 thread_sp->SetResumeState(eStateSuspended);
                             }
                         }

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp?rev=180886&r1=180885&r2=180886&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp Wed May  1 16:54:04 2013
@@ -80,24 +80,14 @@ ThreadGDBRemote::GetQueueName ()
     return NULL;
 }
 
-bool
+void
 ThreadGDBRemote::WillResume (StateType resume_state)
 {
-    // Call the Thread::WillResume first. If we stop at a signal, the stop info
-    // class for signal will set the resume signal that we need below. The signal
-    // stuff obeys the Process::UnixSignal defaults. 
-    // If the thread's WillResume returns false, that means that we aren't going to actually resume,
-    // in which case we should not do the rest of our "resume" work.
-    
-    if (!Thread::WillResume(resume_state))
-        return false;
-    
-    ClearStackFrames();
-
     int signo = GetResumeSignal();
+    const lldb::user_id_t tid = GetProtocolID();
     Log *log(lldb_private::GetLogIfAnyCategoriesSet (GDBR_LOG_THREAD));
     if (log)
-        log->Printf ("Resuming thread: %4.4" PRIx64 " with state: %s.", GetID(), StateAsCString(resume_state));
+        log->Printf ("Resuming thread: %4.4" PRIx64 " with state: %s.", tid, StateAsCString(resume_state));
 
     ProcessSP process_sp (GetProcess());
     if (process_sp)
@@ -112,24 +102,22 @@ ThreadGDBRemote::WillResume (StateType r
 
         case eStateRunning:
             if (gdb_process->GetUnixSignals().SignalIsValid (signo))
-                gdb_process->m_continue_C_tids.push_back(std::make_pair(GetID(), signo));
+                gdb_process->m_continue_C_tids.push_back(std::make_pair(tid, signo));
             else
-                gdb_process->m_continue_c_tids.push_back(GetID());
+                gdb_process->m_continue_c_tids.push_back(tid);
             break;
 
         case eStateStepping:
             if (gdb_process->GetUnixSignals().SignalIsValid (signo))
-                gdb_process->m_continue_S_tids.push_back(std::make_pair(GetID(), signo));
+                gdb_process->m_continue_S_tids.push_back(std::make_pair(tid, signo));
             else
-                gdb_process->m_continue_s_tids.push_back(GetID());
+                gdb_process->m_continue_s_tids.push_back(tid);
             break;
 
         default:
             break;
         }
-        return true;
     }
-    return false;
 }
 
 void
@@ -147,16 +135,6 @@ ThreadGDBRemote::RefreshStateAfterStop()
     GetRegisterContext()->InvalidateIfNeeded (force);
 }
 
-void
-ThreadGDBRemote::ClearStackFrames ()
-{
-    Unwind *unwinder = GetUnwinder ();
-    if (unwinder)
-        unwinder->Clear();
-    Thread::ClearStackFrames();
-}
-
-
 bool
 ThreadGDBRemote::ThreadIDIsValid (lldb::tid_t thread)
 {
@@ -245,7 +223,7 @@ ThreadGDBRemote::GetPrivateStopReason ()
 
             StringExtractorGDBRemote stop_packet;
             ProcessGDBRemote *gdb_process = static_cast<ProcessGDBRemote *>(process_sp.get());
-            if (gdb_process->GetGDBRemote().GetThreadStopInfo(GetID(), stop_packet))
+            if (gdb_process->GetGDBRemote().GetThreadStopInfo(GetProtocolID(), stop_packet))
                 gdb_process->SetThreadStopInfo (stop_packet);
         }
     }

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h?rev=180886&r1=180885&r2=180886&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h Wed May  1 16:54:04 2013
@@ -26,7 +26,7 @@ public:
     virtual
     ~ThreadGDBRemote ();
 
-    virtual bool
+    virtual void
     WillResume (lldb::StateType resume_state);
 
     virtual void
@@ -44,9 +44,6 @@ public:
     virtual lldb::RegisterContextSP
     CreateRegisterContextForFrame (lldb_private::StackFrame *frame);
 
-    virtual void
-    ClearStackFrames ();
-
     void
     Dump (lldb_private::Log *log, uint32_t index);
 

Modified: lldb/trunk/source/Plugins/Process/mach-core/ThreadMachCore.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/mach-core/ThreadMachCore.cpp?rev=180886&r1=180885&r2=180886&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/mach-core/ThreadMachCore.cpp (original)
+++ lldb/trunk/source/Plugins/Process/mach-core/ThreadMachCore.cpp Wed May  1 16:54:04 2013
@@ -73,16 +73,6 @@ ThreadMachCore::RefreshStateAfterStop()
     GetRegisterContext()->InvalidateIfNeeded (force);
 }
 
-void
-ThreadMachCore::ClearStackFrames ()
-{
-    Unwind *unwinder = GetUnwinder ();
-    if (unwinder)
-        unwinder->Clear();
-    Thread::ClearStackFrames();
-}
-
-
 bool
 ThreadMachCore::ThreadIDIsValid (lldb::tid_t thread)
 {

Modified: lldb/trunk/source/Plugins/Process/mach-core/ThreadMachCore.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/mach-core/ThreadMachCore.h?rev=180886&r1=180885&r2=180886&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/mach-core/ThreadMachCore.h (original)
+++ lldb/trunk/source/Plugins/Process/mach-core/ThreadMachCore.h Wed May  1 16:54:04 2013
@@ -37,9 +37,6 @@ public:
     virtual lldb::RegisterContextSP
     CreateRegisterContextForFrame (lldb_private::StackFrame *frame);
 
-    virtual void
-    ClearStackFrames ();
-
     static bool
     ThreadIDIsValid (lldb::tid_t thread);
 

Modified: lldb/trunk/source/Target/OperatingSystem.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/OperatingSystem.cpp?rev=180886&r1=180885&r2=180886&view=diff
==============================================================================
--- lldb/trunk/source/Target/OperatingSystem.cpp (original)
+++ lldb/trunk/source/Target/OperatingSystem.cpp Wed May  1 16:54:04 2013
@@ -13,7 +13,7 @@
 // C++ Includes
 // Other libraries and framework includes
 #include "lldb/Core/PluginManager.h"
-
+#include "lldb/Target/Thread.h"
 
 using namespace lldb;
 using namespace lldb_private;
@@ -54,3 +54,13 @@ OperatingSystem::OperatingSystem (Proces
 OperatingSystem::~OperatingSystem()
 {
 }
+
+
+bool
+OperatingSystem::IsOperatingSystemPluginThread (const lldb::ThreadSP &thread_sp)
+{
+    if (thread_sp)
+        return thread_sp->IsOperatingSystemPluginThread();
+    return false;
+}
+

Modified: lldb/trunk/source/Target/Thread.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Thread.cpp?rev=180886&r1=180885&r2=180886&view=diff
==============================================================================
--- lldb/trunk/source/Target/Thread.cpp (original)
+++ lldb/trunk/source/Target/Thread.cpp Wed May  1 16:54:04 2013
@@ -13,6 +13,7 @@
 #include "lldb/Breakpoint/BreakpointLocation.h"
 #include "lldb/Core/Debugger.h"
 #include "lldb/Core/Log.h"
+#include "lldb/Core/State.h"
 #include "lldb/Core/Stream.h"
 #include "lldb/Core/StreamString.h"
 #include "lldb/Core/RegularExpression.h"
@@ -244,6 +245,7 @@ Thread::Thread (Process &process, lldb::
     m_process_wp (process.shared_from_this()),
     m_actual_stop_info_sp (),
     m_index_id (process.GetNextThreadIndexID(tid)),
+    m_protocol_tid (tid),
     m_reg_context_sp (),
     m_state (eStateUnloaded),
     m_state_mutex (Mutex::eMutexTypeRecursive),
@@ -517,7 +519,7 @@ Thread::SetupForResume ()
 }
 
 bool
-Thread::WillResume (StateType resume_state)
+Thread::ShouldResume (StateType resume_state)
 {
     // At this point clear the completed plan stack.
     m_completed_plan_stack.clear();
@@ -525,6 +527,9 @@ Thread::WillResume (StateType resume_sta
 
     m_temporary_resume_state = resume_state;
     
+    // Make sure m_actual_stop_info_sp is valid
+    GetPrivateStopReason();
+    
     // This is a little dubious, but we are trying to limit how often we actually fetch stop info from
     // the target, 'cause that slows down single stepping.  So assume that if we got to the point where
     // we're about to resume, and we haven't yet had to fetch the stop reason, then it doesn't need to know
@@ -562,6 +567,13 @@ Thread::WillResume (StateType resume_sta
         }
     }
 
+    if (need_to_resume)
+    {
+        ClearStackFrames();
+        // Let Thread subclasses do any special work they need to prior to resuming
+        WillResume (resume_state);
+    }
+
     return need_to_resume;
 }
 
@@ -583,36 +595,40 @@ Thread::ShouldStop (Event* event_ptr)
     if (GetResumeState () == eStateSuspended)
     {
         if (log)
-            log->Printf ("Thread::%s for tid = 0x%4.4" PRIx64 ", should_stop = 0 (ignore since thread was suspended)",
+            log->Printf ("Thread::%s for tid = 0x%4.4" PRIx64 " 0x%4.4" PRIx64 ", should_stop = 0 (ignore since thread was suspended)",
                          __FUNCTION__, 
-                         GetID ());
+                         GetID (),
+                         GetProtocolID());
         return false;
     }
     
     if (GetTemporaryResumeState () == eStateSuspended)
     {
         if (log)
-            log->Printf ("Thread::%s for tid = 0x%4.4" PRIx64 ", should_stop = 0 (ignore since thread was suspended)",
+            log->Printf ("Thread::%s for tid = 0x%4.4" PRIx64 " 0x%4.4" PRIx64 ", should_stop = 0 (ignore since thread was suspended)",
                          __FUNCTION__, 
-                         GetID ());
+                         GetID (),
+                         GetProtocolID());
         return false;
     }
     
     if (ThreadStoppedForAReason() == false)
     {
         if (log)
-            log->Printf ("Thread::%s for tid = 0x%4.4" PRIx64 ", pc = 0x%16.16" PRIx64 ", should_stop = 0 (ignore since no stop reason)",
+            log->Printf ("Thread::%s for tid = 0x%4.4" PRIx64 " 0x%4.4" PRIx64 ", pc = 0x%16.16" PRIx64 ", should_stop = 0 (ignore since no stop reason)",
                          __FUNCTION__, 
-                         GetID (), 
+                         GetID (),
+                         GetProtocolID(),
                          GetRegisterContext() ? GetRegisterContext()->GetPC() : LLDB_INVALID_ADDRESS);
         return false;
     }
     
     if (log)
     {
-        log->Printf ("Thread::%s for tid = 0x%4.4" PRIx64 ", pc = 0x%16.16" PRIx64,
+        log->Printf ("Thread::%s for tid = 0x%4.4" PRIx64 " 0x%4.4" PRIx64 ", pc = 0x%16.16" PRIx64,
                      __FUNCTION__, 
-                     GetID (), 
+                     GetID (),
+                     GetProtocolID (),
                      GetRegisterContext() ? GetRegisterContext()->GetPC() : LLDB_INVALID_ADDRESS);
         log->Printf ("^^^^^^^^ Thread::ShouldStop Begin ^^^^^^^^");
         StreamString s;
@@ -807,21 +823,21 @@ Thread::ShouldReportStop (Event* event_p
     if (thread_state == eStateSuspended || thread_state == eStateInvalid)
     {
         if (log)
-            log->Printf ("Thread::ShouldReportStop() tid = 0x%4.4" PRIx64 ": returning vote %i (state was suspended or invalid)\n", GetID(), eVoteNoOpinion);
+            log->Printf ("Thread::ShouldReportStop() tid = 0x%4.4" PRIx64 ": returning vote %i (state was suspended or invalid)", GetID(), eVoteNoOpinion);
         return eVoteNoOpinion;
     }
 
     if (temp_thread_state == eStateSuspended || temp_thread_state == eStateInvalid)
     {
         if (log)
-            log->Printf ("Thread::ShouldReportStop() tid = 0x%4.4" PRIx64 ": returning vote %i (temporary state was suspended or invalid)\n", GetID(), eVoteNoOpinion);
+            log->Printf ("Thread::ShouldReportStop() tid = 0x%4.4" PRIx64 ": returning vote %i (temporary state was suspended or invalid)", GetID(), eVoteNoOpinion);
         return eVoteNoOpinion;
     }
 
     if (!ThreadStoppedForAReason())
     {
         if (log)
-            log->Printf ("Thread::ShouldReportStop() tid = 0x%4.4" PRIx64 ": returning vote %i (thread didn't stop for a reason.)\n", GetID(), eVoteNoOpinion);
+            log->Printf ("Thread::ShouldReportStop() tid = 0x%4.4" PRIx64 ": returning vote %i (thread didn't stop for a reason.)", GetID(), eVoteNoOpinion);
         return eVoteNoOpinion;
     }
 
@@ -829,7 +845,7 @@ Thread::ShouldReportStop (Event* event_p
     {
         // Don't use GetCompletedPlan here, since that suppresses private plans.
         if (log)
-            log->Printf ("Thread::ShouldReportStop() tid = 0x%4.4" PRIx64 ": returning vote  for complete stack's back plan\n", GetID());
+            log->Printf ("Thread::ShouldReportStop() tid = 0x%4.4" PRIx64 ": returning vote  for complete stack's back plan", GetID());
         return m_completed_plan_stack.back()->ShouldReportStop (event_ptr);
     }
     else
@@ -849,7 +865,7 @@ Thread::ShouldReportStop (Event* event_p
                 plan_ptr = GetPreviousPlan(plan_ptr);
         }
         if (log)
-            log->Printf ("Thread::ShouldReportStop() tid = 0x%4.4" PRIx64 ": returning vote %i for current plan\n", GetID(), thread_vote);
+            log->Printf ("Thread::ShouldReportStop() tid = 0x%4.4" PRIx64 ": returning vote %i for current plan", GetID(), thread_vote);
 
         return thread_vote;
     }
@@ -871,9 +887,10 @@ Thread::ShouldReportRun (Event* event_pt
     {
         // Don't use GetCompletedPlan here, since that suppresses private plans.
         if (log)
-            log->Printf ("Current Plan for thread %d (0x%4.4" PRIx64 "): %s being asked whether we should report run.",
+            log->Printf ("Current Plan for thread %d (0x%4.4" PRIx64 ", %s): %s being asked whether we should report run.",
                          GetIndexID(), 
                          GetID(),
+                         StateAsCString(GetTemporaryResumeState()),
                          m_completed_plan_stack.back()->GetName());
                          
         return m_completed_plan_stack.back()->ShouldReportRun (event_ptr);
@@ -881,9 +898,10 @@ Thread::ShouldReportRun (Event* event_pt
     else
     {
         if (log)
-            log->Printf ("Current Plan for thread %d (0x%4.4" PRIx64 "): %s being asked whether we should report run.",
+            log->Printf ("Current Plan for thread %d (0x%4.4" PRIx64 ", %s): %s being asked whether we should report run.",
                          GetIndexID(), 
                          GetID(),
+                         StateAsCString(GetTemporaryResumeState()),
                          GetCurrentPlan()->GetName());
                          
         return GetCurrentPlan()->ShouldReportRun (event_ptr);
@@ -1502,6 +1520,10 @@ Thread::ClearStackFrames ()
 {
     Mutex::Locker locker(m_frame_mutex);
 
+    Unwind *unwinder = GetUnwinder ();
+    if (unwinder)
+        unwinder->Clear();
+
     // Only store away the old "reference" StackFrameList if we got all its frames:
     // FIXME: At some point we can try to splice in the frames we have fetched into
     // the new frame as we make it, but let's not try that now.

Modified: lldb/trunk/source/Target/ThreadList.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadList.cpp?rev=180886&r1=180885&r2=180886&view=diff
==============================================================================
--- lldb/trunk/source/Target/ThreadList.cpp (original)
+++ lldb/trunk/source/Target/ThreadList.cpp Wed May  1 16:54:04 2013
@@ -132,6 +132,29 @@ ThreadList::FindThreadByID (lldb::tid_t
 }
 
 ThreadSP
+ThreadList::FindThreadByProtocolID (lldb::tid_t tid, bool can_update)
+{
+    Mutex::Locker locker(m_threads_mutex);
+    
+    if (can_update)
+        m_process->UpdateThreadListIfNeeded();
+    
+    ThreadSP thread_sp;
+    uint32_t idx = 0;
+    const uint32_t num_threads = m_threads.size();
+    for (idx = 0; idx < num_threads; ++idx)
+    {
+        if (m_threads[idx]->GetProtocolID() == tid)
+        {
+            thread_sp = m_threads[idx];
+            break;
+        }
+    }
+    return thread_sp;
+}
+
+
+ThreadSP
 ThreadList::RemoveThreadByID (lldb::tid_t tid, bool can_update)
 {
     Mutex::Locker locker(m_threads_mutex);
@@ -155,6 +178,29 @@ ThreadList::RemoveThreadByID (lldb::tid_
 }
 
 ThreadSP
+ThreadList::RemoveThreadByProtocolID (lldb::tid_t tid, bool can_update)
+{
+    Mutex::Locker locker(m_threads_mutex);
+    
+    if (can_update)
+        m_process->UpdateThreadListIfNeeded();
+    
+    ThreadSP thread_sp;
+    uint32_t idx = 0;
+    const uint32_t num_threads = m_threads.size();
+    for (idx = 0; idx < num_threads; ++idx)
+    {
+        if (m_threads[idx]->GetProtocolID() == tid)
+        {
+            thread_sp = m_threads[idx];
+            m_threads.erase(m_threads.begin()+idx);
+            break;
+        }
+    }
+    return thread_sp;
+}
+
+ThreadSP
 ThreadList::GetThreadSPForThreadPtr (Thread *thread_ptr)
 {
     ThreadSP thread_sp;
@@ -522,9 +568,9 @@ ThreadList::WillResume ()
         {
             ThreadSP thread_sp(*pos);
             if (thread_sp.get() == immediate_thread_sp.get())
-                thread_sp->WillResume(thread_sp->GetCurrentPlan()->RunState());
+                thread_sp->ShouldResume(thread_sp->GetCurrentPlan()->RunState());
             else
-                thread_sp->WillResume (eStateSuspended);
+                thread_sp->ShouldResume (eStateSuspended);
         }
     }
     else if (run_me_only_list.GetSize (false) == 0)
@@ -538,7 +584,7 @@ ThreadList::WillResume ()
                 run_state = thread_sp->GetCurrentPlan()->RunState();
             else
                 run_state = eStateSuspended;
-            if (!thread_sp->WillResume(run_state))
+            if (!thread_sp->ShouldResume(run_state))
                 need_to_resume = false;
         }
     }
@@ -566,11 +612,11 @@ ThreadList::WillResume ()
             ThreadSP thread_sp(*pos);
             if (thread_sp == thread_to_run)
             {
-                if (!thread_sp->WillResume(thread_sp->GetCurrentPlan()->RunState()))
+                if (!thread_sp->ShouldResume(thread_sp->GetCurrentPlan()->RunState()))
                     need_to_resume = false;
             }
             else
-                thread_sp->WillResume (eStateSuspended);
+                thread_sp->ShouldResume (eStateSuspended);
         }
     }
 





More information about the lldb-commits mailing list