[Lldb-commits] [lldb] [lldb] Guard SBFrame/SBThread methods against running processes (PR #152020)

Felipe de Azevedo Piovezan via lldb-commits lldb-commits at lists.llvm.org
Fri Aug 8 10:46:26 PDT 2025


https://github.com/felipepiovezan updated https://github.com/llvm/llvm-project/pull/152020

>From 9be92f8ead1294cc1931fe68c13dbaa8c5945423 Mon Sep 17 00:00:00 2001
From: Felipe de Azevedo Piovezan <fpiovezan at apple.com>
Date: Mon, 4 Aug 2025 08:32:20 -0700
Subject: [PATCH 1/6] [lldb] Guard SBFrame/SBThread methods against running
 processes

Prior to this patch, SBFrame/SBThread methods exhibit racy behavior if
called while the process is running, because they do not lock the
`Process::RetRunLock` mutex. If they did, they would fail, correctly
identifying that the process is not running.

Some methods _attempt_ to protect against this with the pattern:

```
ExecutionContext exe_ctx(m_opaque_sp.get(), lock); // this is a different lock
Process *process = exe_ctx.GetProcessPtr();
if (process) {
  Process::StopLocker stop_locker;
  if (stop_locker.TryLock(&process->GetRunLock()))
        .... do work ...
```

However, this is also racy: the constructor of `ExecutionContext` will
access the frame list, which is something that can only be done once the
process is stopped.

With this patch:

1. The constructor of `ExecutionContext` now expects a `ProcessRunLock`
   as an argument. It attempts to lock the run lock, and only fills in
   information about frames and threads if the lock can be acquired.
   Callers of the constructor are expected to check the lock.
2. All uses of ExecutionContext are adjusted to conform to the above.
3. The SBThread.cpp-defined helper function ResumeNewPlan now expects a
   locked ProcessRunLock as _proof_ that the execution is stopped. It
   will unlock the mutex prior to resuming the process.

This commit exposes many opportunities for early-returns, but these
would increase the diff of this patch and distract from the important
changes, so we opt not to do it here.
---
 lldb/include/lldb/API/SBFrame.h               |   4 +
 lldb/include/lldb/Host/ProcessRunLock.h       |   5 +
 lldb/include/lldb/Target/ExecutionContext.h   |   9 +-
 lldb/source/API/SBFrame.cpp                   | 529 ++++++++++--------
 lldb/source/API/SBThread.cpp                  | 329 ++++++-----
 lldb/source/Target/ExecutionContext.cpp       |  12 +-
 .../python_api/run_locker/TestRunLocker.py    |   4 +-
 7 files changed, 508 insertions(+), 384 deletions(-)

diff --git a/lldb/include/lldb/API/SBFrame.h b/lldb/include/lldb/API/SBFrame.h
index 3635ee5a537ad..35198068814d0 100644
--- a/lldb/include/lldb/API/SBFrame.h
+++ b/lldb/include/lldb/API/SBFrame.h
@@ -233,6 +233,10 @@ class LLDB_API SBFrame {
 
   void SetFrameSP(const lldb::StackFrameSP &lldb_object_sp);
 
+  /// Return an SBValue with an error message warning that the process is not
+  /// currently stopped.
+  static SBValue CreateProcessIsRunningExprEvalError();
+
   lldb::ExecutionContextRefSP m_opaque_sp;
 };
 
diff --git a/lldb/include/lldb/Host/ProcessRunLock.h b/lldb/include/lldb/Host/ProcessRunLock.h
index 94683673024d5..5efa46154a61e 100644
--- a/lldb/include/lldb/Host/ProcessRunLock.h
+++ b/lldb/include/lldb/Host/ProcessRunLock.h
@@ -41,9 +41,14 @@ class ProcessRunLock {
   class ProcessRunLocker {
   public:
     ProcessRunLocker() = default;
+    ProcessRunLocker(ProcessRunLocker &&other) : m_lock(other.m_lock) {
+      other.m_lock = nullptr;
+    }
 
     ~ProcessRunLocker() { Unlock(); }
 
+    bool IsLocked() const { return m_lock; }
+
     // Try to lock the read lock, but only do so if there are no writers.
     bool TryLock(ProcessRunLock *lock) {
       if (m_lock) {
diff --git a/lldb/include/lldb/Target/ExecutionContext.h b/lldb/include/lldb/Target/ExecutionContext.h
index aebd0d5308e72..ae6051f576fac 100644
--- a/lldb/include/lldb/Target/ExecutionContext.h
+++ b/lldb/include/lldb/Target/ExecutionContext.h
@@ -11,6 +11,7 @@
 
 #include <mutex>
 
+#include "lldb/Host/ProcessRunLock.h"
 #include "lldb/Target/StackID.h"
 #include "lldb/lldb-private.h"
 
@@ -318,11 +319,13 @@ class ExecutionContext {
   // These two variants take in a locker, and grab the target, lock the API
   // mutex into locker, then fill in the rest of the shared pointers.
   ExecutionContext(const ExecutionContextRef &exe_ctx_ref,
-                   std::unique_lock<std::recursive_mutex> &locker)
-      : ExecutionContext(&exe_ctx_ref, locker) {}
+                   std::unique_lock<std::recursive_mutex> &locker,
+                   ProcessRunLock::ProcessRunLocker &stop_locker)
+      : ExecutionContext(&exe_ctx_ref, locker, stop_locker) {}
 
   ExecutionContext(const ExecutionContextRef *exe_ctx_ref,
-                   std::unique_lock<std::recursive_mutex> &locker);
+                   std::unique_lock<std::recursive_mutex> &locker,
+                   ProcessRunLock::ProcessRunLocker &stop_locker);
   // Create execution contexts from execution context scopes
   ExecutionContext(ExecutionContextScope *exe_scope);
   ExecutionContext(ExecutionContextScope &exe_scope);
diff --git a/lldb/source/API/SBFrame.cpp b/lldb/source/API/SBFrame.cpp
index 5b69cf1ee2641..96891fee61e73 100644
--- a/lldb/source/API/SBFrame.cpp
+++ b/lldb/source/API/SBFrame.cpp
@@ -99,14 +99,15 @@ SBFrame::operator bool() const {
   LLDB_INSTRUMENT_VA(this);
 
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (!stop_locker.IsLocked())
+    return false;
 
   Target *target = exe_ctx.GetTargetPtr();
   Process *process = exe_ctx.GetProcessPtr();
   if (target && process) {
-    Process::StopLocker stop_locker;
-    if (stop_locker.TryLock(&process->GetRunLock()))
-      return GetFrameSP().get() != nullptr;
+    return GetFrameSP().get() != nullptr;
   }
 
   // Without a target & process we can't have a valid stack frame.
@@ -118,16 +119,16 @@ SBSymbolContext SBFrame::GetSymbolContext(uint32_t resolve_scope) const {
 
   SBSymbolContext sb_sym_ctx;
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (!stop_locker.IsLocked())
+    return sb_sym_ctx;
   SymbolContextItem scope = static_cast<SymbolContextItem>(resolve_scope);
   Target *target = exe_ctx.GetTargetPtr();
   Process *process = exe_ctx.GetProcessPtr();
   if (target && process) {
-    Process::StopLocker stop_locker;
-    if (stop_locker.TryLock(&process->GetRunLock())) {
-      if (StackFrame *frame = exe_ctx.GetFramePtr())
-        sb_sym_ctx = frame->GetSymbolContext(scope);
-    }
+    if (StackFrame *frame = exe_ctx.GetFramePtr())
+      sb_sym_ctx = frame->GetSymbolContext(scope);
   }
 
   return sb_sym_ctx;
@@ -139,19 +140,19 @@ SBModule SBFrame::GetModule() const {
   SBModule sb_module;
   ModuleSP module_sp;
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (!stop_locker.IsLocked())
+    return sb_module;
 
   StackFrame *frame = nullptr;
   Target *target = exe_ctx.GetTargetPtr();
   Process *process = exe_ctx.GetProcessPtr();
   if (target && process) {
-    Process::StopLocker stop_locker;
-    if (stop_locker.TryLock(&process->GetRunLock())) {
-      frame = exe_ctx.GetFramePtr();
-      if (frame) {
-        module_sp = frame->GetSymbolContext(eSymbolContextModule).module_sp;
-        sb_module.SetSP(module_sp);
-      }
+    frame = exe_ctx.GetFramePtr();
+    if (frame) {
+      module_sp = frame->GetSymbolContext(eSymbolContextModule).module_sp;
+      sb_module.SetSP(module_sp);
     }
   }
 
@@ -163,19 +164,19 @@ SBCompileUnit SBFrame::GetCompileUnit() const {
 
   SBCompileUnit sb_comp_unit;
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (!stop_locker.IsLocked())
+    return sb_comp_unit;
 
   StackFrame *frame = nullptr;
   Target *target = exe_ctx.GetTargetPtr();
   Process *process = exe_ctx.GetProcessPtr();
   if (target && process) {
-    Process::StopLocker stop_locker;
-    if (stop_locker.TryLock(&process->GetRunLock())) {
-      frame = exe_ctx.GetFramePtr();
-      if (frame) {
-        sb_comp_unit.reset(
-            frame->GetSymbolContext(eSymbolContextCompUnit).comp_unit);
-      }
+    frame = exe_ctx.GetFramePtr();
+    if (frame) {
+      sb_comp_unit.reset(
+          frame->GetSymbolContext(eSymbolContextCompUnit).comp_unit);
     }
   }
 
@@ -187,19 +188,19 @@ SBFunction SBFrame::GetFunction() const {
 
   SBFunction sb_function;
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (!stop_locker.IsLocked())
+    return sb_function;
 
   StackFrame *frame = nullptr;
   Target *target = exe_ctx.GetTargetPtr();
   Process *process = exe_ctx.GetProcessPtr();
   if (target && process) {
-    Process::StopLocker stop_locker;
-    if (stop_locker.TryLock(&process->GetRunLock())) {
-      frame = exe_ctx.GetFramePtr();
-      if (frame) {
-        sb_function.reset(
-            frame->GetSymbolContext(eSymbolContextFunction).function);
-      }
+    frame = exe_ctx.GetFramePtr();
+    if (frame) {
+      sb_function.reset(
+          frame->GetSymbolContext(eSymbolContextFunction).function);
     }
   }
 
@@ -211,18 +212,18 @@ SBSymbol SBFrame::GetSymbol() const {
 
   SBSymbol sb_symbol;
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (!stop_locker.IsLocked())
+    return sb_symbol;
 
   StackFrame *frame = nullptr;
   Target *target = exe_ctx.GetTargetPtr();
   Process *process = exe_ctx.GetProcessPtr();
   if (target && process) {
-    Process::StopLocker stop_locker;
-    if (stop_locker.TryLock(&process->GetRunLock())) {
-      frame = exe_ctx.GetFramePtr();
-      if (frame) {
-        sb_symbol.reset(frame->GetSymbolContext(eSymbolContextSymbol).symbol);
-      }
+    frame = exe_ctx.GetFramePtr();
+    if (frame) {
+      sb_symbol.reset(frame->GetSymbolContext(eSymbolContextSymbol).symbol);
     }
   }
 
@@ -234,18 +235,18 @@ SBBlock SBFrame::GetBlock() const {
 
   SBBlock sb_block;
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (!stop_locker.IsLocked())
+    return sb_block;
 
   StackFrame *frame = nullptr;
   Target *target = exe_ctx.GetTargetPtr();
   Process *process = exe_ctx.GetProcessPtr();
   if (target && process) {
-    Process::StopLocker stop_locker;
-    if (stop_locker.TryLock(&process->GetRunLock())) {
-      frame = exe_ctx.GetFramePtr();
-      if (frame)
-        sb_block.SetPtr(frame->GetSymbolContext(eSymbolContextBlock).block);
-    }
+    frame = exe_ctx.GetFramePtr();
+    if (frame)
+      sb_block.SetPtr(frame->GetSymbolContext(eSymbolContextBlock).block);
   }
   return sb_block;
 }
@@ -255,18 +256,18 @@ SBBlock SBFrame::GetFrameBlock() const {
 
   SBBlock sb_block;
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (!stop_locker.IsLocked())
+    return sb_block;
 
   StackFrame *frame = nullptr;
   Target *target = exe_ctx.GetTargetPtr();
   Process *process = exe_ctx.GetProcessPtr();
   if (target && process) {
-    Process::StopLocker stop_locker;
-    if (stop_locker.TryLock(&process->GetRunLock())) {
-      frame = exe_ctx.GetFramePtr();
-      if (frame)
-        sb_block.SetPtr(frame->GetFrameBlock());
-    }
+    frame = exe_ctx.GetFramePtr();
+    if (frame)
+      sb_block.SetPtr(frame->GetFrameBlock());
   }
   return sb_block;
 }
@@ -276,19 +277,19 @@ SBLineEntry SBFrame::GetLineEntry() const {
 
   SBLineEntry sb_line_entry;
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (!stop_locker.IsLocked())
+    return sb_line_entry;
 
   StackFrame *frame = nullptr;
   Target *target = exe_ctx.GetTargetPtr();
   Process *process = exe_ctx.GetProcessPtr();
   if (target && process) {
-    Process::StopLocker stop_locker;
-    if (stop_locker.TryLock(&process->GetRunLock())) {
-      frame = exe_ctx.GetFramePtr();
-      if (frame) {
-        sb_line_entry.SetLineEntry(
-            frame->GetSymbolContext(eSymbolContextLineEntry).line_entry);
-      }
+    frame = exe_ctx.GetFramePtr();
+    if (frame) {
+      sb_line_entry.SetLineEntry(
+          frame->GetSymbolContext(eSymbolContextLineEntry).line_entry);
     }
   }
   return sb_line_entry;
@@ -300,7 +301,10 @@ uint32_t SBFrame::GetFrameID() const {
   uint32_t frame_idx = UINT32_MAX;
 
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (!stop_locker.IsLocked())
+    return frame_idx;
 
   StackFrame *frame = exe_ctx.GetFramePtr();
   if (frame)
@@ -313,7 +317,10 @@ lldb::addr_t SBFrame::GetCFA() const {
   LLDB_INSTRUMENT_VA(this);
 
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (!stop_locker.IsLocked())
+    return LLDB_INVALID_ADDRESS;
 
   StackFrame *frame = exe_ctx.GetFramePtr();
   if (frame)
@@ -326,19 +333,19 @@ addr_t SBFrame::GetPC() const {
 
   addr_t addr = LLDB_INVALID_ADDRESS;
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (!stop_locker.IsLocked())
+    return addr;
 
   StackFrame *frame = nullptr;
   Target *target = exe_ctx.GetTargetPtr();
   Process *process = exe_ctx.GetProcessPtr();
   if (target && process) {
-    Process::StopLocker stop_locker;
-    if (stop_locker.TryLock(&process->GetRunLock())) {
-      frame = exe_ctx.GetFramePtr();
-      if (frame) {
-        addr = frame->GetFrameCodeAddress().GetOpcodeLoadAddress(
-            target, AddressClass::eCode);
-      }
+    frame = exe_ctx.GetFramePtr();
+    if (frame) {
+      addr = frame->GetFrameCodeAddress().GetOpcodeLoadAddress(
+          target, AddressClass::eCode);
     }
   }
 
@@ -350,17 +357,17 @@ bool SBFrame::SetPC(addr_t new_pc) {
 
   bool ret_val = false;
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (!stop_locker.IsLocked())
+    return ret_val;
 
   Target *target = exe_ctx.GetTargetPtr();
   Process *process = exe_ctx.GetProcessPtr();
   if (target && process) {
-    Process::StopLocker stop_locker;
-    if (stop_locker.TryLock(&process->GetRunLock())) {
-      if (StackFrame *frame = exe_ctx.GetFramePtr()) {
-        if (RegisterContextSP reg_ctx_sp = frame->GetRegisterContext()) {
-          ret_val = reg_ctx_sp->SetPC(new_pc);
-        }
+    if (StackFrame *frame = exe_ctx.GetFramePtr()) {
+      if (RegisterContextSP reg_ctx_sp = frame->GetRegisterContext()) {
+        ret_val = reg_ctx_sp->SetPC(new_pc);
       }
     }
   }
@@ -373,17 +380,17 @@ addr_t SBFrame::GetSP() const {
 
   addr_t addr = LLDB_INVALID_ADDRESS;
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (!stop_locker.IsLocked())
+    return addr;
 
   Target *target = exe_ctx.GetTargetPtr();
   Process *process = exe_ctx.GetProcessPtr();
   if (target && process) {
-    Process::StopLocker stop_locker;
-    if (stop_locker.TryLock(&process->GetRunLock())) {
-      if (StackFrame *frame = exe_ctx.GetFramePtr()) {
-        if (RegisterContextSP reg_ctx_sp = frame->GetRegisterContext()) {
-          addr = reg_ctx_sp->GetSP();
-        }
+    if (StackFrame *frame = exe_ctx.GetFramePtr()) {
+      if (RegisterContextSP reg_ctx_sp = frame->GetRegisterContext()) {
+        addr = reg_ctx_sp->GetSP();
       }
     }
   }
@@ -396,17 +403,17 @@ addr_t SBFrame::GetFP() const {
 
   addr_t addr = LLDB_INVALID_ADDRESS;
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (!stop_locker.IsLocked())
+    return addr;
 
   Target *target = exe_ctx.GetTargetPtr();
   Process *process = exe_ctx.GetProcessPtr();
   if (target && process) {
-    Process::StopLocker stop_locker;
-    if (stop_locker.TryLock(&process->GetRunLock())) {
-      if (StackFrame *frame = exe_ctx.GetFramePtr()) {
-        if (RegisterContextSP reg_ctx_sp = frame->GetRegisterContext()) {
-          addr = reg_ctx_sp->GetFP();
-        }
+    if (StackFrame *frame = exe_ctx.GetFramePtr()) {
+      if (RegisterContextSP reg_ctx_sp = frame->GetRegisterContext()) {
+        addr = reg_ctx_sp->GetFP();
       }
     }
   }
@@ -419,18 +426,18 @@ SBAddress SBFrame::GetPCAddress() const {
 
   SBAddress sb_addr;
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (!stop_locker.IsLocked())
+    return sb_addr;
 
   StackFrame *frame = exe_ctx.GetFramePtr();
   Target *target = exe_ctx.GetTargetPtr();
   Process *process = exe_ctx.GetProcessPtr();
   if (target && process) {
-    Process::StopLocker stop_locker;
-    if (stop_locker.TryLock(&process->GetRunLock())) {
-      frame = exe_ctx.GetFramePtr();
-      if (frame)
-        sb_addr.SetAddress(frame->GetFrameCodeAddress());
-    }
+    frame = exe_ctx.GetFramePtr();
+    if (frame)
+      sb_addr.SetAddress(frame->GetFrameCodeAddress());
   }
   return sb_addr;
 }
@@ -446,7 +453,10 @@ lldb::SBValue SBFrame::GetValueForVariablePath(const char *var_path) {
 
   SBValue sb_value;
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (!stop_locker.IsLocked())
+    return sb_value;
 
   StackFrame *frame = exe_ctx.GetFramePtr();
   Target *target = exe_ctx.GetTargetPtr();
@@ -468,25 +478,25 @@ lldb::SBValue SBFrame::GetValueForVariablePath(const char *var_path,
   }
 
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (!stop_locker.IsLocked())
+    return sb_value;
 
   StackFrame *frame = nullptr;
   Target *target = exe_ctx.GetTargetPtr();
   Process *process = exe_ctx.GetProcessPtr();
   if (target && process) {
-    Process::StopLocker stop_locker;
-    if (stop_locker.TryLock(&process->GetRunLock())) {
-      frame = exe_ctx.GetFramePtr();
-      if (frame) {
-        VariableSP var_sp;
-        Status error;
-        ValueObjectSP value_sp(frame->GetValueForVariableExpressionPath(
-            var_path, eNoDynamicValues,
-            StackFrame::eExpressionPathOptionCheckPtrVsMember |
-                StackFrame::eExpressionPathOptionsAllowDirectIVarAccess,
-            var_sp, error));
-        sb_value.SetSP(value_sp, use_dynamic);
-      }
+    frame = exe_ctx.GetFramePtr();
+    if (frame) {
+      VariableSP var_sp;
+      Status error;
+      ValueObjectSP value_sp(frame->GetValueForVariableExpressionPath(
+          var_path, eNoDynamicValues,
+          StackFrame::eExpressionPathOptionCheckPtrVsMember |
+              StackFrame::eExpressionPathOptionsAllowDirectIVarAccess,
+          var_sp, error));
+      sb_value.SetSP(value_sp, use_dynamic);
     }
   }
   return sb_value;
@@ -497,7 +507,10 @@ SBValue SBFrame::FindVariable(const char *name) {
 
   SBValue value;
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (!stop_locker.IsLocked())
+    return value;
 
   StackFrame *frame = exe_ctx.GetFramePtr();
   Target *target = exe_ctx.GetTargetPtr();
@@ -522,21 +535,21 @@ SBValue SBFrame::FindVariable(const char *name,
 
   ValueObjectSP value_sp;
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (!stop_locker.IsLocked())
+    return sb_value;
 
   StackFrame *frame = nullptr;
   Target *target = exe_ctx.GetTargetPtr();
   Process *process = exe_ctx.GetProcessPtr();
   if (target && process) {
-    Process::StopLocker stop_locker;
-    if (stop_locker.TryLock(&process->GetRunLock())) {
-      frame = exe_ctx.GetFramePtr();
-      if (frame) {
-        value_sp = frame->FindVariable(ConstString(name));
+    frame = exe_ctx.GetFramePtr();
+    if (frame) {
+      value_sp = frame->FindVariable(ConstString(name));
 
-        if (value_sp)
-          sb_value.SetSP(value_sp, use_dynamic);
-      }
+      if (value_sp)
+        sb_value.SetSP(value_sp, use_dynamic);
     }
   }
 
@@ -548,7 +561,10 @@ SBValue SBFrame::FindValue(const char *name, ValueType value_type) {
 
   SBValue value;
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (!stop_locker.IsLocked())
+    return value;
 
   StackFrame *frame = exe_ctx.GetFramePtr();
   Target *target = exe_ctx.GetTargetPtr();
@@ -572,14 +588,14 @@ SBValue SBFrame::FindValue(const char *name, ValueType value_type,
 
   ValueObjectSP value_sp;
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
 
-  StackFrame *frame = nullptr;
-  Target *target = exe_ctx.GetTargetPtr();
-  Process *process = exe_ctx.GetProcessPtr();
-  if (target && process) {
-    Process::StopLocker stop_locker;
-    if (stop_locker.TryLock(&process->GetRunLock())) {
+  if (stop_locker.IsLocked()) {
+    StackFrame *frame = nullptr;
+    Target *target = exe_ctx.GetTargetPtr();
+    Process *process = exe_ctx.GetProcessPtr();
+    if (target && process) {
       frame = exe_ctx.GetFramePtr();
       if (frame) {
         VariableList variable_list;
@@ -699,7 +715,10 @@ SBThread SBFrame::GetThread() const {
   LLDB_INSTRUMENT_VA(this);
 
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (!stop_locker.IsLocked())
+    return SBThread();
 
   ThreadSP thread_sp(exe_ctx.GetThreadSP());
   SBThread sb_thread(thread_sp);
@@ -711,17 +730,17 @@ const char *SBFrame::Disassemble() const {
   LLDB_INSTRUMENT_VA(this);
 
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (!stop_locker.IsLocked())
+    return nullptr;
   Target *target = exe_ctx.GetTargetPtr();
   Process *process = exe_ctx.GetProcessPtr();
   if (!target || !process)
     return nullptr;
 
-  Process::StopLocker stop_locker;
-  if (stop_locker.TryLock(&process->GetRunLock())) {
-    if (auto *frame = exe_ctx.GetFramePtr())
-      return ConstString(frame->Disassemble()).GetCString();
-  }
+  if (auto *frame = exe_ctx.GetFramePtr())
+    return ConstString(frame->Disassemble()).GetCString();
 
   return nullptr;
 }
@@ -732,7 +751,10 @@ SBValueList SBFrame::GetVariables(bool arguments, bool locals, bool statics,
 
   SBValueList value_list;
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (!stop_locker.IsLocked())
+    return value_list;
 
   StackFrame *frame = exe_ctx.GetFramePtr();
   Target *target = exe_ctx.GetTargetPtr();
@@ -762,7 +784,12 @@ lldb::SBValueList SBFrame::GetVariables(bool arguments, bool locals,
                      use_dynamic);
 
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (!stop_locker.IsLocked()) {
+    SBValueList empty_list;
+    return empty_list;
+  }
 
   Target *target = exe_ctx.GetTargetPtr();
   const bool include_runtime_support_values =
@@ -782,27 +809,26 @@ SBValueList SBFrame::GetVariables(const lldb::SBVariablesOptions &options) {
 
   SBValueList value_list;
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (stop_locker.IsLocked()) {
 
-  StackFrame *frame = nullptr;
-  Target *target = exe_ctx.GetTargetPtr();
+    StackFrame *frame = nullptr;
+    Target *target = exe_ctx.GetTargetPtr();
 
-  const bool statics = options.GetIncludeStatics();
-  const bool arguments = options.GetIncludeArguments();
-  const bool recognized_arguments =
+    const bool statics = options.GetIncludeStatics();
+    const bool arguments = options.GetIncludeArguments();
+    const bool recognized_arguments =
         options.GetIncludeRecognizedArguments(SBTarget(exe_ctx.GetTargetSP()));
-  const bool locals = options.GetIncludeLocals();
-  const bool in_scope_only = options.GetInScopeOnly();
-  const bool include_runtime_support_values =
-      options.GetIncludeRuntimeSupportValues();
-  const lldb::DynamicValueType use_dynamic = options.GetUseDynamic();
-
+    const bool locals = options.GetIncludeLocals();
+    const bool in_scope_only = options.GetInScopeOnly();
+    const bool include_runtime_support_values =
+        options.GetIncludeRuntimeSupportValues();
+    const lldb::DynamicValueType use_dynamic = options.GetUseDynamic();
 
-  std::set<VariableSP> variable_set;
-  Process *process = exe_ctx.GetProcessPtr();
-  if (target && process) {
-    Process::StopLocker stop_locker;
-    if (stop_locker.TryLock(&process->GetRunLock())) {
+    std::set<VariableSP> variable_set;
+    Process *process = exe_ctx.GetProcessPtr();
+    if (target && process) {
       frame = exe_ctx.GetFramePtr();
       if (frame) {
         Debugger &dbg = process->GetTarget().GetDebugger();
@@ -893,14 +919,14 @@ SBValueList SBFrame::GetRegisters() {
 
   SBValueList value_list;
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (stop_locker.IsLocked()) {
 
-  StackFrame *frame = nullptr;
-  Target *target = exe_ctx.GetTargetPtr();
-  Process *process = exe_ctx.GetProcessPtr();
-  if (target && process) {
-    Process::StopLocker stop_locker;
-    if (stop_locker.TryLock(&process->GetRunLock())) {
+    StackFrame *frame = nullptr;
+    Target *target = exe_ctx.GetTargetPtr();
+    Process *process = exe_ctx.GetProcessPtr();
+    if (target && process) {
       frame = exe_ctx.GetFramePtr();
       if (frame) {
         RegisterContextSP reg_ctx(frame->GetRegisterContext());
@@ -924,14 +950,13 @@ SBValue SBFrame::FindRegister(const char *name) {
   SBValue result;
   ValueObjectSP value_sp;
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
-
-  StackFrame *frame = nullptr;
-  Target *target = exe_ctx.GetTargetPtr();
-  Process *process = exe_ctx.GetProcessPtr();
-  if (target && process) {
-    Process::StopLocker stop_locker;
-    if (stop_locker.TryLock(&process->GetRunLock())) {
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (stop_locker.IsLocked()) {
+    StackFrame *frame = nullptr;
+    Target *target = exe_ctx.GetTargetPtr();
+    Process *process = exe_ctx.GetProcessPtr();
+    if (target && process) {
       frame = exe_ctx.GetFramePtr();
       if (frame) {
         RegisterContextSP reg_ctx(frame->GetRegisterContext());
@@ -954,7 +979,10 @@ SBError SBFrame::GetDescriptionWithFormat(const SBFormat &format,
   Stream &strm = output.ref();
 
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (!stop_locker.IsLocked())
+    return "Process is not stopped";
 
   StackFrame *frame = nullptr;
   Target *target = exe_ctx.GetTargetPtr();
@@ -967,13 +995,10 @@ SBError SBFrame::GetDescriptionWithFormat(const SBFormat &format,
   }
 
   if (target && process) {
-    Process::StopLocker stop_locker;
-    if (stop_locker.TryLock(&process->GetRunLock())) {
-      frame = exe_ctx.GetFramePtr();
-      if (frame &&
-          frame->DumpUsingFormat(strm, format.GetFormatEntrySP().get())) {
-        return error;
-      }
+    frame = exe_ctx.GetFramePtr();
+    if (frame &&
+        frame->DumpUsingFormat(strm, format.GetFormatEntrySP().get())) {
+      return error;
     }
   }
   error.SetErrorStringWithFormat(
@@ -989,20 +1014,21 @@ bool SBFrame::GetDescription(SBStream &description) {
   Stream &strm = description.ref();
 
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (!stop_locker.IsLocked()) {
+    strm.PutCString("Error: process is not stopped.");
+    return true;
+  }
 
   StackFrame *frame;
   Target *target = exe_ctx.GetTargetPtr();
   Process *process = exe_ctx.GetProcessPtr();
   if (target && process) {
-    Process::StopLocker stop_locker;
-    if (stop_locker.TryLock(&process->GetRunLock())) {
-      frame = exe_ctx.GetFramePtr();
-      if (frame) {
-        frame->DumpUsingSettingsFormat(&strm);
-      }
+    frame = exe_ctx.GetFramePtr();
+    if (frame) {
+      frame->DumpUsingSettingsFormat(&strm);
     }
-
   } else
     strm.PutCString("No value");
 
@@ -1013,7 +1039,10 @@ SBValue SBFrame::EvaluateExpression(const char *expr) {
   LLDB_INSTRUMENT_VA(this, expr);
 
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (!stop_locker.IsLocked())
+    return CreateProcessIsRunningExprEvalError();
 
   StackFrame *frame = exe_ctx.GetFramePtr();
   Target *target = exe_ctx.GetTargetPtr();
@@ -1044,7 +1073,10 @@ SBFrame::EvaluateExpression(const char *expr,
   options.SetUnwindOnError(true);
   options.SetIgnoreBreakpoints(true);
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (!stop_locker.IsLocked())
+    return CreateProcessIsRunningExprEvalError();
 
   StackFrame *frame = exe_ctx.GetFramePtr();
   Target *target = exe_ctx.GetTargetPtr();
@@ -1064,7 +1096,10 @@ SBValue SBFrame::EvaluateExpression(const char *expr,
 
   SBExpressionOptions options;
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (!stop_locker.IsLocked())
+    return CreateProcessIsRunningExprEvalError();
 
   options.SetFetchDynamicValue(fetch_dynamic_value);
   options.SetUnwindOnError(unwind_on_error);
@@ -1080,6 +1115,16 @@ SBValue SBFrame::EvaluateExpression(const char *expr,
   return EvaluateExpression(expr, options);
 }
 
+lldb::SBValue SBFrame::CreateProcessIsRunningExprEvalError() {
+  auto error = Status::FromErrorString("can't evaluate expressions when the "
+                                       "process is running.");
+  ValueObjectSP expr_value_sp =
+      ValueObjectConstResult::Create(nullptr, std::move(error));
+  SBValue expr_result;
+  expr_result.SetSP(expr_value_sp, false);
+  return expr_result;
+}
+
 lldb::SBValue SBFrame::EvaluateExpression(const char *expr,
                                           const SBExpressionOptions &options) {
   LLDB_INSTRUMENT_VA(this, expr, options);
@@ -1095,15 +1140,15 @@ lldb::SBValue SBFrame::EvaluateExpression(const char *expr,
   ValueObjectSP expr_value_sp;
 
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (stop_locker.IsLocked()) {
 
-  StackFrame *frame = nullptr;
-  Target *target = exe_ctx.GetTargetPtr();
-  Process *process = exe_ctx.GetProcessPtr();
+    StackFrame *frame = nullptr;
+    Target *target = exe_ctx.GetTargetPtr();
+    Process *process = exe_ctx.GetProcessPtr();
 
-  if (target && process) {
-    Process::StopLocker stop_locker;
-    if (stop_locker.TryLock(&process->GetRunLock())) {
+    if (target && process) {
       frame = exe_ctx.GetFramePtr();
       if (frame) {
         std::unique_ptr<llvm::PrettyStackTraceFormat> stack_trace;
@@ -1121,18 +1166,13 @@ lldb::SBValue SBFrame::EvaluateExpression(const char *expr,
         expr_result.SetSP(expr_value_sp, options.GetFetchDynamicValue());
       }
     } else {
-      Status error;
-      error = Status::FromErrorString("can't evaluate expressions when the "
-                                      "process is running.");
-      expr_value_sp = ValueObjectConstResult::Create(nullptr, std::move(error));
-      expr_result.SetSP(expr_value_sp, false);
-    }
-  } else {
       Status error;
       error = Status::FromErrorString("sbframe object is not valid.");
       expr_value_sp = ValueObjectConstResult::Create(nullptr, std::move(error));
       expr_result.SetSP(expr_value_sp, false);
-  }
+    }
+  } else
+    expr_result = CreateProcessIsRunningExprEvalError();
 
   if (expr_result.GetError().Success())
     LLDB_LOGF(expr_log,
@@ -1153,7 +1193,10 @@ SBStructuredData SBFrame::GetLanguageSpecificData() const {
 
   SBStructuredData sb_data;
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (!stop_locker.IsLocked())
+    return sb_data;
   StackFrame *frame = exe_ctx.GetFramePtr();
   if (!frame)
     return sb_data;
@@ -1173,18 +1216,18 @@ bool SBFrame::IsInlined() const {
   LLDB_INSTRUMENT_VA(this);
 
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (!stop_locker.IsLocked())
+    return false;
 
   StackFrame *frame = nullptr;
   Target *target = exe_ctx.GetTargetPtr();
   Process *process = exe_ctx.GetProcessPtr();
   if (target && process) {
-    Process::StopLocker stop_locker;
-    if (stop_locker.TryLock(&process->GetRunLock())) {
-      frame = exe_ctx.GetFramePtr();
-      if (frame)
-        return frame->IsInlined();
-    }
+    frame = exe_ctx.GetFramePtr();
+    if (frame)
+      return frame->IsInlined();
   }
   return false;
 }
@@ -1199,7 +1242,10 @@ bool SBFrame::IsArtificial() const {
   LLDB_INSTRUMENT_VA(this);
 
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (!stop_locker.IsLocked())
+    return false;
 
   if (StackFrame *frame = exe_ctx.GetFramePtr())
     return frame->IsArtificial();
@@ -1211,7 +1257,10 @@ bool SBFrame::IsHidden() const {
   LLDB_INSTRUMENT_VA(this);
 
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (!stop_locker.IsLocked())
+    return false;
 
   if (StackFrame *frame = exe_ctx.GetFramePtr())
     return frame->IsHidden();
@@ -1229,18 +1278,18 @@ lldb::LanguageType SBFrame::GuessLanguage() const {
   LLDB_INSTRUMENT_VA(this);
 
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (!stop_locker.IsLocked())
+    return eLanguageTypeUnknown;
 
   StackFrame *frame = nullptr;
   Target *target = exe_ctx.GetTargetPtr();
   Process *process = exe_ctx.GetProcessPtr();
   if (target && process) {
-    Process::StopLocker stop_locker;
-    if (stop_locker.TryLock(&process->GetRunLock())) {
-      frame = exe_ctx.GetFramePtr();
-      if (frame) {
-        return frame->GuessLanguage().AsLanguageType();
-      }
+    frame = exe_ctx.GetFramePtr();
+    if (frame) {
+      return frame->GuessLanguage().AsLanguageType();
     }
   }
   return eLanguageTypeUnknown;
@@ -1251,18 +1300,18 @@ const char *SBFrame::GetFunctionName() const {
 
   const char *name = nullptr;
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (!stop_locker.IsLocked())
+    return name;
 
   StackFrame *frame = nullptr;
   Target *target = exe_ctx.GetTargetPtr();
   Process *process = exe_ctx.GetProcessPtr();
   if (target && process) {
-    Process::StopLocker stop_locker;
-    if (stop_locker.TryLock(&process->GetRunLock())) {
-      frame = exe_ctx.GetFramePtr();
-      if (frame)
-        return frame->GetFunctionName();
-    }
+    frame = exe_ctx.GetFramePtr();
+    if (frame)
+      return frame->GetFunctionName();
   }
   return name;
 }
@@ -1273,18 +1322,18 @@ const char *SBFrame::GetDisplayFunctionName() {
   const char *name = nullptr;
 
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (!stop_locker.IsLocked())
+    return name;
 
   StackFrame *frame = nullptr;
   Target *target = exe_ctx.GetTargetPtr();
   Process *process = exe_ctx.GetProcessPtr();
   if (target && process) {
-    Process::StopLocker stop_locker;
-    if (stop_locker.TryLock(&process->GetRunLock())) {
-      frame = exe_ctx.GetFramePtr();
-      if (frame)
-        return frame->GetDisplayFunctionName();
-    }
+    frame = exe_ctx.GetFramePtr();
+    if (frame)
+      return frame->GetDisplayFunctionName();
   }
   return name;
 }
diff --git a/lldb/source/API/SBThread.cpp b/lldb/source/API/SBThread.cpp
index 74bc66c4f16f1..17d10e4dc2c2b 100644
--- a/lldb/source/API/SBThread.cpp
+++ b/lldb/source/API/SBThread.cpp
@@ -91,15 +91,15 @@ lldb::SBQueue SBThread::GetQueue() const {
   SBQueue sb_queue;
   QueueSP queue_sp;
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (!stop_locker.IsLocked())
+    return SBQueue();
 
   if (exe_ctx.HasThreadScope()) {
-    Process::StopLocker stop_locker;
-    if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
-      queue_sp = exe_ctx.GetThreadPtr()->GetQueue();
-      if (queue_sp) {
-        sb_queue.SetQueue(queue_sp);
-      }
+    queue_sp = exe_ctx.GetThreadPtr()->GetQueue();
+    if (queue_sp) {
+      sb_queue.SetQueue(queue_sp);
     }
   }
 
@@ -114,14 +114,15 @@ SBThread::operator bool() const {
   LLDB_INSTRUMENT_VA(this);
 
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (!stop_locker.IsLocked())
+    return false;
 
   Target *target = exe_ctx.GetTargetPtr();
   Process *process = exe_ctx.GetProcessPtr();
   if (target && process) {
-    Process::StopLocker stop_locker;
-    if (stop_locker.TryLock(&process->GetRunLock()))
-      return m_opaque_sp->GetThreadSP().get() != nullptr;
+    return m_opaque_sp->GetThreadSP().get() != nullptr;
   }
   // Without a valid target & process, this thread can't be valid.
   return false;
@@ -138,13 +139,13 @@ StopReason SBThread::GetStopReason() {
 
   StopReason reason = eStopReasonInvalid;
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (!stop_locker.IsLocked())
+    return reason;
 
   if (exe_ctx.HasThreadScope()) {
-    Process::StopLocker stop_locker;
-    if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
-      return exe_ctx.GetThreadPtr()->GetStopReason();
-    }
+    return exe_ctx.GetThreadPtr()->GetStopReason();
   }
 
   return reason;
@@ -154,11 +155,10 @@ size_t SBThread::GetStopReasonDataCount() {
   LLDB_INSTRUMENT_VA(this);
 
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
-
-  if (exe_ctx.HasThreadScope()) {
-    Process::StopLocker stop_locker;
-    if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (stop_locker.IsLocked()) {
+    if (exe_ctx.HasThreadScope()) {
       StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo();
       if (stop_info_sp) {
         StopReason reason = stop_info_sp->GetStopReason();
@@ -215,11 +215,10 @@ uint64_t SBThread::GetStopReasonDataAtIndex(uint32_t idx) {
   LLDB_INSTRUMENT_VA(this, idx);
 
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
-
-  if (exe_ctx.HasThreadScope()) {
-    Process::StopLocker stop_locker;
-    if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (stop_locker.IsLocked()) {
+    if (exe_ctx.HasThreadScope()) {
       Thread *thread = exe_ctx.GetThreadPtr();
       StopInfoSP stop_info_sp = thread->GetStopInfo();
       if (stop_info_sp) {
@@ -290,7 +289,10 @@ bool SBThread::GetStopReasonExtendedInfoAsJSON(lldb::SBStream &stream) {
   Stream &strm = stream.ref();
 
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (!stop_locker.IsLocked())
+    return false;
 
   if (!exe_ctx.HasThreadScope())
     return false;
@@ -312,7 +314,10 @@ SBThread::GetStopReasonExtendedBacktraces(InstrumentationRuntimeType type) {
   SBThreadCollection threads;
 
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (!stop_locker.IsLocked())
+    return SBThreadCollection();
 
   if (!exe_ctx.HasThreadScope())
     return SBThreadCollection();
@@ -333,7 +338,10 @@ size_t SBThread::GetStopDescription(char *dst, size_t dst_len) {
   LLDB_INSTRUMENT_VA(this, dst, dst_len);
 
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (!stop_locker.IsLocked())
+    return 0;
 
   if (dst)
     *dst = 0;
@@ -341,10 +349,6 @@ size_t SBThread::GetStopDescription(char *dst, size_t dst_len) {
   if (!exe_ctx.HasThreadScope())
     return 0;
 
-  Process::StopLocker stop_locker;
-  if (!stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
-    return 0;
-
   std::string thread_stop_desc = exe_ctx.GetThreadPtr()->GetStopDescription();
   if (thread_stop_desc.empty())
     return 0;
@@ -362,15 +366,15 @@ SBValue SBThread::GetStopReturnValue() {
 
   ValueObjectSP return_valobj_sp;
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (!stop_locker.IsLocked())
+    return SBValue();
 
   if (exe_ctx.HasThreadScope()) {
-    Process::StopLocker stop_locker;
-    if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
-      StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo();
-      if (stop_info_sp) {
-        return_valobj_sp = StopInfo::GetReturnValueObject(stop_info_sp);
-      }
+    StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo();
+    if (stop_info_sp) {
+      return_valobj_sp = StopInfo::GetReturnValueObject(stop_info_sp);
     }
   }
 
@@ -403,32 +407,30 @@ const char *SBThread::GetName() const {
   LLDB_INSTRUMENT_VA(this);
 
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (!stop_locker.IsLocked())
+    return nullptr;
 
   if (!exe_ctx.HasThreadScope())
     return nullptr;
 
-  Process::StopLocker stop_locker;
-  if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
-    return ConstString(exe_ctx.GetThreadPtr()->GetName()).GetCString();
-
-  return nullptr;
+  return ConstString(exe_ctx.GetThreadPtr()->GetName()).GetCString();
 }
 
 const char *SBThread::GetQueueName() const {
   LLDB_INSTRUMENT_VA(this);
 
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (!stop_locker.IsLocked())
+    return nullptr;
 
   if (!exe_ctx.HasThreadScope())
     return nullptr;
 
-  Process::StopLocker stop_locker;
-  if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
-    return ConstString(exe_ctx.GetThreadPtr()->GetQueueName()).GetCString();
-
-  return nullptr;
+  return ConstString(exe_ctx.GetThreadPtr()->GetQueueName()).GetCString();
 }
 
 lldb::queue_id_t SBThread::GetQueueID() const {
@@ -436,13 +438,13 @@ lldb::queue_id_t SBThread::GetQueueID() const {
 
   queue_id_t id = LLDB_INVALID_QUEUE_ID;
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (!stop_locker.IsLocked())
+    return id;
 
   if (exe_ctx.HasThreadScope()) {
-    Process::StopLocker stop_locker;
-    if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
-      id = exe_ctx.GetThreadPtr()->GetQueueID();
-    }
+    id = exe_ctx.GetThreadPtr()->GetQueueID();
   }
 
   return id;
@@ -453,11 +455,10 @@ bool SBThread::GetInfoItemByPathAsString(const char *path, SBStream &strm) {
 
   bool success = false;
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
-
-  if (exe_ctx.HasThreadScope()) {
-    Process::StopLocker stop_locker;
-    if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (stop_locker.IsLocked()) {
+    if (exe_ctx.HasThreadScope()) {
       Thread *thread = exe_ctx.GetThreadPtr();
       StructuredData::ObjectSP info_root_sp = thread->GetExtendedInfo();
       if (info_root_sp) {
@@ -495,7 +496,12 @@ bool SBThread::GetInfoItemByPathAsString(const char *path, SBStream &strm) {
   return success;
 }
 
-static Status ResumeNewPlan(ExecutionContext &exe_ctx, ThreadPlan *new_plan) {
+static Status ResumeNewPlan(ExecutionContext &exe_ctx, ThreadPlan *new_plan,
+                            Process::StopLocker stop_lock) {
+  {
+    assert(stop_lock.IsLocked());
+    auto to_unlock = std::move(stop_lock);
+  }
   Process *process = exe_ctx.GetProcessPtr();
   if (!process)
     return Status::FromErrorString("No process in SBThread::ResumeNewPlan");
@@ -530,7 +536,10 @@ void SBThread::StepOver(lldb::RunMode stop_other_threads, SBError &error) {
   LLDB_INSTRUMENT_VA(this, stop_other_threads, error);
 
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (!stop_locker.IsLocked())
+    return;
 
   if (!exe_ctx.HasThreadScope()) {
     error = Status::FromErrorString("this SBThread object is invalid");
@@ -555,7 +564,7 @@ void SBThread::StepOver(lldb::RunMode stop_other_threads, SBError &error) {
           true, abort_other_plans, stop_other_threads, new_plan_status);
     }
   }
-  error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
+  error = ResumeNewPlan(exe_ctx, new_plan_sp.get(), std::move(stop_locker));
 }
 
 void SBThread::StepInto(lldb::RunMode stop_other_threads) {
@@ -577,7 +586,10 @@ void SBThread::StepInto(const char *target_name, uint32_t end_line,
   LLDB_INSTRUMENT_VA(this, target_name, end_line, error, stop_other_threads);
 
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (!stop_locker.IsLocked())
+    return;
 
   if (!exe_ctx.HasThreadScope()) {
     error = Status::FromErrorString("this SBThread object is invalid");
@@ -618,7 +630,7 @@ void SBThread::StepInto(const char *target_name, uint32_t end_line,
   }
 
   if (new_plan_status.Success())
-    error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
+    error = ResumeNewPlan(exe_ctx, new_plan_sp.get(), std::move(stop_locker));
   else
     error = Status::FromErrorString(new_plan_status.AsCString());
 }
@@ -634,7 +646,10 @@ void SBThread::StepOut(SBError &error) {
   LLDB_INSTRUMENT_VA(this, error);
 
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (!stop_locker.IsLocked())
+    return;
 
   if (!exe_ctx.HasThreadScope()) {
     error = Status::FromErrorString("this SBThread object is invalid");
@@ -653,7 +668,7 @@ void SBThread::StepOut(SBError &error) {
       eVoteNoOpinion, 0, new_plan_status, avoid_no_debug));
 
   if (new_plan_status.Success())
-    error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
+    error = ResumeNewPlan(exe_ctx, new_plan_sp.get(), std::move(stop_locker));
   else
     error = Status::FromErrorString(new_plan_status.AsCString());
 }
@@ -669,7 +684,10 @@ void SBThread::StepOutOfFrame(SBFrame &sb_frame, SBError &error) {
   LLDB_INSTRUMENT_VA(this, sb_frame, error);
 
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (!stop_locker.IsLocked())
+    return;
 
   if (!sb_frame.IsValid()) {
     error = Status::FromErrorString("passed invalid SBFrame object");
@@ -697,7 +715,7 @@ void SBThread::StepOutOfFrame(SBFrame &sb_frame, SBError &error) {
       eVoteNoOpinion, frame_sp->GetFrameIndex(), new_plan_status));
 
   if (new_plan_status.Success())
-    error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
+    error = ResumeNewPlan(exe_ctx, new_plan_sp.get(), std::move(stop_locker));
   else
     error = Status::FromErrorString(new_plan_status.AsCString());
 }
@@ -713,7 +731,10 @@ void SBThread::StepInstruction(bool step_over, SBError &error) {
   LLDB_INSTRUMENT_VA(this, step_over, error);
 
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (!stop_locker.IsLocked())
+    return;
 
   if (!exe_ctx.HasThreadScope()) {
     error = Status::FromErrorString("this SBThread object is invalid");
@@ -726,7 +747,7 @@ void SBThread::StepInstruction(bool step_over, SBError &error) {
       step_over, false, true, new_plan_status));
 
   if (new_plan_status.Success())
-    error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
+    error = ResumeNewPlan(exe_ctx, new_plan_sp.get(), std::move(stop_locker));
   else
     error = Status::FromErrorString(new_plan_status.AsCString());
 }
@@ -742,7 +763,10 @@ void SBThread::RunToAddress(lldb::addr_t addr, SBError &error) {
   LLDB_INSTRUMENT_VA(this, addr, error);
 
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (!stop_locker.IsLocked())
+    return;
 
   if (!exe_ctx.HasThreadScope()) {
     error = Status::FromErrorString("this SBThread object is invalid");
@@ -761,7 +785,7 @@ void SBThread::RunToAddress(lldb::addr_t addr, SBError &error) {
       abort_other_plans, target_addr, stop_other_threads, new_plan_status));
 
   if (new_plan_status.Success())
-    error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
+    error = ResumeNewPlan(exe_ctx, new_plan_sp.get(), std::move(stop_locker));
   else
     error = Status::FromErrorString(new_plan_status.AsCString());
 }
@@ -774,7 +798,10 @@ SBError SBThread::StepOverUntil(lldb::SBFrame &sb_frame,
   char path[PATH_MAX];
 
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (!stop_locker.IsLocked())
+    return sb_error;
 
   StackFrameSP frame_sp(sb_frame.GetFrameSP());
 
@@ -875,7 +902,8 @@ SBError SBThread::StepOverUntil(lldb::SBFrame &sb_frame,
           frame_sp->GetFrameIndex(), new_plan_status));
 
       if (new_plan_status.Success())
-        sb_error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
+        sb_error =
+            ResumeNewPlan(exe_ctx, new_plan_sp.get(), std::move(stop_locker));
       else
         sb_error = Status::FromErrorString(new_plan_status.AsCString());
     }
@@ -908,7 +936,10 @@ SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name,
   SBError error;
 
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (!stop_locker.IsLocked())
+    return error;
 
   if (!exe_ctx.HasThreadScope()) {
     error = Status::FromErrorString("this SBThread object is invalid");
@@ -931,7 +962,7 @@ SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name,
     return error;
 
   if (new_plan_status.Success())
-    error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
+    error = ResumeNewPlan(exe_ctx, new_plan_sp.get(), std::move(stop_locker));
   else
     error = Status::FromErrorString(new_plan_status.AsCString());
 
@@ -944,7 +975,10 @@ SBError SBThread::JumpToLine(lldb::SBFileSpec &file_spec, uint32_t line) {
   SBError sb_error;
 
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (!stop_locker.IsLocked())
+    return sb_error;
 
   if (!exe_ctx.HasThreadScope()) {
     sb_error = Status::FromErrorString("this SBThread object is invalid");
@@ -964,7 +998,10 @@ SBError SBThread::ReturnFromFrame(SBFrame &frame, SBValue &return_value) {
   SBError sb_error;
 
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (!stop_locker.IsLocked())
+    return sb_error;
 
   if (exe_ctx.HasThreadScope()) {
     Thread *thread = exe_ctx.GetThreadPtr();
@@ -981,7 +1018,10 @@ SBError SBThread::UnwindInnermostExpression() {
   SBError sb_error;
 
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (!stop_locker.IsLocked())
+    return sb_error;
 
   if (exe_ctx.HasThreadScope()) {
     Thread *thread = exe_ctx.GetThreadPtr();
@@ -1004,17 +1044,17 @@ bool SBThread::Suspend(SBError &error) {
   LLDB_INSTRUMENT_VA(this, error);
 
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (!stop_locker.IsLocked()) {
+    error = Status::FromErrorString("process is running");
+    return false;
+  }
 
   bool result = false;
   if (exe_ctx.HasThreadScope()) {
-    Process::StopLocker stop_locker;
-    if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
-      exe_ctx.GetThreadPtr()->SetResumeState(eStateSuspended);
-      result = true;
-    } else {
-      error = Status::FromErrorString("process is running");
-    }
+    exe_ctx.GetThreadPtr()->SetResumeState(eStateSuspended);
+    result = true;
   } else
     error = Status::FromErrorString("this SBThread object is invalid");
   return result;
@@ -1031,18 +1071,18 @@ bool SBThread::Resume(SBError &error) {
   LLDB_INSTRUMENT_VA(this, error);
 
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (!stop_locker.IsLocked()) {
+    error = Status::FromErrorString("process is running");
+    return false;
+  }
 
   bool result = false;
   if (exe_ctx.HasThreadScope()) {
-    Process::StopLocker stop_locker;
-    if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
-      const bool override_suspend = true;
-      exe_ctx.GetThreadPtr()->SetResumeState(eStateRunning, override_suspend);
-      result = true;
-    } else {
-      error = Status::FromErrorString("process is running");
-    }
+    const bool override_suspend = true;
+    exe_ctx.GetThreadPtr()->SetResumeState(eStateRunning, override_suspend);
+    result = true;
   } else
     error = Status::FromErrorString("this SBThread object is invalid");
   return result;
@@ -1052,7 +1092,10 @@ bool SBThread::IsSuspended() {
   LLDB_INSTRUMENT_VA(this);
 
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (!stop_locker.IsLocked())
+    return false;
 
   if (exe_ctx.HasThreadScope())
     return exe_ctx.GetThreadPtr()->GetResumeState() == eStateSuspended;
@@ -1063,7 +1106,10 @@ bool SBThread::IsStopped() {
   LLDB_INSTRUMENT_VA(this);
 
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (!stop_locker.IsLocked())
+    return false;
 
   if (exe_ctx.HasThreadScope())
     return StateIsStoppedState(exe_ctx.GetThreadPtr()->GetState(), true);
@@ -1075,7 +1121,10 @@ SBProcess SBThread::GetProcess() {
 
   SBProcess sb_process;
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (!stop_locker.IsLocked())
+    return SBProcess();
 
   if (exe_ctx.HasThreadScope()) {
     // Have to go up to the target so we can get a shared pointer to our
@@ -1091,13 +1140,13 @@ uint32_t SBThread::GetNumFrames() {
 
   uint32_t num_frames = 0;
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (!stop_locker.IsLocked())
+    return 0;
 
   if (exe_ctx.HasThreadScope()) {
-    Process::StopLocker stop_locker;
-    if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
-      num_frames = exe_ctx.GetThreadPtr()->GetStackFrameCount();
-    }
+    num_frames = exe_ctx.GetThreadPtr()->GetStackFrameCount();
   }
 
   return num_frames;
@@ -1109,14 +1158,14 @@ SBFrame SBThread::GetFrameAtIndex(uint32_t idx) {
   SBFrame sb_frame;
   StackFrameSP frame_sp;
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (!stop_locker.IsLocked())
+    return SBFrame();
 
   if (exe_ctx.HasThreadScope()) {
-    Process::StopLocker stop_locker;
-    if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
-      frame_sp = exe_ctx.GetThreadPtr()->GetStackFrameAtIndex(idx);
-      sb_frame.SetFrameSP(frame_sp);
-    }
+    frame_sp = exe_ctx.GetThreadPtr()->GetStackFrameAtIndex(idx);
+    sb_frame.SetFrameSP(frame_sp);
   }
 
   return sb_frame;
@@ -1128,15 +1177,15 @@ lldb::SBFrame SBThread::GetSelectedFrame() {
   SBFrame sb_frame;
   StackFrameSP frame_sp;
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (!stop_locker.IsLocked())
+    return SBFrame();
 
   if (exe_ctx.HasThreadScope()) {
-    Process::StopLocker stop_locker;
-    if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
-      frame_sp =
-          exe_ctx.GetThreadPtr()->GetSelectedFrame(SelectMostRelevantFrame);
-      sb_frame.SetFrameSP(frame_sp);
-    }
+    frame_sp =
+        exe_ctx.GetThreadPtr()->GetSelectedFrame(SelectMostRelevantFrame);
+    sb_frame.SetFrameSP(frame_sp);
   }
 
   return sb_frame;
@@ -1148,17 +1197,17 @@ lldb::SBFrame SBThread::SetSelectedFrame(uint32_t idx) {
   SBFrame sb_frame;
   StackFrameSP frame_sp;
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (!stop_locker.IsLocked())
+    return SBFrame();
 
   if (exe_ctx.HasThreadScope()) {
-    Process::StopLocker stop_locker;
-    if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
-      Thread *thread = exe_ctx.GetThreadPtr();
-      frame_sp = thread->GetStackFrameAtIndex(idx);
-      if (frame_sp) {
-        thread->SetSelectedFrame(frame_sp.get());
-        sb_frame.SetFrameSP(frame_sp);
-      }
+    Thread *thread = exe_ctx.GetThreadPtr();
+    frame_sp = thread->GetStackFrameAtIndex(idx);
+    if (frame_sp) {
+      thread->SetSelectedFrame(frame_sp.get());
+      sb_frame.SetFrameSP(frame_sp);
     }
   }
 
@@ -1203,7 +1252,10 @@ bool SBThread::GetStatus(SBStream &status) const {
   Stream &strm = status.ref();
 
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (!stop_locker.IsLocked())
+    return false;
 
   if (exe_ctx.HasThreadScope()) {
     exe_ctx.GetThreadPtr()->GetStatus(strm, 0, 1, 1, true,
@@ -1226,7 +1278,10 @@ bool SBThread::GetDescription(SBStream &description, bool stop_format) const {
   Stream &strm = description.ref();
 
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (!stop_locker.IsLocked())
+    return false;
 
   if (exe_ctx.HasThreadScope()) {
     exe_ctx.GetThreadPtr()->DumpUsingSettingsFormat(
@@ -1248,7 +1303,10 @@ SBError SBThread::GetDescriptionWithFormat(const SBFormat &format,
   }
 
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+  Process::StopLocker stop_locker;
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  if (!stop_locker.IsLocked())
+    return error;
 
   if (exe_ctx.HasThreadScope()) {
     if (exe_ctx.GetThreadPtr()->DumpUsingFormat(
@@ -1268,11 +1326,10 @@ SBThread SBThread::GetExtendedBacktraceThread(const char *type) {
   LLDB_INSTRUMENT_VA(this, type);
 
   std::unique_lock<std::recursive_mutex> lock;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
-  SBThread sb_origin_thread;
-
   Process::StopLocker stop_locker;
-  if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  SBThread sb_origin_thread;
+  if (stop_locker.IsLocked()) {
     if (exe_ctx.HasThreadScope()) {
       ThreadSP real_thread(exe_ctx.GetThreadSP());
       if (real_thread) {
diff --git a/lldb/source/Target/ExecutionContext.cpp b/lldb/source/Target/ExecutionContext.cpp
index 3f54ea55c9c81..cef21f7ff6d78 100644
--- a/lldb/source/Target/ExecutionContext.cpp
+++ b/lldb/source/Target/ExecutionContext.cpp
@@ -125,8 +125,10 @@ ExecutionContext::ExecutionContext(const ExecutionContextRef *exe_ctx_ref_ptr,
   }
 }
 
-ExecutionContext::ExecutionContext(const ExecutionContextRef *exe_ctx_ref_ptr,
-                                   std::unique_lock<std::recursive_mutex> &lock)
+ExecutionContext::ExecutionContext(
+    const ExecutionContextRef *exe_ctx_ref_ptr,
+    std::unique_lock<std::recursive_mutex> &lock,
+    ProcessRunLock::ProcessRunLocker &stop_locker)
     : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
   if (exe_ctx_ref_ptr) {
     m_target_sp = exe_ctx_ref_ptr->GetTargetSP();
@@ -134,8 +136,10 @@ ExecutionContext::ExecutionContext(const ExecutionContextRef *exe_ctx_ref_ptr,
       lock = std::unique_lock<std::recursive_mutex>(m_target_sp->GetAPIMutex());
 
       m_process_sp = exe_ctx_ref_ptr->GetProcessSP();
-      m_thread_sp = exe_ctx_ref_ptr->GetThreadSP();
-      m_frame_sp = exe_ctx_ref_ptr->GetFrameSP();
+      if (m_process_sp && stop_locker.TryLock(&m_process_sp->GetRunLock())) {
+        m_thread_sp = exe_ctx_ref_ptr->GetThreadSP();
+        m_frame_sp = exe_ctx_ref_ptr->GetFrameSP();
+      }
     }
   }
 }
diff --git a/lldb/test/API/python_api/run_locker/TestRunLocker.py b/lldb/test/API/python_api/run_locker/TestRunLocker.py
index b7b4941214e86..d525bbf6b406f 100644
--- a/lldb/test/API/python_api/run_locker/TestRunLocker.py
+++ b/lldb/test/API/python_api/run_locker/TestRunLocker.py
@@ -107,4 +107,6 @@ def runlocker_test(self, stop_at_entry):
             "script var = lldb.frame.EvaluateExpression('SomethingToCall()'); var.GetError().GetCString()",
             result,
         )
-        self.assertIn("sbframe object is not valid", result.GetOutput())
+        self.assertIn(
+            "can't evaluate expressions when the process is running", result.GetOutput()
+        )

>From 37da24439225699f422f8cb5dc7121497e1634ee Mon Sep 17 00:00:00 2001
From: Felipe de Azevedo Piovezan <fpiovezan at apple.com>
Date: Tue, 5 Aug 2025 11:13:22 -0700
Subject: [PATCH 2/6] fixup! Address review comments

---
 lldb/include/lldb/API/SBFrame.h             |  4 +-
 lldb/include/lldb/Target/ExecutionContext.h | 23 +++++++----
 lldb/source/API/SBFrame.cpp                 |  2 +
 lldb/source/API/SBThread.cpp                | 32 +++++++++------
 lldb/source/Target/ExecutionContext.cpp     | 45 +++++++++++++++------
 5 files changed, 72 insertions(+), 34 deletions(-)

diff --git a/lldb/include/lldb/API/SBFrame.h b/lldb/include/lldb/API/SBFrame.h
index 35198068814d0..08de0605b3240 100644
--- a/lldb/include/lldb/API/SBFrame.h
+++ b/lldb/include/lldb/API/SBFrame.h
@@ -233,8 +233,8 @@ class LLDB_API SBFrame {
 
   void SetFrameSP(const lldb::StackFrameSP &lldb_object_sp);
 
-  /// Return an SBValue with an error message warning that the process is not
-  /// currently stopped.
+  /// Return an SBValue containing an error message that warns the process is
+  /// not currently stopped.
   static SBValue CreateProcessIsRunningExprEvalError();
 
   lldb::ExecutionContextRefSP m_opaque_sp;
diff --git a/lldb/include/lldb/Target/ExecutionContext.h b/lldb/include/lldb/Target/ExecutionContext.h
index ae6051f576fac..63e305f0106a1 100644
--- a/lldb/include/lldb/Target/ExecutionContext.h
+++ b/lldb/include/lldb/Target/ExecutionContext.h
@@ -316,16 +316,25 @@ class ExecutionContext {
   ExecutionContext(const ExecutionContextRef *exe_ctx_ref,
                    bool thread_and_frame_only_if_stopped = false);
 
-  // These two variants take in a locker, and grab the target, lock the API
-  // mutex into locker, then fill in the rest of the shared pointers.
+  /// These two variants take in an API lock and a process run lock.
+  /// If the ExecutionContextRef has a Target, the API lock will be acquired.
+  /// If the ExecutionContextRef also has a Process, an attempt to acquire
+  /// ProcessRunLock is made. If successful (i.e. the Process is stopped), frame
+  /// and thread information might be available.
+  /// As a corollary, if the ProcessRunLocker has been locked, this
+  /// ExecutionContext contains non-null Process and Target pointers.
+  /// If a Status object is provided, it will be updated if the
+  /// ExecutionContextRef/Process/Target are null, or if the process is running.
   ExecutionContext(const ExecutionContextRef &exe_ctx_ref,
-                   std::unique_lock<std::recursive_mutex> &locker,
-                   ProcessRunLock::ProcessRunLocker &stop_locker)
-      : ExecutionContext(&exe_ctx_ref, locker, stop_locker) {}
+                   std::unique_lock<std::recursive_mutex> &api_lock,
+                   ProcessRunLock::ProcessRunLocker &stop_locker,
+                   Status *status = nullptr)
+      : ExecutionContext(&exe_ctx_ref, api_lock, stop_locker, status) {}
 
   ExecutionContext(const ExecutionContextRef *exe_ctx_ref,
-                   std::unique_lock<std::recursive_mutex> &locker,
-                   ProcessRunLock::ProcessRunLocker &stop_locker);
+                   std::unique_lock<std::recursive_mutex> &api_lock,
+                   ProcessRunLock::ProcessRunLocker &stop_locker,
+                   Status *status = nullptr);
   // Create execution contexts from execution context scopes
   ExecutionContext(ExecutionContextScope *exe_scope);
   ExecutionContext(ExecutionContextScope &exe_scope);
diff --git a/lldb/source/API/SBFrame.cpp b/lldb/source/API/SBFrame.cpp
index 96891fee61e73..08946eddf7d96 100644
--- a/lldb/source/API/SBFrame.cpp
+++ b/lldb/source/API/SBFrame.cpp
@@ -97,6 +97,8 @@ bool SBFrame::IsValid() const {
 }
 SBFrame::operator bool() const {
   LLDB_INSTRUMENT_VA(this);
+  if (!m_opaque_sp)
+    return false;
 
   std::unique_lock<std::recursive_mutex> lock;
   Process::StopLocker stop_locker;
diff --git a/lldb/source/API/SBThread.cpp b/lldb/source/API/SBThread.cpp
index 17d10e4dc2c2b..506981eb13008 100644
--- a/lldb/source/API/SBThread.cpp
+++ b/lldb/source/API/SBThread.cpp
@@ -112,6 +112,8 @@ bool SBThread::IsValid() const {
 }
 SBThread::operator bool() const {
   LLDB_INSTRUMENT_VA(this);
+  if (!m_opaque_sp)
+    return false;
 
   std::unique_lock<std::recursive_mutex> lock;
   Process::StopLocker stop_locker;
@@ -537,7 +539,7 @@ void SBThread::StepOver(lldb::RunMode stop_other_threads, SBError &error) {
 
   std::unique_lock<std::recursive_mutex> lock;
   Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker, &error.ref());
   if (!stop_locker.IsLocked())
     return;
 
@@ -587,7 +589,7 @@ void SBThread::StepInto(const char *target_name, uint32_t end_line,
 
   std::unique_lock<std::recursive_mutex> lock;
   Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker, &error.ref());
   if (!stop_locker.IsLocked())
     return;
 
@@ -647,7 +649,7 @@ void SBThread::StepOut(SBError &error) {
 
   std::unique_lock<std::recursive_mutex> lock;
   Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker, &error.ref());
   if (!stop_locker.IsLocked())
     return;
 
@@ -685,7 +687,7 @@ void SBThread::StepOutOfFrame(SBFrame &sb_frame, SBError &error) {
 
   std::unique_lock<std::recursive_mutex> lock;
   Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker, &error.ref());
   if (!stop_locker.IsLocked())
     return;
 
@@ -732,7 +734,7 @@ void SBThread::StepInstruction(bool step_over, SBError &error) {
 
   std::unique_lock<std::recursive_mutex> lock;
   Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker, &error.ref());
   if (!stop_locker.IsLocked())
     return;
 
@@ -764,7 +766,7 @@ void SBThread::RunToAddress(lldb::addr_t addr, SBError &error) {
 
   std::unique_lock<std::recursive_mutex> lock;
   Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker, &error.ref());
   if (!stop_locker.IsLocked())
     return;
 
@@ -799,7 +801,8 @@ SBError SBThread::StepOverUntil(lldb::SBFrame &sb_frame,
 
   std::unique_lock<std::recursive_mutex> lock;
   Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker,
+                           &sb_error.ref());
   if (!stop_locker.IsLocked())
     return sb_error;
 
@@ -937,7 +940,7 @@ SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name,
 
   std::unique_lock<std::recursive_mutex> lock;
   Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker, &error.ref());
   if (!stop_locker.IsLocked())
     return error;
 
@@ -976,7 +979,8 @@ SBError SBThread::JumpToLine(lldb::SBFileSpec &file_spec, uint32_t line) {
 
   std::unique_lock<std::recursive_mutex> lock;
   Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker,
+                           &sb_error.ref());
   if (!stop_locker.IsLocked())
     return sb_error;
 
@@ -999,7 +1003,8 @@ SBError SBThread::ReturnFromFrame(SBFrame &frame, SBValue &return_value) {
 
   std::unique_lock<std::recursive_mutex> lock;
   Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker,
+                           &sb_error.ref());
   if (!stop_locker.IsLocked())
     return sb_error;
 
@@ -1019,7 +1024,8 @@ SBError SBThread::UnwindInnermostExpression() {
 
   std::unique_lock<std::recursive_mutex> lock;
   Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker,
+                           &sb_error.ref());
   if (!stop_locker.IsLocked())
     return sb_error;
 
@@ -1045,7 +1051,7 @@ bool SBThread::Suspend(SBError &error) {
 
   std::unique_lock<std::recursive_mutex> lock;
   Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker, &error.ref());
   if (!stop_locker.IsLocked()) {
     error = Status::FromErrorString("process is running");
     return false;
@@ -1072,7 +1078,7 @@ bool SBThread::Resume(SBError &error) {
 
   std::unique_lock<std::recursive_mutex> lock;
   Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker, &error.ref());
   if (!stop_locker.IsLocked()) {
     error = Status::FromErrorString("process is running");
     return false;
diff --git a/lldb/source/Target/ExecutionContext.cpp b/lldb/source/Target/ExecutionContext.cpp
index cef21f7ff6d78..bc9540314d03f 100644
--- a/lldb/source/Target/ExecutionContext.cpp
+++ b/lldb/source/Target/ExecutionContext.cpp
@@ -12,6 +12,7 @@
 #include "lldb/Target/StackFrame.h"
 #include "lldb/Target/Target.h"
 #include "lldb/Target/Thread.h"
+#include "lldb/Utility/LLDBLog.h"
 #include "lldb/Utility/State.h"
 
 using namespace lldb_private;
@@ -127,21 +128,41 @@ ExecutionContext::ExecutionContext(const ExecutionContextRef *exe_ctx_ref_ptr,
 
 ExecutionContext::ExecutionContext(
     const ExecutionContextRef *exe_ctx_ref_ptr,
-    std::unique_lock<std::recursive_mutex> &lock,
-    ProcessRunLock::ProcessRunLocker &stop_locker)
+    std::unique_lock<std::recursive_mutex> &api_lock,
+    ProcessRunLock::ProcessRunLocker &stop_locker, Status *status)
     : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
-  if (exe_ctx_ref_ptr) {
-    m_target_sp = exe_ctx_ref_ptr->GetTargetSP();
-    if (m_target_sp) {
-      lock = std::unique_lock<std::recursive_mutex>(m_target_sp->GetAPIMutex());
+  auto set_status = [&](const char *msg) {
+    if (status)
+      *status = Status::FromErrorString(msg);
+  };
+
+  if (!exe_ctx_ref_ptr) {
+    set_status("ExecutionContext created with an empty ExecutionContextRef");
+    return;
+  }
 
-      m_process_sp = exe_ctx_ref_ptr->GetProcessSP();
-      if (m_process_sp && stop_locker.TryLock(&m_process_sp->GetRunLock())) {
-        m_thread_sp = exe_ctx_ref_ptr->GetThreadSP();
-        m_frame_sp = exe_ctx_ref_ptr->GetFrameSP();
-      }
-    }
+  m_target_sp = exe_ctx_ref_ptr->GetTargetSP();
+  if (!m_target_sp) {
+    set_status("ExecutionContext created with a null target");
+    return;
   }
+
+  api_lock = std::unique_lock<std::recursive_mutex>(m_target_sp->GetAPIMutex());
+  m_process_sp = exe_ctx_ref_ptr->GetProcessSP();
+  if (!m_process_sp) {
+    set_status("ExecutionContext created with a null process");
+    return;
+  }
+
+  if (!stop_locker.TryLock(&m_process_sp->GetRunLock())) {
+    const char *msg = "ExecutionContext created with a running process";
+    set_status(msg);
+    LLDB_LOG(GetLog(LLDBLog::API), msg);
+    return;
+  }
+
+  m_thread_sp = exe_ctx_ref_ptr->GetThreadSP();
+  m_frame_sp = exe_ctx_ref_ptr->GetFrameSP();
 }
 
 ExecutionContext::ExecutionContext(ExecutionContextScope *exe_scope_ptr)

>From 66e610526b2b19840891e0b47e34ae41b3eabc29 Mon Sep 17 00:00:00 2001
From: Felipe de Azevedo Piovezan <fpiovezan at apple.com>
Date: Tue, 5 Aug 2025 13:12:45 -0700
Subject: [PATCH 3/6] fixup! Fix linux buildbot issue

---
 lldb/source/API/SBThread.cpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/lldb/source/API/SBThread.cpp b/lldb/source/API/SBThread.cpp
index 506981eb13008..5b9ff0f5b2abf 100644
--- a/lldb/source/API/SBThread.cpp
+++ b/lldb/source/API/SBThread.cpp
@@ -339,15 +339,15 @@ SBThread::GetStopReasonExtendedBacktraces(InstrumentationRuntimeType type) {
 size_t SBThread::GetStopDescription(char *dst, size_t dst_len) {
   LLDB_INSTRUMENT_VA(this, dst, dst_len);
 
+  if (dst)
+    *dst = 0;
+
   std::unique_lock<std::recursive_mutex> lock;
   Process::StopLocker stop_locker;
   ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
   if (!stop_locker.IsLocked())
     return 0;
 
-  if (dst)
-    *dst = 0;
-
   if (!exe_ctx.HasThreadScope())
     return 0;
 

>From 69bf651b43966bd314c019cef0a0cea98e43d6ae Mon Sep 17 00:00:00 2001
From: Felipe de Azevedo Piovezan <fpiovezan at apple.com>
Date: Fri, 8 Aug 2025 08:43:26 -0700
Subject: [PATCH 4/6] fixup! Create all-or-nothing factory method

---
 lldb/include/lldb/API/SBError.h             |   1 +
 lldb/include/lldb/Host/ProcessRunLock.h     |   8 +
 lldb/include/lldb/Target/ExecutionContext.h |  66 +-
 lldb/source/API/SBFrame.cpp                 | 863 ++++++++------------
 lldb/source/API/SBThread.cpp                | 545 ++++++------
 lldb/source/Target/ExecutionContext.cpp     |  73 +-
 6 files changed, 727 insertions(+), 829 deletions(-)

diff --git a/lldb/include/lldb/API/SBError.h b/lldb/include/lldb/API/SBError.h
index 58b45ebd793af..6a4a39c4db314 100644
--- a/lldb/include/lldb/API/SBError.h
+++ b/lldb/include/lldb/API/SBError.h
@@ -87,6 +87,7 @@ class LLDB_API SBError {
   friend class SBDebugger;
   friend class SBFile;
   friend class SBFormat;
+  friend class SBFrame;
   friend class SBHostOS;
   friend class SBPlatform;
   friend class SBProcess;
diff --git a/lldb/include/lldb/Host/ProcessRunLock.h b/lldb/include/lldb/Host/ProcessRunLock.h
index 5efa46154a61e..27d10942ddb4c 100644
--- a/lldb/include/lldb/Host/ProcessRunLock.h
+++ b/lldb/include/lldb/Host/ProcessRunLock.h
@@ -44,6 +44,14 @@ class ProcessRunLock {
     ProcessRunLocker(ProcessRunLocker &&other) : m_lock(other.m_lock) {
       other.m_lock = nullptr;
     }
+    ProcessRunLocker &operator=(ProcessRunLocker &&other) {
+      if (this != &other) {
+        Unlock();
+        m_lock = other.m_lock;
+        other.m_lock = nullptr;
+      }
+      return *this;
+    }
 
     ~ProcessRunLocker() { Unlock(); }
 
diff --git a/lldb/include/lldb/Target/ExecutionContext.h b/lldb/include/lldb/Target/ExecutionContext.h
index 63e305f0106a1..f7e0b7c5e4d63 100644
--- a/lldb/include/lldb/Target/ExecutionContext.h
+++ b/lldb/include/lldb/Target/ExecutionContext.h
@@ -316,25 +316,6 @@ class ExecutionContext {
   ExecutionContext(const ExecutionContextRef *exe_ctx_ref,
                    bool thread_and_frame_only_if_stopped = false);
 
-  /// These two variants take in an API lock and a process run lock.
-  /// If the ExecutionContextRef has a Target, the API lock will be acquired.
-  /// If the ExecutionContextRef also has a Process, an attempt to acquire
-  /// ProcessRunLock is made. If successful (i.e. the Process is stopped), frame
-  /// and thread information might be available.
-  /// As a corollary, if the ProcessRunLocker has been locked, this
-  /// ExecutionContext contains non-null Process and Target pointers.
-  /// If a Status object is provided, it will be updated if the
-  /// ExecutionContextRef/Process/Target are null, or if the process is running.
-  ExecutionContext(const ExecutionContextRef &exe_ctx_ref,
-                   std::unique_lock<std::recursive_mutex> &api_lock,
-                   ProcessRunLock::ProcessRunLocker &stop_locker,
-                   Status *status = nullptr)
-      : ExecutionContext(&exe_ctx_ref, api_lock, stop_locker, status) {}
-
-  ExecutionContext(const ExecutionContextRef *exe_ctx_ref,
-                   std::unique_lock<std::recursive_mutex> &api_lock,
-                   ProcessRunLock::ProcessRunLocker &stop_locker,
-                   Status *status = nullptr);
   // Create execution contexts from execution context scopes
   ExecutionContext(ExecutionContextScope *exe_scope);
   ExecutionContext(ExecutionContextScope &exe_scope);
@@ -578,6 +559,53 @@ class ExecutionContext {
   lldb::StackFrameSP m_frame_sp; ///< The stack frame in thread.
 };
 
+/// A wrapper class representing an execution context with non-null Target
+/// and Process pointers, a locked API mutex and a locked ProcessRunLock.
+/// The locks are private by design: to unlock them, destroy the
+/// CompleteExecutionContext.
+struct CompleteExecutionContext : ExecutionContext {
+  CompleteExecutionContext(lldb::TargetSP &target_sp,
+                           lldb::ProcessSP &process_sp,
+                           lldb::ThreadSP &thread_sp,
+                           lldb::StackFrameSP &frame_sp,
+                           std::unique_lock<std::recursive_mutex> api_lock,
+                           ProcessRunLock::ProcessRunLocker stop_locker)
+      : m_api_lock(std::move(api_lock)), m_stop_locker(std::move(stop_locker)) {
+    assert(target_sp);
+    assert(process_sp);
+    assert(m_api_lock.owns_lock());
+    assert(m_stop_locker.IsLocked());
+    SetTargetSP(target_sp);
+    SetProcessSP(process_sp);
+    SetThreadSP(thread_sp);
+    SetFrameSP(frame_sp);
+  }
+
+  /// Transfers ownership of the locks from `other` to `this`, making `other`
+  /// unusable.
+  CompleteExecutionContext(CompleteExecutionContext &&other)
+      : CompleteExecutionContext(other.m_target_sp, other.m_process_sp,
+                                 other.m_thread_sp, other.m_frame_sp,
+                                 std::move(other.m_api_lock),
+                                 std::move(other.m_stop_locker)) {
+    other.Clear();
+  }
+
+  /// Clears this context, unlocking the ProcessRunLock and returning the
+  /// locked API lock. Like after a move operation, this object is no longer
+  /// usable.
+  [[nodiscard]] std::unique_lock<std::recursive_mutex> ClearAndGetAPILock();
+
+private:
+  std::unique_lock<std::recursive_mutex> m_api_lock;
+  ProcessRunLock::ProcessRunLocker m_stop_locker;
+};
+
+llvm::Expected<CompleteExecutionContext>
+GetCompleteExecutionContext(const ExecutionContextRef *exe_ctx_ref_ptr);
+llvm::Expected<CompleteExecutionContext>
+GetCompleteExecutionContext(const lldb::ExecutionContextRefSP &exe_ctx_ref_ptr);
+
 } // namespace lldb_private
 
 #endif // LLDB_TARGET_EXECUTIONCONTEXT_H
diff --git a/lldb/source/API/SBFrame.cpp b/lldb/source/API/SBFrame.cpp
index 08946eddf7d96..2af8b0be5c0a5 100644
--- a/lldb/source/API/SBFrame.cpp
+++ b/lldb/source/API/SBFrame.cpp
@@ -97,235 +97,176 @@ bool SBFrame::IsValid() const {
 }
 SBFrame::operator bool() const {
   LLDB_INSTRUMENT_VA(this);
-  if (!m_opaque_sp)
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (!exe_ctx) {
+    llvm::consumeError(exe_ctx.takeError());
     return false;
-
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
-  if (!stop_locker.IsLocked())
-    return false;
-
-  Target *target = exe_ctx.GetTargetPtr();
-  Process *process = exe_ctx.GetProcessPtr();
-  if (target && process) {
-    return GetFrameSP().get() != nullptr;
   }
 
-  // Without a target & process we can't have a valid stack frame.
-  return false;
+  return GetFrameSP().get() != nullptr;
 }
 
 SBSymbolContext SBFrame::GetSymbolContext(uint32_t resolve_scope) const {
   LLDB_INSTRUMENT_VA(this, resolve_scope);
 
   SBSymbolContext sb_sym_ctx;
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
-  if (!stop_locker.IsLocked())
+
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (!exe_ctx) {
+    llvm::consumeError(exe_ctx.takeError());
     return sb_sym_ctx;
-  SymbolContextItem scope = static_cast<SymbolContextItem>(resolve_scope);
-  Target *target = exe_ctx.GetTargetPtr();
-  Process *process = exe_ctx.GetProcessPtr();
-  if (target && process) {
-    if (StackFrame *frame = exe_ctx.GetFramePtr())
-      sb_sym_ctx = frame->GetSymbolContext(scope);
   }
 
+  SymbolContextItem scope = static_cast<SymbolContextItem>(resolve_scope);
+  if (StackFrame *frame = exe_ctx->GetFramePtr())
+    sb_sym_ctx = frame->GetSymbolContext(scope);
+
   return sb_sym_ctx;
 }
 
 SBModule SBFrame::GetModule() const {
   LLDB_INSTRUMENT_VA(this);
 
-  SBModule sb_module;
-  ModuleSP module_sp;
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
-  if (!stop_locker.IsLocked())
-    return sb_module;
-
-  StackFrame *frame = nullptr;
-  Target *target = exe_ctx.GetTargetPtr();
-  Process *process = exe_ctx.GetProcessPtr();
-  if (target && process) {
-    frame = exe_ctx.GetFramePtr();
-    if (frame) {
-      module_sp = frame->GetSymbolContext(eSymbolContextModule).module_sp;
-      sb_module.SetSP(module_sp);
-    }
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (!exe_ctx) {
+    llvm::consumeError(exe_ctx.takeError());
+    return SBModule();
   }
 
+  ModuleSP module_sp;
+  StackFrame *frame = exe_ctx->GetFramePtr();
+  if (!frame)
+    return SBModule();
+
+  SBModule sb_module;
+  module_sp = frame->GetSymbolContext(eSymbolContextModule).module_sp;
+  sb_module.SetSP(module_sp);
   return sb_module;
 }
 
 SBCompileUnit SBFrame::GetCompileUnit() const {
   LLDB_INSTRUMENT_VA(this);
 
-  SBCompileUnit sb_comp_unit;
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
-  if (!stop_locker.IsLocked())
-    return sb_comp_unit;
-
-  StackFrame *frame = nullptr;
-  Target *target = exe_ctx.GetTargetPtr();
-  Process *process = exe_ctx.GetProcessPtr();
-  if (target && process) {
-    frame = exe_ctx.GetFramePtr();
-    if (frame) {
-      sb_comp_unit.reset(
-          frame->GetSymbolContext(eSymbolContextCompUnit).comp_unit);
-    }
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (!exe_ctx) {
+    llvm::consumeError(exe_ctx.takeError());
+    return SBCompileUnit();
   }
 
-  return sb_comp_unit;
+  if (StackFrame *frame = exe_ctx->GetFramePtr())
+    return SBCompileUnit(
+        frame->GetSymbolContext(eSymbolContextCompUnit).comp_unit);
+  return SBCompileUnit();
 }
 
 SBFunction SBFrame::GetFunction() const {
   LLDB_INSTRUMENT_VA(this);
 
-  SBFunction sb_function;
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
-  if (!stop_locker.IsLocked())
-    return sb_function;
-
-  StackFrame *frame = nullptr;
-  Target *target = exe_ctx.GetTargetPtr();
-  Process *process = exe_ctx.GetProcessPtr();
-  if (target && process) {
-    frame = exe_ctx.GetFramePtr();
-    if (frame) {
-      sb_function.reset(
-          frame->GetSymbolContext(eSymbolContextFunction).function);
-    }
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (!exe_ctx) {
+    llvm::consumeError(exe_ctx.takeError());
+    return SBFunction();
   }
 
-  return sb_function;
+  if (StackFrame *frame = exe_ctx->GetFramePtr())
+    return SBFunction(frame->GetSymbolContext(eSymbolContextFunction).function);
+  return SBFunction();
 }
 
 SBSymbol SBFrame::GetSymbol() const {
   LLDB_INSTRUMENT_VA(this);
 
-  SBSymbol sb_symbol;
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
-  if (!stop_locker.IsLocked())
-    return sb_symbol;
-
-  StackFrame *frame = nullptr;
-  Target *target = exe_ctx.GetTargetPtr();
-  Process *process = exe_ctx.GetProcessPtr();
-  if (target && process) {
-    frame = exe_ctx.GetFramePtr();
-    if (frame) {
-      sb_symbol.reset(frame->GetSymbolContext(eSymbolContextSymbol).symbol);
-    }
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (!exe_ctx) {
+    llvm::consumeError(exe_ctx.takeError());
+    return SBSymbol();
   }
 
-  return sb_symbol;
+  if (StackFrame *frame = exe_ctx->GetFramePtr())
+    return SBSymbol(frame->GetSymbolContext(eSymbolContextSymbol).symbol);
+  return SBSymbol();
 }
 
 SBBlock SBFrame::GetBlock() const {
   LLDB_INSTRUMENT_VA(this);
 
-  SBBlock sb_block;
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
-  if (!stop_locker.IsLocked())
-    return sb_block;
-
-  StackFrame *frame = nullptr;
-  Target *target = exe_ctx.GetTargetPtr();
-  Process *process = exe_ctx.GetProcessPtr();
-  if (target && process) {
-    frame = exe_ctx.GetFramePtr();
-    if (frame)
-      sb_block.SetPtr(frame->GetSymbolContext(eSymbolContextBlock).block);
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (!exe_ctx) {
+    llvm::consumeError(exe_ctx.takeError());
+    return SBBlock();
   }
-  return sb_block;
+
+  if (StackFrame *frame = exe_ctx->GetFramePtr())
+    return SBBlock(frame->GetSymbolContext(eSymbolContextBlock).block);
+  return SBBlock();
 }
 
 SBBlock SBFrame::GetFrameBlock() const {
   LLDB_INSTRUMENT_VA(this);
 
-  SBBlock sb_block;
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
-  if (!stop_locker.IsLocked())
-    return sb_block;
-
-  StackFrame *frame = nullptr;
-  Target *target = exe_ctx.GetTargetPtr();
-  Process *process = exe_ctx.GetProcessPtr();
-  if (target && process) {
-    frame = exe_ctx.GetFramePtr();
-    if (frame)
-      sb_block.SetPtr(frame->GetFrameBlock());
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (!exe_ctx) {
+    llvm::consumeError(exe_ctx.takeError());
+    return SBBlock();
   }
-  return sb_block;
+
+  if (StackFrame *frame = exe_ctx->GetFramePtr())
+    return SBBlock(frame->GetFrameBlock());
+  return SBBlock();
 }
 
 SBLineEntry SBFrame::GetLineEntry() const {
   LLDB_INSTRUMENT_VA(this);
 
-  SBLineEntry sb_line_entry;
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
-  if (!stop_locker.IsLocked())
-    return sb_line_entry;
-
-  StackFrame *frame = nullptr;
-  Target *target = exe_ctx.GetTargetPtr();
-  Process *process = exe_ctx.GetProcessPtr();
-  if (target && process) {
-    frame = exe_ctx.GetFramePtr();
-    if (frame) {
-      sb_line_entry.SetLineEntry(
-          frame->GetSymbolContext(eSymbolContextLineEntry).line_entry);
-    }
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (!exe_ctx) {
+    llvm::consumeError(exe_ctx.takeError());
+    return SBLineEntry();
   }
-  return sb_line_entry;
+
+  if (StackFrame *frame = exe_ctx->GetFramePtr())
+    return SBLineEntry(
+        &frame->GetSymbolContext(eSymbolContextLineEntry).line_entry);
+  return SBLineEntry();
 }
 
 uint32_t SBFrame::GetFrameID() const {
   LLDB_INSTRUMENT_VA(this);
 
-  uint32_t frame_idx = UINT32_MAX;
+  constexpr uint32_t error_frame_idx = UINT32_MAX;
 
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
-  if (!stop_locker.IsLocked())
-    return frame_idx;
-
-  StackFrame *frame = exe_ctx.GetFramePtr();
-  if (frame)
-    frame_idx = frame->GetFrameIndex();
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (!exe_ctx) {
+    llvm::consumeError(exe_ctx.takeError());
+    return error_frame_idx;
+  }
 
-  return frame_idx;
+  if (StackFrame *frame = exe_ctx->GetFramePtr())
+    return frame->GetFrameIndex();
+  return error_frame_idx;
 }
 
 lldb::addr_t SBFrame::GetCFA() const {
   LLDB_INSTRUMENT_VA(this);
 
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
-  if (!stop_locker.IsLocked())
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (!exe_ctx) {
+    llvm::consumeError(exe_ctx.takeError());
     return LLDB_INVALID_ADDRESS;
+  }
 
-  StackFrame *frame = exe_ctx.GetFramePtr();
-  if (frame)
+  if (StackFrame *frame = exe_ctx->GetFramePtr())
     return frame->GetStackID().GetCallFrameAddress();
   return LLDB_INVALID_ADDRESS;
 }
@@ -334,114 +275,86 @@ addr_t SBFrame::GetPC() const {
   LLDB_INSTRUMENT_VA(this);
 
   addr_t addr = LLDB_INVALID_ADDRESS;
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
-  if (!stop_locker.IsLocked())
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (!exe_ctx) {
+    llvm::consumeError(exe_ctx.takeError());
     return addr;
-
-  StackFrame *frame = nullptr;
-  Target *target = exe_ctx.GetTargetPtr();
-  Process *process = exe_ctx.GetProcessPtr();
-  if (target && process) {
-    frame = exe_ctx.GetFramePtr();
-    if (frame) {
-      addr = frame->GetFrameCodeAddress().GetOpcodeLoadAddress(
-          target, AddressClass::eCode);
-    }
   }
 
+  Target *target = exe_ctx->GetTargetPtr();
+  if (StackFrame *frame = exe_ctx->GetFramePtr())
+    return frame->GetFrameCodeAddress().GetOpcodeLoadAddress(
+        target, AddressClass::eCode);
+
   return addr;
 }
 
 bool SBFrame::SetPC(addr_t new_pc) {
   LLDB_INSTRUMENT_VA(this, new_pc);
 
-  bool ret_val = false;
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
-  if (!stop_locker.IsLocked())
-    return ret_val;
-
-  Target *target = exe_ctx.GetTargetPtr();
-  Process *process = exe_ctx.GetProcessPtr();
-  if (target && process) {
-    if (StackFrame *frame = exe_ctx.GetFramePtr()) {
-      if (RegisterContextSP reg_ctx_sp = frame->GetRegisterContext()) {
-        ret_val = reg_ctx_sp->SetPC(new_pc);
-      }
-    }
+  constexpr bool error_ret_val = false;
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (!exe_ctx) {
+    llvm::consumeError(exe_ctx.takeError());
+    return error_ret_val;
   }
 
-  return ret_val;
+  if (StackFrame *frame = exe_ctx->GetFramePtr())
+    if (RegisterContextSP reg_ctx_sp = frame->GetRegisterContext())
+      return reg_ctx_sp->SetPC(new_pc);
+
+  return error_ret_val;
 }
 
 addr_t SBFrame::GetSP() const {
   LLDB_INSTRUMENT_VA(this);
 
-  addr_t addr = LLDB_INVALID_ADDRESS;
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
-  if (!stop_locker.IsLocked())
-    return addr;
-
-  Target *target = exe_ctx.GetTargetPtr();
-  Process *process = exe_ctx.GetProcessPtr();
-  if (target && process) {
-    if (StackFrame *frame = exe_ctx.GetFramePtr()) {
-      if (RegisterContextSP reg_ctx_sp = frame->GetRegisterContext()) {
-        addr = reg_ctx_sp->GetSP();
-      }
-    }
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (!exe_ctx) {
+    llvm::consumeError(exe_ctx.takeError());
+    return LLDB_INVALID_ADDRESS;
   }
 
-  return addr;
+  if (StackFrame *frame = exe_ctx->GetFramePtr())
+    if (RegisterContextSP reg_ctx_sp = frame->GetRegisterContext())
+      return reg_ctx_sp->GetSP();
+
+  return LLDB_INVALID_ADDRESS;
 }
 
 addr_t SBFrame::GetFP() const {
   LLDB_INSTRUMENT_VA(this);
 
-  addr_t addr = LLDB_INVALID_ADDRESS;
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
-  if (!stop_locker.IsLocked())
-    return addr;
-
-  Target *target = exe_ctx.GetTargetPtr();
-  Process *process = exe_ctx.GetProcessPtr();
-  if (target && process) {
-    if (StackFrame *frame = exe_ctx.GetFramePtr()) {
-      if (RegisterContextSP reg_ctx_sp = frame->GetRegisterContext()) {
-        addr = reg_ctx_sp->GetFP();
-      }
-    }
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (!exe_ctx) {
+    llvm::consumeError(exe_ctx.takeError());
+    return LLDB_INVALID_ADDRESS;
   }
 
-  return addr;
+  if (StackFrame *frame = exe_ctx->GetFramePtr())
+    if (RegisterContextSP reg_ctx_sp = frame->GetRegisterContext())
+      return reg_ctx_sp->GetFP();
+
+  return LLDB_INVALID_ADDRESS;
 }
 
 SBAddress SBFrame::GetPCAddress() const {
   LLDB_INSTRUMENT_VA(this);
 
-  SBAddress sb_addr;
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
-  if (!stop_locker.IsLocked())
-    return sb_addr;
-
-  StackFrame *frame = exe_ctx.GetFramePtr();
-  Target *target = exe_ctx.GetTargetPtr();
-  Process *process = exe_ctx.GetProcessPtr();
-  if (target && process) {
-    frame = exe_ctx.GetFramePtr();
-    if (frame)
-      sb_addr.SetAddress(frame->GetFrameCodeAddress());
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (!exe_ctx) {
+    llvm::consumeError(exe_ctx.takeError());
+    return SBAddress();
   }
-  return sb_addr;
+
+  if (StackFrame *frame = exe_ctx->GetFramePtr())
+    return SBAddress(frame->GetFrameCodeAddress());
+  return SBAddress();
 }
 
 void SBFrame::Clear() {
@@ -454,15 +367,14 @@ lldb::SBValue SBFrame::GetValueForVariablePath(const char *var_path) {
   LLDB_INSTRUMENT_VA(this, var_path);
 
   SBValue sb_value;
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
-  if (!stop_locker.IsLocked())
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (!exe_ctx) {
+    llvm::consumeError(exe_ctx.takeError());
     return sb_value;
+  }
 
-  StackFrame *frame = exe_ctx.GetFramePtr();
-  Target *target = exe_ctx.GetTargetPtr();
-  if (frame && target) {
+  if (StackFrame *frame = exe_ctx->GetFramePtr()) {
     lldb::DynamicValueType use_dynamic =
         frame->CalculateTarget()->GetPreferDynamicValue();
     sb_value = GetValueForVariablePath(var_path, use_dynamic);
@@ -479,27 +391,22 @@ lldb::SBValue SBFrame::GetValueForVariablePath(const char *var_path,
     return sb_value;
   }
 
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
-  if (!stop_locker.IsLocked())
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (!exe_ctx) {
+    llvm::consumeError(exe_ctx.takeError());
     return sb_value;
+  }
 
-  StackFrame *frame = nullptr;
-  Target *target = exe_ctx.GetTargetPtr();
-  Process *process = exe_ctx.GetProcessPtr();
-  if (target && process) {
-    frame = exe_ctx.GetFramePtr();
-    if (frame) {
-      VariableSP var_sp;
-      Status error;
-      ValueObjectSP value_sp(frame->GetValueForVariableExpressionPath(
-          var_path, eNoDynamicValues,
-          StackFrame::eExpressionPathOptionCheckPtrVsMember |
-              StackFrame::eExpressionPathOptionsAllowDirectIVarAccess,
-          var_sp, error));
-      sb_value.SetSP(value_sp, use_dynamic);
-    }
+  if (StackFrame *frame = exe_ctx->GetFramePtr()) {
+    VariableSP var_sp;
+    Status error;
+    ValueObjectSP value_sp(frame->GetValueForVariableExpressionPath(
+        var_path, eNoDynamicValues,
+        StackFrame::eExpressionPathOptionCheckPtrVsMember |
+            StackFrame::eExpressionPathOptionsAllowDirectIVarAccess,
+        var_sp, error));
+    sb_value.SetSP(value_sp, use_dynamic);
   }
   return sb_value;
 }
@@ -507,21 +414,19 @@ lldb::SBValue SBFrame::GetValueForVariablePath(const char *var_path,
 SBValue SBFrame::FindVariable(const char *name) {
   LLDB_INSTRUMENT_VA(this, name);
 
-  SBValue value;
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
-  if (!stop_locker.IsLocked())
-    return value;
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (!exe_ctx) {
+    llvm::consumeError(exe_ctx.takeError());
+    return SBValue();
+  }
 
-  StackFrame *frame = exe_ctx.GetFramePtr();
-  Target *target = exe_ctx.GetTargetPtr();
-  if (frame && target) {
+  if (StackFrame *frame = exe_ctx->GetFramePtr()) {
     lldb::DynamicValueType use_dynamic =
         frame->CalculateTarget()->GetPreferDynamicValue();
-    value = FindVariable(name, use_dynamic);
+    return FindVariable(name, use_dynamic);
   }
-  return value;
+  return SBValue();
 }
 
 SBValue SBFrame::FindVariable(const char *name,
@@ -535,26 +440,17 @@ SBValue SBFrame::FindVariable(const char *name,
     return sb_value;
   }
 
-  ValueObjectSP value_sp;
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
-  if (!stop_locker.IsLocked())
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (!exe_ctx) {
+    llvm::consumeError(exe_ctx.takeError());
     return sb_value;
-
-  StackFrame *frame = nullptr;
-  Target *target = exe_ctx.GetTargetPtr();
-  Process *process = exe_ctx.GetProcessPtr();
-  if (target && process) {
-    frame = exe_ctx.GetFramePtr();
-    if (frame) {
-      value_sp = frame->FindVariable(ConstString(name));
-
-      if (value_sp)
-        sb_value.SetSP(value_sp, use_dynamic);
-    }
   }
 
+  if (StackFrame *frame = exe_ctx->GetFramePtr())
+    if (ValueObjectSP value_sp = frame->FindVariable(ConstString(name)))
+      sb_value.SetSP(value_sp, use_dynamic);
+
   return sb_value;
 }
 
@@ -562,15 +458,14 @@ SBValue SBFrame::FindValue(const char *name, ValueType value_type) {
   LLDB_INSTRUMENT_VA(this, name, value_type);
 
   SBValue value;
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
-  if (!stop_locker.IsLocked())
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (!exe_ctx) {
+    llvm::consumeError(exe_ctx.takeError());
     return value;
+  }
 
-  StackFrame *frame = exe_ctx.GetFramePtr();
-  Target *target = exe_ctx.GetTargetPtr();
-  if (frame && target) {
+  if (StackFrame *frame = exe_ctx->GetFramePtr()) {
     lldb::DynamicValueType use_dynamic =
         frame->CalculateTarget()->GetPreferDynamicValue();
     value = FindValue(name, value_type, use_dynamic);
@@ -589,17 +484,17 @@ SBValue SBFrame::FindValue(const char *name, ValueType value_type,
   }
 
   ValueObjectSP value_sp;
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
-
-  if (stop_locker.IsLocked()) {
-    StackFrame *frame = nullptr;
-    Target *target = exe_ctx.GetTargetPtr();
-    Process *process = exe_ctx.GetProcessPtr();
-    if (target && process) {
-      frame = exe_ctx.GetFramePtr();
-      if (frame) {
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+
+  if (!exe_ctx) {
+    llvm::consumeError(exe_ctx.takeError());
+    return value_sp;
+  } else {
+    Target *target = exe_ctx->GetTargetPtr();
+    Process *process = exe_ctx->GetProcessPtr();
+    if (target && process) { // FIXME: this check is redundant.
+      if (StackFrame *frame = exe_ctx->GetFramePtr()) {
         VariableList variable_list;
 
         switch (value_type) {
@@ -716,13 +611,14 @@ bool SBFrame::operator!=(const SBFrame &rhs) const {
 SBThread SBFrame::GetThread() const {
   LLDB_INSTRUMENT_VA(this);
 
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
-  if (!stop_locker.IsLocked())
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (!exe_ctx) {
+    llvm::consumeError(exe_ctx.takeError());
     return SBThread();
+  }
 
-  ThreadSP thread_sp(exe_ctx.GetThreadSP());
+  ThreadSP thread_sp(exe_ctx->GetThreadSP());
   SBThread sb_thread(thread_sp);
 
   return sb_thread;
@@ -731,17 +627,14 @@ SBThread SBFrame::GetThread() const {
 const char *SBFrame::Disassemble() const {
   LLDB_INSTRUMENT_VA(this);
 
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
-  if (!stop_locker.IsLocked())
-    return nullptr;
-  Target *target = exe_ctx.GetTargetPtr();
-  Process *process = exe_ctx.GetProcessPtr();
-  if (!target || !process)
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (!exe_ctx) {
+    llvm::consumeError(exe_ctx.takeError());
     return nullptr;
+  }
 
-  if (auto *frame = exe_ctx.GetFramePtr())
+  if (auto *frame = exe_ctx->GetFramePtr())
     return ConstString(frame->Disassemble()).GetCString();
 
   return nullptr;
@@ -752,15 +645,15 @@ SBValueList SBFrame::GetVariables(bool arguments, bool locals, bool statics,
   LLDB_INSTRUMENT_VA(this, arguments, locals, statics, in_scope_only);
 
   SBValueList value_list;
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
-  if (!stop_locker.IsLocked())
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (!exe_ctx) {
+    llvm::consumeError(exe_ctx.takeError());
     return value_list;
+  }
 
-  StackFrame *frame = exe_ctx.GetFramePtr();
-  Target *target = exe_ctx.GetTargetPtr();
-  if (frame && target) {
+  if (StackFrame *frame = exe_ctx->GetFramePtr()) {
+    Target *target = exe_ctx->GetTargetPtr();
     lldb::DynamicValueType use_dynamic =
         frame->CalculateTarget()->GetPreferDynamicValue();
     const bool include_runtime_support_values =
@@ -785,17 +678,16 @@ lldb::SBValueList SBFrame::GetVariables(bool arguments, bool locals,
   LLDB_INSTRUMENT_VA(this, arguments, locals, statics, in_scope_only,
                      use_dynamic);
 
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
-  if (!stop_locker.IsLocked()) {
-    SBValueList empty_list;
-    return empty_list;
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (!exe_ctx) {
+    llvm::consumeError(exe_ctx.takeError());
+    return SBValueList();
   }
 
-  Target *target = exe_ctx.GetTargetPtr();
+  Target *target = exe_ctx->GetTargetPtr();
   const bool include_runtime_support_values =
-      target ? target->GetDisplayRuntimeSupportValues() : false;
+      target->GetDisplayRuntimeSupportValues();
   SBVariablesOptions options;
   options.SetIncludeArguments(arguments);
   options.SetIncludeLocals(locals);
@@ -810,18 +702,16 @@ SBValueList SBFrame::GetVariables(const lldb::SBVariablesOptions &options) {
   LLDB_INSTRUMENT_VA(this, options);
 
   SBValueList value_list;
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
-  if (stop_locker.IsLocked()) {
-
-    StackFrame *frame = nullptr;
-    Target *target = exe_ctx.GetTargetPtr();
-
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (!exe_ctx) {
+    llvm::consumeError(exe_ctx.takeError());
+    return SBValueList();
+  } else {
     const bool statics = options.GetIncludeStatics();
     const bool arguments = options.GetIncludeArguments();
     const bool recognized_arguments =
-        options.GetIncludeRecognizedArguments(SBTarget(exe_ctx.GetTargetSP()));
+        options.GetIncludeRecognizedArguments(SBTarget(exe_ctx->GetTargetSP()));
     const bool locals = options.GetIncludeLocals();
     const bool in_scope_only = options.GetInScopeOnly();
     const bool include_runtime_support_values =
@@ -829,10 +719,9 @@ SBValueList SBFrame::GetVariables(const lldb::SBVariablesOptions &options) {
     const lldb::DynamicValueType use_dynamic = options.GetUseDynamic();
 
     std::set<VariableSP> variable_set;
-    Process *process = exe_ctx.GetProcessPtr();
-    if (target && process) {
-      frame = exe_ctx.GetFramePtr();
-      if (frame) {
+    Process *process = exe_ctx->GetProcessPtr();
+    if (process) { // FIXME: this check is redundant.
+      if (StackFrame *frame = exe_ctx->GetFramePtr()) {
         Debugger &dbg = process->GetTarget().GetDebugger();
         VariableList *variable_list = nullptr;
         Status var_error;
@@ -920,17 +809,16 @@ SBValueList SBFrame::GetRegisters() {
   LLDB_INSTRUMENT_VA(this);
 
   SBValueList value_list;
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
-  if (stop_locker.IsLocked()) {
-
-    StackFrame *frame = nullptr;
-    Target *target = exe_ctx.GetTargetPtr();
-    Process *process = exe_ctx.GetProcessPtr();
-    if (target && process) {
-      frame = exe_ctx.GetFramePtr();
-      if (frame) {
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (!exe_ctx) {
+    llvm::consumeError(exe_ctx.takeError());
+    return SBValueList();
+  } else {
+    Target *target = exe_ctx->GetTargetPtr();
+    Process *process = exe_ctx->GetProcessPtr();
+    if (target && process) { // FIXME: this check is redundant.
+      if (StackFrame *frame = exe_ctx->GetFramePtr()) {
         RegisterContextSP reg_ctx(frame->GetRegisterContext());
         if (reg_ctx) {
           const uint32_t num_sets = reg_ctx->GetRegisterSetCount();
@@ -951,16 +839,16 @@ SBValue SBFrame::FindRegister(const char *name) {
 
   SBValue result;
   ValueObjectSP value_sp;
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
-  if (stop_locker.IsLocked()) {
-    StackFrame *frame = nullptr;
-    Target *target = exe_ctx.GetTargetPtr();
-    Process *process = exe_ctx.GetProcessPtr();
-    if (target && process) {
-      frame = exe_ctx.GetFramePtr();
-      if (frame) {
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (!exe_ctx) {
+    llvm::consumeError(exe_ctx.takeError());
+    return SBValue();
+  } else {
+    Target *target = exe_ctx->GetTargetPtr();
+    Process *process = exe_ctx->GetProcessPtr();
+    if (target && process) { // FIXME: this check is redundant.
+      if (StackFrame *frame = exe_ctx->GetFramePtr()) {
         RegisterContextSP reg_ctx(frame->GetRegisterContext());
         if (reg_ctx) {
           if (const RegisterInfo *reg_info =
@@ -980,15 +868,11 @@ SBError SBFrame::GetDescriptionWithFormat(const SBFormat &format,
                                           SBStream &output) {
   Stream &strm = output.ref();
 
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
-  if (!stop_locker.IsLocked())
-    return "Process is not stopped";
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (!exe_ctx)
+    return Status::FromError(exe_ctx.takeError());
 
-  StackFrame *frame = nullptr;
-  Target *target = exe_ctx.GetTargetPtr();
-  Process *process = exe_ctx.GetProcessPtr();
   SBError error;
 
   if (!format) {
@@ -996,13 +880,9 @@ SBError SBFrame::GetDescriptionWithFormat(const SBFormat &format,
     return error;
   }
 
-  if (target && process) {
-    frame = exe_ctx.GetFramePtr();
-    if (frame &&
-        frame->DumpUsingFormat(strm, format.GetFormatEntrySP().get())) {
-      return error;
-    }
-  }
+  if (StackFrame *frame = exe_ctx->GetFramePtr();
+      frame && frame->DumpUsingFormat(strm, format.GetFormatEntrySP().get()))
+    return error;
   error.SetErrorStringWithFormat(
       "It was not possible to generate a frame "
       "description with the given format string '%s'",
@@ -1015,24 +895,16 @@ bool SBFrame::GetDescription(SBStream &description) {
 
   Stream &strm = description.ref();
 
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
-  if (!stop_locker.IsLocked()) {
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (!exe_ctx) {
+    llvm::consumeError(exe_ctx.takeError());
     strm.PutCString("Error: process is not stopped.");
     return true;
   }
 
-  StackFrame *frame;
-  Target *target = exe_ctx.GetTargetPtr();
-  Process *process = exe_ctx.GetProcessPtr();
-  if (target && process) {
-    frame = exe_ctx.GetFramePtr();
-    if (frame) {
-      frame->DumpUsingSettingsFormat(&strm);
-    }
-  } else
-    strm.PutCString("No value");
+  if (StackFrame *frame = exe_ctx->GetFramePtr())
+    frame->DumpUsingSettingsFormat(&strm);
 
   return true;
 }
@@ -1040,25 +912,24 @@ bool SBFrame::GetDescription(SBStream &description) {
 SBValue SBFrame::EvaluateExpression(const char *expr) {
   LLDB_INSTRUMENT_VA(this, expr);
 
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
-  if (!stop_locker.IsLocked())
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (!exe_ctx) {
+    llvm::consumeError(exe_ctx.takeError());
     return CreateProcessIsRunningExprEvalError();
+  }
 
-  StackFrame *frame = exe_ctx.GetFramePtr();
-  Target *target = exe_ctx.GetTargetPtr();
   SBExpressionOptions options;
-  if (frame && target) {
+  StackFrame *frame = exe_ctx->GetFramePtr();
+  if (frame) {
     lldb::DynamicValueType fetch_dynamic_value =
         frame->CalculateTarget()->GetPreferDynamicValue();
     options.SetFetchDynamicValue(fetch_dynamic_value);
   }
   options.SetUnwindOnError(true);
   options.SetIgnoreBreakpoints(true);
-  SourceLanguage language;
-  if (target)
-    language = target->GetLanguage();
+  Target *target = exe_ctx->GetTargetPtr();
+  SourceLanguage language = target->GetLanguage();
   if (!language && frame)
     language = frame->GetLanguage();
   options.SetLanguage((SBSourceLanguageName)language.name, language.version);
@@ -1074,17 +945,16 @@ SBFrame::EvaluateExpression(const char *expr,
   options.SetFetchDynamicValue(fetch_dynamic_value);
   options.SetUnwindOnError(true);
   options.SetIgnoreBreakpoints(true);
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
-  if (!stop_locker.IsLocked())
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (!exe_ctx) {
+    llvm::consumeError(exe_ctx.takeError());
     return CreateProcessIsRunningExprEvalError();
+  }
 
-  StackFrame *frame = exe_ctx.GetFramePtr();
-  Target *target = exe_ctx.GetTargetPtr();
-  SourceLanguage language;
-  if (target)
-    language = target->GetLanguage();
+  StackFrame *frame = exe_ctx->GetFramePtr();
+  Target *target = exe_ctx->GetTargetPtr();
+  SourceLanguage language = target->GetLanguage();
   if (!language && frame)
     language = frame->GetLanguage();
   options.SetLanguage((SBSourceLanguageName)language.name, language.version);
@@ -1097,20 +967,19 @@ SBValue SBFrame::EvaluateExpression(const char *expr,
   LLDB_INSTRUMENT_VA(this, expr, fetch_dynamic_value, unwind_on_error);
 
   SBExpressionOptions options;
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
-  if (!stop_locker.IsLocked())
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (!exe_ctx) {
+    llvm::consumeError(exe_ctx.takeError());
     return CreateProcessIsRunningExprEvalError();
+  }
 
   options.SetFetchDynamicValue(fetch_dynamic_value);
   options.SetUnwindOnError(unwind_on_error);
   options.SetIgnoreBreakpoints(true);
-  StackFrame *frame = exe_ctx.GetFramePtr();
-  Target *target = exe_ctx.GetTargetPtr();
-  SourceLanguage language;
-  if (target)
-    language = target->GetLanguage();
+  StackFrame *frame = exe_ctx->GetFramePtr();
+  Target *target = exe_ctx->GetTargetPtr();
+  SourceLanguage language = target->GetLanguage();
   if (!language && frame)
     language = frame->GetLanguage();
   options.SetLanguage((SBSourceLanguageName)language.name, language.version);
@@ -1141,18 +1010,16 @@ lldb::SBValue SBFrame::EvaluateExpression(const char *expr,
 
   ValueObjectSP expr_value_sp;
 
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
-  if (stop_locker.IsLocked()) {
-
-    StackFrame *frame = nullptr;
-    Target *target = exe_ctx.GetTargetPtr();
-    Process *process = exe_ctx.GetProcessPtr();
-
-    if (target && process) {
-      frame = exe_ctx.GetFramePtr();
-      if (frame) {
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (!exe_ctx) {
+    llvm::consumeError(exe_ctx.takeError());
+    expr_result = CreateProcessIsRunningExprEvalError();
+  } else {
+    Target *target = exe_ctx->GetTargetPtr();
+    Process *process = exe_ctx->GetProcessPtr();
+    if (target && process) { // FIXME: this check is redundant.
+      if (StackFrame *frame = exe_ctx->GetFramePtr()) {
         std::unique_ptr<llvm::PrettyStackTraceFormat> stack_trace;
         if (target->GetDisplayExpressionsInCrashlogs()) {
           StreamString frame_description;
@@ -1173,8 +1040,7 @@ lldb::SBValue SBFrame::EvaluateExpression(const char *expr,
       expr_value_sp = ValueObjectConstResult::Create(nullptr, std::move(error));
       expr_result.SetSP(expr_value_sp, false);
     }
-  } else
-    expr_result = CreateProcessIsRunningExprEvalError();
+  }
 
   if (expr_result.GetError().Success())
     LLDB_LOGF(expr_log,
@@ -1194,12 +1060,13 @@ SBStructuredData SBFrame::GetLanguageSpecificData() const {
   LLDB_INSTRUMENT_VA(this);
 
   SBStructuredData sb_data;
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
-  if (!stop_locker.IsLocked())
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (!exe_ctx) {
+    llvm::consumeError(exe_ctx.takeError());
     return sb_data;
-  StackFrame *frame = exe_ctx.GetFramePtr();
+  }
+  StackFrame *frame = exe_ctx->GetFramePtr();
   if (!frame)
     return sb_data;
 
@@ -1217,20 +1084,15 @@ bool SBFrame::IsInlined() {
 bool SBFrame::IsInlined() const {
   LLDB_INSTRUMENT_VA(this);
 
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
-  if (!stop_locker.IsLocked())
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (!exe_ctx) {
+    llvm::consumeError(exe_ctx.takeError());
     return false;
-
-  StackFrame *frame = nullptr;
-  Target *target = exe_ctx.GetTargetPtr();
-  Process *process = exe_ctx.GetProcessPtr();
-  if (target && process) {
-    frame = exe_ctx.GetFramePtr();
-    if (frame)
-      return frame->IsInlined();
   }
+
+  if (StackFrame *frame = exe_ctx->GetFramePtr())
+    return frame->IsInlined();
   return false;
 }
 
@@ -1243,13 +1105,14 @@ bool SBFrame::IsArtificial() {
 bool SBFrame::IsArtificial() const {
   LLDB_INSTRUMENT_VA(this);
 
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
-  if (!stop_locker.IsLocked())
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (!exe_ctx) {
+    llvm::consumeError(exe_ctx.takeError());
     return false;
+  }
 
-  if (StackFrame *frame = exe_ctx.GetFramePtr())
+  if (StackFrame *frame = exe_ctx->GetFramePtr())
     return frame->IsArtificial();
 
   return false;
@@ -1258,13 +1121,14 @@ bool SBFrame::IsArtificial() const {
 bool SBFrame::IsHidden() const {
   LLDB_INSTRUMENT_VA(this);
 
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
-  if (!stop_locker.IsLocked())
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (!exe_ctx) {
+    llvm::consumeError(exe_ctx.takeError());
     return false;
+  }
 
-  if (StackFrame *frame = exe_ctx.GetFramePtr())
+  if (StackFrame *frame = exe_ctx->GetFramePtr())
     return frame->IsHidden();
 
   return false;
@@ -1279,63 +1143,44 @@ const char *SBFrame::GetFunctionName() {
 lldb::LanguageType SBFrame::GuessLanguage() const {
   LLDB_INSTRUMENT_VA(this);
 
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
-  if (!stop_locker.IsLocked())
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (!exe_ctx) {
+    llvm::consumeError(exe_ctx.takeError());
     return eLanguageTypeUnknown;
-
-  StackFrame *frame = nullptr;
-  Target *target = exe_ctx.GetTargetPtr();
-  Process *process = exe_ctx.GetProcessPtr();
-  if (target && process) {
-    frame = exe_ctx.GetFramePtr();
-    if (frame) {
-      return frame->GuessLanguage().AsLanguageType();
-    }
   }
+
+  if (StackFrame *frame = exe_ctx->GetFramePtr())
+    return frame->GuessLanguage().AsLanguageType();
   return eLanguageTypeUnknown;
 }
 
 const char *SBFrame::GetFunctionName() const {
   LLDB_INSTRUMENT_VA(this);
 
-  const char *name = nullptr;
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
-  if (!stop_locker.IsLocked())
-    return name;
-
-  StackFrame *frame = nullptr;
-  Target *target = exe_ctx.GetTargetPtr();
-  Process *process = exe_ctx.GetProcessPtr();
-  if (target && process) {
-    frame = exe_ctx.GetFramePtr();
-    if (frame)
-      return frame->GetFunctionName();
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (!exe_ctx) {
+    llvm::consumeError(exe_ctx.takeError());
+    return nullptr;
   }
-  return name;
+
+  if (StackFrame *frame = exe_ctx->GetFramePtr())
+    return frame->GetFunctionName();
+  return nullptr;
 }
 
 const char *SBFrame::GetDisplayFunctionName() {
   LLDB_INSTRUMENT_VA(this);
 
-  const char *name = nullptr;
-
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
-  if (!stop_locker.IsLocked())
-    return name;
-
-  StackFrame *frame = nullptr;
-  Target *target = exe_ctx.GetTargetPtr();
-  Process *process = exe_ctx.GetProcessPtr();
-  if (target && process) {
-    frame = exe_ctx.GetFramePtr();
-    if (frame)
-      return frame->GetDisplayFunctionName();
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (!exe_ctx) {
+    llvm::consumeError(exe_ctx.takeError());
+    return nullptr;
   }
-  return name;
+
+  if (StackFrame *frame = exe_ctx->GetFramePtr())
+    return frame->GetDisplayFunctionName();
+  return nullptr;
 }
diff --git a/lldb/source/API/SBThread.cpp b/lldb/source/API/SBThread.cpp
index 5b9ff0f5b2abf..bc0d0e9b55ee5 100644
--- a/lldb/source/API/SBThread.cpp
+++ b/lldb/source/API/SBThread.cpp
@@ -90,14 +90,15 @@ lldb::SBQueue SBThread::GetQueue() const {
 
   SBQueue sb_queue;
   QueueSP queue_sp;
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
-  if (!stop_locker.IsLocked())
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (!exe_ctx) {
+    llvm::consumeError(exe_ctx.takeError());
     return SBQueue();
+  }
 
-  if (exe_ctx.HasThreadScope()) {
-    queue_sp = exe_ctx.GetThreadPtr()->GetQueue();
+  if (exe_ctx->HasThreadScope()) {
+    queue_sp = exe_ctx->GetThreadPtr()->GetQueue();
     if (queue_sp) {
       sb_queue.SetQueue(queue_sp);
     }
@@ -115,19 +116,14 @@ SBThread::operator bool() const {
   if (!m_opaque_sp)
     return false;
 
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
-  if (!stop_locker.IsLocked())
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (!exe_ctx) {
+    llvm::consumeError(exe_ctx.takeError());
     return false;
-
-  Target *target = exe_ctx.GetTargetPtr();
-  Process *process = exe_ctx.GetProcessPtr();
-  if (target && process) {
-    return m_opaque_sp->GetThreadSP().get() != nullptr;
   }
-  // Without a valid target & process, this thread can't be valid.
-  return false;
+
+  return m_opaque_sp->GetThreadSP().get() != nullptr;
 }
 
 void SBThread::Clear() {
@@ -140,28 +136,27 @@ StopReason SBThread::GetStopReason() {
   LLDB_INSTRUMENT_VA(this);
 
   StopReason reason = eStopReasonInvalid;
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
-  if (!stop_locker.IsLocked())
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (!exe_ctx) {
+    llvm::consumeError(exe_ctx.takeError());
     return reason;
-
-  if (exe_ctx.HasThreadScope()) {
-    return exe_ctx.GetThreadPtr()->GetStopReason();
   }
 
+  if (exe_ctx->HasThreadScope())
+    return exe_ctx->GetThreadPtr()->GetStopReason();
+
   return reason;
 }
 
 size_t SBThread::GetStopReasonDataCount() {
   LLDB_INSTRUMENT_VA(this);
 
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
-  if (stop_locker.IsLocked()) {
-    if (exe_ctx.HasThreadScope()) {
-      StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo();
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (exe_ctx) {
+    if (exe_ctx->HasThreadScope()) {
+      StopInfoSP stop_info_sp = exe_ctx->GetThreadPtr()->GetStopInfo();
       if (stop_info_sp) {
         StopReason reason = stop_info_sp->GetStopReason();
         switch (reason) {
@@ -181,7 +176,7 @@ size_t SBThread::GetStopReasonDataCount() {
         case eStopReasonBreakpoint: {
           break_id_t site_id = stop_info_sp->GetValue();
           lldb::BreakpointSiteSP bp_site_sp(
-              exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID(
+              exe_ctx->GetProcessPtr()->GetBreakpointSiteList().FindByID(
                   site_id));
           if (bp_site_sp)
             return bp_site_sp->GetNumberOfConstituents() * 2;
@@ -209,6 +204,9 @@ size_t SBThread::GetStopReasonDataCount() {
         }
       }
     }
+  } else {
+    llvm::consumeError(exe_ctx.takeError());
+    return 0;
   }
   return 0;
 }
@@ -216,12 +214,11 @@ size_t SBThread::GetStopReasonDataCount() {
 uint64_t SBThread::GetStopReasonDataAtIndex(uint32_t idx) {
   LLDB_INSTRUMENT_VA(this, idx);
 
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
-  if (stop_locker.IsLocked()) {
-    if (exe_ctx.HasThreadScope()) {
-      Thread *thread = exe_ctx.GetThreadPtr();
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (exe_ctx) {
+    if (exe_ctx->HasThreadScope()) {
+      Thread *thread = exe_ctx->GetThreadPtr();
       StopInfoSP stop_info_sp = thread->GetStopInfo();
       if (stop_info_sp) {
         StopReason reason = stop_info_sp->GetStopReason();
@@ -242,7 +239,7 @@ uint64_t SBThread::GetStopReasonDataAtIndex(uint32_t idx) {
         case eStopReasonBreakpoint: {
           break_id_t site_id = stop_info_sp->GetValue();
           lldb::BreakpointSiteSP bp_site_sp(
-              exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID(
+              exe_ctx->GetProcessPtr()->GetBreakpointSiteList().FindByID(
                   site_id));
           if (bp_site_sp) {
             uint32_t bp_index = idx / 2;
@@ -281,6 +278,9 @@ uint64_t SBThread::GetStopReasonDataAtIndex(uint32_t idx) {
         }
       }
     }
+  } else {
+    llvm::consumeError(exe_ctx.takeError());
+    return 0;
   }
   return 0;
 }
@@ -290,16 +290,17 @@ bool SBThread::GetStopReasonExtendedInfoAsJSON(lldb::SBStream &stream) {
 
   Stream &strm = stream.ref();
 
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
-  if (!stop_locker.IsLocked())
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (!exe_ctx) {
+    llvm::consumeError(exe_ctx.takeError());
     return false;
+  }
 
-  if (!exe_ctx.HasThreadScope())
+  if (!exe_ctx->HasThreadScope())
     return false;
 
-  StopInfoSP stop_info = exe_ctx.GetThreadPtr()->GetStopInfo();
+  StopInfoSP stop_info = exe_ctx->GetThreadPtr()->GetStopInfo();
   StructuredData::ObjectSP info = stop_info->GetExtendedInfo();
   if (!info)
     return false;
@@ -315,18 +316,19 @@ SBThread::GetStopReasonExtendedBacktraces(InstrumentationRuntimeType type) {
 
   SBThreadCollection threads;
 
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
-  if (!stop_locker.IsLocked())
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (!exe_ctx) {
+    llvm::consumeError(exe_ctx.takeError());
     return SBThreadCollection();
+  }
 
-  if (!exe_ctx.HasThreadScope())
+  if (!exe_ctx->HasThreadScope())
     return SBThreadCollection();
 
-  ProcessSP process_sp = exe_ctx.GetProcessSP();
+  ProcessSP process_sp = exe_ctx->GetProcessSP();
 
-  StopInfoSP stop_info = exe_ctx.GetThreadPtr()->GetStopInfo();
+  StopInfoSP stop_info = exe_ctx->GetThreadPtr()->GetStopInfo();
   StructuredData::ObjectSP info = stop_info->GetExtendedInfo();
   if (!info)
     return threads;
@@ -342,16 +344,17 @@ size_t SBThread::GetStopDescription(char *dst, size_t dst_len) {
   if (dst)
     *dst = 0;
 
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
-  if (!stop_locker.IsLocked())
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (!exe_ctx) {
+    llvm::consumeError(exe_ctx.takeError());
     return 0;
+  }
 
-  if (!exe_ctx.HasThreadScope())
+  if (!exe_ctx->HasThreadScope())
     return 0;
 
-  std::string thread_stop_desc = exe_ctx.GetThreadPtr()->GetStopDescription();
+  std::string thread_stop_desc = exe_ctx->GetThreadPtr()->GetStopDescription();
   if (thread_stop_desc.empty())
     return 0;
 
@@ -367,14 +370,15 @@ SBValue SBThread::GetStopReturnValue() {
   LLDB_INSTRUMENT_VA(this);
 
   ValueObjectSP return_valobj_sp;
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
-  if (!stop_locker.IsLocked())
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (!exe_ctx) {
+    llvm::consumeError(exe_ctx.takeError());
     return SBValue();
+  }
 
-  if (exe_ctx.HasThreadScope()) {
-    StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo();
+  if (exe_ctx->HasThreadScope()) {
+    StopInfoSP stop_info_sp = exe_ctx->GetThreadPtr()->GetStopInfo();
     if (stop_info_sp) {
       return_valobj_sp = StopInfo::GetReturnValueObject(stop_info_sp);
     }
@@ -408,45 +412,48 @@ uint32_t SBThread::GetIndexID() const {
 const char *SBThread::GetName() const {
   LLDB_INSTRUMENT_VA(this);
 
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
-  if (!stop_locker.IsLocked())
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (!exe_ctx) {
+    llvm::consumeError(exe_ctx.takeError());
     return nullptr;
+  }
 
-  if (!exe_ctx.HasThreadScope())
+  if (!exe_ctx->HasThreadScope())
     return nullptr;
 
-  return ConstString(exe_ctx.GetThreadPtr()->GetName()).GetCString();
+  return ConstString(exe_ctx->GetThreadPtr()->GetName()).GetCString();
 }
 
 const char *SBThread::GetQueueName() const {
   LLDB_INSTRUMENT_VA(this);
 
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
-  if (!stop_locker.IsLocked())
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (!exe_ctx) {
+    llvm::consumeError(exe_ctx.takeError());
     return nullptr;
+  }
 
-  if (!exe_ctx.HasThreadScope())
+  if (!exe_ctx->HasThreadScope())
     return nullptr;
 
-  return ConstString(exe_ctx.GetThreadPtr()->GetQueueName()).GetCString();
+  return ConstString(exe_ctx->GetThreadPtr()->GetQueueName()).GetCString();
 }
 
 lldb::queue_id_t SBThread::GetQueueID() const {
   LLDB_INSTRUMENT_VA(this);
 
   queue_id_t id = LLDB_INVALID_QUEUE_ID;
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
-  if (!stop_locker.IsLocked())
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (!exe_ctx) {
+    llvm::consumeError(exe_ctx.takeError());
     return id;
+  }
 
-  if (exe_ctx.HasThreadScope()) {
-    id = exe_ctx.GetThreadPtr()->GetQueueID();
+  if (exe_ctx->HasThreadScope()) {
+    id = exe_ctx->GetThreadPtr()->GetQueueID();
   }
 
   return id;
@@ -456,12 +463,11 @@ bool SBThread::GetInfoItemByPathAsString(const char *path, SBStream &strm) {
   LLDB_INSTRUMENT_VA(this, path, strm);
 
   bool success = false;
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
-  if (stop_locker.IsLocked()) {
-    if (exe_ctx.HasThreadScope()) {
-      Thread *thread = exe_ctx.GetThreadPtr();
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (exe_ctx) {
+    if (exe_ctx->HasThreadScope()) {
+      Thread *thread = exe_ctx->GetThreadPtr();
       StructuredData::ObjectSP info_root_sp = thread->GetExtendedInfo();
       if (info_root_sp) {
         StructuredData::ObjectSP node =
@@ -493,21 +499,16 @@ bool SBThread::GetInfoItemByPathAsString(const char *path, SBStream &strm) {
         }
       }
     }
+  } else {
+    llvm::consumeError(exe_ctx.takeError());
+    return success;
   }
 
   return success;
 }
 
-static Status ResumeNewPlan(ExecutionContext &exe_ctx, ThreadPlan *new_plan,
-                            Process::StopLocker stop_lock) {
-  {
-    assert(stop_lock.IsLocked());
-    auto to_unlock = std::move(stop_lock);
-  }
-  Process *process = exe_ctx.GetProcessPtr();
-  if (!process)
-    return Status::FromErrorString("No process in SBThread::ResumeNewPlan");
-
+static Status ResumeNewPlan(CompleteExecutionContext exe_ctx,
+                            ThreadPlan *new_plan) {
   Thread *thread = exe_ctx.GetThreadPtr();
   if (!thread)
     return Status::FromErrorString("No thread in SBThread::ResumeNewPlan");
@@ -520,8 +521,12 @@ static Status ResumeNewPlan(ExecutionContext &exe_ctx, ThreadPlan *new_plan,
   }
 
   // Why do we need to set the current thread by ID here???
+  Process *process = exe_ctx.GetProcessPtr();
   process->GetThreadList().SetSelectedThreadByID(thread->GetID());
 
+  // Release the run lock but keep the API lock.
+  std::unique_lock<std::recursive_mutex> api_lock =
+      exe_ctx.ClearAndGetAPILock();
   if (process->GetTarget().GetDebugger().GetAsyncExecution())
     return process->Resume();
   return process->ResumeSynchronous(nullptr);
@@ -537,18 +542,19 @@ void SBThread::StepOver(lldb::RunMode stop_other_threads) {
 void SBThread::StepOver(lldb::RunMode stop_other_threads, SBError &error) {
   LLDB_INSTRUMENT_VA(this, stop_other_threads, error);
 
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker, &error.ref());
-  if (!stop_locker.IsLocked())
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (!exe_ctx) {
+    error = Status::FromError(exe_ctx.takeError());
     return;
+  }
 
-  if (!exe_ctx.HasThreadScope()) {
+  if (!exe_ctx->HasThreadScope()) {
     error = Status::FromErrorString("this SBThread object is invalid");
     return;
   }
 
-  Thread *thread = exe_ctx.GetThreadPtr();
+  Thread *thread = exe_ctx->GetThreadPtr();
   bool abort_other_plans = false;
   StackFrameSP frame_sp(thread->GetStackFrameAtIndex(0));
 
@@ -566,7 +572,7 @@ void SBThread::StepOver(lldb::RunMode stop_other_threads, SBError &error) {
           true, abort_other_plans, stop_other_threads, new_plan_status);
     }
   }
-  error = ResumeNewPlan(exe_ctx, new_plan_sp.get(), std::move(stop_locker));
+  error = ResumeNewPlan(std::move(*exe_ctx), new_plan_sp.get());
 }
 
 void SBThread::StepInto(lldb::RunMode stop_other_threads) {
@@ -587,20 +593,21 @@ void SBThread::StepInto(const char *target_name, uint32_t end_line,
                         SBError &error, lldb::RunMode stop_other_threads) {
   LLDB_INSTRUMENT_VA(this, target_name, end_line, error, stop_other_threads);
 
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker, &error.ref());
-  if (!stop_locker.IsLocked())
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (!exe_ctx) {
+    error = Status::FromError(exe_ctx.takeError());
     return;
+  }
 
-  if (!exe_ctx.HasThreadScope()) {
+  if (!exe_ctx->HasThreadScope()) {
     error = Status::FromErrorString("this SBThread object is invalid");
     return;
   }
 
   bool abort_other_plans = false;
 
-  Thread *thread = exe_ctx.GetThreadPtr();
+  Thread *thread = exe_ctx->GetThreadPtr();
   StackFrameSP frame_sp(thread->GetStackFrameAtIndex(0));
   ThreadPlanSP new_plan_sp;
   Status new_plan_status;
@@ -632,7 +639,7 @@ void SBThread::StepInto(const char *target_name, uint32_t end_line,
   }
 
   if (new_plan_status.Success())
-    error = ResumeNewPlan(exe_ctx, new_plan_sp.get(), std::move(stop_locker));
+    error = ResumeNewPlan(std::move(*exe_ctx), new_plan_sp.get());
   else
     error = Status::FromErrorString(new_plan_status.AsCString());
 }
@@ -647,13 +654,14 @@ void SBThread::StepOut() {
 void SBThread::StepOut(SBError &error) {
   LLDB_INSTRUMENT_VA(this, error);
 
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker, &error.ref());
-  if (!stop_locker.IsLocked())
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (!exe_ctx) {
+    error = Status::FromError(exe_ctx.takeError());
     return;
+  }
 
-  if (!exe_ctx.HasThreadScope()) {
+  if (!exe_ctx->HasThreadScope()) {
     error = Status::FromErrorString("this SBThread object is invalid");
     return;
   }
@@ -661,7 +669,7 @@ void SBThread::StepOut(SBError &error) {
   bool abort_other_plans = false;
   bool stop_other_threads = false;
 
-  Thread *thread = exe_ctx.GetThreadPtr();
+  Thread *thread = exe_ctx->GetThreadPtr();
 
   const LazyBool avoid_no_debug = eLazyBoolCalculate;
   Status new_plan_status;
@@ -670,7 +678,7 @@ void SBThread::StepOut(SBError &error) {
       eVoteNoOpinion, 0, new_plan_status, avoid_no_debug));
 
   if (new_plan_status.Success())
-    error = ResumeNewPlan(exe_ctx, new_plan_sp.get(), std::move(stop_locker));
+    error = ResumeNewPlan(std::move(*exe_ctx), new_plan_sp.get());
   else
     error = Status::FromErrorString(new_plan_status.AsCString());
 }
@@ -685,11 +693,12 @@ void SBThread::StepOutOfFrame(SBFrame &sb_frame) {
 void SBThread::StepOutOfFrame(SBFrame &sb_frame, SBError &error) {
   LLDB_INSTRUMENT_VA(this, sb_frame, error);
 
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker, &error.ref());
-  if (!stop_locker.IsLocked())
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (!exe_ctx) {
+    error = Status::FromError(exe_ctx.takeError());
     return;
+  }
 
   if (!sb_frame.IsValid()) {
     error = Status::FromErrorString("passed invalid SBFrame object");
@@ -698,14 +707,14 @@ void SBThread::StepOutOfFrame(SBFrame &sb_frame, SBError &error) {
 
   StackFrameSP frame_sp(sb_frame.GetFrameSP());
 
-  if (!exe_ctx.HasThreadScope()) {
+  if (!exe_ctx->HasThreadScope()) {
     error = Status::FromErrorString("this SBThread object is invalid");
     return;
   }
 
   bool abort_other_plans = false;
   bool stop_other_threads = false;
-  Thread *thread = exe_ctx.GetThreadPtr();
+  Thread *thread = exe_ctx->GetThreadPtr();
   if (sb_frame.GetThread().GetThreadID() != thread->GetID()) {
     error = Status::FromErrorString("passed a frame from another thread");
     return;
@@ -717,7 +726,7 @@ void SBThread::StepOutOfFrame(SBFrame &sb_frame, SBError &error) {
       eVoteNoOpinion, frame_sp->GetFrameIndex(), new_plan_status));
 
   if (new_plan_status.Success())
-    error = ResumeNewPlan(exe_ctx, new_plan_sp.get(), std::move(stop_locker));
+    error = ResumeNewPlan(std::move(*exe_ctx), new_plan_sp.get());
   else
     error = Status::FromErrorString(new_plan_status.AsCString());
 }
@@ -732,24 +741,25 @@ void SBThread::StepInstruction(bool step_over) {
 void SBThread::StepInstruction(bool step_over, SBError &error) {
   LLDB_INSTRUMENT_VA(this, step_over, error);
 
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker, &error.ref());
-  if (!stop_locker.IsLocked())
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (!exe_ctx) {
+    error = Status::FromError(exe_ctx.takeError());
     return;
+  }
 
-  if (!exe_ctx.HasThreadScope()) {
+  if (!exe_ctx->HasThreadScope()) {
     error = Status::FromErrorString("this SBThread object is invalid");
     return;
   }
 
-  Thread *thread = exe_ctx.GetThreadPtr();
+  Thread *thread = exe_ctx->GetThreadPtr();
   Status new_plan_status;
   ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepSingleInstruction(
       step_over, false, true, new_plan_status));
 
   if (new_plan_status.Success())
-    error = ResumeNewPlan(exe_ctx, new_plan_sp.get(), std::move(stop_locker));
+    error = ResumeNewPlan(std::move(*exe_ctx), new_plan_sp.get());
   else
     error = Status::FromErrorString(new_plan_status.AsCString());
 }
@@ -764,13 +774,14 @@ void SBThread::RunToAddress(lldb::addr_t addr) {
 void SBThread::RunToAddress(lldb::addr_t addr, SBError &error) {
   LLDB_INSTRUMENT_VA(this, addr, error);
 
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker, &error.ref());
-  if (!stop_locker.IsLocked())
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (!exe_ctx) {
+    error = Status::FromError(exe_ctx.takeError());
     return;
+  }
 
-  if (!exe_ctx.HasThreadScope()) {
+  if (!exe_ctx->HasThreadScope()) {
     error = Status::FromErrorString("this SBThread object is invalid");
     return;
   }
@@ -780,14 +791,14 @@ void SBThread::RunToAddress(lldb::addr_t addr, SBError &error) {
 
   Address target_addr(addr);
 
-  Thread *thread = exe_ctx.GetThreadPtr();
+  Thread *thread = exe_ctx->GetThreadPtr();
 
   Status new_plan_status;
   ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForRunToAddress(
       abort_other_plans, target_addr, stop_other_threads, new_plan_status));
 
   if (new_plan_status.Success())
-    error = ResumeNewPlan(exe_ctx, new_plan_sp.get(), std::move(stop_locker));
+    error = ResumeNewPlan(std::move(*exe_ctx), new_plan_sp.get());
   else
     error = Status::FromErrorString(new_plan_status.AsCString());
 }
@@ -799,18 +810,16 @@ SBError SBThread::StepOverUntil(lldb::SBFrame &sb_frame,
   SBError sb_error;
   char path[PATH_MAX];
 
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker,
-                           &sb_error.ref());
-  if (!stop_locker.IsLocked())
-    return sb_error;
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (!exe_ctx)
+    return Status::FromError(exe_ctx.takeError());
 
   StackFrameSP frame_sp(sb_frame.GetFrameSP());
 
-  if (exe_ctx.HasThreadScope()) {
-    Target *target = exe_ctx.GetTargetPtr();
-    Thread *thread = exe_ctx.GetThreadPtr();
+  if (exe_ctx->HasThreadScope()) {
+    Target *target = exe_ctx->GetTargetPtr();
+    Thread *thread = exe_ctx->GetThreadPtr();
 
     if (line == 0) {
       sb_error = Status::FromErrorString("invalid line argument");
@@ -905,8 +914,7 @@ SBError SBThread::StepOverUntil(lldb::SBFrame &sb_frame,
           frame_sp->GetFrameIndex(), new_plan_status));
 
       if (new_plan_status.Success())
-        sb_error =
-            ResumeNewPlan(exe_ctx, new_plan_sp.get(), std::move(stop_locker));
+        sb_error = ResumeNewPlan(std::move(*exe_ctx), new_plan_sp.get());
       else
         sb_error = Status::FromErrorString(new_plan_status.AsCString());
     }
@@ -938,18 +946,17 @@ SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name,
 
   SBError error;
 
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker, &error.ref());
-  if (!stop_locker.IsLocked())
-    return error;
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (!exe_ctx)
+    return Status::FromError(exe_ctx.takeError());
 
-  if (!exe_ctx.HasThreadScope()) {
+  if (!exe_ctx->HasThreadScope()) {
     error = Status::FromErrorString("this SBThread object is invalid");
     return error;
   }
 
-  Thread *thread = exe_ctx.GetThreadPtr();
+  Thread *thread = exe_ctx->GetThreadPtr();
   Status new_plan_status;
   StructuredData::ObjectSP obj_sp = args_data.m_impl_up->GetObjectSP();
 
@@ -965,7 +972,7 @@ SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name,
     return error;
 
   if (new_plan_status.Success())
-    error = ResumeNewPlan(exe_ctx, new_plan_sp.get(), std::move(stop_locker));
+    error = ResumeNewPlan(std::move(*exe_ctx), new_plan_sp.get());
   else
     error = Status::FromErrorString(new_plan_status.AsCString());
 
@@ -977,19 +984,17 @@ SBError SBThread::JumpToLine(lldb::SBFileSpec &file_spec, uint32_t line) {
 
   SBError sb_error;
 
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker,
-                           &sb_error.ref());
-  if (!stop_locker.IsLocked())
-    return sb_error;
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (!exe_ctx)
+    return Status::FromError(exe_ctx.takeError());
 
-  if (!exe_ctx.HasThreadScope()) {
+  if (!exe_ctx->HasThreadScope()) {
     sb_error = Status::FromErrorString("this SBThread object is invalid");
     return sb_error;
   }
 
-  Thread *thread = exe_ctx.GetThreadPtr();
+  Thread *thread = exe_ctx->GetThreadPtr();
 
   Status err = thread->JumpToLine(file_spec.ref(), line, true);
   sb_error.SetError(std::move(err));
@@ -1001,15 +1006,13 @@ SBError SBThread::ReturnFromFrame(SBFrame &frame, SBValue &return_value) {
 
   SBError sb_error;
 
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker,
-                           &sb_error.ref());
-  if (!stop_locker.IsLocked())
-    return sb_error;
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (!exe_ctx)
+    return Status::FromError(exe_ctx.takeError());
 
-  if (exe_ctx.HasThreadScope()) {
-    Thread *thread = exe_ctx.GetThreadPtr();
+  if (exe_ctx->HasThreadScope()) {
+    Thread *thread = exe_ctx->GetThreadPtr();
     sb_error.SetError(
         thread->ReturnFromFrame(frame.GetFrameSP(), return_value.GetSP()));
   }
@@ -1022,15 +1025,13 @@ SBError SBThread::UnwindInnermostExpression() {
 
   SBError sb_error;
 
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker,
-                           &sb_error.ref());
-  if (!stop_locker.IsLocked())
-    return sb_error;
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (!exe_ctx)
+    return Status::FromError(exe_ctx.takeError());
 
-  if (exe_ctx.HasThreadScope()) {
-    Thread *thread = exe_ctx.GetThreadPtr();
+  if (exe_ctx->HasThreadScope()) {
+    Thread *thread = exe_ctx->GetThreadPtr();
     sb_error.SetError(thread->UnwindInnermostExpression());
     if (sb_error.Success())
       thread->SetSelectedFrameByIndex(0, false);
@@ -1049,17 +1050,16 @@ bool SBThread::Suspend() {
 bool SBThread::Suspend(SBError &error) {
   LLDB_INSTRUMENT_VA(this, error);
 
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker, &error.ref());
-  if (!stop_locker.IsLocked()) {
-    error = Status::FromErrorString("process is running");
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (!exe_ctx) {
+    error = Status::FromError(exe_ctx.takeError());
     return false;
   }
 
   bool result = false;
-  if (exe_ctx.HasThreadScope()) {
-    exe_ctx.GetThreadPtr()->SetResumeState(eStateSuspended);
+  if (exe_ctx->HasThreadScope()) {
+    exe_ctx->GetThreadPtr()->SetResumeState(eStateSuspended);
     result = true;
   } else
     error = Status::FromErrorString("this SBThread object is invalid");
@@ -1076,18 +1076,18 @@ bool SBThread::Resume() {
 bool SBThread::Resume(SBError &error) {
   LLDB_INSTRUMENT_VA(this, error);
 
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker, &error.ref());
-  if (!stop_locker.IsLocked()) {
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (!exe_ctx) {
+    llvm::consumeError(exe_ctx.takeError());
     error = Status::FromErrorString("process is running");
     return false;
   }
 
   bool result = false;
-  if (exe_ctx.HasThreadScope()) {
+  if (exe_ctx->HasThreadScope()) {
     const bool override_suspend = true;
-    exe_ctx.GetThreadPtr()->SetResumeState(eStateRunning, override_suspend);
+    exe_ctx->GetThreadPtr()->SetResumeState(eStateRunning, override_suspend);
     result = true;
   } else
     error = Status::FromErrorString("this SBThread object is invalid");
@@ -1097,28 +1097,30 @@ bool SBThread::Resume(SBError &error) {
 bool SBThread::IsSuspended() {
   LLDB_INSTRUMENT_VA(this);
 
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
-  if (!stop_locker.IsLocked())
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (!exe_ctx) {
+    llvm::consumeError(exe_ctx.takeError());
     return false;
+  }
 
-  if (exe_ctx.HasThreadScope())
-    return exe_ctx.GetThreadPtr()->GetResumeState() == eStateSuspended;
+  if (exe_ctx->HasThreadScope())
+    return exe_ctx->GetThreadPtr()->GetResumeState() == eStateSuspended;
   return false;
 }
 
 bool SBThread::IsStopped() {
   LLDB_INSTRUMENT_VA(this);
 
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
-  if (!stop_locker.IsLocked())
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (!exe_ctx) {
+    llvm::consumeError(exe_ctx.takeError());
     return false;
+  }
 
-  if (exe_ctx.HasThreadScope())
-    return StateIsStoppedState(exe_ctx.GetThreadPtr()->GetState(), true);
+  if (exe_ctx->HasThreadScope())
+    return StateIsStoppedState(exe_ctx->GetThreadPtr()->GetState(), true);
   return false;
 }
 
@@ -1126,16 +1128,17 @@ SBProcess SBThread::GetProcess() {
   LLDB_INSTRUMENT_VA(this);
 
   SBProcess sb_process;
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
-  if (!stop_locker.IsLocked())
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (!exe_ctx) {
+    llvm::consumeError(exe_ctx.takeError());
     return SBProcess();
+  }
 
-  if (exe_ctx.HasThreadScope()) {
+  if (exe_ctx->HasThreadScope()) {
     // Have to go up to the target so we can get a shared pointer to our
     // process...
-    sb_process.SetSP(exe_ctx.GetProcessSP());
+    sb_process.SetSP(exe_ctx->GetProcessSP());
   }
 
   return sb_process;
@@ -1144,33 +1147,32 @@ SBProcess SBThread::GetProcess() {
 uint32_t SBThread::GetNumFrames() {
   LLDB_INSTRUMENT_VA(this);
 
-  uint32_t num_frames = 0;
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
-  if (!stop_locker.IsLocked())
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (!exe_ctx) {
+    llvm::consumeError(exe_ctx.takeError());
     return 0;
-
-  if (exe_ctx.HasThreadScope()) {
-    num_frames = exe_ctx.GetThreadPtr()->GetStackFrameCount();
   }
 
-  return num_frames;
+  if (exe_ctx->HasThreadScope())
+    return exe_ctx->GetThreadPtr()->GetStackFrameCount();
+
+  return 0;
 }
 
 SBFrame SBThread::GetFrameAtIndex(uint32_t idx) {
   LLDB_INSTRUMENT_VA(this, idx);
 
   SBFrame sb_frame;
-  StackFrameSP frame_sp;
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
-  if (!stop_locker.IsLocked())
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (!exe_ctx) {
+    llvm::consumeError(exe_ctx.takeError());
     return SBFrame();
+  }
 
-  if (exe_ctx.HasThreadScope()) {
-    frame_sp = exe_ctx.GetThreadPtr()->GetStackFrameAtIndex(idx);
+  if (exe_ctx->HasThreadScope()) {
+    StackFrameSP frame_sp = exe_ctx->GetThreadPtr()->GetStackFrameAtIndex(idx);
     sb_frame.SetFrameSP(frame_sp);
   }
 
@@ -1181,16 +1183,16 @@ lldb::SBFrame SBThread::GetSelectedFrame() {
   LLDB_INSTRUMENT_VA(this);
 
   SBFrame sb_frame;
-  StackFrameSP frame_sp;
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
-  if (!stop_locker.IsLocked())
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (!exe_ctx) {
+    llvm::consumeError(exe_ctx.takeError());
     return SBFrame();
+  }
 
-  if (exe_ctx.HasThreadScope()) {
-    frame_sp =
-        exe_ctx.GetThreadPtr()->GetSelectedFrame(SelectMostRelevantFrame);
+  if (exe_ctx->HasThreadScope()) {
+    StackFrameSP frame_sp =
+        exe_ctx->GetThreadPtr()->GetSelectedFrame(SelectMostRelevantFrame);
     sb_frame.SetFrameSP(frame_sp);
   }
 
@@ -1202,14 +1204,15 @@ lldb::SBFrame SBThread::SetSelectedFrame(uint32_t idx) {
 
   SBFrame sb_frame;
   StackFrameSP frame_sp;
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
-  if (!stop_locker.IsLocked())
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (!exe_ctx) {
+    llvm::consumeError(exe_ctx.takeError());
     return SBFrame();
+  }
 
-  if (exe_ctx.HasThreadScope()) {
-    Thread *thread = exe_ctx.GetThreadPtr();
+  if (exe_ctx->HasThreadScope()) {
+    Thread *thread = exe_ctx->GetThreadPtr();
     frame_sp = thread->GetStackFrameAtIndex(idx);
     if (frame_sp) {
       thread->SetSelectedFrame(frame_sp.get());
@@ -1257,15 +1260,16 @@ bool SBThread::GetStatus(SBStream &status) const {
 
   Stream &strm = status.ref();
 
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
-  if (!stop_locker.IsLocked())
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (!exe_ctx) {
+    llvm::consumeError(exe_ctx.takeError());
     return false;
+  }
 
-  if (exe_ctx.HasThreadScope()) {
-    exe_ctx.GetThreadPtr()->GetStatus(strm, 0, 1, 1, true,
-                                      /*show_hidden=*/true);
+  if (exe_ctx->HasThreadScope()) {
+    exe_ctx->GetThreadPtr()->GetStatus(strm, 0, 1, 1, true,
+                                       /*show_hidden=*/true);
   } else
     strm.PutCString("No status");
 
@@ -1283,14 +1287,15 @@ bool SBThread::GetDescription(SBStream &description, bool stop_format) const {
 
   Stream &strm = description.ref();
 
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
-  if (!stop_locker.IsLocked())
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (!exe_ctx) {
+    llvm::consumeError(exe_ctx.takeError());
     return false;
+  }
 
-  if (exe_ctx.HasThreadScope()) {
-    exe_ctx.GetThreadPtr()->DumpUsingSettingsFormat(
+  if (exe_ctx->HasThreadScope()) {
+    exe_ctx->GetThreadPtr()->DumpUsingSettingsFormat(
         strm, LLDB_INVALID_THREAD_ID, stop_format);
   } else
     strm.PutCString("No value");
@@ -1308,14 +1313,15 @@ SBError SBThread::GetDescriptionWithFormat(const SBFormat &format,
     return error;
   }
 
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
-  if (!stop_locker.IsLocked())
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
+  if (!exe_ctx) {
+    llvm::consumeError(exe_ctx.takeError());
     return error;
+  }
 
-  if (exe_ctx.HasThreadScope()) {
-    if (exe_ctx.GetThreadPtr()->DumpUsingFormat(
+  if (exe_ctx->HasThreadScope()) {
+    if (exe_ctx->GetThreadPtr()->DumpUsingFormat(
             strm, LLDB_INVALID_THREAD_ID, format.GetFormatEntrySP().get())) {
       return error;
     }
@@ -1331,16 +1337,15 @@ SBError SBThread::GetDescriptionWithFormat(const SBFormat &format,
 SBThread SBThread::GetExtendedBacktraceThread(const char *type) {
   LLDB_INSTRUMENT_VA(this, type);
 
-  std::unique_lock<std::recursive_mutex> lock;
-  Process::StopLocker stop_locker;
-  ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker);
+  llvm::Expected<CompleteExecutionContext> exe_ctx =
+      GetCompleteExecutionContext(m_opaque_sp);
   SBThread sb_origin_thread;
-  if (stop_locker.IsLocked()) {
-    if (exe_ctx.HasThreadScope()) {
-      ThreadSP real_thread(exe_ctx.GetThreadSP());
+  if (exe_ctx) {
+    if (exe_ctx->HasThreadScope()) {
+      ThreadSP real_thread(exe_ctx->GetThreadSP());
       if (real_thread) {
         ConstString type_const(type);
-        Process *process = exe_ctx.GetProcessPtr();
+        Process *process = exe_ctx->GetProcessPtr();
         if (process) {
           SystemRuntime *runtime = process->GetSystemRuntime();
           if (runtime) {
@@ -1356,6 +1361,8 @@ SBThread SBThread::GetExtendedBacktraceThread(const char *type) {
         }
       }
     }
+  } else {
+    llvm::consumeError(exe_ctx.takeError());
   }
 
   return sb_origin_thread;
diff --git a/lldb/source/Target/ExecutionContext.cpp b/lldb/source/Target/ExecutionContext.cpp
index bc9540314d03f..c56d3c949f56b 100644
--- a/lldb/source/Target/ExecutionContext.cpp
+++ b/lldb/source/Target/ExecutionContext.cpp
@@ -14,6 +14,7 @@
 #include "lldb/Target/Thread.h"
 #include "lldb/Utility/LLDBLog.h"
 #include "lldb/Utility/State.h"
+#include <mutex>
 
 using namespace lldb_private;
 
@@ -126,43 +127,51 @@ ExecutionContext::ExecutionContext(const ExecutionContextRef *exe_ctx_ref_ptr,
   }
 }
 
-ExecutionContext::ExecutionContext(
-    const ExecutionContextRef *exe_ctx_ref_ptr,
-    std::unique_lock<std::recursive_mutex> &api_lock,
-    ProcessRunLock::ProcessRunLocker &stop_locker, Status *status)
-    : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
-  auto set_status = [&](const char *msg) {
-    if (status)
-      *status = Status::FromErrorString(msg);
-  };
-
-  if (!exe_ctx_ref_ptr) {
-    set_status("ExecutionContext created with an empty ExecutionContextRef");
-    return;
-  }
+llvm::Expected<CompleteExecutionContext>
+lldb_private::GetCompleteExecutionContext(
+    const lldb::ExecutionContextRefSP &exe_ctx_ref_ptr) {
+  return GetCompleteExecutionContext(exe_ctx_ref_ptr.get());
+}
 
-  m_target_sp = exe_ctx_ref_ptr->GetTargetSP();
-  if (!m_target_sp) {
-    set_status("ExecutionContext created with a null target");
-    return;
-  }
+llvm::Expected<CompleteExecutionContext>
+lldb_private::GetCompleteExecutionContext(
+    const ExecutionContextRef *exe_ctx_ref_ptr) {
+  if (!exe_ctx_ref_ptr)
+    return llvm::createStringError(
+        "ExecutionContext created with an empty ExecutionContextRef");
 
-  api_lock = std::unique_lock<std::recursive_mutex>(m_target_sp->GetAPIMutex());
-  m_process_sp = exe_ctx_ref_ptr->GetProcessSP();
-  if (!m_process_sp) {
-    set_status("ExecutionContext created with a null process");
-    return;
-  }
+  lldb::TargetSP target_sp = exe_ctx_ref_ptr->GetTargetSP();
+  if (!target_sp)
+    return llvm::createStringError(
+        "ExecutionContext created with a null target");
 
-  if (!stop_locker.TryLock(&m_process_sp->GetRunLock())) {
-    const char *msg = "ExecutionContext created with a running process";
-    set_status(msg);
-    LLDB_LOG(GetLog(LLDBLog::API), msg);
-    return;
+  auto api_lock =
+      std::unique_lock<std::recursive_mutex>(target_sp->GetAPIMutex());
+
+  auto process_sp = exe_ctx_ref_ptr->GetProcessSP();
+  if (!process_sp)
+    return llvm::createStringError(
+        "ExecutionContext created with a null process");
+
+  ProcessRunLock::ProcessRunLocker stop_locker;
+  if (!stop_locker.TryLock(&process_sp->GetRunLock())) {
+    auto *error_msg =
+        "Attempted to create an ExecutionContext with a running process";
+    LLDB_LOG(GetLog(LLDBLog::API), error_msg);
+    return llvm::createStringError(error_msg);
   }
 
-  m_thread_sp = exe_ctx_ref_ptr->GetThreadSP();
-  m_frame_sp = exe_ctx_ref_ptr->GetFrameSP();
+  auto thread_sp = exe_ctx_ref_ptr->GetThreadSP();
+  auto frame_sp = exe_ctx_ref_ptr->GetFrameSP();
+  return CompleteExecutionContext(target_sp, process_sp, thread_sp, frame_sp,
+                                  std::move(api_lock), std::move(stop_locker));
+}
+
+std::unique_lock<std::recursive_mutex>
+CompleteExecutionContext::ClearAndGetAPILock() {
+  Clear();
+  m_stop_locker = ProcessRunLock::ProcessRunLocker();
+  return std::move(m_api_lock);
 }
 
 ExecutionContext::ExecutionContext(ExecutionContextScope *exe_scope_ptr)

>From ef8362bcdc17a3b34b58aa79cc04b9f2902ce9ca Mon Sep 17 00:00:00 2001
From: Felipe de Azevedo Piovezan <fpiovezan at apple.com>
Date: Fri, 8 Aug 2025 10:28:39 -0700
Subject: [PATCH 5/6] fixup! Rename CompleteExecutionContext ->
 StoppedExecutionContext

---
 lldb/include/lldb/Target/ExecutionContext.h |  34 ++--
 lldb/source/API/SBFrame.cpp                 | 168 ++++++++++----------
 lldb/source/API/SBThread.cpp                | 150 ++++++++---------
 lldb/source/Target/ExecutionContext.cpp     |  16 +-
 4 files changed, 184 insertions(+), 184 deletions(-)

diff --git a/lldb/include/lldb/Target/ExecutionContext.h b/lldb/include/lldb/Target/ExecutionContext.h
index f7e0b7c5e4d63..d79ab8a3910b1 100644
--- a/lldb/include/lldb/Target/ExecutionContext.h
+++ b/lldb/include/lldb/Target/ExecutionContext.h
@@ -562,14 +562,14 @@ class ExecutionContext {
 /// A wrapper class representing an execution context with non-null Target
 /// and Process pointers, a locked API mutex and a locked ProcessRunLock.
 /// The locks are private by design: to unlock them, destroy the
-/// CompleteExecutionContext.
-struct CompleteExecutionContext : ExecutionContext {
-  CompleteExecutionContext(lldb::TargetSP &target_sp,
-                           lldb::ProcessSP &process_sp,
-                           lldb::ThreadSP &thread_sp,
-                           lldb::StackFrameSP &frame_sp,
-                           std::unique_lock<std::recursive_mutex> api_lock,
-                           ProcessRunLock::ProcessRunLocker stop_locker)
+/// StoppedExecutionContext.
+struct StoppedExecutionContext : ExecutionContext {
+  StoppedExecutionContext(lldb::TargetSP &target_sp,
+                          lldb::ProcessSP &process_sp,
+                          lldb::ThreadSP &thread_sp,
+                          lldb::StackFrameSP &frame_sp,
+                          std::unique_lock<std::recursive_mutex> api_lock,
+                          ProcessRunLock::ProcessRunLocker stop_locker)
       : m_api_lock(std::move(api_lock)), m_stop_locker(std::move(stop_locker)) {
     assert(target_sp);
     assert(process_sp);
@@ -583,11 +583,11 @@ struct CompleteExecutionContext : ExecutionContext {
 
   /// Transfers ownership of the locks from `other` to `this`, making `other`
   /// unusable.
-  CompleteExecutionContext(CompleteExecutionContext &&other)
-      : CompleteExecutionContext(other.m_target_sp, other.m_process_sp,
-                                 other.m_thread_sp, other.m_frame_sp,
-                                 std::move(other.m_api_lock),
-                                 std::move(other.m_stop_locker)) {
+  StoppedExecutionContext(StoppedExecutionContext &&other)
+      : StoppedExecutionContext(other.m_target_sp, other.m_process_sp,
+                                other.m_thread_sp, other.m_frame_sp,
+                                std::move(other.m_api_lock),
+                                std::move(other.m_stop_locker)) {
     other.Clear();
   }
 
@@ -601,10 +601,10 @@ struct CompleteExecutionContext : ExecutionContext {
   ProcessRunLock::ProcessRunLocker m_stop_locker;
 };
 
-llvm::Expected<CompleteExecutionContext>
-GetCompleteExecutionContext(const ExecutionContextRef *exe_ctx_ref_ptr);
-llvm::Expected<CompleteExecutionContext>
-GetCompleteExecutionContext(const lldb::ExecutionContextRefSP &exe_ctx_ref_ptr);
+llvm::Expected<StoppedExecutionContext>
+GetStoppedExecutionContext(const ExecutionContextRef *exe_ctx_ref_ptr);
+llvm::Expected<StoppedExecutionContext>
+GetStoppedExecutionContext(const lldb::ExecutionContextRefSP &exe_ctx_ref_ptr);
 
 } // namespace lldb_private
 
diff --git a/lldb/source/API/SBFrame.cpp b/lldb/source/API/SBFrame.cpp
index 2af8b0be5c0a5..f4dcab704e948 100644
--- a/lldb/source/API/SBFrame.cpp
+++ b/lldb/source/API/SBFrame.cpp
@@ -97,8 +97,8 @@ bool SBFrame::IsValid() const {
 }
 SBFrame::operator bool() const {
   LLDB_INSTRUMENT_VA(this);
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
     llvm::consumeError(exe_ctx.takeError());
     return false;
@@ -112,8 +112,8 @@ SBSymbolContext SBFrame::GetSymbolContext(uint32_t resolve_scope) const {
 
   SBSymbolContext sb_sym_ctx;
 
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
     llvm::consumeError(exe_ctx.takeError());
     return sb_sym_ctx;
@@ -129,8 +129,8 @@ SBSymbolContext SBFrame::GetSymbolContext(uint32_t resolve_scope) const {
 SBModule SBFrame::GetModule() const {
   LLDB_INSTRUMENT_VA(this);
 
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
     llvm::consumeError(exe_ctx.takeError());
     return SBModule();
@@ -150,8 +150,8 @@ SBModule SBFrame::GetModule() const {
 SBCompileUnit SBFrame::GetCompileUnit() const {
   LLDB_INSTRUMENT_VA(this);
 
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
     llvm::consumeError(exe_ctx.takeError());
     return SBCompileUnit();
@@ -166,8 +166,8 @@ SBCompileUnit SBFrame::GetCompileUnit() const {
 SBFunction SBFrame::GetFunction() const {
   LLDB_INSTRUMENT_VA(this);
 
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
     llvm::consumeError(exe_ctx.takeError());
     return SBFunction();
@@ -181,8 +181,8 @@ SBFunction SBFrame::GetFunction() const {
 SBSymbol SBFrame::GetSymbol() const {
   LLDB_INSTRUMENT_VA(this);
 
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
     llvm::consumeError(exe_ctx.takeError());
     return SBSymbol();
@@ -196,8 +196,8 @@ SBSymbol SBFrame::GetSymbol() const {
 SBBlock SBFrame::GetBlock() const {
   LLDB_INSTRUMENT_VA(this);
 
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
     llvm::consumeError(exe_ctx.takeError());
     return SBBlock();
@@ -211,8 +211,8 @@ SBBlock SBFrame::GetBlock() const {
 SBBlock SBFrame::GetFrameBlock() const {
   LLDB_INSTRUMENT_VA(this);
 
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
     llvm::consumeError(exe_ctx.takeError());
     return SBBlock();
@@ -226,8 +226,8 @@ SBBlock SBFrame::GetFrameBlock() const {
 SBLineEntry SBFrame::GetLineEntry() const {
   LLDB_INSTRUMENT_VA(this);
 
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
     llvm::consumeError(exe_ctx.takeError());
     return SBLineEntry();
@@ -244,8 +244,8 @@ uint32_t SBFrame::GetFrameID() const {
 
   constexpr uint32_t error_frame_idx = UINT32_MAX;
 
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
     llvm::consumeError(exe_ctx.takeError());
     return error_frame_idx;
@@ -259,8 +259,8 @@ uint32_t SBFrame::GetFrameID() const {
 lldb::addr_t SBFrame::GetCFA() const {
   LLDB_INSTRUMENT_VA(this);
 
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
     llvm::consumeError(exe_ctx.takeError());
     return LLDB_INVALID_ADDRESS;
@@ -275,8 +275,8 @@ addr_t SBFrame::GetPC() const {
   LLDB_INSTRUMENT_VA(this);
 
   addr_t addr = LLDB_INVALID_ADDRESS;
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
     llvm::consumeError(exe_ctx.takeError());
     return addr;
@@ -294,8 +294,8 @@ bool SBFrame::SetPC(addr_t new_pc) {
   LLDB_INSTRUMENT_VA(this, new_pc);
 
   constexpr bool error_ret_val = false;
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
     llvm::consumeError(exe_ctx.takeError());
     return error_ret_val;
@@ -311,8 +311,8 @@ bool SBFrame::SetPC(addr_t new_pc) {
 addr_t SBFrame::GetSP() const {
   LLDB_INSTRUMENT_VA(this);
 
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
     llvm::consumeError(exe_ctx.takeError());
     return LLDB_INVALID_ADDRESS;
@@ -328,8 +328,8 @@ addr_t SBFrame::GetSP() const {
 addr_t SBFrame::GetFP() const {
   LLDB_INSTRUMENT_VA(this);
 
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
     llvm::consumeError(exe_ctx.takeError());
     return LLDB_INVALID_ADDRESS;
@@ -345,8 +345,8 @@ addr_t SBFrame::GetFP() const {
 SBAddress SBFrame::GetPCAddress() const {
   LLDB_INSTRUMENT_VA(this);
 
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
     llvm::consumeError(exe_ctx.takeError());
     return SBAddress();
@@ -367,8 +367,8 @@ lldb::SBValue SBFrame::GetValueForVariablePath(const char *var_path) {
   LLDB_INSTRUMENT_VA(this, var_path);
 
   SBValue sb_value;
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
     llvm::consumeError(exe_ctx.takeError());
     return sb_value;
@@ -391,8 +391,8 @@ lldb::SBValue SBFrame::GetValueForVariablePath(const char *var_path,
     return sb_value;
   }
 
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
     llvm::consumeError(exe_ctx.takeError());
     return sb_value;
@@ -414,8 +414,8 @@ lldb::SBValue SBFrame::GetValueForVariablePath(const char *var_path,
 SBValue SBFrame::FindVariable(const char *name) {
   LLDB_INSTRUMENT_VA(this, name);
 
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
     llvm::consumeError(exe_ctx.takeError());
     return SBValue();
@@ -440,8 +440,8 @@ SBValue SBFrame::FindVariable(const char *name,
     return sb_value;
   }
 
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
     llvm::consumeError(exe_ctx.takeError());
     return sb_value;
@@ -458,8 +458,8 @@ SBValue SBFrame::FindValue(const char *name, ValueType value_type) {
   LLDB_INSTRUMENT_VA(this, name, value_type);
 
   SBValue value;
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
     llvm::consumeError(exe_ctx.takeError());
     return value;
@@ -484,8 +484,8 @@ SBValue SBFrame::FindValue(const char *name, ValueType value_type,
   }
 
   ValueObjectSP value_sp;
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
 
   if (!exe_ctx) {
     llvm::consumeError(exe_ctx.takeError());
@@ -611,8 +611,8 @@ bool SBFrame::operator!=(const SBFrame &rhs) const {
 SBThread SBFrame::GetThread() const {
   LLDB_INSTRUMENT_VA(this);
 
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
     llvm::consumeError(exe_ctx.takeError());
     return SBThread();
@@ -627,8 +627,8 @@ SBThread SBFrame::GetThread() const {
 const char *SBFrame::Disassemble() const {
   LLDB_INSTRUMENT_VA(this);
 
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
     llvm::consumeError(exe_ctx.takeError());
     return nullptr;
@@ -645,8 +645,8 @@ SBValueList SBFrame::GetVariables(bool arguments, bool locals, bool statics,
   LLDB_INSTRUMENT_VA(this, arguments, locals, statics, in_scope_only);
 
   SBValueList value_list;
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
     llvm::consumeError(exe_ctx.takeError());
     return value_list;
@@ -678,8 +678,8 @@ lldb::SBValueList SBFrame::GetVariables(bool arguments, bool locals,
   LLDB_INSTRUMENT_VA(this, arguments, locals, statics, in_scope_only,
                      use_dynamic);
 
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
     llvm::consumeError(exe_ctx.takeError());
     return SBValueList();
@@ -702,8 +702,8 @@ SBValueList SBFrame::GetVariables(const lldb::SBVariablesOptions &options) {
   LLDB_INSTRUMENT_VA(this, options);
 
   SBValueList value_list;
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
     llvm::consumeError(exe_ctx.takeError());
     return SBValueList();
@@ -809,8 +809,8 @@ SBValueList SBFrame::GetRegisters() {
   LLDB_INSTRUMENT_VA(this);
 
   SBValueList value_list;
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
     llvm::consumeError(exe_ctx.takeError());
     return SBValueList();
@@ -839,8 +839,8 @@ SBValue SBFrame::FindRegister(const char *name) {
 
   SBValue result;
   ValueObjectSP value_sp;
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
     llvm::consumeError(exe_ctx.takeError());
     return SBValue();
@@ -868,8 +868,8 @@ SBError SBFrame::GetDescriptionWithFormat(const SBFormat &format,
                                           SBStream &output) {
   Stream &strm = output.ref();
 
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx)
     return Status::FromError(exe_ctx.takeError());
 
@@ -895,8 +895,8 @@ bool SBFrame::GetDescription(SBStream &description) {
 
   Stream &strm = description.ref();
 
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
     llvm::consumeError(exe_ctx.takeError());
     strm.PutCString("Error: process is not stopped.");
@@ -912,8 +912,8 @@ bool SBFrame::GetDescription(SBStream &description) {
 SBValue SBFrame::EvaluateExpression(const char *expr) {
   LLDB_INSTRUMENT_VA(this, expr);
 
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
     llvm::consumeError(exe_ctx.takeError());
     return CreateProcessIsRunningExprEvalError();
@@ -945,8 +945,8 @@ SBFrame::EvaluateExpression(const char *expr,
   options.SetFetchDynamicValue(fetch_dynamic_value);
   options.SetUnwindOnError(true);
   options.SetIgnoreBreakpoints(true);
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
     llvm::consumeError(exe_ctx.takeError());
     return CreateProcessIsRunningExprEvalError();
@@ -967,8 +967,8 @@ SBValue SBFrame::EvaluateExpression(const char *expr,
   LLDB_INSTRUMENT_VA(this, expr, fetch_dynamic_value, unwind_on_error);
 
   SBExpressionOptions options;
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
     llvm::consumeError(exe_ctx.takeError());
     return CreateProcessIsRunningExprEvalError();
@@ -1010,8 +1010,8 @@ lldb::SBValue SBFrame::EvaluateExpression(const char *expr,
 
   ValueObjectSP expr_value_sp;
 
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
     llvm::consumeError(exe_ctx.takeError());
     expr_result = CreateProcessIsRunningExprEvalError();
@@ -1060,8 +1060,8 @@ SBStructuredData SBFrame::GetLanguageSpecificData() const {
   LLDB_INSTRUMENT_VA(this);
 
   SBStructuredData sb_data;
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
     llvm::consumeError(exe_ctx.takeError());
     return sb_data;
@@ -1084,8 +1084,8 @@ bool SBFrame::IsInlined() {
 bool SBFrame::IsInlined() const {
   LLDB_INSTRUMENT_VA(this);
 
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
     llvm::consumeError(exe_ctx.takeError());
     return false;
@@ -1105,8 +1105,8 @@ bool SBFrame::IsArtificial() {
 bool SBFrame::IsArtificial() const {
   LLDB_INSTRUMENT_VA(this);
 
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
     llvm::consumeError(exe_ctx.takeError());
     return false;
@@ -1121,8 +1121,8 @@ bool SBFrame::IsArtificial() const {
 bool SBFrame::IsHidden() const {
   LLDB_INSTRUMENT_VA(this);
 
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
     llvm::consumeError(exe_ctx.takeError());
     return false;
@@ -1143,8 +1143,8 @@ const char *SBFrame::GetFunctionName() {
 lldb::LanguageType SBFrame::GuessLanguage() const {
   LLDB_INSTRUMENT_VA(this);
 
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
     llvm::consumeError(exe_ctx.takeError());
     return eLanguageTypeUnknown;
@@ -1158,8 +1158,8 @@ lldb::LanguageType SBFrame::GuessLanguage() const {
 const char *SBFrame::GetFunctionName() const {
   LLDB_INSTRUMENT_VA(this);
 
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
     llvm::consumeError(exe_ctx.takeError());
     return nullptr;
@@ -1173,8 +1173,8 @@ const char *SBFrame::GetFunctionName() const {
 const char *SBFrame::GetDisplayFunctionName() {
   LLDB_INSTRUMENT_VA(this);
 
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
     llvm::consumeError(exe_ctx.takeError());
     return nullptr;
diff --git a/lldb/source/API/SBThread.cpp b/lldb/source/API/SBThread.cpp
index bc0d0e9b55ee5..28ef1729f31fe 100644
--- a/lldb/source/API/SBThread.cpp
+++ b/lldb/source/API/SBThread.cpp
@@ -90,8 +90,8 @@ lldb::SBQueue SBThread::GetQueue() const {
 
   SBQueue sb_queue;
   QueueSP queue_sp;
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
     llvm::consumeError(exe_ctx.takeError());
     return SBQueue();
@@ -116,8 +116,8 @@ SBThread::operator bool() const {
   if (!m_opaque_sp)
     return false;
 
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
     llvm::consumeError(exe_ctx.takeError());
     return false;
@@ -136,8 +136,8 @@ StopReason SBThread::GetStopReason() {
   LLDB_INSTRUMENT_VA(this);
 
   StopReason reason = eStopReasonInvalid;
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
     llvm::consumeError(exe_ctx.takeError());
     return reason;
@@ -152,8 +152,8 @@ StopReason SBThread::GetStopReason() {
 size_t SBThread::GetStopReasonDataCount() {
   LLDB_INSTRUMENT_VA(this);
 
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (exe_ctx) {
     if (exe_ctx->HasThreadScope()) {
       StopInfoSP stop_info_sp = exe_ctx->GetThreadPtr()->GetStopInfo();
@@ -214,8 +214,8 @@ size_t SBThread::GetStopReasonDataCount() {
 uint64_t SBThread::GetStopReasonDataAtIndex(uint32_t idx) {
   LLDB_INSTRUMENT_VA(this, idx);
 
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (exe_ctx) {
     if (exe_ctx->HasThreadScope()) {
       Thread *thread = exe_ctx->GetThreadPtr();
@@ -290,8 +290,8 @@ bool SBThread::GetStopReasonExtendedInfoAsJSON(lldb::SBStream &stream) {
 
   Stream &strm = stream.ref();
 
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
     llvm::consumeError(exe_ctx.takeError());
     return false;
@@ -316,8 +316,8 @@ SBThread::GetStopReasonExtendedBacktraces(InstrumentationRuntimeType type) {
 
   SBThreadCollection threads;
 
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
     llvm::consumeError(exe_ctx.takeError());
     return SBThreadCollection();
@@ -344,8 +344,8 @@ size_t SBThread::GetStopDescription(char *dst, size_t dst_len) {
   if (dst)
     *dst = 0;
 
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
     llvm::consumeError(exe_ctx.takeError());
     return 0;
@@ -370,8 +370,8 @@ SBValue SBThread::GetStopReturnValue() {
   LLDB_INSTRUMENT_VA(this);
 
   ValueObjectSP return_valobj_sp;
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
     llvm::consumeError(exe_ctx.takeError());
     return SBValue();
@@ -412,8 +412,8 @@ uint32_t SBThread::GetIndexID() const {
 const char *SBThread::GetName() const {
   LLDB_INSTRUMENT_VA(this);
 
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
     llvm::consumeError(exe_ctx.takeError());
     return nullptr;
@@ -428,8 +428,8 @@ const char *SBThread::GetName() const {
 const char *SBThread::GetQueueName() const {
   LLDB_INSTRUMENT_VA(this);
 
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
     llvm::consumeError(exe_ctx.takeError());
     return nullptr;
@@ -445,8 +445,8 @@ lldb::queue_id_t SBThread::GetQueueID() const {
   LLDB_INSTRUMENT_VA(this);
 
   queue_id_t id = LLDB_INVALID_QUEUE_ID;
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
     llvm::consumeError(exe_ctx.takeError());
     return id;
@@ -463,8 +463,8 @@ bool SBThread::GetInfoItemByPathAsString(const char *path, SBStream &strm) {
   LLDB_INSTRUMENT_VA(this, path, strm);
 
   bool success = false;
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (exe_ctx) {
     if (exe_ctx->HasThreadScope()) {
       Thread *thread = exe_ctx->GetThreadPtr();
@@ -507,7 +507,7 @@ bool SBThread::GetInfoItemByPathAsString(const char *path, SBStream &strm) {
   return success;
 }
 
-static Status ResumeNewPlan(CompleteExecutionContext exe_ctx,
+static Status ResumeNewPlan(StoppedExecutionContext exe_ctx,
                             ThreadPlan *new_plan) {
   Thread *thread = exe_ctx.GetThreadPtr();
   if (!thread)
@@ -542,8 +542,8 @@ void SBThread::StepOver(lldb::RunMode stop_other_threads) {
 void SBThread::StepOver(lldb::RunMode stop_other_threads, SBError &error) {
   LLDB_INSTRUMENT_VA(this, stop_other_threads, error);
 
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
     error = Status::FromError(exe_ctx.takeError());
     return;
@@ -593,8 +593,8 @@ void SBThread::StepInto(const char *target_name, uint32_t end_line,
                         SBError &error, lldb::RunMode stop_other_threads) {
   LLDB_INSTRUMENT_VA(this, target_name, end_line, error, stop_other_threads);
 
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
     error = Status::FromError(exe_ctx.takeError());
     return;
@@ -654,8 +654,8 @@ void SBThread::StepOut() {
 void SBThread::StepOut(SBError &error) {
   LLDB_INSTRUMENT_VA(this, error);
 
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
     error = Status::FromError(exe_ctx.takeError());
     return;
@@ -693,8 +693,8 @@ void SBThread::StepOutOfFrame(SBFrame &sb_frame) {
 void SBThread::StepOutOfFrame(SBFrame &sb_frame, SBError &error) {
   LLDB_INSTRUMENT_VA(this, sb_frame, error);
 
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
     error = Status::FromError(exe_ctx.takeError());
     return;
@@ -741,8 +741,8 @@ void SBThread::StepInstruction(bool step_over) {
 void SBThread::StepInstruction(bool step_over, SBError &error) {
   LLDB_INSTRUMENT_VA(this, step_over, error);
 
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
     error = Status::FromError(exe_ctx.takeError());
     return;
@@ -774,8 +774,8 @@ void SBThread::RunToAddress(lldb::addr_t addr) {
 void SBThread::RunToAddress(lldb::addr_t addr, SBError &error) {
   LLDB_INSTRUMENT_VA(this, addr, error);
 
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
     error = Status::FromError(exe_ctx.takeError());
     return;
@@ -810,8 +810,8 @@ SBError SBThread::StepOverUntil(lldb::SBFrame &sb_frame,
   SBError sb_error;
   char path[PATH_MAX];
 
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx)
     return Status::FromError(exe_ctx.takeError());
 
@@ -946,8 +946,8 @@ SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name,
 
   SBError error;
 
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx)
     return Status::FromError(exe_ctx.takeError());
 
@@ -984,8 +984,8 @@ SBError SBThread::JumpToLine(lldb::SBFileSpec &file_spec, uint32_t line) {
 
   SBError sb_error;
 
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx)
     return Status::FromError(exe_ctx.takeError());
 
@@ -1006,8 +1006,8 @@ SBError SBThread::ReturnFromFrame(SBFrame &frame, SBValue &return_value) {
 
   SBError sb_error;
 
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx)
     return Status::FromError(exe_ctx.takeError());
 
@@ -1025,8 +1025,8 @@ SBError SBThread::UnwindInnermostExpression() {
 
   SBError sb_error;
 
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx)
     return Status::FromError(exe_ctx.takeError());
 
@@ -1050,8 +1050,8 @@ bool SBThread::Suspend() {
 bool SBThread::Suspend(SBError &error) {
   LLDB_INSTRUMENT_VA(this, error);
 
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
     error = Status::FromError(exe_ctx.takeError());
     return false;
@@ -1076,8 +1076,8 @@ bool SBThread::Resume() {
 bool SBThread::Resume(SBError &error) {
   LLDB_INSTRUMENT_VA(this, error);
 
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
     llvm::consumeError(exe_ctx.takeError());
     error = Status::FromErrorString("process is running");
@@ -1097,8 +1097,8 @@ bool SBThread::Resume(SBError &error) {
 bool SBThread::IsSuspended() {
   LLDB_INSTRUMENT_VA(this);
 
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
     llvm::consumeError(exe_ctx.takeError());
     return false;
@@ -1112,8 +1112,8 @@ bool SBThread::IsSuspended() {
 bool SBThread::IsStopped() {
   LLDB_INSTRUMENT_VA(this);
 
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
     llvm::consumeError(exe_ctx.takeError());
     return false;
@@ -1128,8 +1128,8 @@ SBProcess SBThread::GetProcess() {
   LLDB_INSTRUMENT_VA(this);
 
   SBProcess sb_process;
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
     llvm::consumeError(exe_ctx.takeError());
     return SBProcess();
@@ -1147,8 +1147,8 @@ SBProcess SBThread::GetProcess() {
 uint32_t SBThread::GetNumFrames() {
   LLDB_INSTRUMENT_VA(this);
 
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
     llvm::consumeError(exe_ctx.takeError());
     return 0;
@@ -1164,8 +1164,8 @@ SBFrame SBThread::GetFrameAtIndex(uint32_t idx) {
   LLDB_INSTRUMENT_VA(this, idx);
 
   SBFrame sb_frame;
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
     llvm::consumeError(exe_ctx.takeError());
     return SBFrame();
@@ -1183,8 +1183,8 @@ lldb::SBFrame SBThread::GetSelectedFrame() {
   LLDB_INSTRUMENT_VA(this);
 
   SBFrame sb_frame;
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
     llvm::consumeError(exe_ctx.takeError());
     return SBFrame();
@@ -1204,8 +1204,8 @@ lldb::SBFrame SBThread::SetSelectedFrame(uint32_t idx) {
 
   SBFrame sb_frame;
   StackFrameSP frame_sp;
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
     llvm::consumeError(exe_ctx.takeError());
     return SBFrame();
@@ -1260,8 +1260,8 @@ bool SBThread::GetStatus(SBStream &status) const {
 
   Stream &strm = status.ref();
 
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
     llvm::consumeError(exe_ctx.takeError());
     return false;
@@ -1287,8 +1287,8 @@ bool SBThread::GetDescription(SBStream &description, bool stop_format) const {
 
   Stream &strm = description.ref();
 
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
     llvm::consumeError(exe_ctx.takeError());
     return false;
@@ -1313,8 +1313,8 @@ SBError SBThread::GetDescriptionWithFormat(const SBFormat &format,
     return error;
   }
 
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
     llvm::consumeError(exe_ctx.takeError());
     return error;
@@ -1337,8 +1337,8 @@ SBError SBThread::GetDescriptionWithFormat(const SBFormat &format,
 SBThread SBThread::GetExtendedBacktraceThread(const char *type) {
   LLDB_INSTRUMENT_VA(this, type);
 
-  llvm::Expected<CompleteExecutionContext> exe_ctx =
-      GetCompleteExecutionContext(m_opaque_sp);
+  llvm::Expected<StoppedExecutionContext> exe_ctx =
+      GetStoppedExecutionContext(m_opaque_sp);
   SBThread sb_origin_thread;
   if (exe_ctx) {
     if (exe_ctx->HasThreadScope()) {
diff --git a/lldb/source/Target/ExecutionContext.cpp b/lldb/source/Target/ExecutionContext.cpp
index c56d3c949f56b..d2bc4b3cfd99c 100644
--- a/lldb/source/Target/ExecutionContext.cpp
+++ b/lldb/source/Target/ExecutionContext.cpp
@@ -127,14 +127,14 @@ ExecutionContext::ExecutionContext(const ExecutionContextRef *exe_ctx_ref_ptr,
   }
 }
 
-llvm::Expected<CompleteExecutionContext>
-lldb_private::GetCompleteExecutionContext(
+llvm::Expected<StoppedExecutionContext>
+lldb_private::GetStoppedExecutionContext(
     const lldb::ExecutionContextRefSP &exe_ctx_ref_ptr) {
-  return GetCompleteExecutionContext(exe_ctx_ref_ptr.get());
+  return GetStoppedExecutionContext(exe_ctx_ref_ptr.get());
 }
 
-llvm::Expected<CompleteExecutionContext>
-lldb_private::GetCompleteExecutionContext(
+llvm::Expected<StoppedExecutionContext>
+lldb_private::GetStoppedExecutionContext(
     const ExecutionContextRef *exe_ctx_ref_ptr) {
   if (!exe_ctx_ref_ptr)
     return llvm::createStringError(
@@ -163,12 +163,12 @@ lldb_private::GetCompleteExecutionContext(
 
   auto thread_sp = exe_ctx_ref_ptr->GetThreadSP();
   auto frame_sp = exe_ctx_ref_ptr->GetFrameSP();
-  return CompleteExecutionContext(target_sp, process_sp, thread_sp, frame_sp,
-                                  std::move(api_lock), std::move(stop_locker));
+  return StoppedExecutionContext(target_sp, process_sp, thread_sp, frame_sp,
+                                 std::move(api_lock), std::move(stop_locker));
 }
 
 std::unique_lock<std::recursive_mutex>
-CompleteExecutionContext::ClearAndGetAPILock() {
+StoppedExecutionContext::ClearAndGetAPILock() {
   Clear();
   m_stop_locker = ProcessRunLock::ProcessRunLocker();
   return std::move(m_api_lock);

>From 415afe07bd04cf79d09fca6bb8410497f682f6e7 Mon Sep 17 00:00:00 2001
From: Felipe de Azevedo Piovezan <fpiovezan at apple.com>
Date: Fri, 8 Aug 2025 10:46:11 -0700
Subject: [PATCH 6/6] fixup! Move logging to call sites

---
 lldb/source/API/SBThread.cpp            | 50 ++++++++++++-------------
 lldb/source/Target/ExecutionContext.cpp |  9 ++---
 2 files changed, 28 insertions(+), 31 deletions(-)

diff --git a/lldb/source/API/SBThread.cpp b/lldb/source/API/SBThread.cpp
index 28ef1729f31fe..cc69b1ee4286d 100644
--- a/lldb/source/API/SBThread.cpp
+++ b/lldb/source/API/SBThread.cpp
@@ -93,7 +93,7 @@ lldb::SBQueue SBThread::GetQueue() const {
   llvm::Expected<StoppedExecutionContext> exe_ctx =
       GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
-    llvm::consumeError(exe_ctx.takeError());
+    LLDB_LOG_ERROR(GetLog(LLDBLog::API), exe_ctx.takeError(), "{0}");
     return SBQueue();
   }
 
@@ -119,7 +119,7 @@ SBThread::operator bool() const {
   llvm::Expected<StoppedExecutionContext> exe_ctx =
       GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
-    llvm::consumeError(exe_ctx.takeError());
+    LLDB_LOG_ERROR(GetLog(LLDBLog::API), exe_ctx.takeError(), "{0}");
     return false;
   }
 
@@ -139,7 +139,7 @@ StopReason SBThread::GetStopReason() {
   llvm::Expected<StoppedExecutionContext> exe_ctx =
       GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
-    llvm::consumeError(exe_ctx.takeError());
+    LLDB_LOG_ERROR(GetLog(LLDBLog::API), exe_ctx.takeError(), "{0}");
     return reason;
   }
 
@@ -205,7 +205,7 @@ size_t SBThread::GetStopReasonDataCount() {
       }
     }
   } else {
-    llvm::consumeError(exe_ctx.takeError());
+    LLDB_LOG_ERROR(GetLog(LLDBLog::API), exe_ctx.takeError(), "{0}");
     return 0;
   }
   return 0;
@@ -279,7 +279,7 @@ uint64_t SBThread::GetStopReasonDataAtIndex(uint32_t idx) {
       }
     }
   } else {
-    llvm::consumeError(exe_ctx.takeError());
+    LLDB_LOG_ERROR(GetLog(LLDBLog::API), exe_ctx.takeError(), "{0}");
     return 0;
   }
   return 0;
@@ -293,7 +293,7 @@ bool SBThread::GetStopReasonExtendedInfoAsJSON(lldb::SBStream &stream) {
   llvm::Expected<StoppedExecutionContext> exe_ctx =
       GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
-    llvm::consumeError(exe_ctx.takeError());
+    LLDB_LOG_ERROR(GetLog(LLDBLog::API), exe_ctx.takeError(), "{0}");
     return false;
   }
 
@@ -319,7 +319,7 @@ SBThread::GetStopReasonExtendedBacktraces(InstrumentationRuntimeType type) {
   llvm::Expected<StoppedExecutionContext> exe_ctx =
       GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
-    llvm::consumeError(exe_ctx.takeError());
+    LLDB_LOG_ERROR(GetLog(LLDBLog::API), exe_ctx.takeError(), "{0}");
     return SBThreadCollection();
   }
 
@@ -347,7 +347,7 @@ size_t SBThread::GetStopDescription(char *dst, size_t dst_len) {
   llvm::Expected<StoppedExecutionContext> exe_ctx =
       GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
-    llvm::consumeError(exe_ctx.takeError());
+    LLDB_LOG_ERROR(GetLog(LLDBLog::API), exe_ctx.takeError(), "{0}");
     return 0;
   }
 
@@ -373,7 +373,7 @@ SBValue SBThread::GetStopReturnValue() {
   llvm::Expected<StoppedExecutionContext> exe_ctx =
       GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
-    llvm::consumeError(exe_ctx.takeError());
+    LLDB_LOG_ERROR(GetLog(LLDBLog::API), exe_ctx.takeError(), "{0}");
     return SBValue();
   }
 
@@ -415,7 +415,7 @@ const char *SBThread::GetName() const {
   llvm::Expected<StoppedExecutionContext> exe_ctx =
       GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
-    llvm::consumeError(exe_ctx.takeError());
+    LLDB_LOG_ERROR(GetLog(LLDBLog::API), exe_ctx.takeError(), "{0}");
     return nullptr;
   }
 
@@ -431,7 +431,7 @@ const char *SBThread::GetQueueName() const {
   llvm::Expected<StoppedExecutionContext> exe_ctx =
       GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
-    llvm::consumeError(exe_ctx.takeError());
+    LLDB_LOG_ERROR(GetLog(LLDBLog::API), exe_ctx.takeError(), "{0}");
     return nullptr;
   }
 
@@ -448,7 +448,7 @@ lldb::queue_id_t SBThread::GetQueueID() const {
   llvm::Expected<StoppedExecutionContext> exe_ctx =
       GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
-    llvm::consumeError(exe_ctx.takeError());
+    LLDB_LOG_ERROR(GetLog(LLDBLog::API), exe_ctx.takeError(), "{0}");
     return id;
   }
 
@@ -500,7 +500,7 @@ bool SBThread::GetInfoItemByPathAsString(const char *path, SBStream &strm) {
       }
     }
   } else {
-    llvm::consumeError(exe_ctx.takeError());
+    LLDB_LOG_ERROR(GetLog(LLDBLog::API), exe_ctx.takeError(), "{0}");
     return success;
   }
 
@@ -1079,7 +1079,7 @@ bool SBThread::Resume(SBError &error) {
   llvm::Expected<StoppedExecutionContext> exe_ctx =
       GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
-    llvm::consumeError(exe_ctx.takeError());
+    LLDB_LOG_ERROR(GetLog(LLDBLog::API), exe_ctx.takeError(), "{0}");
     error = Status::FromErrorString("process is running");
     return false;
   }
@@ -1100,7 +1100,7 @@ bool SBThread::IsSuspended() {
   llvm::Expected<StoppedExecutionContext> exe_ctx =
       GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
-    llvm::consumeError(exe_ctx.takeError());
+    LLDB_LOG_ERROR(GetLog(LLDBLog::API), exe_ctx.takeError(), "{0}");
     return false;
   }
 
@@ -1115,7 +1115,7 @@ bool SBThread::IsStopped() {
   llvm::Expected<StoppedExecutionContext> exe_ctx =
       GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
-    llvm::consumeError(exe_ctx.takeError());
+    LLDB_LOG_ERROR(GetLog(LLDBLog::API), exe_ctx.takeError(), "{0}");
     return false;
   }
 
@@ -1131,7 +1131,7 @@ SBProcess SBThread::GetProcess() {
   llvm::Expected<StoppedExecutionContext> exe_ctx =
       GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
-    llvm::consumeError(exe_ctx.takeError());
+    LLDB_LOG_ERROR(GetLog(LLDBLog::API), exe_ctx.takeError(), "{0}");
     return SBProcess();
   }
 
@@ -1150,7 +1150,7 @@ uint32_t SBThread::GetNumFrames() {
   llvm::Expected<StoppedExecutionContext> exe_ctx =
       GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
-    llvm::consumeError(exe_ctx.takeError());
+    LLDB_LOG_ERROR(GetLog(LLDBLog::API), exe_ctx.takeError(), "{0}");
     return 0;
   }
 
@@ -1167,7 +1167,7 @@ SBFrame SBThread::GetFrameAtIndex(uint32_t idx) {
   llvm::Expected<StoppedExecutionContext> exe_ctx =
       GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
-    llvm::consumeError(exe_ctx.takeError());
+    LLDB_LOG_ERROR(GetLog(LLDBLog::API), exe_ctx.takeError(), "{0}");
     return SBFrame();
   }
 
@@ -1186,7 +1186,7 @@ lldb::SBFrame SBThread::GetSelectedFrame() {
   llvm::Expected<StoppedExecutionContext> exe_ctx =
       GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
-    llvm::consumeError(exe_ctx.takeError());
+    LLDB_LOG_ERROR(GetLog(LLDBLog::API), exe_ctx.takeError(), "{0}");
     return SBFrame();
   }
 
@@ -1207,7 +1207,7 @@ lldb::SBFrame SBThread::SetSelectedFrame(uint32_t idx) {
   llvm::Expected<StoppedExecutionContext> exe_ctx =
       GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
-    llvm::consumeError(exe_ctx.takeError());
+    LLDB_LOG_ERROR(GetLog(LLDBLog::API), exe_ctx.takeError(), "{0}");
     return SBFrame();
   }
 
@@ -1263,7 +1263,7 @@ bool SBThread::GetStatus(SBStream &status) const {
   llvm::Expected<StoppedExecutionContext> exe_ctx =
       GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
-    llvm::consumeError(exe_ctx.takeError());
+    LLDB_LOG_ERROR(GetLog(LLDBLog::API), exe_ctx.takeError(), "{0}");
     return false;
   }
 
@@ -1290,7 +1290,7 @@ bool SBThread::GetDescription(SBStream &description, bool stop_format) const {
   llvm::Expected<StoppedExecutionContext> exe_ctx =
       GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
-    llvm::consumeError(exe_ctx.takeError());
+    LLDB_LOG_ERROR(GetLog(LLDBLog::API), exe_ctx.takeError(), "{0}");
     return false;
   }
 
@@ -1316,7 +1316,7 @@ SBError SBThread::GetDescriptionWithFormat(const SBFormat &format,
   llvm::Expected<StoppedExecutionContext> exe_ctx =
       GetStoppedExecutionContext(m_opaque_sp);
   if (!exe_ctx) {
-    llvm::consumeError(exe_ctx.takeError());
+    LLDB_LOG_ERROR(GetLog(LLDBLog::API), exe_ctx.takeError(), "{0}");
     return error;
   }
 
@@ -1362,7 +1362,7 @@ SBThread SBThread::GetExtendedBacktraceThread(const char *type) {
       }
     }
   } else {
-    llvm::consumeError(exe_ctx.takeError());
+    LLDB_LOG_ERROR(GetLog(LLDBLog::API), exe_ctx.takeError(), "{0}");
   }
 
   return sb_origin_thread;
diff --git a/lldb/source/Target/ExecutionContext.cpp b/lldb/source/Target/ExecutionContext.cpp
index d2bc4b3cfd99c..831521ce6a92d 100644
--- a/lldb/source/Target/ExecutionContext.cpp
+++ b/lldb/source/Target/ExecutionContext.cpp
@@ -154,12 +154,9 @@ lldb_private::GetStoppedExecutionContext(
         "ExecutionContext created with a null process");
 
   ProcessRunLock::ProcessRunLocker stop_locker;
-  if (!stop_locker.TryLock(&process_sp->GetRunLock())) {
-    auto *error_msg =
-        "Attempted to create an ExecutionContext with a running process";
-    LLDB_LOG(GetLog(LLDBLog::API), error_msg);
-    return llvm::createStringError(error_msg);
-  }
+  if (!stop_locker.TryLock(&process_sp->GetRunLock()))
+    return llvm::createStringError(
+        "Attempted to create an ExecutionContext with a running process");
 
   auto thread_sp = exe_ctx_ref_ptr->GetThreadSP();
   auto frame_sp = exe_ctx_ref_ptr->GetFrameSP();



More information about the lldb-commits mailing list