<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.



git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@180886 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/lldb/Target/OperatingSystem.h b/include/lldb/Target/OperatingSystem.h
index c568a40..3455333 100644
--- a/include/lldb/Target/OperatingSystem.h
+++ b/include/lldb/Target/OperatingSystem.h
@@ -81,6 +81,10 @@
     {
         return lldb::ThreadSP();
     }
+    
+    virtual bool
+    IsOperatingSystemPluginThread (const lldb::ThreadSP &thread_sp);
+
 protected:
     //------------------------------------------------------------------
     // Member variables.
diff --git a/include/lldb/Target/RegisterContext.h b/include/lldb/Target/RegisterContext.h
index a68629d..dd0e73f 100644
--- a/include/lldb/Target/RegisterContext.h
+++ b/include/lldb/Target/RegisterContext.h
@@ -111,10 +111,10 @@
     //------------------------------------------------------------------
     // Subclasses should not override these
     //------------------------------------------------------------------
-    lldb::tid_t
+    virtual lldb::tid_t
     GetThreadID() const;
 
-    Thread &
+    virtual Thread &
     GetThread ()
     {
         return m_thread;
diff --git a/include/lldb/Target/StopInfo.h b/include/lldb/Target/StopInfo.h
index 51b5455..c4f243e 100644
--- a/include/lldb/Target/StopInfo.h
+++ b/include/lldb/Target/StopInfo.h
@@ -40,6 +40,12 @@
     bool
     IsValid () const;
 
+    void
+    SetThread (const lldb::ThreadSP &thread_sp)
+    {
+        m_thread_wp = thread_sp;
+    }
+
     lldb::ThreadSP
     GetThread() const
     {
diff --git a/include/lldb/Target/Thread.h b/include/lldb/Target/Thread.h
index e76cb88..c1cd2a7 100644
--- a/include/lldb/Target/Thread.h
+++ b/include/lldb/Target/Thread.h
@@ -255,17 +255,22 @@
         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 @@
     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 @@
     // 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 @@
         return m_temporary_resume_state;
     }
 
+    void
+    SetStopInfo (const lldb::StopInfoSP &stop_info_sp);
+
 protected:
 
     friend class ThreadPlan;
@@ -905,6 +934,7 @@
     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 @@
 
     typedef std::vector<lldb::ThreadPlanSP> plan_stack;
 
-    void
-    SetStopInfo (const lldb::StopInfoSP &stop_info_sp);
-
     virtual bool
     SaveFrameZeroState (RegisterCheckpoint &checkpoint);
 
@@ -943,6 +970,17 @@
     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 @@
     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 @@
     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
diff --git a/include/lldb/Target/ThreadList.h b/include/lldb/Target/ThreadList.h
index 345cefd..c219434 100644
--- a/include/lldb/Target/ThreadList.h
+++ b/include/lldb/Target/ThreadList.h
@@ -73,9 +73,15 @@
 
     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);
diff --git a/lldb.xcodeproj/project.pbxproj b/lldb.xcodeproj/project.pbxproj
index 81c8995..6c75fe7 100644
--- a/lldb.xcodeproj/project.pbxproj
+++ b/lldb.xcodeproj/project.pbxproj
@@ -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 */,
diff --git a/source/Core/Debugger.cpp b/source/Core/Debugger.cpp
index 42a1540..ab2f817 100644
--- a/source/Core/Debugger.cpp
+++ b/source/Core/Debugger.cpp
@@ -1964,6 +1964,11 @@
                                             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());
diff --git a/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp b/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp
index a7aaedb..fc05d6e 100644
--- a/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp
+++ b/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp
@@ -247,8 +247,8 @@
             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 @@
             //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 @@
             
             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 @@
 {
     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 @@
         // 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 @@
         // 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)
diff --git a/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp b/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp
index a8b1b08..6f0116e 100644
--- a/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp
+++ b/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp
@@ -66,23 +66,6 @@
     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 @@
         reg_ctx_sp->InvalidateIfNeeded (force);
 }
 
-void
-ThreadKDP::ClearStackFrames ()
-{
-    Unwind *unwinder = GetUnwinder ();
-    if (unwinder)
-        unwinder->Clear();
-    Thread::ClearStackFrames();
-}
-
-
 bool
 ThreadKDP::ThreadIDIsValid (lldb::tid_t thread)
 {
diff --git a/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.h b/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.h
index 5454f2b..5a980f5 100644
--- a/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.h
+++ b/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.h
@@ -26,9 +26,6 @@
     virtual
     ~ThreadKDP ();
 
-    virtual bool
-    WillResume (lldb::StateType resume_state);
-
     virtual void
     RefreshStateAfterStop();
 
@@ -44,9 +41,6 @@
     virtual lldb::RegisterContextSP
     CreateRegisterContextForFrame (lldb_private::StackFrame *frame);
 
-    virtual void
-    ClearStackFrames ();
-
     void
     Dump (lldb_private::Log *log, uint32_t index);
 
diff --git a/source/Plugins/Process/POSIX/POSIXThread.cpp b/source/Plugins/Process/POSIX/POSIXThread.cpp
index 3b2ae03..9210408 100644
--- a/source/Plugins/Process/POSIX/POSIXThread.cpp
+++ b/source/Plugins/Process/POSIX/POSIXThread.cpp
@@ -150,19 +150,12 @@
     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
diff --git a/source/Plugins/Process/POSIX/POSIXThread.h b/source/Plugins/Process/POSIX/POSIXThread.h
index 3a28204..094e140 100644
--- a/source/Plugins/Process/POSIX/POSIXThread.h
+++ b/source/Plugins/Process/POSIX/POSIXThread.h
@@ -36,7 +36,7 @@
     void
     RefreshStateAfterStop();
 
-    bool
+    virtual void
     WillResume(lldb::StateType resume_state);
 
     const char *
diff --git a/source/Plugins/Process/Utility/RegisterContextThreadMemory.cpp b/source/Plugins/Process/Utility/RegisterContextThreadMemory.cpp
new file mode 100644
index 0000000..1cef63d
--- /dev/null
+++ b/source/Plugins/Process/Utility/RegisterContextThreadMemory.cpp
@@ -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;
+}
diff --git a/source/Plugins/Process/Utility/RegisterContextThreadMemory.h b/source/Plugins/Process/Utility/RegisterContextThreadMemory.h
new file mode 100644
index 0000000..8d7a4b6
--- /dev/null
+++ b/source/Plugins/Process/Utility/RegisterContextThreadMemory.h
@@ -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_
diff --git a/source/Plugins/Process/Utility/ThreadMemory.cpp b/source/Plugins/Process/Utility/ThreadMemory.cpp
index 62c6aeb..3d08026 100644
--- a/source/Plugins/Process/Utility/ThreadMemory.cpp
+++ b/source/Plugins/Process/Utility/ThreadMemory.cpp
@@ -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 @@
     DestroyThread();
 }
 
-bool
+void
 ThreadMemory::WillResume (StateType resume_state)
 {
-    ClearStackFrames();
-    Thread::WillResume(resume_state);
-
     if (m_backing_thread_sp)
-        return m_backing_thread_sp->WillResume(resume_state);
-    return true;
+        m_backing_thread_sp->WillResume(resume_state);
+}
+
+void
+ThreadMemory::ClearStackFrames ()
+{
+    if (m_backing_thread_sp)
+        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 @@
     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 @@
 {
     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);
-    }
 }
diff --git a/source/Plugins/Process/Utility/ThreadMemory.h b/source/Plugins/Process/Utility/ThreadMemory.h
index 51a2486..2a1f7d6 100644
--- a/source/Plugins/Process/Utility/ThreadMemory.h
+++ b/source/Plugins/Process/Utility/ThreadMemory.h
@@ -70,7 +70,7 @@
         return NULL;
     }
 
-    virtual bool
+    virtual void
     WillResume (lldb::StateType resume_state);
 
     virtual void
@@ -79,6 +79,14 @@
         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 @@
     }
     
     virtual void
+    ClearStackFrames ();
+
+    virtual void
     ClearBackingThread ()
     {
         m_backing_thread_sp.reset();
@@ -98,6 +109,7 @@
     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 @@
     }
 
 protected:
+    
+    virtual bool
+    IsOperatingSystemPluginThread () const
+    {
+        return true;
+    }
+    
+
     //------------------------------------------------------------------
     // For ThreadMemory and subclasses
     //------------------------------------------------------------------
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
index bf3dc4d..b17a6af 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
@@ -155,7 +155,7 @@
     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 @@
         {
             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 @@
                 {
                     // 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 @@
                               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 @@
 
     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 @@
         {
             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 @@
                                               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 @@
         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 @@
                     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 @@
     {
         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 @@
                                                           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(),
diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index 35e455d..1b4627a 100644
--- a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -1322,7 +1322,13 @@
         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 @@
         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 @@
             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 @@
                     // 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 @@
                     // 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 @@
                             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 @@
 
             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 @@
                     {
                         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 @@
                         {
                             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 @@
                             // 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 @@
                                 // 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 @@
                             || 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 @@
                                 && 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);
                             }
                         }
diff --git a/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp b/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
index f1084d6..321fe8d 100644
--- a/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
+++ b/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
@@ -80,24 +80,14 @@
     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 @@
 
         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 @@
     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 @@
 
             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);
         }
     }
diff --git a/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h b/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h
index 375b7a5..8dfc4bb 100644
--- a/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h
+++ b/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h
@@ -26,7 +26,7 @@
     virtual
     ~ThreadGDBRemote ();
 
-    virtual bool
+    virtual void
     WillResume (lldb::StateType resume_state);
 
     virtual void
@@ -44,9 +44,6 @@
     virtual lldb::RegisterContextSP
     CreateRegisterContextForFrame (lldb_private::StackFrame *frame);
 
-    virtual void
-    ClearStackFrames ();
-
     void
     Dump (lldb_private::Log *log, uint32_t index);
 
diff --git a/source/Plugins/Process/mach-core/ThreadMachCore.cpp b/source/Plugins/Process/mach-core/ThreadMachCore.cpp
index 81d3426..a4e3661 100644
--- a/source/Plugins/Process/mach-core/ThreadMachCore.cpp
+++ b/source/Plugins/Process/mach-core/ThreadMachCore.cpp
@@ -73,16 +73,6 @@
     GetRegisterContext()->InvalidateIfNeeded (force);
 }
 
-void
-ThreadMachCore::ClearStackFrames ()
-{
-    Unwind *unwinder = GetUnwinder ();
-    if (unwinder)
-        unwinder->Clear();
-    Thread::ClearStackFrames();
-}
-
-
 bool
 ThreadMachCore::ThreadIDIsValid (lldb::tid_t thread)
 {
diff --git a/source/Plugins/Process/mach-core/ThreadMachCore.h b/source/Plugins/Process/mach-core/ThreadMachCore.h
index a2d3b7a..cc68757 100644
--- a/source/Plugins/Process/mach-core/ThreadMachCore.h
+++ b/source/Plugins/Process/mach-core/ThreadMachCore.h
@@ -37,9 +37,6 @@
     virtual lldb::RegisterContextSP
     CreateRegisterContextForFrame (lldb_private::StackFrame *frame);
 
-    virtual void
-    ClearStackFrames ();
-
     static bool
     ThreadIDIsValid (lldb::tid_t thread);
 
diff --git a/source/Target/OperatingSystem.cpp b/source/Target/OperatingSystem.cpp
index 33ae584..3fecb4a 100644
--- a/source/Target/OperatingSystem.cpp
+++ b/source/Target/OperatingSystem.cpp
@@ -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()
 {
 }
+
+
+bool
+OperatingSystem::IsOperatingSystemPluginThread (const lldb::ThreadSP &thread_sp)
+{
+    if (thread_sp)
+        return thread_sp->IsOperatingSystemPluginThread();
+    return false;
+}
+
diff --git a/source/Target/Thread.cpp b/source/Target/Thread.cpp
index 72c9a2a..a7e03a2 100644
--- a/source/Target/Thread.cpp
+++ b/source/Target/Thread.cpp
@@ -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 @@
     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 @@
 }
 
 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 @@
 
     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 @@
         }
     }
 
+    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 @@
     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 @@
     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 @@
     {
         // 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 @@
                 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 @@
     {
         // 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 @@
     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 @@
 {
     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.
diff --git a/source/Target/ThreadList.cpp b/source/Target/ThreadList.cpp
index 620a7cc..d59d805 100644
--- a/source/Target/ThreadList.cpp
+++ b/source/Target/ThreadList.cpp
@@ -132,6 +132,29 @@
 }
 
 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 @@
 }
 
 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 @@
         {
             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 @@
                 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 @@
             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);
         }
     }