Thread hardening part 3. Now lldb_private::Thread objects have std::weak_ptr
objects for the backlink to the lldb_private::Process. The issues we were
running into before was someone was holding onto a shared pointer to a 
lldb_private::Thread for too long, and the lldb_private::Process parent object
would get destroyed and the lldb_private::Thread had a "Process &m_process"
member which would just treat whatever memory that used to be a Process as a
valid Process. This was mostly happening for lldb_private::StackFrame objects
that had a member like "Thread &m_thread". So this completes the internal
strong/weak changes.

Documented the ExecutionContext and ExecutionContextRef classes so that our
LLDB developers can understand when and where to use ExecutionContext and 
ExecutionContextRef objects.



git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@151009 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp b/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
index ab872f8..3b45691 100644
--- a/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
+++ b/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
@@ -312,7 +312,7 @@
         lldb::tid_t tid = cpu_mask_bit;
         ThreadSP thread_sp (old_thread_list.FindThreadByID (tid, false));
         if (!thread_sp)
-            thread_sp.reset(new ThreadKDP (*this, tid));
+            thread_sp.reset(new ThreadKDP (shared_from_this(), tid));
         new_thread_list.AddThread(thread_sp);
     }
     return new_thread_list.GetSize(false);
diff --git a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.cpp b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.cpp
index fdd22b2..296fbba 100644
--- a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.cpp
+++ b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.cpp
@@ -33,11 +33,15 @@
 int
 RegisterContextKDP_arm::DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr)
 {
-    Error error;
-    if (m_kdp_thread.GetKDPProcess().GetCommunication().SendRequestReadRegisters (tid, GPRRegSet, &gpr, sizeof(gpr), error))
+    ProcessSP process_sp (CalculateProcess());
+    if (process_sp)
     {
-        if (error.Success())
-            return 0;
+        Error error;
+        if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestReadRegisters (tid, GPRRegSet, &gpr, sizeof(gpr), error))
+        {
+            if (error.Success())
+                return 0;
+        }
     }
     return -1;
 }
@@ -45,11 +49,15 @@
 int
 RegisterContextKDP_arm::DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu)
 {
-    Error error;
-    if (m_kdp_thread.GetKDPProcess().GetCommunication().SendRequestReadRegisters (tid, FPURegSet, &fpu, sizeof(fpu), error))
+    ProcessSP process_sp (CalculateProcess());
+    if (process_sp)
     {
-        if (error.Success())
-            return 0;
+        Error error;
+        if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestReadRegisters (tid, FPURegSet, &fpu, sizeof(fpu), error))
+        {
+            if (error.Success())
+                return 0;
+        }
     }
     return -1;
 }
@@ -57,11 +65,15 @@
 int
 RegisterContextKDP_arm::DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc)
 {
-    Error error;
-    if (m_kdp_thread.GetKDPProcess().GetCommunication().SendRequestReadRegisters (tid, EXCRegSet, &exc, sizeof(exc), error))
+    ProcessSP process_sp (CalculateProcess());
+    if (process_sp)
     {
-        if (error.Success())
-            return 0;
+        Error error;
+        if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestReadRegisters (tid, EXCRegSet, &exc, sizeof(exc), error))
+        {
+            if (error.Success())
+                return 0;
+        }
     }
     return -1;
 }
@@ -69,11 +81,15 @@
 int
 RegisterContextKDP_arm::DoReadDBG (lldb::tid_t tid, int flavor, DBG &dbg)
 {
-    Error error;
-    if (m_kdp_thread.GetKDPProcess().GetCommunication().SendRequestReadRegisters (tid, DBGRegSet, &dbg, sizeof(dbg), error))
+    ProcessSP process_sp (CalculateProcess());
+    if (process_sp)
     {
-        if (error.Success())
-            return 0;
+        Error error;
+        if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestReadRegisters (tid, DBGRegSet, &dbg, sizeof(dbg), error))
+        {
+            if (error.Success())
+                return 0;
+        }
     }
     return -1;
 }
diff --git a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.cpp b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.cpp
index 503ce75..504ea07 100644
--- a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.cpp
+++ b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.cpp
@@ -33,11 +33,15 @@
 int
 RegisterContextKDP_i386::DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr)
 {
-    Error error;
-    if (m_kdp_thread.GetKDPProcess().GetCommunication().SendRequestReadRegisters (tid, GPRRegSet, &gpr, sizeof(gpr), error))
+    ProcessSP process_sp (CalculateProcess());
+    if (process_sp)
     {
-        if (error.Success())
-            return 0;
+        Error error;
+        if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestReadRegisters (tid, GPRRegSet, &gpr, sizeof(gpr), error))
+        {
+            if (error.Success())
+                return 0;
+        }
     }
     return -1;
 }
@@ -45,11 +49,15 @@
 int
 RegisterContextKDP_i386::DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu)
 {
-    Error error;
-    if (m_kdp_thread.GetKDPProcess().GetCommunication().SendRequestReadRegisters (tid, FPURegSet, &fpu, sizeof(fpu), error))
+    ProcessSP process_sp (CalculateProcess());
+    if (process_sp)
     {
-        if (error.Success())
-            return 0;
+        Error error;
+        if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestReadRegisters (tid, FPURegSet, &fpu, sizeof(fpu), error))
+        {
+            if (error.Success())
+                return 0;
+        }
     }
     return -1;
 }
@@ -57,11 +65,15 @@
 int
 RegisterContextKDP_i386::DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc)
 {
-    Error error;
-    if (m_kdp_thread.GetKDPProcess().GetCommunication().SendRequestReadRegisters (tid, EXCRegSet, &exc, sizeof(exc), error))
+    ProcessSP process_sp (CalculateProcess());
+    if (process_sp)
     {
-        if (error.Success())
-            return 0;
+        Error error;
+        if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestReadRegisters (tid, EXCRegSet, &exc, sizeof(exc), error))
+        {
+            if (error.Success())
+                return 0;
+        }
     }
     return -1;
 }
@@ -69,19 +81,19 @@
 int
 RegisterContextKDP_i386::DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr)
 {
-    return ::thread_set_state(tid, flavor, (thread_state_t)&gpr, GPRWordCount);
+    return -1;
 }
 
 int
 RegisterContextKDP_i386::DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu)
 {
-    return ::thread_set_state(tid, flavor, (thread_state_t)&fpu, FPUWordCount);
+    return -1;
 }
 
 int
 RegisterContextKDP_i386::DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc)
 {
-    return ::thread_set_state(tid, flavor, (thread_state_t)&exc, EXCWordCount);
+    return -1;
 }
 
 
diff --git a/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp b/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp
index 6fb9470..9f68d10 100644
--- a/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp
+++ b/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp
@@ -36,18 +36,18 @@
 // Thread Registers
 //----------------------------------------------------------------------
 
-ThreadKDP::ThreadKDP (ProcessKDP &process, lldb::tid_t tid) :
-    Thread(process, tid),
+ThreadKDP::ThreadKDP (const lldb::ProcessSP &process_sp, lldb::tid_t tid) :
+    Thread(process_sp, tid),
     m_thread_name (),
     m_dispatch_queue_name (),
     m_thread_dispatch_qaddr (LLDB_INVALID_ADDRESS)
 {
-    ProcessKDPLog::LogIf(KDP_LOG_THREAD, "%p: ThreadKDP::ThreadKDP (pid = %i, tid = 0x%4.4x)", this, m_process.GetID(), GetID());
+    ProcessKDPLog::LogIf(KDP_LOG_THREAD, "%p: ThreadKDP::ThreadKDP (tid = 0x%4.4x)", this, GetID());
 }
 
 ThreadKDP::~ThreadKDP ()
 {
-    ProcessKDPLog::LogIf(KDP_LOG_THREAD, "%p: ThreadKDP::~ThreadKDP (pid = %i, tid = 0x%4.4x)", this, m_process.GetID(), GetID());
+    ProcessKDPLog::LogIf(KDP_LOG_THREAD, "%p: ThreadKDP::~ThreadKDP (tid = 0x%4.4x)", this, GetID());
     DestroyThread();
 }
 
@@ -157,20 +157,24 @@
 
     if (concrete_frame_idx == 0)
     {
-        switch (GetKDPProcess().GetCommunication().GetCPUType())
+        ProcessSP process_sp (CalculateProcess());
+        if (process_sp)
         {
-            case llvm::MachO::CPUTypeARM:
-                reg_ctx_sp.reset (new RegisterContextKDP_arm (*this, concrete_frame_idx));
-                break;
-            case llvm::MachO::CPUTypeI386:
-                reg_ctx_sp.reset (new RegisterContextKDP_i386 (*this, concrete_frame_idx));
-                break;
-            case llvm::MachO::CPUTypeX86_64:
-                reg_ctx_sp.reset (new RegisterContextKDP_x86_64 (*this, concrete_frame_idx));
-                break;
-            default:
-                assert (!"Add CPU type support in KDP");
-                break;
+            switch (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().GetCPUType())
+            {
+                case llvm::MachO::CPUTypeARM:
+                    reg_ctx_sp.reset (new RegisterContextKDP_arm (*this, concrete_frame_idx));
+                    break;
+                case llvm::MachO::CPUTypeI386:
+                    reg_ctx_sp.reset (new RegisterContextKDP_i386 (*this, concrete_frame_idx));
+                    break;
+                case llvm::MachO::CPUTypeX86_64:
+                    reg_ctx_sp.reset (new RegisterContextKDP_x86_64 (*this, concrete_frame_idx));
+                    break;
+                default:
+                    assert (!"Add CPU type support in KDP");
+                    break;
+            }
         }
     }
     else if (m_unwinder_ap.get())
@@ -181,26 +185,30 @@
 lldb::StopInfoSP
 ThreadKDP::GetPrivateStopReason ()
 {
-    const uint32_t process_stop_id = GetProcess().GetStopID();
-    if (m_thread_stop_reason_stop_id != process_stop_id ||
-        (m_actual_stop_info_sp && !m_actual_stop_info_sp->IsValid()))
+    ProcessSP process_sp (GetProcess());
+    if (process_sp)
     {
-        // TODO: can we query the initial state of the thread here?
-        // For now I am just going to pretend that a SIGSTOP happened.
+        const uint32_t process_stop_id = process_sp->GetStopID();
+        if (m_thread_stop_reason_stop_id != process_stop_id ||
+            (m_actual_stop_info_sp && !m_actual_stop_info_sp->IsValid()))
+        {
+            // TODO: can we query the initial state of the thread here?
+            // For now I am just going to pretend that a SIGSTOP happened.
 
-        SetStopInfo(StopInfo::CreateStopReasonWithSignal (*this, SIGSTOP));
+            SetStopInfo(StopInfo::CreateStopReasonWithSignal (*this, SIGSTOP));
 
-        // If GetKDPProcess().SetThreadStopInfo() doesn't find a stop reason
-        // for this thread, then m_actual_stop_info_sp will not ever contain
-        // a valid stop reason and the "m_actual_stop_info_sp->IsValid() == false"
-        // check will never be able to tell us if we have the correct stop info
-        // for this thread and we will continually send qThreadStopInfo packets
-        // down to the remote KDP server, so we need to keep our own notion
-        // of the stop ID that m_actual_stop_info_sp is valid for (even if it
-        // contains nothing). We use m_thread_stop_reason_stop_id for this below.
-//        m_thread_stop_reason_stop_id = process_stop_id;
-//        m_actual_stop_info_sp.reset();
+            // If GetKDPProcess().SetThreadStopInfo() doesn't find a stop reason
+            // for this thread, then m_actual_stop_info_sp will not ever contain
+            // a valid stop reason and the "m_actual_stop_info_sp->IsValid() == false"
+            // check will never be able to tell us if we have the correct stop info
+            // for this thread and we will continually send qThreadStopInfo packets
+            // down to the remote KDP server, so we need to keep our own notion
+            // of the stop ID that m_actual_stop_info_sp is valid for (even if it
+            // contains nothing). We use m_thread_stop_reason_stop_id for this below.
+    //        m_thread_stop_reason_stop_id = process_stop_id;
+    //        m_actual_stop_info_sp.reset();
 
+        }
     }
     return m_actual_stop_info_sp;
 }
diff --git a/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.h b/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.h
index a37fa91..1bf688d 100644
--- a/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.h
+++ b/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.h
@@ -20,7 +20,7 @@
 class ThreadKDP : public lldb_private::Thread
 {
 public:
-    ThreadKDP (ProcessKDP &process, 
+    ThreadKDP (const lldb::ProcessSP &process_sp, 
                lldb::tid_t tid);
 
     virtual
@@ -47,12 +47,6 @@
     virtual void
     ClearStackFrames ();
 
-    ProcessKDP &
-    GetKDPProcess ()
-    {
-        return (ProcessKDP &)m_process;
-    }
-
     void
     Dump (lldb_private::Log *log, uint32_t index);
 
diff --git a/source/Plugins/Process/Utility/RegisterContextLLDB.cpp b/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
index 3ae19f9..1b23087 100644
--- a/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
@@ -85,7 +85,9 @@
 void
 RegisterContextLLDB::InitializeZerothFrame()
 {
+    ExecutionContext exe_ctx(m_thread.shared_from_this());
     StackFrameSP frame_sp (m_thread.GetStackFrameAtIndex (0));
+    exe_ctx.SetFrameSP (frame_sp);
 
     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
 
@@ -158,7 +160,7 @@
         if (active_row && log)
         {
             StreamString active_row_strm;
-            active_row->Dump(active_row_strm, m_full_unwind_plan_sp.get(), &m_thread, m_start_pc.GetLoadAddress(&m_thread.GetProcess().GetTarget()));
+            active_row->Dump(active_row_strm, m_full_unwind_plan_sp.get(), &m_thread, m_start_pc.GetLoadAddress(exe_ctx.GetTargetPtr()));
             log->Printf("%*sFrame %u active row: %s",
                         m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number, active_row_strm.GetString().c_str());
         }
@@ -210,7 +212,7 @@
                     m_frame_number < 100 ? m_frame_number : 100, "", 
                     m_thread.GetIndexID(), 
                     m_frame_number,
-                    (uint64_t) m_current_pc.GetLoadAddress (&m_thread.GetProcess().GetTarget()), 
+                    (uint64_t) m_current_pc.GetLoadAddress (exe_ctx.GetTargetPtr()), 
                     (uint64_t) m_cfa,
                     m_full_unwind_plan_sp->GetSourceName().GetCString());
     }
@@ -274,13 +276,15 @@
         return;
     }
     
+    ExecutionContext exe_ctx(m_thread.shared_from_this());
+    Process *process = exe_ctx.GetProcessPtr();
     // Let ABIs fixup code addresses to make sure they are valid. In ARM ABIs
     // this will strip bit zero in case we read a PC from memory or from the LR.   
-    ABI *abi = m_thread.GetProcess().GetABI().get();
+    ABI *abi = process->GetABI().get();
     if (abi)
         pc = abi->FixCodeAddress(pc);
 
-    m_thread.GetProcess().GetTarget().GetSectionLoadList().ResolveLoadAddress (pc, m_current_pc);
+    process->GetTarget().GetSectionLoadList().ResolveLoadAddress (pc, m_current_pc);
 
     // If we don't have a Module for some reason, we're not going to find symbol/function information - just
     // stick in some reasonable defaults and hope we can unwind past this frame.
@@ -294,7 +298,7 @@
         
         // Test the pc value to see if we know it's in an unmapped/non-executable region of memory.
         uint32_t permissions;
-        if (m_thread.GetProcess().GetLoadAddressPermissions(pc, permissions)
+        if (process->GetLoadAddressPermissions(pc, permissions)
             && (permissions & ePermissionsExecutable) == 0)
         {
             // If this is the second frame off the stack, we may have unwound the first frame
@@ -366,7 +370,7 @@
 
                 // cfa_regval should point into the stack memory; if we can query memory region permissions,
                 // see if the memory is allocated & readable.
-                if (m_thread.GetProcess().GetLoadAddressPermissions(cfa_regval, permissions)
+                if (process->GetLoadAddressPermissions(cfa_regval, permissions)
                     && (permissions & ePermissionsReadable) == 0)
                 {
                     m_frame_type = eNotAValidFrame;
@@ -495,7 +499,7 @@
         if (active_row && log)
         {
             StreamString active_row_strm;
-            active_row->Dump(active_row_strm, m_full_unwind_plan_sp.get(), &m_thread, m_start_pc.GetLoadAddress(&m_thread.GetProcess().GetTarget()));
+            active_row->Dump(active_row_strm, m_full_unwind_plan_sp.get(), &m_thread, m_start_pc.GetLoadAddress(exe_ctx.GetTargetPtr()));
             log->Printf("%*sFrame %u active row: %s",
                         m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number, active_row_strm.GetString().c_str());
         }
@@ -510,7 +514,7 @@
             if (active_row && log)
             {
                 StreamString active_row_strm;
-                active_row->Dump(active_row_strm, m_full_unwind_plan_sp.get(), &m_thread, m_start_pc.GetLoadAddress(&m_thread.GetProcess().GetTarget()));
+                active_row->Dump(active_row_strm, m_full_unwind_plan_sp.get(), &m_thread, m_start_pc.GetLoadAddress(exe_ctx.GetTargetPtr()));
                 log->Printf("%*sFrame %u active row: %s",
                             m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number, active_row_strm.GetString().c_str());
             }
@@ -594,7 +598,7 @@
     {
         log->Printf("%*sFrame %u initialized frame current pc is 0x%llx cfa is 0x%llx", 
                     m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number,
-                    (uint64_t) m_current_pc.GetLoadAddress (&m_thread.GetProcess().GetTarget()), (uint64_t) m_cfa);
+                    (uint64_t) m_current_pc.GetLoadAddress (exe_ctx.GetTargetPtr()), (uint64_t) m_cfa);
     }
 }
 
@@ -671,8 +675,9 @@
     UnwindPlanSP unwind_plan_sp;
     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
     UnwindPlanSP arch_default_unwind_plan_sp;
-
-    ABI *abi = m_thread.GetProcess().GetABI().get();
+    ExecutionContext exe_ctx(m_thread.shared_from_this());
+    Process *process = exe_ctx.GetProcessPtr();
+    ABI *abi = process ? process->GetABI().get() : NULL;
     if (abi)
     {
         arch_default_unwind_plan_sp.reset (new UnwindPlan (lldb::eRegisterKindGeneric));
@@ -699,9 +704,9 @@
     if ((!m_sym_ctx_valid  || m_sym_ctx.function == NULL) && behaves_like_zeroth_frame && m_current_pc.IsValid())
     {
         uint32_t permissions;
-        addr_t current_pc_addr = m_current_pc.GetLoadAddress (&m_thread.GetProcess().GetTarget());
+        addr_t current_pc_addr = m_current_pc.GetLoadAddress (exe_ctx.GetTargetPtr());
         if (current_pc_addr == 0
-            || (m_thread.GetProcess().GetLoadAddressPermissions(current_pc_addr, permissions)
+            || (process->GetLoadAddressPermissions(current_pc_addr, permissions)
                 && (permissions & ePermissionsExecutable) == 0))
         {
             unwind_plan_sp.reset (new UnwindPlan (lldb::eRegisterKindGeneric));
@@ -749,8 +754,7 @@
     // right thing.  It'd be nice if there was a way to ask the eh_frame directly if it is asynchronous
     // (can be trusted at every instruction point) or synchronous (the normal case - only at call sites).
     // But there is not.
-    if (m_thread.GetProcess().GetDynamicLoader() 
-        && m_thread.GetProcess().GetDynamicLoader()->AlwaysRelyOnEHUnwindInfo (m_sym_ctx))
+    if (process->GetDynamicLoader() && process->GetDynamicLoader()->AlwaysRelyOnEHUnwindInfo (m_sym_ctx))
     {
         unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtCallSite (m_current_offset_backed_up_one);
         if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress (m_current_pc))
@@ -1075,12 +1079,15 @@
             }
         }
     }
-
+    
+    
+    ExecutionContext exe_ctx(m_thread.shared_from_this());
+    Process *process = exe_ctx.GetProcessPtr();
     if (have_unwindplan_regloc == false)
     {
         // If a volatile register is being requested, we don't want to forward the next frame's register contents 
         // up the stack -- the register is not retrievable at this frame.
-        ABI *abi = m_thread.GetProcess().GetABI().get();
+        ABI *abi = process ? process->GetABI().get() : NULL;
         if (abi)
         {
             const RegisterInfo *reg_info = GetRegisterInfoAtIndex(lldb_regnum);
@@ -1198,10 +1205,9 @@
     {
         DataExtractor dwarfdata (unwindplan_regloc.GetDWARFExpressionBytes(), 
                                  unwindplan_regloc.GetDWARFExpressionLength(), 
-                                 m_thread.GetProcess().GetByteOrder(), m_thread.GetProcess().GetAddressByteSize());
+                                 process->GetByteOrder(), process->GetAddressByteSize());
         DWARFExpression dwarfexpr (dwarfdata, 0, unwindplan_regloc.GetDWARFExpressionLength());
         dwarfexpr.SetRegisterKind (unwindplan_registerkind);
-        ExecutionContext exe_ctx (&m_thread.GetProcess(), &m_thread, NULL);
         Value result;
         Error error;
         if (dwarfexpr.Evaluate (&exe_ctx, NULL, NULL, NULL, this, 0, NULL, result, &error))
@@ -1432,7 +1438,7 @@
     {
         return ReadPC (start_pc); 
     }
-    start_pc = m_start_pc.GetLoadAddress (&m_thread.GetProcess().GetTarget());
+    start_pc = m_start_pc.GetLoadAddress (CalculateTarget().get());
     return true;
 }
 
diff --git a/source/Plugins/Process/Utility/RegisterContextMemory.cpp b/source/Plugins/Process/Utility/RegisterContextMemory.cpp
index ff077b4..03610a2 100644
--- a/source/Plugins/Process/Utility/RegisterContextMemory.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextMemory.cpp
@@ -134,11 +134,15 @@
 {
     if (m_reg_data_addr != LLDB_INVALID_ADDRESS)
     {
-        Error error;
-        if (m_thread.GetProcess().ReadMemory(m_reg_data_addr, data_sp->GetBytes(), data_sp->GetByteSize(), error) == data_sp->GetByteSize())
+        ProcessSP process_sp (CalculateProcess());
+        if (process_sp)
         {
-            SetAllRegisterValid (true);
-            return true;
+            Error error;
+            if (process_sp->ReadMemory(m_reg_data_addr, data_sp->GetBytes(), data_sp->GetByteSize(), error) == data_sp->GetByteSize())
+            {
+                SetAllRegisterValid (true);
+                return true;
+            }
         }
     }
     return false;
@@ -149,10 +153,14 @@
 {
     if (m_reg_data_addr != LLDB_INVALID_ADDRESS)
     {
-        Error error;
-        SetAllRegisterValid (false);
-        if (m_thread.GetProcess().WriteMemory(m_reg_data_addr, data_sp->GetBytes(), data_sp->GetByteSize(), error) == data_sp->GetByteSize())
-            return true;
+        ProcessSP process_sp (CalculateProcess());
+        if (process_sp)
+        {
+            Error error;
+            SetAllRegisterValid (false);
+            if (process_sp->WriteMemory(m_reg_data_addr, data_sp->GetBytes(), data_sp->GetByteSize(), error) == data_sp->GetByteSize())
+                return true;
+        }
     }
     return false;
 }
diff --git a/source/Plugins/Process/Utility/StopInfoMachException.cpp b/source/Plugins/Process/Utility/StopInfoMachException.cpp
index 8915dd7..95f3633 100644
--- a/source/Plugins/Process/Utility/StopInfoMachException.cpp
+++ b/source/Plugins/Process/Utility/StopInfoMachException.cpp
@@ -16,6 +16,7 @@
 #include "lldb/Breakpoint/Watchpoint.h"
 #include "lldb/Core/ArchSpec.h"
 #include "lldb/Core/StreamString.h"
+#include "lldb/Target/ExecutionContext.h"
 #include "lldb/Target/Process.h"
 #include "lldb/Target/RegisterContext.h"
 #include "lldb/Target/Target.h"
@@ -31,7 +32,9 @@
 {
     if (m_description.empty() && m_value != 0)
     {
-        const llvm::Triple::ArchType cpu = m_thread.GetProcess().GetTarget().GetArchitecture().GetMachine();
+        ExecutionContext exe_ctx (m_thread.shared_from_this());
+        Target *target = exe_ctx.GetTargetPtr();
+        const llvm::Triple::ArchType cpu = target ? target->GetArchitecture().GetMachine() : llvm::Triple::InvalidArch;
 
         const char *exc_desc = NULL;
         const char *code_label = "code";
@@ -252,7 +255,9 @@
 {
     if (exc_type != 0)
     {
-        const llvm::Triple::ArchType cpu = thread.GetProcess().GetTarget().GetArchitecture().GetMachine();
+        ExecutionContext exe_ctx (thread.shared_from_this());
+        Target *target = exe_ctx.GetTargetPtr();
+        const llvm::Triple::ArchType cpu = target ? target->GetArchitecture().GetMachine() : llvm::Triple::InvalidArch;
 
         switch (exc_type)
         {
@@ -306,8 +311,9 @@
 
                         // It's a watchpoint, then.
                         // The exc_sub_code indicates the data break address.
-                        lldb::WatchpointSP wp_sp =
-                            thread.GetProcess().GetTarget().GetWatchpointList().FindByAddress((lldb::addr_t)exc_sub_code);
+                        lldb::WatchpointSP wp_sp;
+                        if (target)
+                            wp_sp = target->GetWatchpointList().FindByAddress((lldb::addr_t)exc_sub_code);
                         if (wp_sp)
                         {
                             // Debugserver may piggyback the hardware index of the fired watchpoint in the exception data.
@@ -345,7 +351,11 @@
                 if (is_software_breakpoint)
                 {
                     addr_t pc = thread.GetRegisterContext()->GetPC();
-                    lldb::BreakpointSiteSP bp_site_sp = thread.GetProcess().GetBreakpointSiteList().FindByAddress(pc);
+                    ProcessSP process_sp (thread.CalculateProcess());
+
+                    lldb::BreakpointSiteSP bp_site_sp;
+                    if (process_sp)
+                        bp_site_sp = process_sp->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,
diff --git a/source/Plugins/Process/Utility/ThreadMemory.cpp b/source/Plugins/Process/Utility/ThreadMemory.cpp
index 95f05fd..dfcc2b0 100644
--- a/source/Plugins/Process/Utility/ThreadMemory.cpp
+++ b/source/Plugins/Process/Utility/ThreadMemory.cpp
@@ -17,10 +17,10 @@
 using namespace lldb;
 using namespace lldb_private;
 
-ThreadMemory::ThreadMemory (Process &process, 
+ThreadMemory::ThreadMemory (const ProcessSP &process_sp, 
                               tid_t tid, 
                               const ValueObjectSP &thread_info_valobj_sp) :
-    Thread (process, tid),
+    Thread (process_sp, tid),
     m_thread_info_valobj_sp (thread_info_valobj_sp)
 {
 }
@@ -47,9 +47,13 @@
 {
     if (!m_reg_context_sp)
     {
-        OperatingSystem *os = m_process.GetOperatingSystem ();
-        if (os)
-            m_reg_context_sp = os->CreateRegisterContextForThread (this);
+        ProcessSP process_sp (GetProcess());
+        if (process_sp)
+        {
+            OperatingSystem *os = process_sp->GetOperatingSystem ();
+            if (os)
+                m_reg_context_sp = os->CreateRegisterContextForThread (this);
+        }
     }
     return m_reg_context_sp;
 }
@@ -77,24 +81,29 @@
 lldb::StopInfoSP
 ThreadMemory::GetPrivateStopReason ()
 {
-    const uint32_t process_stop_id = GetProcess().GetStopID();
-    if (m_thread_stop_reason_stop_id != process_stop_id ||
-        (m_actual_stop_info_sp && !m_actual_stop_info_sp->IsValid()))
+    ProcessSP process_sp (GetProcess());
+
+    if (process_sp)
     {
-        // If GetGDBProcess().SetThreadStopInfo() doesn't find a stop reason
-        // for this thread, then m_actual_stop_info_sp will not ever contain
-        // a valid stop reason and the "m_actual_stop_info_sp->IsValid() == false"
-        // check will never be able to tell us if we have the correct stop info
-        // for this thread and we will continually send qThreadStopInfo packets
-        // down to the remote GDB server, so we need to keep our own notion
-        // of the stop ID that m_actual_stop_info_sp is valid for (even if it
-        // contains nothing). We use m_thread_stop_reason_stop_id for this below.
-        m_thread_stop_reason_stop_id = process_stop_id;
-        m_actual_stop_info_sp.reset();
-        
-        OperatingSystem *os = m_process.GetOperatingSystem ();
-        if (os)
-            m_actual_stop_info_sp = os->CreateThreadStopReason (this);
+        const uint32_t process_stop_id = process_sp->GetStopID();
+        if (m_thread_stop_reason_stop_id != process_stop_id ||
+            (m_actual_stop_info_sp && !m_actual_stop_info_sp->IsValid()))
+        {
+            // If GetGDBProcess().SetThreadStopInfo() doesn't find a stop reason
+            // for this thread, then m_actual_stop_info_sp will not ever contain
+            // a valid stop reason and the "m_actual_stop_info_sp->IsValid() == false"
+            // check will never be able to tell us if we have the correct stop info
+            // for this thread and we will continually send qThreadStopInfo packets
+            // down to the remote GDB server, so we need to keep our own notion
+            // of the stop ID that m_actual_stop_info_sp is valid for (even if it
+            // contains nothing). We use m_thread_stop_reason_stop_id for this below.
+            m_thread_stop_reason_stop_id = process_stop_id;
+            m_actual_stop_info_sp.reset();
+            
+            OperatingSystem *os = process_sp->GetOperatingSystem ();
+            if (os)
+                m_actual_stop_info_sp = os->CreateThreadStopReason (this);
+        }
     }
     return m_actual_stop_info_sp;
     
diff --git a/source/Plugins/Process/Utility/ThreadMemory.h b/source/Plugins/Process/Utility/ThreadMemory.h
index 93cc255..96b40a0 100644
--- a/source/Plugins/Process/Utility/ThreadMemory.h
+++ b/source/Plugins/Process/Utility/ThreadMemory.h
@@ -17,9 +17,9 @@
 {
 public:
 
-    ThreadMemory (lldb_private::Process &process, 
-                   lldb::tid_t tid,
-                   const lldb::ValueObjectSP &thread_info_valobj_sp);
+    ThreadMemory (const lldb::ProcessSP &process_sp, 
+                  lldb::tid_t tid,
+                  const lldb::ValueObjectSP &thread_info_valobj_sp);
 
     virtual 
     ~ThreadMemory();
diff --git a/source/Plugins/Process/Utility/UnwindLLDB.cpp b/source/Plugins/Process/Utility/UnwindLLDB.cpp
index bf71b00..1ba3f0f 100644
--- a/source/Plugins/Process/Utility/UnwindLLDB.cpp
+++ b/source/Plugins/Process/Utility/UnwindLLDB.cpp
@@ -42,7 +42,8 @@
         if (!AddFirstFrame ())
             return 0;
 
-        ABI *abi = m_thread.GetProcess().GetABI().get();
+        ProcessSP process_sp (m_thread.GetProcess());
+        ABI *abi = process_sp ? process_sp->GetABI().get() : NULL;
 
         while (AddOneMoreFrame (abi))
         {
@@ -186,7 +187,8 @@
             return false;
     }
 
-    ABI *abi = m_thread.GetProcess().GetABI().get();
+    ProcessSP process_sp (m_thread.GetProcess());
+    ABI *abi = process_sp ? process_sp->GetABI().get() : NULL;
 
     while (idx >= m_frames.size() && AddOneMoreFrame (abi))
         ;
@@ -217,7 +219,8 @@
             return reg_ctx_sp;
     }
 
-    ABI *abi = m_thread.GetProcess().GetABI().get();
+    ProcessSP process_sp (m_thread.GetProcess());
+    ABI *abi = process_sp ? process_sp->GetABI().get() : NULL;
 
     while (idx >= m_frames.size())
     {
diff --git a/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp b/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp
index 5706c6d..f1cb915 100644
--- a/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp
+++ b/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp
@@ -12,9 +12,10 @@
 // Other libraries and framework includes
 // Project includes
 #include "lldb/Core/ArchSpec.h"
-#include "lldb/Target/Thread.h"
+#include "lldb/Target/ExecutionContext.h"
 #include "lldb/Target/Process.h"
 #include "lldb/Target/Target.h"
+#include "lldb/Target/Thread.h"
 
 #include "RegisterContextMacOSXFrameBackchain.h"
 
@@ -32,14 +33,19 @@
 {
     if (m_cursors.empty())
     {
-        const ArchSpec& target_arch = m_thread.GetProcess().GetTarget().GetArchitecture ();
-        // Frame zero should always be supplied by the thread...
-        StackFrameSP frame_sp (m_thread.GetStackFrameAtIndex (0));
-        
-        if (target_arch.GetAddressByteSize() == 8)
-            GetStackFrameData_x86_64 (frame_sp.get());
-        else
-            GetStackFrameData_i386 (frame_sp.get());
+        ExecutionContext exe_ctx (m_thread.shared_from_this());
+        Target *target = exe_ctx.GetTargetPtr();
+        if (target)
+        {
+            const ArchSpec& target_arch = target->GetArchitecture ();
+            // Frame zero should always be supplied by the thread...
+            exe_ctx.SetFrameSP (m_thread.GetStackFrameAtIndex (0));
+            
+            if (target_arch.GetAddressByteSize() == 8)
+                GetStackFrameData_x86_64 (exe_ctx);
+            else
+                GetStackFrameData_i386 (exe_ctx);
+        }
     }
     return m_cursors.size();
 }
@@ -75,10 +81,16 @@
 }
 
 size_t
-UnwindMacOSXFrameBackchain::GetStackFrameData_i386 (StackFrame *first_frame)
+UnwindMacOSXFrameBackchain::GetStackFrameData_i386 (const ExecutionContext &exe_ctx)
 {
     m_cursors.clear();
+    
+    StackFrame *first_frame = exe_ctx.GetFramePtr();
 
+    Process *process = exe_ctx.GetProcessPtr();
+    if (process == NULL)
+        return 0;
+    
     std::pair<lldb::addr_t, lldb::addr_t> fp_pc_pair;
 
     struct Frame_i386
@@ -103,7 +115,7 @@
     while (frame.fp != 0 && frame.pc != 0 && ((frame.fp & 7) == 0))
     {
         // Read both the FP and PC (8 bytes)
-        if (m_thread.GetProcess().ReadMemory (frame.fp, &frame.fp, k_frame_size, error) != k_frame_size)
+        if (process->ReadMemory (frame.fp, &frame.fp, k_frame_size, error) != k_frame_size)
             break;
         if (frame.pc >= 0x1000)
         {
@@ -137,7 +149,7 @@
                     // previous PC by dereferencing the SP
                     lldb::addr_t first_frame_sp = reg_ctx->GetSP (0);
                     // Read the real second frame return address into frame.pc
-                    if (first_frame_sp && m_thread.GetProcess().ReadMemory (first_frame_sp, &frame.pc, sizeof(frame.pc), error) == sizeof(frame.pc))
+                    if (first_frame_sp && process->ReadMemory (first_frame_sp, &frame.pc, sizeof(frame.pc), error) == sizeof(frame.pc))
                     {
                         cursor.fp = m_cursors.front().fp;
                         cursor.pc = frame.pc;           // Set the new second frame PC
@@ -163,10 +175,16 @@
 
 
 size_t
-UnwindMacOSXFrameBackchain::GetStackFrameData_x86_64 (StackFrame *first_frame)
+UnwindMacOSXFrameBackchain::GetStackFrameData_x86_64 (const ExecutionContext &exe_ctx)
 {
     m_cursors.clear();
 
+    Process *process = exe_ctx.GetProcessPtr();
+    if (process == NULL)
+        return 0;
+    
+    StackFrame *first_frame = exe_ctx.GetFramePtr();
+
     std::pair<lldb::addr_t, lldb::addr_t> fp_pc_pair;
 
     struct Frame_x86_64
@@ -190,7 +208,7 @@
     while (frame.fp != 0 && frame.pc != 0 && ((frame.fp & 7) == 0))
     {
         // Read both the FP and PC (16 bytes)
-        if (m_thread.GetProcess().ReadMemory (frame.fp, &frame.fp, k_frame_size, error) != k_frame_size)
+        if (process->ReadMemory (frame.fp, &frame.fp, k_frame_size, error) != k_frame_size)
             break;
 
         if (frame.pc >= 0x1000)
@@ -225,7 +243,7 @@
                     // previous PC by dereferencing the SP
                     lldb::addr_t first_frame_sp = reg_ctx->GetSP (0);
                     // Read the real second frame return address into frame.pc
-                    if (m_thread.GetProcess().ReadMemory (first_frame_sp, &frame.pc, sizeof(frame.pc), error) == sizeof(frame.pc))
+                    if (process->ReadMemory (first_frame_sp, &frame.pc, sizeof(frame.pc), error) == sizeof(frame.pc))
                     {
                         cursor.fp = m_cursors.front().fp;
                         cursor.pc = frame.pc;           // Set the new second frame PC
diff --git a/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.h b/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.h
index 5667aaf..2695376 100644
--- a/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.h
+++ b/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.h
@@ -60,10 +60,10 @@
     std::vector<Cursor> m_cursors;
 
     size_t
-    GetStackFrameData_i386 (lldb_private::StackFrame *first_frame);
+    GetStackFrameData_i386 (const lldb_private::ExecutionContext &exe_ctx);
 
     size_t
-    GetStackFrameData_x86_64 (lldb_private::StackFrame *first_frame);
+    GetStackFrameData_x86_64 (const lldb_private::ExecutionContext &exe_ctx);
 
     //------------------------------------------------------------------
     // For UnwindMacOSXFrameBackchain only
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
index 07b17b4..0648845 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
@@ -17,6 +17,7 @@
 #include "lldb/Core/RegisterValue.h"
 #include "lldb/Core/Scalar.h"
 #include "lldb/Core/StreamString.h"
+#include "lldb/Target/ExecutionContext.h"
 // Project includes
 #include "Utility/StringExtractorGDBRemote.h"
 #include "ProcessGDBRemote.h"
@@ -61,18 +62,6 @@
 {
 }
 
-ProcessGDBRemote &
-GDBRemoteRegisterContext::GetGDBProcess()
-{
-    return static_cast<ProcessGDBRemote &>(m_thread.GetProcess());
-}
-
-ThreadGDBRemote &
-GDBRemoteRegisterContext::GetGDBThread()
-{
-    return static_cast<ThreadGDBRemote &>(m_thread);
-}
-
 void
 GDBRemoteRegisterContext::InvalidateAllRegisters ()
 {
@@ -158,7 +147,14 @@
 bool
 GDBRemoteRegisterContext::ReadRegisterBytes (const RegisterInfo *reg_info, DataExtractor &data)
 {
-    GDBRemoteCommunicationClient &gdb_comm (GetGDBProcess().GetGDBRemote());
+    ExecutionContext exe_ctx (CalculateThread());
+    
+    Process *process = exe_ctx.GetProcessPtr();
+    Thread *thread = exe_ctx.GetThreadPtr();
+    if (process == NULL || thread == NULL)
+        return false;
+
+    GDBRemoteCommunicationClient &gdb_comm (((ProcessGDBRemote *)process)->GetGDBRemote());
 
     InvalidateIfNeeded(false);
 
@@ -170,7 +166,8 @@
         if (gdb_comm.GetSequenceMutex (locker))
         {
             const bool thread_suffix_supported = gdb_comm.GetThreadSuffixSupported();
-            if (thread_suffix_supported || GetGDBProcess().GetGDBRemote().SetCurrentThread(m_thread.GetID()))
+            ProcessSP process_sp (m_thread.GetProcess());
+            if (thread_suffix_supported || static_cast<ProcessGDBRemote *>(process_sp.get())->GetGDBRemote().SetCurrentThread(m_thread.GetID()))
             {
                 char packet[64];
                 StringExtractorGDBRemote response;
@@ -238,7 +235,14 @@
 bool
 GDBRemoteRegisterContext::WriteRegisterBytes (const lldb_private::RegisterInfo *reg_info, DataExtractor &data, uint32_t data_offset)
 {
-    GDBRemoteCommunicationClient &gdb_comm (GetGDBProcess().GetGDBRemote());
+    ExecutionContext exe_ctx (CalculateThread());
+    
+    Process *process = exe_ctx.GetProcessPtr();
+    Thread *thread = exe_ctx.GetThreadPtr();
+    if (process == NULL || thread == NULL)
+        return false;
+    
+    GDBRemoteCommunicationClient &gdb_comm (((ProcessGDBRemote *)process)->GetGDBRemote());
 // FIXME: This check isn't right because IsRunning checks the Public state, but this
 // is work you need to do - for instance in ShouldStop & friends - before the public 
 // state has been changed.
@@ -264,7 +268,8 @@
         if (gdb_comm.GetSequenceMutex (locker))
         {
             const bool thread_suffix_supported = gdb_comm.GetThreadSuffixSupported();
-            if (thread_suffix_supported || GetGDBProcess().GetGDBRemote().SetCurrentThread(m_thread.GetID()))
+            ProcessSP process_sp (m_thread.GetProcess());
+            if (thread_suffix_supported || static_cast<ProcessGDBRemote *>(process_sp.get())->GetGDBRemote().SetCurrentThread(m_thread.GetID()))
             {
                 uint32_t offset, end_offset;
                 StreamString packet;
@@ -334,7 +339,15 @@
 bool
 GDBRemoteRegisterContext::ReadAllRegisterValues (lldb::DataBufferSP &data_sp)
 {
-    GDBRemoteCommunicationClient &gdb_comm (GetGDBProcess().GetGDBRemote());
+    ExecutionContext exe_ctx (CalculateThread());
+    
+    Process *process = exe_ctx.GetProcessPtr();
+    Thread *thread = exe_ctx.GetThreadPtr();
+    if (process == NULL || thread == NULL)
+        return false;
+    
+    GDBRemoteCommunicationClient &gdb_comm (((ProcessGDBRemote *)process)->GetGDBRemote());
+
     StringExtractorGDBRemote response;
     
     Mutex::Locker locker;
@@ -342,7 +355,8 @@
     {
         char packet[32];
         const bool thread_suffix_supported = gdb_comm.GetThreadSuffixSupported();
-        if (thread_suffix_supported || GetGDBProcess().GetGDBRemote().SetCurrentThread(m_thread.GetID()))
+        ProcessSP process_sp (m_thread.GetProcess());
+        if (thread_suffix_supported || static_cast<ProcessGDBRemote *>(process_sp.get())->GetGDBRemote().SetCurrentThread(m_thread.GetID()))
         {
             int packet_len = 0;
             if (thread_suffix_supported)
@@ -382,13 +396,22 @@
     if (!data_sp || data_sp->GetBytes() == NULL || data_sp->GetByteSize() == 0)
         return false;
 
-    GDBRemoteCommunicationClient &gdb_comm (GetGDBProcess().GetGDBRemote());
+    ExecutionContext exe_ctx (CalculateThread());
+    
+    Process *process = exe_ctx.GetProcessPtr();
+    Thread *thread = exe_ctx.GetThreadPtr();
+    if (process == NULL || thread == NULL)
+        return false;
+    
+    GDBRemoteCommunicationClient &gdb_comm (((ProcessGDBRemote *)process)->GetGDBRemote());
+
     StringExtractorGDBRemote response;
     Mutex::Locker locker;
     if (gdb_comm.GetSequenceMutex (locker))
     {
         const bool thread_suffix_supported = gdb_comm.GetThreadSuffixSupported();
-        if (thread_suffix_supported || GetGDBProcess().GetGDBRemote().SetCurrentThread(m_thread.GetID()))
+        ProcessSP process_sp (m_thread.GetProcess());
+        if (thread_suffix_supported || static_cast<ProcessGDBRemote *>(process_sp.get())->GetGDBRemote().SetCurrentThread(m_thread.GetID()))
         {
             // The data_sp contains the entire G response packet including the
             // G, and if the thread suffix is supported, it has the thread suffix
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h b/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h
index d1955e8..9f96e77 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h
@@ -240,12 +240,6 @@
     void
     SetAllRegisterValid (bool b);
 
-    ProcessGDBRemote &
-    GetGDBProcess();
-
-    ThreadGDBRemote &
-    GetGDBThread();
-
     GDBRemoteDynamicRegisterInfo &m_reg_info;
     std::vector<bool> m_reg_valid;
     lldb_private::DataExtractor m_reg_data;
diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index 8424d2a..53b7a24 100644
--- a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -1125,7 +1125,7 @@
             tid_t tid = thread_ids[i];
             ThreadSP thread_sp (old_thread_list.FindThreadByID (tid, false));
             if (!thread_sp)
-                thread_sp.reset (new ThreadGDBRemote (*this, tid));
+                thread_sp.reset (new ThreadGDBRemote (shared_from_this(), tid));
             new_thread_list.AddThread(thread_sp);
         }
     }
@@ -1201,7 +1201,7 @@
                     if (!thread_sp)
                     {
                         // Create the thread if we need to
-                        thread_sp.reset (new ThreadGDBRemote (*this, tid));
+                        thread_sp.reset (new ThreadGDBRemote (shared_from_this(), tid));
                         m_thread_list.AddThread(thread_sp);
                     }
                 }
@@ -1292,7 +1292,7 @@
                         else if (reason.compare("breakpoint") == 0)
                         {
                             addr_t pc = gdb_thread->GetRegisterContext()->GetPC();
-                            lldb::BreakpointSiteSP bp_site_sp = gdb_thread->GetProcess().GetBreakpointSiteList().FindByAddress(pc);
+                            lldb::BreakpointSiteSP bp_site_sp = gdb_thread->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,
@@ -1335,7 +1335,7 @@
                             // Currently we are going to assume SIGTRAP means we are either
                             // hitting a breakpoint or hardware single stepping. 
                             addr_t pc = gdb_thread->GetRegisterContext()->GetPC();
-                            lldb::BreakpointSiteSP bp_site_sp = gdb_thread->GetProcess().GetBreakpointSiteList().FindByAddress(pc);
+                            lldb::BreakpointSiteSP bp_site_sp = gdb_thread->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,
diff --git a/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp b/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
index 4938591..55cb222 100644
--- a/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
+++ b/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
@@ -32,18 +32,25 @@
 // Thread Registers
 //----------------------------------------------------------------------
 
-ThreadGDBRemote::ThreadGDBRemote (ProcessGDBRemote &process, lldb::tid_t tid) :
-    Thread(process, tid),
+ThreadGDBRemote::ThreadGDBRemote (const ProcessSP &process_sp, lldb::tid_t tid) :
+    Thread(process_sp, tid),
     m_thread_name (),
     m_dispatch_queue_name (),
     m_thread_dispatch_qaddr (LLDB_INVALID_ADDRESS)
 {
-    ProcessGDBRemoteLog::LogIf(GDBR_LOG_THREAD, "%p: ThreadGDBRemote::ThreadGDBRemote (pid = %i, tid = 0x%4.4x)", this, m_process.GetID(), GetID());
+    ProcessGDBRemoteLog::LogIf(GDBR_LOG_THREAD, "%p: ThreadGDBRemote::ThreadGDBRemote (pid = %i, tid = 0x%4.4x)", 
+                               this, 
+                               process_sp ? process_sp->GetID() : LLDB_INVALID_PROCESS_ID, 
+                               GetID());
 }
 
 ThreadGDBRemote::~ThreadGDBRemote ()
 {
-    ProcessGDBRemoteLog::LogIf(GDBR_LOG_THREAD, "%p: ThreadGDBRemote::~ThreadGDBRemote (pid = %i, tid = 0x%4.4x)", this, m_process.GetID(), GetID());
+    ProcessSP process_sp(GetProcess());
+    ProcessGDBRemoteLog::LogIf(GDBR_LOG_THREAD, "%p: ThreadGDBRemote::~ThreadGDBRemote (pid = %i, tid = 0x%4.4x)", 
+                               this, 
+                               process_sp ? process_sp->GetID() : LLDB_INVALID_PROCESS_ID, 
+                               GetID());
     DestroyThread();
 }
 
@@ -60,8 +67,16 @@
 ThreadGDBRemote::GetQueueName ()
 {
     // Always re-fetch the dispatch queue name since it can change
+
     if (m_thread_dispatch_qaddr != 0 || m_thread_dispatch_qaddr != LLDB_INVALID_ADDRESS)
-        return GetGDBProcess().GetDispatchQueueNameForThread (m_thread_dispatch_qaddr, m_dispatch_queue_name);
+    {
+        ProcessSP process_sp (GetProcess());
+        if (process_sp)
+        {
+            ProcessGDBRemote *gdb_process = static_cast<ProcessGDBRemote *>(process_sp.get());
+            return gdb_process->GetDispatchQueueNameForThread (m_thread_dispatch_qaddr, m_dispatch_queue_name);
+        }
+    }
     return NULL;
 }
 
@@ -79,32 +94,37 @@
     if (log)
         log->Printf ("Resuming thread: %4.4llx with state: %s.", GetID(), StateAsCString(resume_state));
 
-    ProcessGDBRemote &process = GetGDBProcess();
-    switch (resume_state)
+    ProcessSP process_sp (GetProcess());
+    if (process_sp)
     {
-    case eStateSuspended:
-    case eStateStopped:
-        // Don't append anything for threads that should stay stopped.
-        break;
+        ProcessGDBRemote *gdb_process = static_cast<ProcessGDBRemote *>(process_sp.get());
+        switch (resume_state)
+        {
+        case eStateSuspended:
+        case eStateStopped:
+            // Don't append anything for threads that should stay stopped.
+            break;
 
-    case eStateRunning:
-        if (m_process.GetUnixSignals().SignalIsValid (signo))
-            process.m_continue_C_tids.push_back(std::make_pair(GetID(), signo));
-        else
-            process.m_continue_c_tids.push_back(GetID());
-        break;
+        case eStateRunning:
+            if (gdb_process->GetUnixSignals().SignalIsValid (signo))
+                gdb_process->m_continue_C_tids.push_back(std::make_pair(GetID(), signo));
+            else
+                gdb_process->m_continue_c_tids.push_back(GetID());
+            break;
 
-    case eStateStepping:
-        if (m_process.GetUnixSignals().SignalIsValid (signo))
-            process.m_continue_S_tids.push_back(std::make_pair(GetID(), signo));
-        else
-            process.m_continue_s_tids.push_back(GetID());
-        break;
+        case eStateStepping:
+            if (gdb_process->GetUnixSignals().SignalIsValid (signo))
+                gdb_process->m_continue_S_tids.push_back(std::make_pair(GetID(), signo));
+            else
+                gdb_process->m_continue_s_tids.push_back(GetID());
+            break;
 
-    default:
-        break;
+        default:
+            break;
+        }
+        return true;
     }
-    return true;
+    return false;
 }
 
 void
@@ -167,8 +187,16 @@
     if (frame)
         concrete_frame_idx = frame->GetConcreteFrameIndex ();
 
+    
     if (concrete_frame_idx == 0)
-        reg_ctx_sp.reset (new GDBRemoteRegisterContext (*this, concrete_frame_idx, GetGDBProcess().m_register_info, read_all_registers_at_once));
+    {
+        ProcessSP process_sp (GetProcess());
+        if (process_sp)
+        {
+            ProcessGDBRemote *gdb_process = static_cast<ProcessGDBRemote *>(process_sp.get());
+            reg_ctx_sp.reset (new GDBRemoteRegisterContext (*this, concrete_frame_idx, gdb_process->m_register_info, read_all_registers_at_once));
+        }
+    }
     else if (m_unwinder_ap.get())
         reg_ctx_sp = m_unwinder_ap->CreateRegisterContextForFrame (frame);
     return reg_ctx_sp;
@@ -185,25 +213,29 @@
 lldb::StopInfoSP
 ThreadGDBRemote::GetPrivateStopReason ()
 {
-    const uint32_t process_stop_id = GetProcess().GetStopID();
-    if (m_thread_stop_reason_stop_id != process_stop_id ||
-        (m_actual_stop_info_sp && !m_actual_stop_info_sp->IsValid()))
+    ProcessSP process_sp (GetProcess());
+    if (process_sp)
     {
-        // If GetGDBProcess().SetThreadStopInfo() doesn't find a stop reason
-        // for this thread, then m_actual_stop_info_sp will not ever contain
-        // a valid stop reason and the "m_actual_stop_info_sp->IsValid() == false"
-        // check will never be able to tell us if we have the correct stop info
-        // for this thread and we will continually send qThreadStopInfo packets
-        // down to the remote GDB server, so we need to keep our own notion
-        // of the stop ID that m_actual_stop_info_sp is valid for (even if it
-        // contains nothing). We use m_thread_stop_reason_stop_id for this below.
-        m_thread_stop_reason_stop_id = process_stop_id;
-        m_actual_stop_info_sp.reset();
+        const uint32_t process_stop_id = process_sp->GetStopID();
+        if (m_thread_stop_reason_stop_id != process_stop_id ||
+            (m_actual_stop_info_sp && !m_actual_stop_info_sp->IsValid()))
+        {
+            // If GetGDBProcess().SetThreadStopInfo() doesn't find a stop reason
+            // for this thread, then m_actual_stop_info_sp will not ever contain
+            // a valid stop reason and the "m_actual_stop_info_sp->IsValid() == false"
+            // check will never be able to tell us if we have the correct stop info
+            // for this thread and we will continually send qThreadStopInfo packets
+            // down to the remote GDB server, so we need to keep our own notion
+            // of the stop ID that m_actual_stop_info_sp is valid for (even if it
+            // contains nothing). We use m_thread_stop_reason_stop_id for this below.
+            m_thread_stop_reason_stop_id = process_stop_id;
+            m_actual_stop_info_sp.reset();
 
-        StringExtractorGDBRemote stop_packet;
-        ProcessGDBRemote &gdb_process = GetGDBProcess();
-        if (gdb_process.GetGDBRemote().GetThreadStopInfo(GetID(), stop_packet))
-            gdb_process.SetThreadStopInfo (stop_packet);
+            StringExtractorGDBRemote stop_packet;
+            ProcessGDBRemote *gdb_process = static_cast<ProcessGDBRemote *>(process_sp.get());
+            if (gdb_process->GetGDBRemote().GetThreadStopInfo(GetID(), stop_packet))
+                gdb_process->SetThreadStopInfo (stop_packet);
+        }
     }
     return m_actual_stop_info_sp;
 }
diff --git a/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h b/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h
index 09f8684..3eb6295 100644
--- a/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h
+++ b/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h
@@ -21,7 +21,7 @@
 class ThreadGDBRemote : public lldb_private::Thread
 {
 public:
-    ThreadGDBRemote (ProcessGDBRemote &process, lldb::tid_t tid);
+    ThreadGDBRemote (const lldb::ProcessSP &process_sp, lldb::tid_t tid);
 
     virtual
     ~ThreadGDBRemote ();
@@ -47,18 +47,6 @@
     virtual void
     ClearStackFrames ();
 
-    ProcessGDBRemote &
-    GetGDBProcess ()
-    {
-        return (ProcessGDBRemote &)m_process;
-    }
-
-    const ProcessGDBRemote &
-    GetGDBProcess () const
-    {
-        return (ProcessGDBRemote &)m_process;
-    }
-
     void
     Dump (lldb_private::Log *log, uint32_t index);
 
diff --git a/source/Plugins/Process/mach-core/ProcessMachCore.cpp b/source/Plugins/Process/mach-core/ProcessMachCore.cpp
index 0dff8fd..8cd5b1b 100644
--- a/source/Plugins/Process/mach-core/ProcessMachCore.cpp
+++ b/source/Plugins/Process/mach-core/ProcessMachCore.cpp
@@ -354,7 +354,7 @@
             const uint32_t num_threads = core_objfile->GetNumThreadContexts ();
             for (lldb::tid_t tid = 0; tid < num_threads; ++tid)
             {
-                ThreadSP thread_sp(new ThreadMachCore (*this, tid));
+                ThreadSP thread_sp(new ThreadMachCore (shared_from_this(), tid));
                 new_thread_list.AddThread (thread_sp);
             }
         }
diff --git a/source/Plugins/Process/mach-core/ThreadMachCore.cpp b/source/Plugins/Process/mach-core/ThreadMachCore.cpp
index 7944996..c0eefe1 100644
--- a/source/Plugins/Process/mach-core/ThreadMachCore.cpp
+++ b/source/Plugins/Process/mach-core/ThreadMachCore.cpp
@@ -35,11 +35,12 @@
 // Thread Registers
 //----------------------------------------------------------------------
 
-ThreadMachCore::ThreadMachCore (ProcessMachCore &process, lldb::tid_t tid) :
-    Thread(process, tid),
+ThreadMachCore::ThreadMachCore (const lldb::ProcessSP &process_sp, lldb::tid_t tid) :
+    Thread(process_sp, tid),
     m_thread_name (),
     m_dispatch_queue_name (),
-    m_thread_dispatch_qaddr (LLDB_INVALID_ADDRESS)
+    m_thread_dispatch_qaddr (LLDB_INVALID_ADDRESS),
+    m_thread_reg_ctx_sp ()
 {
 }
 
@@ -106,38 +107,51 @@
 
     if (concrete_frame_idx == 0)
     {
-        ObjectFile *core_objfile = GetMachCoreProcess ().GetCoreObjectFile ();
-        if (core_objfile)
-            reg_ctx_sp = core_objfile->GetThreadContextAtIndex (GetID(), *this);
+        if (!m_thread_reg_ctx_sp)
+        {
+            ProcessSP process_sp (GetProcess());
+            
+            ObjectFile *core_objfile = static_cast<ProcessMachCore *>(process_sp.get())->GetCoreObjectFile ();
+            if (core_objfile)
+                m_thread_reg_ctx_sp = core_objfile->GetThreadContextAtIndex (GetID(), *this);
+        }
+        reg_ctx_sp = m_thread_reg_ctx_sp;
     }
     else if (m_unwinder_ap.get())
+    {
         reg_ctx_sp = m_unwinder_ap->CreateRegisterContextForFrame (frame);
+    }
     return reg_ctx_sp;
 }
 
 lldb::StopInfoSP
 ThreadMachCore::GetPrivateStopReason ()
 {
-    const uint32_t process_stop_id = GetProcess().GetStopID();
-    if (m_thread_stop_reason_stop_id != process_stop_id ||
-        (m_actual_stop_info_sp && !m_actual_stop_info_sp->IsValid()))
+    ProcessSP process_sp (GetProcess());
+
+    if (process_sp)
     {
-        // TODO: can we query the initial state of the thread here?
-        // For now I am just going to pretend that a SIGSTOP happened.
+        const uint32_t process_stop_id = process_sp->GetStopID();
+        if (m_thread_stop_reason_stop_id != process_stop_id ||
+            (m_actual_stop_info_sp && !m_actual_stop_info_sp->IsValid()))
+        {
+            // TODO: can we query the initial state of the thread here?
+            // For now I am just going to pretend that a SIGSTOP happened.
 
-        SetStopInfo(StopInfo::CreateStopReasonWithSignal (*this, SIGSTOP));
+            SetStopInfo(StopInfo::CreateStopReasonWithSignal (*this, SIGSTOP));
 
-        // If GetKDPProcess().SetThreadStopInfo() doesn't find a stop reason
-        // for this thread, then m_actual_stop_info_sp will not ever contain
-        // a valid stop reason and the "m_actual_stop_info_sp->IsValid() == false"
-        // check will never be able to tell us if we have the correct stop info
-        // for this thread and we will continually send qThreadStopInfo packets
-        // down to the remote KDP server, so we need to keep our own notion
-        // of the stop ID that m_actual_stop_info_sp is valid for (even if it
-        // contains nothing). We use m_thread_stop_reason_stop_id for this below.
-//        m_thread_stop_reason_stop_id = process_stop_id;
-//        m_actual_stop_info_sp.reset();
+            // If GetKDPProcess().SetThreadStopInfo() doesn't find a stop reason
+            // for this thread, then m_actual_stop_info_sp will not ever contain
+            // a valid stop reason and the "m_actual_stop_info_sp->IsValid() == false"
+            // check will never be able to tell us if we have the correct stop info
+            // for this thread and we will continually send qThreadStopInfo packets
+            // down to the remote KDP server, so we need to keep our own notion
+            // of the stop ID that m_actual_stop_info_sp is valid for (even if it
+            // contains nothing). We use m_thread_stop_reason_stop_id for this below.
+    //        m_thread_stop_reason_stop_id = process_stop_id;
+    //        m_actual_stop_info_sp.reset();
 
+        }
     }
     return m_actual_stop_info_sp;
 }
diff --git a/source/Plugins/Process/mach-core/ThreadMachCore.h b/source/Plugins/Process/mach-core/ThreadMachCore.h
index dbfae48..497620c 100644
--- a/source/Plugins/Process/mach-core/ThreadMachCore.h
+++ b/source/Plugins/Process/mach-core/ThreadMachCore.h
@@ -19,7 +19,7 @@
 class ThreadMachCore : public lldb_private::Thread
 {
 public:
-    ThreadMachCore (ProcessMachCore &process, 
+    ThreadMachCore (const lldb::ProcessSP &process_sp,
                     lldb::tid_t tid);
 
     virtual
@@ -40,12 +40,6 @@
     virtual void
     ClearStackFrames ();
 
-    ProcessMachCore &
-    GetMachCoreProcess ()
-    {
-        return (ProcessMachCore &)m_process;
-    }
-
     static bool
     ThreadIDIsValid (lldb::tid_t thread);
 
@@ -86,6 +80,7 @@
     std::string m_thread_name;
     std::string m_dispatch_queue_name;
     lldb::addr_t m_thread_dispatch_qaddr;
+    lldb::RegisterContextSP m_thread_reg_ctx_sp;
     //------------------------------------------------------------------
     // Member variables.
     //------------------------------------------------------------------