https://github.com/adrian-prantl updated 
https://github.com/llvm/llvm-project/pull/216389

>From f7ccb2080235c02ba9e4366d6b0e2bc275553e0e Mon Sep 17 00:00:00 2001
From: Adrian Prantl <[email protected]>
Date: Fri, 14 Aug 2026 12:15:49 -0700
Subject: [PATCH] [lldb] Return llvm::Expected from
 Process::ReadPointerFromMemory

The function reported failure twice, through a Status out-parameter
and by returning LLDB_INVALID_ADDRESS. Returning
llvm::Expected<lldb::addr_t> collapses those into a single channel
that cannot be ignored.

Note that ReadScalarIntegerFromMemory can report a short read without
setting the Status so callers could previously get a success Status
alongside LLDB_INVALID_ADDRESS. That case now yields an error.

Call sites that already discarded the Status consume the error
explicitly to preserve their behavior. Error-path logging uses
LLDB_LOG_ERROR instead of passing takeError() to LLDB_LOG/LLDB_LOGF,
which only evaluate their arguments when the channel is enabled and
would otherwise leave the error unchecked and abort.

Assisted-by: Claude
---
 lldb/include/lldb/Target/Process.h            |   2 +-
 lldb/source/API/SBProcess.cpp                 |   6 +-
 lldb/source/Core/Address.cpp                  |  13 +-
 lldb/source/Core/DynamicLoader.cpp            |  10 +-
 lldb/source/Expression/ExpressionVariable.cpp |  15 +-
 .../DynamicLoaderFreeBSDKernel.cpp            |  54 ++++---
 .../Hexagon-DYLD/HexagonDYLDRendezvous.cpp    |  21 ++-
 .../MacOSX-DYLD/DynamicLoaderMacOS.cpp        |  37 +++--
 .../POSIX-DYLD/DYLDRendezvous.cpp             |  23 +--
 .../Plugins/Language/CPlusPlus/Coroutines.cpp |  11 +-
 .../Language/CPlusPlus/MsvcStlDeque.cpp       |  11 +-
 lldb/source/Plugins/Language/ObjC/CF.cpp      |  14 +-
 .../Plugins/Language/ObjC/NSDictionary.cpp    | 132 ++++++++++++------
 lldb/source/Plugins/Language/ObjC/NSError.cpp |  31 ++--
 .../Plugins/Language/ObjC/NSException.cpp     |  34 +++--
 lldb/source/Plugins/Language/ObjC/NSSet.cpp   |  29 ++--
 .../source/Plugins/Language/ObjC/NSString.cpp |  26 +++-
 .../CPlusPlus/CPPLanguageRuntime.cpp          |  50 +++----
 .../CPlusPlus/ItaniumABIRuntime.cpp           |  10 +-
 .../AppleObjCClassDescriptorV2.cpp            |   9 +-
 .../AppleObjCRuntime/AppleObjCRuntime.cpp     |  12 +-
 .../AppleObjCRuntime/AppleObjCRuntimeV2.cpp   | 112 +++++++++------
 .../AppleObjCTrampolineHandler.cpp            |  17 ++-
 .../ObjC/ObjCLanguageRuntime.cpp              |   9 +-
 .../Plugins/Platform/POSIX/PlatformPOSIX.cpp  |  41 +++---
 .../Platform/Windows/PlatformWindows.cpp      |  13 +-
 .../ProcessFreeBSDKernelCore.cpp              |  52 ++++---
 .../MacOSX/SystemRuntimeMacOSX.cpp            |  90 ++++++------
 .../TypeSystem/Clang/TypeSystemClang.cpp      |   9 +-
 lldb/source/Target/Process.cpp                |  15 +-
 lldb/source/Target/RegisterContextUnwind.cpp  |  13 +-
 lldb/source/ValueObject/ValueObjectVTable.cpp |  10 +-
 32 files changed, 570 insertions(+), 361 deletions(-)

diff --git a/lldb/include/lldb/Target/Process.h 
b/lldb/include/lldb/Target/Process.h
index c260a4204d2f7..c16bb5b731067 100644
--- a/lldb/include/lldb/Target/Process.h
+++ b/lldb/include/lldb/Target/Process.h
@@ -1783,7 +1783,7 @@ class Process : public 
std::enable_shared_from_this<Process>,
   int64_t ReadSignedIntegerFromMemory(lldb::addr_t load_addr, size_t byte_size,
                                       int64_t fail_value, Status &error);
 
-  lldb::addr_t ReadPointerFromMemory(lldb::addr_t vm_addr, Status &error);
+  llvm::Expected<lldb::addr_t> ReadPointerFromMemory(lldb::addr_t vm_addr);
 
   /// Use Process::ReadMemoryRanges to efficiently read multiple pointers from
   /// memory at once.
diff --git a/lldb/source/API/SBProcess.cpp b/lldb/source/API/SBProcess.cpp
index 0984daa0e92b9..a7980251c9578 100644
--- a/lldb/source/API/SBProcess.cpp
+++ b/lldb/source/API/SBProcess.cpp
@@ -960,7 +960,11 @@ lldb::addr_t SBProcess::ReadPointerFromMemory(addr_t addr,
     if (stop_locker.TryLock(&process_sp->GetRunLock())) {
       TargetAPIMutex api_lock = process_sp->GetTarget().GetAPIMutex();
       std::lock_guard<TargetAPIMutex> guard(api_lock);
-      ptr = process_sp->ReadPointerFromMemory(addr, sb_error.ref());
+      if (llvm::Expected<lldb::addr_t> ptr_or_err =
+              process_sp->ReadPointerFromMemory(addr))
+        ptr = *ptr_or_err;
+      else
+        sb_error = Status::FromError(ptr_or_err.takeError());
     } else {
       sb_error = Status::FromErrorString("process is running");
     }
diff --git a/lldb/source/Core/Address.cpp b/lldb/source/Core/Address.cpp
index 07d9c4cef5269..86e1964fc7249 100644
--- a/lldb/source/Core/Address.cpp
+++ b/lldb/source/Core/Address.cpp
@@ -40,10 +40,12 @@
 
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/Compiler.h"
+#include "llvm/Support/Error.h"
 #include "llvm/TargetParser/Triple.h"
 
 #include <cstdint>
 #include <memory>
+#include <optional>
 #include <vector>
 
 #include <cassert>
@@ -767,18 +769,17 @@ bool Address::Dump(Stream *s, ExecutionContextScope 
*exe_scope, DumpStyle style,
     if (process) {
       addr_t load_addr = GetLoadAddress(target);
       if (load_addr != LLDB_INVALID_ADDRESS) {
-        Status memory_error;
-        addr_t dereferenced_load_addr =
-            process->ReadPointerFromMemory(load_addr, memory_error);
-        if (dereferenced_load_addr != LLDB_INVALID_ADDRESS) {
+        std::optional<addr_t> dereferenced_load_addr =
+            
llvm::expectedToOptional(process->ReadPointerFromMemory(load_addr));
+        if (dereferenced_load_addr) {
           Address dereferenced_addr;
-          if (dereferenced_addr.SetLoadAddress(dereferenced_load_addr,
+          if (dereferenced_addr.SetLoadAddress(*dereferenced_load_addr,
                                                target)) {
             StreamString strm;
             if (dereferenced_addr.Dump(&strm, exe_scope,
                                        DumpStyleResolvedDescription,
                                        DumpStyleInvalid, addr_size)) {
-              DumpAddress(s->AsRawOstream(), dereferenced_load_addr, addr_size,
+              DumpAddress(s->AsRawOstream(), *dereferenced_load_addr, 
addr_size,
                           " -> ", " ");
               s->Write(strm.GetString().data(), strm.GetSize());
               return true;
diff --git a/lldb/source/Core/DynamicLoader.cpp 
b/lldb/source/Core/DynamicLoader.cpp
index 7eaf329766c2a..d120b9ecf9af6 100644
--- a/lldb/source/Core/DynamicLoader.cpp
+++ b/lldb/source/Core/DynamicLoader.cpp
@@ -452,12 +452,12 @@ int64_t 
DynamicLoader::ReadUnsignedIntWithSizeInBytes(addr_t addr,
 }
 
 addr_t DynamicLoader::ReadPointer(addr_t addr) {
-  Status error;
-  addr_t value = m_process->ReadPointerFromMemory(addr, error);
-  if (error.Fail())
+  llvm::Expected<lldb::addr_t> value = m_process->ReadPointerFromMemory(addr);
+  if (!value) {
+    llvm::consumeError(value.takeError());
     return LLDB_INVALID_ADDRESS;
-  else
-    return value;
+  }
+  return *value;
 }
 
 void DynamicLoader::LoadOperatingSystemPlugin(bool flush)
diff --git a/lldb/source/Expression/ExpressionVariable.cpp 
b/lldb/source/Expression/ExpressionVariable.cpp
index 4c9568106b346..de1519f805af6 100644
--- a/lldb/source/Expression/ExpressionVariable.cpp
+++ b/lldb/source/Expression/ExpressionVariable.cpp
@@ -11,6 +11,9 @@
 #include "lldb/Target/Target.h"
 #include "lldb/Utility/LLDBLog.h"
 #include "lldb/Utility/Log.h"
+
+#include "llvm/Support/Error.h"
+
 #include <optional>
 
 using namespace lldb_private;
@@ -81,16 +84,18 @@ void ExpressionVariable::TransferAddress(bool force) {
 
     Status error;
     Log *log = GetLog(LLDBLog::Expressions);
-    lldb::addr_t cur_value =
-        process_sp->ReadPointerFromMemory(live_addr, error);
-    if (error.Fail())
+    llvm::Expected<lldb::addr_t> cur_value =
+        process_sp->ReadPointerFromMemory(live_addr);
+    if (!cur_value) {
+      llvm::consumeError(cur_value.takeError());
       return;
+    }
 
-    if (cur_value != static_addr.address) {
+    if (*cur_value != static_addr.address) {
       LLDB_LOG(log,
                "Stored value: {0} read from {1} doesn't "
                "match static addr: {2}",
-               cur_value, live_addr, static_addr.address);
+               *cur_value, live_addr, static_addr.address);
       return;
     }
 
diff --git 
a/lldb/source/Plugins/DynamicLoader/FreeBSD-Kernel/DynamicLoaderFreeBSDKernel.cpp
 
b/lldb/source/Plugins/DynamicLoader/FreeBSD-Kernel/DynamicLoaderFreeBSDKernel.cpp
index b5201dee4dce4..ffda99cfcc736 100644
--- 
a/lldb/source/Plugins/DynamicLoader/FreeBSD-Kernel/DynamicLoaderFreeBSDKernel.cpp
+++ 
b/lldb/source/Plugins/DynamicLoader/FreeBSD-Kernel/DynamicLoaderFreeBSDKernel.cpp
@@ -28,6 +28,8 @@
 #include "lldb/Utility/Log.h"
 #include "lldb/Utility/State.h"
 
+#include "llvm/Support/Error.h"
+
 #include "Plugins/ObjectFile/ELF/ObjectFileELF.h"
 
 #include "DynamicLoaderFreeBSDKernel.h"
@@ -520,16 +522,14 @@ bool DynamicLoaderFreeBSDKernel::ReadKmodsListHeader() {
 
   if (m_linker_file_list_struct_addr.IsValid()) {
     // Get tqh_first struct element from linker_files
-    Status error;
-    addr_t address = m_process->ReadPointerFromMemory(
-        m_linker_file_list_struct_addr.GetLoadAddress(&m_process->GetTarget()),
-        error);
-    if (address != LLDB_INVALID_ADDRESS && error.Success()) {
-      m_linker_file_head_addr = Address(address);
-    } else {
+    llvm::Expected<lldb::addr_t> address = m_process->ReadPointerFromMemory(
+        
m_linker_file_list_struct_addr.GetLoadAddress(&m_process->GetTarget()));
+    if (!address) {
+      llvm::consumeError(address.takeError());
       m_linker_file_list_struct_addr.Clear();
       return false;
     }
+    m_linker_file_head_addr = Address(*address);
 
     if (!m_linker_file_head_addr.IsValid() ||
         m_linker_file_head_addr.GetFileAddress() == 0) {
@@ -647,27 +647,34 @@ bool DynamicLoaderFreeBSDKernel::ReadAllKmods(
       linker_files_head_addr.GetLoadAddress(&m_process->GetTarget());
 
   while (current_kld != 0) {
-    addr_t kld_filename_addr =
-        m_process->ReadPointerFromMemory(current_kld + kld_off_filename, 
error);
-    if (error.Fail())
+    llvm::Expected<lldb::addr_t> kld_filename_addr =
+        m_process->ReadPointerFromMemory(current_kld + kld_off_filename);
+    if (!kld_filename_addr) {
+      llvm::consumeError(kld_filename_addr.takeError());
       return false;
-    addr_t kld_pathname_addr =
-        m_process->ReadPointerFromMemory(current_kld + kld_off_pathname, 
error);
-    if (error.Fail())
+    }
+    llvm::Expected<lldb::addr_t> kld_pathname_addr =
+        m_process->ReadPointerFromMemory(current_kld + kld_off_pathname);
+    if (!kld_pathname_addr) {
+      llvm::consumeError(kld_pathname_addr.takeError());
       return false;
+    }
 
-    m_process->ReadCStringFromMemory(kld_filename_addr, kld_filename,
+    m_process->ReadCStringFromMemory(*kld_filename_addr, kld_filename,
                                      sizeof(kld_filename), error);
     if (error.Fail())
       return false;
-    m_process->ReadCStringFromMemory(kld_pathname_addr, kld_pathname,
+    m_process->ReadCStringFromMemory(*kld_pathname_addr, kld_pathname,
                                      sizeof(kld_pathname), error);
     if (error.Fail())
       return false;
-    kld_load_addr =
-        m_process->ReadPointerFromMemory(current_kld + kld_off_address, error);
-    if (error.Fail())
+    llvm::Expected<lldb::addr_t> kld_load_addr_or_err =
+        m_process->ReadPointerFromMemory(current_kld + kld_off_address);
+    if (!kld_load_addr_or_err) {
+      llvm::consumeError(kld_load_addr_or_err.takeError());
       return false;
+    }
+    kld_load_addr = *kld_load_addr_or_err;
 
     kmods_list.emplace_back();
     KModImageInfo &kmod_info = kmods_list.back();
@@ -675,12 +682,17 @@ bool DynamicLoaderFreeBSDKernel::ReadAllKmods(
     kmod_info.SetLoadAddress(kld_load_addr);
     kmod_info.SetPath(kld_pathname);
 
-    current_kld =
-        m_process->ReadPointerFromMemory(current_kld + kld_off_next, error);
+    llvm::Expected<lldb::addr_t> next_kld =
+        m_process->ReadPointerFromMemory(current_kld + kld_off_next);
+
     if (kmod_info.GetName() == "kernel")
       kmods_list.pop_back();
-    if (error.Fail())
+
+    if (!next_kld) {
+      llvm::consumeError(next_kld.takeError());
       return false;
+    }
+    current_kld = *next_kld;
   }
 
   return true;
diff --git 
a/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.cpp 
b/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.cpp
index 7b5bcc2567dda..93a13c37f94cb 100644
--- a/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.cpp
+++ b/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.cpp
@@ -15,6 +15,8 @@
 #include "lldb/Utility/Log.h"
 #include "lldb/Utility/Status.h"
 
+#include "llvm/Support/Error.h"
+
 #include "HexagonDYLDRendezvous.h"
 
 using namespace lldb;
@@ -25,16 +27,19 @@ using namespace lldb_private;
 static addr_t ResolveRendezvousAddress(Process *process) {
   addr_t info_location;
   addr_t info_addr;
-  Status error;
 
   info_location = process->GetImageInfoAddress();
 
   if (info_location == LLDB_INVALID_ADDRESS)
     return LLDB_INVALID_ADDRESS;
 
-  info_addr = process->ReadPointerFromMemory(info_location, error);
-  if (error.Fail())
+  llvm::Expected<lldb::addr_t> info_addr_or_err =
+      process->ReadPointerFromMemory(info_location);
+  if (!info_addr_or_err) {
+    llvm::consumeError(info_addr_or_err.takeError());
     return LLDB_INVALID_ADDRESS;
+  }
+  info_addr = *info_addr_or_err;
 
   if (info_addr == 0)
     return LLDB_INVALID_ADDRESS;
@@ -224,11 +229,13 @@ addr_t HexagonDYLDRendezvous::ReadWord(addr_t addr, 
uint64_t *dst,
 }
 
 addr_t HexagonDYLDRendezvous::ReadPointer(addr_t addr, addr_t *dst) {
-  Status error;
-
-  *dst = m_process->ReadPointerFromMemory(addr, error);
-  if (error.Fail())
+  llvm::Expected<lldb::addr_t> dst_or_err =
+      m_process->ReadPointerFromMemory(addr);
+  if (!dst_or_err) {
+    llvm::consumeError(dst_or_err.takeError());
     return 0;
+  }
+  *dst = *dst_or_err;
 
   return addr + m_process->GetAddressByteSize();
 }
diff --git 
a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.cpp 
b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.cpp
index 863317b5953ec..103a04c4b8213 100644
--- a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.cpp
+++ b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.cpp
@@ -22,6 +22,8 @@
 #include "lldb/Utility/Log.h"
 #include "lldb/Utility/State.h"
 
+#include "llvm/Support/Error.h"
+
 #include "DynamicLoaderDarwin.h"
 #include "DynamicLoaderMacOS.h"
 
@@ -423,18 +425,18 @@ bool DynamicLoaderMacOS::NotifyBreakpointHit(void *baton,
               addr_t notification_location = all_image_infos + 4 + // version
                                              4 +        // infoArrayCount
                                              addr_size; // infoArray
-              Status error;
-              addr_t notification_addr =
-                  process->ReadPointerFromMemory(notification_location, error);
-              if (!error.Success()) {
+              llvm::Expected<lldb::addr_t> notification_addr =
+                  process->ReadPointerFromMemory(notification_location);
+              if (!notification_addr) {
+                llvm::consumeError(notification_addr.takeError());
                 Debugger::ReportWarning(
                     "DynamicLoaderMacOS::NotifyBreakpointHit unable "
                     "to read address of dyld-handover notification function at 
"
                     "0x%" PRIx64,
                     notification_location);
               } else {
-                notification_addr = process->FixCodeAddress(notification_addr);
-                dyld_instance->SetDYLDHandoverBreakpoint(notification_addr);
+                dyld_instance->SetDYLDHandoverBreakpoint(
+                    process->FixCodeAddress(*notification_addr));
               }
             }
           }
@@ -572,22 +574,27 @@ addr_t 
DynamicLoaderMacOS::GetNotificationFuncAddrFromImageInfos() {
   // the actual address of this struct, dyld has not started
   // executing yet.  The 'notification' field can't be used by
   // lldb until it's resolved to an actual address.
-  Status error;
-  addr_t registered_infos_addr = m_process->ReadPointerFromMemory(
-      all_image_infos_addr + registered_infos_addr_offset, error);
-  if (!error.Success())
+  llvm::Expected<lldb::addr_t> registered_infos_addr =
+      m_process->ReadPointerFromMemory(all_image_infos_addr +
+                                       registered_infos_addr_offset);
+  if (!registered_infos_addr) {
+    llvm::consumeError(registered_infos_addr.takeError());
     return notification_addr;
-  if (registered_infos_addr != all_image_infos_addr)
+  }
+  if (*registered_infos_addr != all_image_infos_addr)
     return notification_addr;
 
   offset_t notification_fptr_offset = sizeof(uint32_t) + // version
                                       sizeof(uint32_t) + // infoArrayCount
                                       addr_size;         // infoArray
 
-  addr_t notification_fptr = m_process->ReadPointerFromMemory(
-      all_image_infos_addr + notification_fptr_offset, error);
-  if (error.Success())
-    notification_addr = m_process->FixCodeAddress(notification_fptr);
+  llvm::Expected<lldb::addr_t> notification_fptr =
+      m_process->ReadPointerFromMemory(all_image_infos_addr +
+                                       notification_fptr_offset);
+  if (notification_fptr)
+    notification_addr = m_process->FixCodeAddress(*notification_fptr);
+  else
+    llvm::consumeError(notification_fptr.takeError());
   return notification_addr;
 }
 
diff --git a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp 
b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp
index 2d0eef666f688..93a7200bf89ca 100644
--- a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp
+++ b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp
@@ -18,6 +18,7 @@
 #include "lldb/Utility/Log.h"
 #include "lldb/Utility/Status.h"
 
+#include "llvm/Support/Error.h"
 #include "llvm/Support/Path.h"
 
 #include "DYLDRendezvous.h"
@@ -64,7 +65,6 @@ addr_t DYLDRendezvous::ResolveRendezvousAddress() {
   Log *log = GetLog(LLDBLog::DynamicLoader);
   addr_t info_location;
   addr_t info_addr;
-  Status error;
 
   if (!m_process) {
     LLDB_LOGF(log, "%s null process provided", __FUNCTION__);
@@ -120,12 +120,15 @@ addr_t DYLDRendezvous::ResolveRendezvousAddress() {
   LLDB_LOGF(log, "%s reading pointer (%" PRIu32 " bytes) from 0x%" PRIx64,
             __FUNCTION__, m_process->GetAddressByteSize(), info_location);
 
-  info_addr = m_process->ReadPointerFromMemory(info_location, error);
-  if (error.Fail()) {
-    LLDB_LOGF(log, "%s FAILED - could not read from the info location: %s",
-              __FUNCTION__, error.AsCString());
+  llvm::Expected<lldb::addr_t> info_addr_or_err =
+      m_process->ReadPointerFromMemory(info_location);
+  if (!info_addr_or_err) {
+    LLDB_LOG_ERROR(log, info_addr_or_err.takeError(),
+                   "{1} FAILED - could not read from the info location: {0}",
+                   __FUNCTION__);
     return LLDB_INVALID_ADDRESS;
   }
+  info_addr = *info_addr_or_err;
 
   if (info_addr == 0) {
     LLDB_LOGF(log,
@@ -598,11 +601,13 @@ addr_t DYLDRendezvous::ReadWord(addr_t addr, uint64_t 
*dst, size_t size) {
 }
 
 addr_t DYLDRendezvous::ReadPointer(addr_t addr, addr_t *dst) {
-  Status error;
-
-  *dst = m_process->ReadPointerFromMemory(addr, error);
-  if (error.Fail())
+  llvm::Expected<lldb::addr_t> dst_or_err =
+      m_process->ReadPointerFromMemory(addr);
+  if (!dst_or_err) {
+    llvm::consumeError(dst_or_err.takeError());
     return 0;
+  }
+  *dst = *dst_or_err;
 
   return addr + m_process->GetAddressByteSize();
 }
diff --git a/lldb/source/Plugins/Language/CPlusPlus/Coroutines.cpp 
b/lldb/source/Plugins/Language/CPlusPlus/Coroutines.cpp
index 4cca7aa46abf9..b3ef9bded5367 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/Coroutines.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/Coroutines.cpp
@@ -46,15 +46,16 @@ static Function *ExtractDestroyFunction(lldb::TargetSP 
target_sp,
   lldb::ProcessSP process_sp = target_sp->GetProcessSP();
   auto ptr_size = process_sp->GetAddressByteSize();
 
-  Status error;
   auto destroy_func_ptr_addr = frame_ptr_addr + ptr_size;
-  lldb::addr_t destroy_func_addr =
-      process_sp->ReadPointerFromMemory(destroy_func_ptr_addr, error);
-  if (error.Fail())
+  llvm::Expected<lldb::addr_t> destroy_func_addr =
+      process_sp->ReadPointerFromMemory(destroy_func_ptr_addr);
+  if (!destroy_func_addr) {
+    llvm::consumeError(destroy_func_addr.takeError());
     return nullptr;
+  }
 
   Address destroy_func_address;
-  if (!target_sp->ResolveLoadAddress(destroy_func_addr, destroy_func_address))
+  if (!target_sp->ResolveLoadAddress(*destroy_func_addr, destroy_func_address))
     return nullptr;
 
   return destroy_func_address.CalculateSymbolContextFunction();
diff --git a/lldb/source/Plugins/Language/CPlusPlus/MsvcStlDeque.cpp 
b/lldb/source/Plugins/Language/CPlusPlus/MsvcStlDeque.cpp
index 10cbf498286a2..2e23ae6603838 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/MsvcStlDeque.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/MsvcStlDeque.cpp
@@ -76,14 +76,15 @@ 
lldb_private::formatters::MsvcStlDequeSyntheticFrontEnd::GetChildAtIndex(
   lldb::addr_t first_address = m_map->GetValueAsUnsigned(0) +
                                first_idx * process_sp->GetAddressByteSize();
 
-  Status err;
-  lldb::addr_t second_base =
-      process_sp->ReadPointerFromMemory(first_address, err);
-  if (err.Fail())
+  llvm::Expected<lldb::addr_t> second_base =
+      process_sp->ReadPointerFromMemory(first_address);
+  if (!second_base) {
+    llvm::consumeError(second_base.takeError());
     return nullptr;
+  }
 
   size_t second_idx = (idx + m_offset) % m_block_size;
-  size_t second_address = second_base + second_idx * m_element_size;
+  size_t second_address = *second_base + second_idx * m_element_size;
 
   StreamString name;
   name.Printf("[%" PRIu64 "]", (uint64_t)idx);
diff --git a/lldb/source/Plugins/Language/ObjC/CF.cpp 
b/lldb/source/Plugins/Language/ObjC/CF.cpp
index 2d5095fb52858..c68d591d97fa5 100644
--- a/lldb/source/Plugins/Language/ObjC/CF.cpp
+++ b/lldb/source/Plugins/Language/ObjC/CF.cpp
@@ -19,6 +19,8 @@
 #include "lldb/ValueObject/ValueObject.h"
 #include "lldb/ValueObject/ValueObjectConstResult.h"
 
+#include "llvm/Support/Error.h"
+
 #include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h"
 
 using namespace lldb;
@@ -155,16 +157,18 @@ bool lldb_private::formatters::CFBitVectorSummaryProvider(
   if (error.Fail())
     return false;
   uint64_t num_bytes = count / 8 + ((count & 7) ? 1 : 0);
-  addr_t data_ptr = process_sp->ReadPointerFromMemory(
-      valobj_addr + 2 * ptr_size + 2 * ptr_size, error);
-  if (error.Fail())
+  llvm::Expected<addr_t> data_ptr = process_sp->ReadPointerFromMemory(
+      valobj_addr + 2 * ptr_size + 2 * ptr_size);
+  if (!data_ptr) {
+    llvm::consumeError(data_ptr.takeError());
     return false;
+  }
   // make sure we do not try to read huge amounts of data
   if (num_bytes > 1024)
     num_bytes = 1024;
   WritableDataBufferSP buffer_sp(new DataBufferHeap(num_bytes, 0));
-  num_bytes =
-      process_sp->ReadMemory(data_ptr, buffer_sp->GetBytes(), num_bytes, 
error);
+  num_bytes = process_sp->ReadMemory(*data_ptr, buffer_sp->GetBytes(),
+                                     num_bytes, error);
   if (error.Fail() || num_bytes == 0)
     return false;
   uint8_t *bytes = buffer_sp->GetBytes();
diff --git a/lldb/source/Plugins/Language/ObjC/NSDictionary.cpp 
b/lldb/source/Plugins/Language/ObjC/NSDictionary.cpp
index e9a73b4013249..6540e92838dc9 100644
--- a/lldb/source/Plugins/Language/ObjC/NSDictionary.cpp
+++ b/lldb/source/Plugins/Language/ObjC/NSDictionary.cpp
@@ -654,13 +654,20 @@ 
lldb_private::formatters::NSDictionaryISyntheticFrontEnd::GetChildAtIndex(
       ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP();
       if (!process_sp)
         return lldb::ValueObjectSP();
-      Status error;
-      key_at_idx = process_sp->ReadPointerFromMemory(key_at_idx, error);
-      if (error.Fail())
+      llvm::Expected<lldb::addr_t> key =
+          process_sp->ReadPointerFromMemory(key_at_idx);
+      if (!key) {
+        llvm::consumeError(key.takeError());
         return lldb::ValueObjectSP();
-      val_at_idx = process_sp->ReadPointerFromMemory(val_at_idx, error);
-      if (error.Fail())
+      }
+      key_at_idx = *key;
+      llvm::Expected<lldb::addr_t> val =
+          process_sp->ReadPointerFromMemory(val_at_idx);
+      if (!val) {
+        llvm::consumeError(val.takeError());
         return lldb::ValueObjectSP();
+      }
+      val_at_idx = *val;
 
       test_idx++;
 
@@ -757,7 +764,6 @@ 
lldb_private::formatters::NSCFDictionarySyntheticFrontEnd::GetChildAtIndex(
     if (!process_sp)
       return lldb::ValueObjectSP();
 
-    Status error;
     lldb::addr_t key_at_idx = 0, val_at_idx = 0;
 
     uint32_t tries = 0;
@@ -771,12 +777,20 @@ 
lldb_private::formatters::NSCFDictionarySyntheticFrontEnd::GetChildAtIndex(
       key_at_idx = m_keys_ptr + (test_idx * m_ptr_size);
       val_at_idx = m_values_ptr + (test_idx * m_ptr_size);
 
-      key_at_idx = process_sp->ReadPointerFromMemory(key_at_idx, error);
-      if (error.Fail())
+      llvm::Expected<lldb::addr_t> key =
+          process_sp->ReadPointerFromMemory(key_at_idx);
+      if (!key) {
+        llvm::consumeError(key.takeError());
         return lldb::ValueObjectSP();
-      val_at_idx = process_sp->ReadPointerFromMemory(val_at_idx, error);
-      if (error.Fail())
+      }
+      key_at_idx = *key;
+      llvm::Expected<lldb::addr_t> val =
+          process_sp->ReadPointerFromMemory(val_at_idx);
+      if (!val) {
+        llvm::consumeError(val.takeError());
         return lldb::ValueObjectSP();
+      }
+      val_at_idx = *val;
 
       test_idx++;
 
@@ -860,15 +874,22 @@ 
lldb_private::formatters::NSConstantDictionarySyntheticFrontEnd::Update() {
       valobj_addr + 2 * m_ptr_size, m_ptr_size, 0, error);
   if (error.Fail())
     return lldb::ChildCacheState::eRefetch;
-  m_keys_ptr =
-      process_sp->ReadPointerFromMemory(valobj_addr + 3 * m_ptr_size, error);
-  if (error.Fail())
+  llvm::Expected<lldb::addr_t> keys_ptr =
+      process_sp->ReadPointerFromMemory(valobj_addr + 3 * m_ptr_size);
+  if (!keys_ptr) {
+    llvm::consumeError(keys_ptr.takeError());
     return lldb::ChildCacheState::eRefetch;
-  m_objects_ptr =
-      process_sp->ReadPointerFromMemory(valobj_addr + 4 * m_ptr_size, error);
+  }
+  m_keys_ptr = *keys_ptr;
+  llvm::Expected<lldb::addr_t> objects_ptr =
+      process_sp->ReadPointerFromMemory(valobj_addr + 4 * m_ptr_size);
+  if (!objects_ptr) {
+    llvm::consumeError(objects_ptr.takeError());
+    return lldb::ChildCacheState::eRefetch;
+  }
+  m_objects_ptr = *objects_ptr;
 
-  return error.Success() ? lldb::ChildCacheState::eReuse
-                         : lldb::ChildCacheState::eRefetch;
+  return lldb::ChildCacheState::eReuse;
 }
 
 lldb::ValueObjectSP lldb_private::formatters::
@@ -886,15 +907,20 @@ lldb::ValueObjectSP lldb_private::formatters::
       return lldb::ValueObjectSP();
 
     for (unsigned int child = 0; child < num_children; ++child) {
-      Status error;
-      key_at_idx = process_sp->ReadPointerFromMemory(
-          m_keys_ptr + child * m_ptr_size, error);
-      if (error.Fail())
+      llvm::Expected<lldb::addr_t> key =
+          process_sp->ReadPointerFromMemory(m_keys_ptr + child * m_ptr_size);
+      if (!key) {
+        llvm::consumeError(key.takeError());
         return lldb::ValueObjectSP();
-      val_at_idx = process_sp->ReadPointerFromMemory(
-          m_objects_ptr + child * m_ptr_size, error);
-      if (error.Fail())
+      }
+      key_at_idx = *key;
+      llvm::Expected<lldb::addr_t> val =
+          process_sp->ReadPointerFromMemory(m_objects_ptr + child * 
m_ptr_size);
+      if (!val) {
+        llvm::consumeError(val.takeError());
         return lldb::ValueObjectSP();
+      }
+      val_at_idx = *val;
       DictionaryItemDescriptor descriptor = {key_at_idx, val_at_idx,
                                              lldb::ValueObjectSP()};
       m_children.push_back(descriptor);
@@ -978,14 +1004,18 @@ 
lldb_private::formatters::NSDictionary1SyntheticFrontEnd::GetChildAtIndex(
       m_backend.GetValueAsUnsigned(LLDB_INVALID_ADDRESS) + ptr_size;
   lldb::addr_t value_ptr = key_ptr + ptr_size;
 
-  Status error;
-
-  lldb::addr_t value_at_idx = process_sp->ReadPointerFromMemory(key_ptr, 
error);
-  if (error.Fail())
+  llvm::Expected<lldb::addr_t> value_at_idx =
+      process_sp->ReadPointerFromMemory(key_ptr);
+  if (!value_at_idx) {
+    llvm::consumeError(value_at_idx.takeError());
     return nullptr;
-  lldb::addr_t key_at_idx = process_sp->ReadPointerFromMemory(value_ptr, 
error);
-  if (error.Fail())
+  }
+  llvm::Expected<lldb::addr_t> key_at_idx =
+      process_sp->ReadPointerFromMemory(value_ptr);
+  if (!key_at_idx) {
+    llvm::consumeError(key_at_idx.takeError());
     return nullptr;
+  }
 
   auto pair_type =
       GetLLDBNSPairType(process_sp->GetTarget().shared_from_this());
@@ -994,12 +1024,12 @@ 
lldb_private::formatters::NSDictionary1SyntheticFrontEnd::GetChildAtIndex(
 
   if (ptr_size == 8) {
     uint64_t *data_ptr = (uint64_t *)buffer_sp->GetBytes();
-    *data_ptr = key_at_idx;
-    *(data_ptr + 1) = value_at_idx;
+    *data_ptr = *key_at_idx;
+    *(data_ptr + 1) = *value_at_idx;
   } else {
     uint32_t *data_ptr = (uint32_t *)buffer_sp->GetBytes();
-    *data_ptr = key_at_idx;
-    *(data_ptr + 1) = value_at_idx;
+    *data_ptr = *key_at_idx;
+    *(data_ptr + 1) = *value_at_idx;
   }
 
   DataExtractor data(buffer_sp, process_sp->GetByteOrder(), ptr_size);
@@ -1105,13 +1135,20 @@ 
lldb_private::formatters::GenericNSDictionaryMSyntheticFrontEnd<
       ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP();
       if (!process_sp)
         return lldb::ValueObjectSP();
-      Status error;
-      key_at_idx = process_sp->ReadPointerFromMemory(key_at_idx, error);
-      if (error.Fail())
+      llvm::Expected<lldb::addr_t> key =
+          process_sp->ReadPointerFromMemory(key_at_idx);
+      if (!key) {
+        llvm::consumeError(key.takeError());
         return lldb::ValueObjectSP();
-      val_at_idx = process_sp->ReadPointerFromMemory(val_at_idx, error);
-      if (error.Fail())
+      }
+      key_at_idx = *key;
+      llvm::Expected<lldb::addr_t> val =
+          process_sp->ReadPointerFromMemory(val_at_idx);
+      if (!val) {
+        llvm::consumeError(val.takeError());
         return lldb::ValueObjectSP();
+      }
+      val_at_idx = *val;
 
       test_idx++;
 
@@ -1241,13 +1278,20 @@ lldb_private::formatters::Foundation1100::
       ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP();
       if (!process_sp)
         return lldb::ValueObjectSP();
-      Status error;
-      key_at_idx = process_sp->ReadPointerFromMemory(key_at_idx, error);
-      if (error.Fail())
+      llvm::Expected<lldb::addr_t> key =
+          process_sp->ReadPointerFromMemory(key_at_idx);
+      if (!key) {
+        llvm::consumeError(key.takeError());
         return lldb::ValueObjectSP();
-      val_at_idx = process_sp->ReadPointerFromMemory(val_at_idx, error);
-      if (error.Fail())
+      }
+      key_at_idx = *key;
+      llvm::Expected<lldb::addr_t> val =
+          process_sp->ReadPointerFromMemory(val_at_idx);
+      if (!val) {
+        llvm::consumeError(val.takeError());
         return lldb::ValueObjectSP();
+      }
+      val_at_idx = *val;
 
       test_idx++;
 
diff --git a/lldb/source/Plugins/Language/ObjC/NSError.cpp 
b/lldb/source/Plugins/Language/ObjC/NSError.cpp
index 00f83329333fa..50914b8adf222 100644
--- a/lldb/source/Plugins/Language/ObjC/NSError.cpp
+++ b/lldb/source/Plugins/Language/ObjC/NSError.cpp
@@ -37,10 +37,10 @@ static lldb::addr_t DerefToNSErrorPointer(ValueObject 
&valobj) {
       CompilerType pointee_type(valobj_type.GetPointeeType());
       Flags pointee_flags(pointee_type.GetTypeInfo());
       if (pointee_flags.AllSet(eTypeIsPointer)) {
-        if (ProcessSP process_sp = valobj.GetProcessSP()) {
-          Status error;
-          ptr_value = process_sp->ReadPointerFromMemory(ptr_value, error);
-        }
+        if (ProcessSP process_sp = valobj.GetProcessSP())
+          ptr_value = llvm::expectedToOptional(
+                          process_sp->ReadPointerFromMemory(ptr_value))
+                          .value_or(LLDB_INVALID_ADDRESS);
       }
     }
     return ptr_value;
@@ -69,17 +69,19 @@ bool lldb_private::formatters::NSError_SummaryProvider(
   if (error.Fail())
     return false;
 
-  lldb::addr_t domain_str_value =
-      process_sp->ReadPointerFromMemory(domain_location, error);
-  if (error.Fail() || domain_str_value == LLDB_INVALID_ADDRESS)
+  llvm::Expected<lldb::addr_t> domain_str_value =
+      process_sp->ReadPointerFromMemory(domain_location);
+  if (!domain_str_value) {
+    llvm::consumeError(domain_str_value.takeError());
     return false;
+  }
 
-  if (!domain_str_value) {
+  if (!*domain_str_value) {
     stream.Printf("domain: nil - code: %" PRIi64, code);
     return true;
   }
 
-  InferiorSizedWord isw(domain_str_value, *process_sp);
+  InferiorSizedWord isw(*domain_str_value, *process_sp);
   TypeSystemClangSP scratch_ts_sp =
       ScratchTypeSystemClang::GetForTarget(process_sp->GetTarget());
 
@@ -146,12 +148,13 @@ class NSErrorSyntheticFrontEnd : public 
SyntheticChildrenFrontEnd {
     size_t ptr_size = process_sp->GetAddressByteSize();
 
     userinfo_location += 4 * ptr_size;
-    Status error;
-    lldb::addr_t userinfo =
-        process_sp->ReadPointerFromMemory(userinfo_location, error);
-    if (userinfo == LLDB_INVALID_ADDRESS || error.Fail())
+    llvm::Expected<lldb::addr_t> userinfo =
+        process_sp->ReadPointerFromMemory(userinfo_location);
+    if (!userinfo) {
+      llvm::consumeError(userinfo.takeError());
       return lldb::ChildCacheState::eRefetch;
-    InferiorSizedWord isw(userinfo, *process_sp);
+    }
+    InferiorSizedWord isw(*userinfo, *process_sp);
     TypeSystemClangSP scratch_ts_sp =
         ScratchTypeSystemClang::GetForTarget(process_sp->GetTarget());
     if (!scratch_ts_sp)
diff --git a/lldb/source/Plugins/Language/ObjC/NSException.cpp 
b/lldb/source/Plugins/Language/ObjC/NSException.cpp
index 18f3f19c36c69..c66440915ced2 100644
--- a/lldb/source/Plugins/Language/ObjC/NSException.cpp
+++ b/lldb/source/Plugins/Language/ObjC/NSException.cpp
@@ -25,6 +25,8 @@
 #include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h"
 #include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
 
+#include <optional>
+
 using namespace lldb;
 using namespace lldb_private;
 using namespace lldb_private::formatters;
@@ -51,24 +53,30 @@ static bool ExtractFields(ValueObject &valobj, 
ValueObjectSP *name_sp,
     return false;
   size_t ptr_size = process_sp->GetAddressByteSize();
 
-  Status error;
-  auto name = process_sp->ReadPointerFromMemory(ptr + 1 * ptr_size, error);
-  if (error.Fail() || name == LLDB_INVALID_ADDRESS)
+  // Read the ivar at the given pointer-sized slot in the NSException object.
+  // Returns std::nullopt if the read fails.
+  auto read_field = [&](size_t slot) {
+    return llvm::expectedToOptional(
+        process_sp->ReadPointerFromMemory(ptr + slot * ptr_size));
+  };
+
+  std::optional<lldb::addr_t> name = read_field(1);
+  if (!name)
     return false;
-  auto reason = process_sp->ReadPointerFromMemory(ptr + 2 * ptr_size, error);
-  if (error.Fail() || reason == LLDB_INVALID_ADDRESS)
+  std::optional<lldb::addr_t> reason = read_field(2);
+  if (!reason)
     return false;
-  auto userinfo = process_sp->ReadPointerFromMemory(ptr + 3 * ptr_size, error);
-  if (error.Fail() || userinfo == LLDB_INVALID_ADDRESS)
+  std::optional<lldb::addr_t> userinfo = read_field(3);
+  if (!userinfo)
     return false;
-  auto reserved = process_sp->ReadPointerFromMemory(ptr + 4 * ptr_size, error);
-  if (error.Fail() || reserved == LLDB_INVALID_ADDRESS)
+  std::optional<lldb::addr_t> reserved = read_field(4);
+  if (!reserved)
     return false;
 
-  InferiorSizedWord name_isw(name, *process_sp);
-  InferiorSizedWord reason_isw(reason, *process_sp);
-  InferiorSizedWord userinfo_isw(userinfo, *process_sp);
-  InferiorSizedWord reserved_isw(reserved, *process_sp);
+  InferiorSizedWord name_isw(*name, *process_sp);
+  InferiorSizedWord reason_isw(*reason, *process_sp);
+  InferiorSizedWord userinfo_isw(*userinfo, *process_sp);
+  InferiorSizedWord reserved_isw(*reserved, *process_sp);
 
   TypeSystemClangSP scratch_ts_sp =
       ScratchTypeSystemClang::GetForTarget(process_sp->GetTarget());
diff --git a/lldb/source/Plugins/Language/ObjC/NSSet.cpp 
b/lldb/source/Plugins/Language/ObjC/NSSet.cpp
index 9dd177b52fb83..6e39650306762 100644
--- a/lldb/source/Plugins/Language/ObjC/NSSet.cpp
+++ b/lldb/source/Plugins/Language/ObjC/NSSet.cpp
@@ -20,6 +20,8 @@
 #include "lldb/ValueObject/ValueObject.h"
 #include "lldb/ValueObject/ValueObjectConstResult.h"
 
+#include "llvm/Support/Error.h"
+
 using namespace lldb;
 using namespace lldb_private;
 using namespace lldb_private::formatters;
@@ -444,10 +446,13 @@ 
lldb_private::formatters::NSSetISyntheticFrontEnd::GetChildAtIndex(
       obj_at_idx = m_data_ptr + (test_idx * m_ptr_size);
       if (!process_sp)
         return lldb::ValueObjectSP();
-      Status error;
-      obj_at_idx = process_sp->ReadPointerFromMemory(obj_at_idx, error);
-      if (error.Fail())
+      llvm::Expected<lldb::addr_t> obj_at_idx_or_err =
+          process_sp->ReadPointerFromMemory(obj_at_idx);
+      if (!obj_at_idx_or_err) {
+        llvm::consumeError(obj_at_idx_or_err.takeError());
         return lldb::ValueObjectSP();
+      }
+      obj_at_idx = *obj_at_idx_or_err;
 
       test_idx++;
 
@@ -543,7 +548,6 @@ 
lldb_private::formatters::NSCFSetSyntheticFrontEnd::GetChildAtIndex(
     if (!process_sp)
       return lldb::ValueObjectSP();
 
-    Status error;
     lldb::addr_t val_at_idx = 0;
 
     uint32_t tries = 0;
@@ -556,9 +560,13 @@ 
lldb_private::formatters::NSCFSetSyntheticFrontEnd::GetChildAtIndex(
     while (tries < num_children) {
       val_at_idx = m_values_ptr + (test_idx * m_ptr_size);
 
-      val_at_idx = process_sp->ReadPointerFromMemory(val_at_idx, error);
-      if (error.Fail())
+      llvm::Expected<lldb::addr_t> val_at_idx_or_err =
+          process_sp->ReadPointerFromMemory(val_at_idx);
+      if (!val_at_idx_or_err) {
+        llvm::consumeError(val_at_idx_or_err.takeError());
         return lldb::ValueObjectSP();
+      }
+      val_at_idx = *val_at_idx_or_err;
 
       test_idx++;
 
@@ -696,10 +704,13 @@ lldb_private::formatters::
       obj_at_idx = m_objs_addr + (test_idx * m_ptr_size);
       if (!process_sp)
         return lldb::ValueObjectSP();
-      Status error;
-      obj_at_idx = process_sp->ReadPointerFromMemory(obj_at_idx, error);
-      if (error.Fail())
+      llvm::Expected<lldb::addr_t> obj_at_idx_or_err =
+          process_sp->ReadPointerFromMemory(obj_at_idx);
+      if (!obj_at_idx_or_err) {
+        llvm::consumeError(obj_at_idx_or_err.takeError());
         return lldb::ValueObjectSP();
+      }
+      obj_at_idx = *obj_at_idx_or_err;
 
       test_idx++;
 
diff --git a/lldb/source/Plugins/Language/ObjC/NSString.cpp 
b/lldb/source/Plugins/Language/ObjC/NSString.cpp
index 7a295119bd031..cf9f21ad68df2 100644
--- a/lldb/source/Plugins/Language/ObjC/NSString.cpp
+++ b/lldb/source/Plugins/Language/ObjC/NSString.cpp
@@ -20,6 +20,8 @@
 #include "lldb/ValueObject/ValueObject.h"
 #include "lldb/ValueObject/ValueObjectConstResult.h"
 
+#include "llvm/Support/Error.h"
+
 using namespace lldb;
 using namespace lldb_private;
 using namespace lldb_private::formatters;
@@ -141,9 +143,13 @@ bool lldb_private::formatters::NSStringSummaryProvider(
 
   if (is_mutable) {
     uint64_t location = 2 * ptr_size + valobj_addr;
-    location = process_sp->ReadPointerFromMemory(location, error);
-    if (error.Fail())
+    llvm::Expected<lldb::addr_t> location_or_err =
+        process_sp->ReadPointerFromMemory(location);
+    if (!location_or_err) {
+      llvm::consumeError(location_or_err.takeError());
       return false;
+    }
+    location = *location_or_err;
     if (has_explicit_length && is_unicode) {
       options.SetLocation(Address(location));
       options.SetTargetSP(valobj.GetTargetSP());
@@ -190,9 +196,13 @@ bool lldb_private::formatters::NSStringSummaryProvider(
       } else
         location += ptr_size;
     } else {
-      location = process_sp->ReadPointerFromMemory(location, error);
-      if (error.Fail())
+      llvm::Expected<lldb::addr_t> location_or_err =
+          process_sp->ReadPointerFromMemory(location);
+      if (!location_or_err) {
+        llvm::consumeError(location_or_err.takeError());
         return false;
+      }
+      location = *location_or_err;
     }
     options.SetLocation(Address(location));
     options.SetTargetSP(valobj.GetTargetSP());
@@ -266,9 +276,13 @@ bool lldb_private::formatters::NSStringSummaryProvider(
           StringPrinter::StringElementType::ASCII>(options);
   } else {
     uint64_t location = valobj_addr + 2 * ptr_size;
-    location = process_sp->ReadPointerFromMemory(location, error);
-    if (error.Fail())
+    llvm::Expected<lldb::addr_t> location_or_err =
+        process_sp->ReadPointerFromMemory(location);
+    if (!location_or_err) {
+      llvm::consumeError(location_or_err.takeError());
       return false;
+    }
+    location = *location_or_err;
     if (has_explicit_length && !has_null)
       explicit_length++; // account for the fact that there is no NULL and we
                          // need to have one added
diff --git 
a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp 
b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp
index e562266e80d23..b3e77db6d44c0 100644
--- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp
@@ -17,6 +17,7 @@
 #include "VerboseTrapFrameRecognizer.h"
 
 #include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Error.h"
 
 #include "lldb/Symbol/Block.h"
 #include "lldb/Symbol/Variable.h"
@@ -247,43 +248,48 @@ CPPLanguageRuntime::FindLibCppStdFunctionCallableInfo(
     return optional_info;
 
   uint32_t address_size = process->GetAddressByteSize();
-  Status status;
 
   // First item pointed to by __f_ should be the pointer to the vtable for
   // a __base object.
-  lldb::addr_t vtable_address =
-      process->ReadPointerFromMemory(member_f_pointer_value, status);
+  llvm::Expected<lldb::addr_t> vtable_address_or_err =
+      process->ReadPointerFromMemory(member_f_pointer_value);
+  if (!vtable_address_or_err) {
+    llvm::consumeError(vtable_address_or_err.takeError());
+    return optional_info;
+  }
+  lldb::addr_t vtable_address = *vtable_address_or_err;
 
   ABISP abi_sp = process->GetABI();
   if (abi_sp)
     vtable_address = abi_sp->FixCodeAddress(vtable_address);
 
-  if (status.Fail())
+  llvm::Expected<lldb::addr_t> vtable_address_first_entry_or_err =
+      process->ReadPointerFromMemory(vtable_address + address_size);
+  if (!vtable_address_first_entry_or_err) {
+    llvm::consumeError(vtable_address_first_entry_or_err.takeError());
     return optional_info;
-
-  lldb::addr_t vtable_address_first_entry =
-      process->ReadPointerFromMemory(vtable_address + address_size, status);
+  }
+  lldb::addr_t vtable_address_first_entry = *vtable_address_first_entry_or_err;
 
   if (abi_sp)
     vtable_address_first_entry =
         abi_sp->FixCodeAddress(vtable_address_first_entry);
 
-  if (status.Fail())
-    return optional_info;
-
   lldb::addr_t address_after_vtable = member_f_pointer_value + address_size;
   // As commented above we may not have a function pointer but if we do we will
   // need it.
-  lldb::addr_t possible_function_address =
-      process->ReadPointerFromMemory(address_after_vtable, status);
+  llvm::Expected<lldb::addr_t> possible_function_address_or_err =
+      process->ReadPointerFromMemory(address_after_vtable);
+  if (!possible_function_address_or_err) {
+    llvm::consumeError(possible_function_address_or_err.takeError());
+    return optional_info;
+  }
+  lldb::addr_t possible_function_address = *possible_function_address_or_err;
 
   if (abi_sp)
     possible_function_address =
         abi_sp->FixCodeAddress(possible_function_address);
 
-  if (status.Fail())
-    return optional_info;
-
   Target &target = process->GetTarget();
 
   if (!target.HasLoadedSections())
@@ -782,15 +788,11 @@ CPPLanguageRuntime::GetVTableInfoEntry(ValueObject 
&in_value, bool check_type) {
     return llvm::createStringError(std::errc::invalid_argument,
                                    "failed to get the address of the value");
 
-  Status error;
-  lldb::addr_t vtable_load_addr =
-      process->ReadPointerFromMemory(original_ptr, error);
-
-  if (!error.Success() || vtable_load_addr == LLDB_INVALID_ADDRESS)
-    return llvm::createStringError(
-        std::errc::invalid_argument,
-        "failed to read vtable pointer from memory at 0x%" PRIx64,
-        original_ptr);
+  llvm::Expected<lldb::addr_t> vtable_load_addr_or_err =
+      process->ReadPointerFromMemory(original_ptr);
+  if (!vtable_load_addr_or_err)
+    return vtable_load_addr_or_err.takeError();
+  lldb::addr_t vtable_load_addr = *vtable_load_addr_or_err;
 
   // The vtable load address can have authentication bits with
   // AArch64 targets on Darwin.
diff --git 
a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABIRuntime.cpp 
b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABIRuntime.cpp
index cd86d4a0ddb3a..fa80f5a8b6786 100644
--- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABIRuntime.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABIRuntime.cpp
@@ -13,6 +13,7 @@
 #include "lldb/Expression/DiagnosticManager.h"
 #include "lldb/Expression/FunctionCaller.h"
 #include "lldb/Utility/LLDBLog.h"
+#include "llvm/Support/Error.h"
 
 using namespace lldb;
 using namespace lldb_private;
@@ -239,14 +240,15 @@ ItaniumABIRuntime::GetExceptionObjectForThread(ThreadSP 
thread_sp) {
 
   size_t ptr_size = m_process->GetAddressByteSize();
   addr_t result_ptr = results.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
-  addr_t exception_addr =
-      m_process->ReadPointerFromMemory(result_ptr - ptr_size, error);
+  llvm::Expected<lldb::addr_t> exception_addr =
+      m_process->ReadPointerFromMemory(result_ptr - ptr_size);
 
-  if (!error.Success()) {
+  if (!exception_addr) {
+    llvm::consumeError(exception_addr.takeError());
     return ValueObjectSP();
   }
 
-  lldb_private::formatters::InferiorSizedWord exception_isw(exception_addr,
+  lldb_private::formatters::InferiorSizedWord exception_isw(*exception_addr,
                                                             *m_process);
   ValueObjectSP exception = ValueObject::CreateValueObjectFromData(
       "exception", exception_isw.GetAsData(m_process->GetByteOrder()), exe_ctx,
diff --git 
a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp
 
b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp
index 1b5527e26b338..945f99ceed5ad 100644
--- 
a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp
+++ 
b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp
@@ -315,12 +315,15 @@ bool ClassDescriptorV2::method_t::Read(DataExtractor 
&extractor,
 
     m_name_ptr = addr + nameref_offset;
 
-    Status error;
     if (!has_direct_sel) {
       // The SEL offset points to a SELRef. We need to dereference twice.
-      m_name_ptr = process->ReadPointerFromMemory(m_name_ptr, error);
-      if (error.Fail())
+      llvm::Expected<lldb::addr_t> name_ptr =
+          process->ReadPointerFromMemory(m_name_ptr);
+      if (!name_ptr) {
+        llvm::consumeError(name_ptr.takeError());
         return false;
+      }
+      m_name_ptr = *name_ptr;
     } else if (relative_string_base_addr != LLDB_INVALID_ADDRESS) {
       m_name_ptr = relative_string_base_addr + nameref_offset;
     }
diff --git 
a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
 
b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
index 23173ffd94146..3b627f01bb7f5 100644
--- 
a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
+++ 
b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
@@ -40,6 +40,8 @@
 
 #include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
 
+#include "llvm/Support/Error.h"
+
 #include <vector>
 
 using namespace lldb;
@@ -584,10 +586,12 @@ ThreadSP 
AppleObjCRuntime::GetBacktraceThreadFromException(
   size_t ptr_size = m_process->GetAddressByteSize();
   std::vector<lldb::addr_t> pcs;
   for (size_t idx = 0; idx < count; idx++) {
-    Status error;
-    addr_t pc = m_process->ReadPointerFromMemory(
-        frames_addr + (ignore + idx) * ptr_size, error);
-    pcs.push_back(pc);
+    // Record unreadable frames as invalid rather than dropping them, so the
+    // history thread keeps one entry per frame in the exception.
+    pcs.push_back(
+        llvm::expectedToOptional(m_process->ReadPointerFromMemory(
+                                     frames_addr + (ignore + idx) * ptr_size))
+            .value_or(LLDB_INVALID_ADDRESS));
   }
 
   if (pcs.empty())
diff --git 
a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
 
b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
index 17b66bf636748..48cb00943d7ad 100644
--- 
a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
+++ 
b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
@@ -63,9 +63,11 @@
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/ScopeExit.h"
 #include "llvm/ADT/Sequence.h"
+#include "llvm/Support/Error.h"
 
 #include <cstdint>
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
@@ -1441,9 +1443,12 @@ class RemoteNXMapTable {
         cursor += unsigned_byte_size;
 
         // void *buckets;
-        m_buckets_ptr = m_process->ReadPointerFromMemory(cursor, err);
+        std::optional<lldb::addr_t> buckets_ptr =
+            llvm::expectedToOptional(m_process->ReadPointerFromMemory(cursor));
+        if (buckets_ptr)
+          m_buckets_ptr = *buckets_ptr;
 
-        success = m_count > 0 && m_buckets_ptr != LLDB_INVALID_ADDRESS;
+        success = m_count > 0 && buckets_ptr.has_value();
       }
     }
 
@@ -1507,25 +1512,29 @@ class RemoteNXMapTable {
       size_t map_pair_size = m_parent.m_map_pair_size;
       lldb::addr_t pair_ptr = pairs_ptr + (m_index * map_pair_size);
 
-      Status err;
-
-      lldb::addr_t key =
-          m_parent.m_process->ReadPointerFromMemory(pair_ptr, err);
-      if (!err.Success())
+      llvm::Expected<lldb::addr_t> key =
+          m_parent.m_process->ReadPointerFromMemory(pair_ptr);
+      if (!key) {
+        llvm::consumeError(key.takeError());
         return element();
-      lldb::addr_t value = m_parent.m_process->ReadPointerFromMemory(
-          pair_ptr + m_parent.m_process->GetAddressByteSize(), err);
-      if (!err.Success())
+      }
+      llvm::Expected<lldb::addr_t> value =
+          m_parent.m_process->ReadPointerFromMemory(
+              pair_ptr + m_parent.m_process->GetAddressByteSize());
+      if (!value) {
+        llvm::consumeError(value.takeError());
         return element();
+      }
 
       std::string key_string;
 
-      m_parent.m_process->ReadCStringFromMemory(key, key_string, err);
+      Status err;
+      m_parent.m_process->ReadCStringFromMemory(*key, key_string, err);
       if (!err.Success())
         return element();
 
       return element(ConstString(key_string),
-                     (ObjCLanguageRuntime::ObjCISA)value);
+                     (ObjCLanguageRuntime::ObjCISA)*value);
     }
 
   private:
@@ -1536,19 +1545,19 @@ class RemoteNXMapTable {
       const lldb::addr_t pairs_ptr = m_parent.m_buckets_ptr;
       const size_t map_pair_size = m_parent.m_map_pair_size;
       const lldb::addr_t invalid_key = m_parent.m_invalid_key;
-      Status err;
 
       while (m_index--) {
         lldb::addr_t pair_ptr = pairs_ptr + (m_index * map_pair_size);
-        lldb::addr_t key =
-            m_parent.m_process->ReadPointerFromMemory(pair_ptr, err);
+        llvm::Expected<lldb::addr_t> key =
+            m_parent.m_process->ReadPointerFromMemory(pair_ptr);
 
-        if (!err.Success()) {
+        if (!key) {
+          llvm::consumeError(key.takeError());
           m_index = -1;
           return;
         }
 
-        if (key != invalid_key)
+        if (*key != invalid_key)
           return;
       }
     }
@@ -1660,10 +1669,13 @@ AppleObjCRuntimeV2::GetClassDescriptorImpl(ValueObject 
&valobj,
   if (!process)
     return objc_class_sp;
 
-  Status error;
-  ObjCISA isa = process->ReadPointerFromMemory(isa_pointer, error);
-  if (isa == LLDB_INVALID_ADDRESS)
+  llvm::Expected<lldb::addr_t> isa_or_err =
+      process->ReadPointerFromMemory(isa_pointer);
+  if (!isa_or_err) {
+    llvm::consumeError(isa_or_err.takeError());
     return objc_class_sp;
+  }
+  ObjCISA isa = *isa_or_err;
 
   objc_class_sp = GetClassDescriptorFromISA(isa);
   if (!objc_class_sp) {
@@ -1701,11 +1713,11 @@ lldb::addr_t 
AppleObjCRuntimeV2::GetTaggedPointerObfuscator() {
     lldb::addr_t g_gdb_obj_obfuscator_ptr =
         symbol->GetLoadAddress(&process->GetTarget());
 
-    if (g_gdb_obj_obfuscator_ptr != LLDB_INVALID_ADDRESS) {
-      Status error;
+    if (g_gdb_obj_obfuscator_ptr != LLDB_INVALID_ADDRESS)
       m_tagged_pointer_obfuscator =
-          process->ReadPointerFromMemory(g_gdb_obj_obfuscator_ptr, error);
-    }
+          llvm::expectedToOptional(
+              process->ReadPointerFromMemory(g_gdb_obj_obfuscator_ptr))
+              .value_or(LLDB_INVALID_ADDRESS);
   }
   // If we don't have a correct value at this point, there must be no
   // obfuscation.
@@ -1732,11 +1744,11 @@ lldb::addr_t 
AppleObjCRuntimeV2::GetISAHashTablePointer() {
       lldb::addr_t gdb_objc_realized_classes_ptr =
           symbol->GetLoadAddress(&process->GetTarget());
 
-      if (gdb_objc_realized_classes_ptr != LLDB_INVALID_ADDRESS) {
-        Status error;
-        m_isa_hash_table_ptr = process->ReadPointerFromMemory(
-            gdb_objc_realized_classes_ptr, error);
-      }
+      if (gdb_objc_realized_classes_ptr != LLDB_INVALID_ADDRESS)
+        m_isa_hash_table_ptr =
+            llvm::expectedToOptional(
+                process->ReadPointerFromMemory(gdb_objc_realized_classes_ptr))
+                .value_or(LLDB_INVALID_ADDRESS);
     }
   }
   return m_isa_hash_table_ptr;
@@ -1767,19 +1779,22 @@ 
AppleObjCRuntimeV2::SharedCacheImageHeaders::CreateSharedCacheImageHeaders(
     return nullptr;
   }
 
-  Status error;
-  lldb::addr_t objc_debug_headerInfoRWs_ptr =
-      process->ReadPointerFromMemory(objc_debug_headerInfoRWs_addr, error);
-  if (error.Fail()) {
+  llvm::Expected<lldb::addr_t> objc_debug_headerInfoRWs_ptr_or_err =
+      process->ReadPointerFromMemory(objc_debug_headerInfoRWs_addr);
+  if (!objc_debug_headerInfoRWs_ptr_or_err) {
+    llvm::consumeError(objc_debug_headerInfoRWs_ptr_or_err.takeError());
     LLDB_LOG(log,
              "Failed to read address of 'objc_debug_headerInfoRWs' at {0:x}",
              objc_debug_headerInfoRWs_addr);
     return nullptr;
   }
+  lldb::addr_t objc_debug_headerInfoRWs_ptr =
+      *objc_debug_headerInfoRWs_ptr_or_err;
 
   const size_t metadata_size =
       sizeof(uint32_t) + sizeof(uint32_t); // count + entsize
   DataBufferHeap metadata_buffer(metadata_size, '\0');
+  Status error;
   process->ReadMemory(objc_debug_headerInfoRWs_ptr, metadata_buffer.GetBytes(),
                       metadata_size, error);
   if (error.Fail()) {
@@ -3212,10 +3227,14 @@ 
AppleObjCRuntimeV2::TaggedPointerVendorRuntimeAssisted::GetClassDescriptor(
     Process *process(m_runtime.GetProcess());
     uintptr_t slot_ptr = slot * process->GetAddressByteSize() +
                          m_objc_debug_taggedpointer_classes;
-    Status error;
-    uintptr_t slot_data = process->ReadPointerFromMemory(slot_ptr, error);
-    if (error.Fail() || slot_data == 0 ||
-        slot_data == uintptr_t(LLDB_INVALID_ADDRESS))
+    llvm::Expected<lldb::addr_t> slot_data_or_err =
+        process->ReadPointerFromMemory(slot_ptr);
+    if (!slot_data_or_err) {
+      llvm::consumeError(slot_data_or_err.takeError());
+      return nullptr;
+    }
+    uintptr_t slot_data = *slot_data_or_err;
+    if (slot_data == 0)
       return nullptr;
     actual_class_descriptor_sp =
         m_runtime.GetClassDescriptorFromISA((ObjCISA)slot_data);
@@ -3308,10 +3327,14 @@ 
AppleObjCRuntimeV2::TaggedPointerVendorExtended::GetClassDescriptor(
     Process *process(m_runtime.GetProcess());
     uintptr_t slot_ptr = slot * process->GetAddressByteSize() +
                          m_objc_debug_taggedpointer_ext_classes;
-    Status error;
-    uintptr_t slot_data = process->ReadPointerFromMemory(slot_ptr, error);
-    if (error.Fail() || slot_data == 0 ||
-        slot_data == uintptr_t(LLDB_INVALID_ADDRESS))
+    llvm::Expected<lldb::addr_t> slot_data_or_err =
+        process->ReadPointerFromMemory(slot_ptr);
+    if (!slot_data_or_err) {
+      llvm::consumeError(slot_data_or_err.takeError());
+      return nullptr;
+    }
+    uintptr_t slot_data = *slot_data_or_err;
+    if (slot_data == 0)
       return nullptr;
     actual_class_descriptor_sp =
         m_runtime.GetClassDescriptorFromISA((ObjCISA)slot_data);
@@ -3519,11 +3542,8 @@ bool AppleObjCRuntimeV2::GetCFBooleanValuesIfNeeded() {
       return LLDB_INVALID_ADDRESS;
 
     lldb::addr_t addr = symbol->GetLoadAddress(&GetProcess()->GetTarget());
-    Status error;
-    addr = GetProcess()->ReadPointerFromMemory(addr, error);
-    if (error.Fail())
-      return LLDB_INVALID_ADDRESS;
-    return addr;
+    return llvm::expectedToOptional(GetProcess()->ReadPointerFromMemory(addr))
+        .value_or(LLDB_INVALID_ADDRESS);
   };
 
   lldb::addr_t false_addr = get_symbol(g_dunder_kCFBooleanFalse, 
g_kCFBooleanFalse);
diff --git 
a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp
 
b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp
index 9e0ebf2090b62..7f91bf78cd5ff 100644
--- 
a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp
+++ 
b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp
@@ -33,6 +33,7 @@
 
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/ScopeExit.h"
+#include "llvm/Support/Error.h"
 
 #include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h"
 
@@ -448,15 +449,17 @@ bool 
AppleObjCTrampolineHandler::AppleObjCVTables::ReadRegions() {
   m_regions.clear();
   if (!InitializeVTableSymbols())
     return false;
-  Status error;
   ProcessSP process_sp = GetProcessSP();
-  if (process_sp) {
-    lldb::addr_t region_addr =
-        process_sp->ReadPointerFromMemory(m_trampoline_header, error);
-    if (error.Success())
-      return ReadRegions(region_addr);
+  if (!process_sp)
+    return false;
+
+  llvm::Expected<lldb::addr_t> region_addr =
+      process_sp->ReadPointerFromMemory(m_trampoline_header);
+  if (!region_addr) {
+    llvm::consumeError(region_addr.takeError());
+    return false;
   }
-  return false;
+  return ReadRegions(*region_addr);
 }
 
 bool AppleObjCTrampolineHandler::AppleObjCVTables::ReadRegions(
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp 
b/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp
index fbde6ecc91ff6..1cf75287c67bc 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp
@@ -27,6 +27,7 @@
 
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/DJB.h"
+#include "llvm/Support/Error.h"
 #include <optional>
 
 using namespace lldb;
@@ -280,10 +281,10 @@ ObjCLanguageRuntime::GetClassDescriptor(ValueObject 
&valobj) {
 
       Process *process = exe_ctx.GetProcessPtr();
       if (process) {
-        Status error;
-        ObjCISA isa = process->ReadPointerFromMemory(isa_pointer, error);
-        if (isa != LLDB_INVALID_ADDRESS)
-          objc_class_sp = GetClassDescriptorFromISA(isa);
+        std::optional<lldb::addr_t> isa = llvm::expectedToOptional(
+            process->ReadPointerFromMemory(isa_pointer));
+        if (isa)
+          objc_class_sp = GetClassDescriptorFromISA(*isa);
       }
     }
   }
diff --git a/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp 
b/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
index d297b97ab24f7..68460496a144f 100644
--- a/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
+++ b/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
@@ -33,6 +33,8 @@
 #include "lldb/Utility/StreamString.h"
 #include "lldb/ValueObject/ValueObject.h"
 #include "llvm/ADT/ScopeExit.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/FormatAdapters.h"
 #include <optional>
 
 using namespace lldb;
@@ -914,17 +916,17 @@ uint32_t PlatformPOSIX::DoLoadImage(lldb_private::Process 
*process,
   }
   
   // Read the dlopen token from the return area:
-  lldb::addr_t token = process->ReadPointerFromMemory(return_addr, 
-                                                      utility_error);
-  if (utility_error.Fail()) {
-    error = Status::FromErrorStringWithFormat(
-        "dlopen error: could not read the return struct: %s",
-        utility_error.AsCString());
+  llvm::Expected<lldb::addr_t> token =
+      process->ReadPointerFromMemory(return_addr);
+  if (!token) {
+    error = Status::FromErrorStringWithFormatv(
+        "dlopen error: could not read the return struct: {0}",
+        llvm::fmt_consume(token.takeError()));
     return LLDB_INVALID_IMAGE_TOKEN;
   }
-  
+
   // The dlopen succeeded!
-  if (token != 0x0) {
+  if (*token != 0x0) {
     if (loaded_image && buffer_addr != 0x0)
     {
       // Capture the image which was loaded.  We leave it in the buffer on
@@ -934,23 +936,22 @@ uint32_t PlatformPOSIX::DoLoadImage(lldb_private::Process 
*process,
       if (utility_error.Success())
         loaded_image->SetFile(name_string, llvm::sys::path::Style::posix);
     }
-    return process->AddImageToken(token);
+    return process->AddImageToken(*token);
   }
-    
+
   // We got an error, lets read in the error string:
   std::string dlopen_error_str;
-  lldb::addr_t error_addr 
-    = process->ReadPointerFromMemory(return_addr + addr_size, utility_error);
-  if (utility_error.Fail()) {
-    error = Status::FromErrorStringWithFormat(
-        "dlopen error: could not read error string: %s",
-        utility_error.AsCString());
+  llvm::Expected<lldb::addr_t> error_addr =
+      process->ReadPointerFromMemory(return_addr + addr_size);
+  if (!error_addr) {
+    error = Status::FromErrorStringWithFormatv(
+        "dlopen error: could not read error string: {0}",
+        llvm::fmt_consume(error_addr.takeError()));
     return LLDB_INVALID_IMAGE_TOKEN;
   }
-  
-  size_t num_chars = process->ReadCStringFromMemory(error_addr + addr_size, 
-                                                    dlopen_error_str, 
-                                                    utility_error);
+
+  size_t num_chars = process->ReadCStringFromMemory(
+      *error_addr + addr_size, dlopen_error_str, utility_error);
   if (utility_error.Success() && num_chars > 0)
     error = Status::FromErrorStringWithFormat("dlopen error: %s",
                                               dlopen_error_str.c_str());
diff --git a/lldb/source/Plugins/Platform/Windows/PlatformWindows.cpp 
b/lldb/source/Plugins/Platform/Windows/PlatformWindows.cpp
index 56be2eed0e293..924ce798433cf 100644
--- a/lldb/source/Plugins/Platform/Windows/PlatformWindows.cpp
+++ b/lldb/source/Plugins/Platform/Windows/PlatformWindows.cpp
@@ -39,6 +39,8 @@
 
 #include "llvm/ADT/ScopeExit.h"
 #include "llvm/Support/ConvertUTF.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/FormatAdapters.h"
 #include "llvm/Support/FormatVariadic.h"
 
 using namespace lldb;
@@ -448,12 +450,15 @@ uint32_t PlatformWindows::DoLoadImage(Process *process,
   }
 
   /* Read result */
-  lldb::addr_t token = process->ReadPointerFromMemory(injected_result, status);
-  if (status.Fail()) {
-    error = Status::FromErrorStringWithFormat(
-        "LoadLibrary error: could not read the result: %s", 
status.AsCString());
+  llvm::Expected<lldb::addr_t> token_or_err =
+      process->ReadPointerFromMemory(injected_result);
+  if (!token_or_err) {
+    error = Status::FromErrorStringWithFormatv(
+        "LoadLibrary error: could not read the result: {0}",
+        llvm::fmt_consume(token_or_err.takeError()));
     return LLDB_INVALID_IMAGE_TOKEN;
   }
+  lldb::addr_t token = *token_or_err;
 
   if (!token) {
     // ErrorCode is a 4-byte `unsigned` field in __lldb_LoadLibraryResult.
diff --git 
a/lldb/source/Plugins/Process/FreeBSD-Kernel-Core/ProcessFreeBSDKernelCore.cpp 
b/lldb/source/Plugins/Process/FreeBSD-Kernel-Core/ProcessFreeBSDKernelCore.cpp
index 208069d7f9ff3..22e574c6e2624 100644
--- 
a/lldb/source/Plugins/Process/FreeBSD-Kernel-Core/ProcessFreeBSDKernelCore.cpp
+++ 
b/lldb/source/Plugins/Process/FreeBSD-Kernel-Core/ProcessFreeBSDKernelCore.cpp
@@ -17,6 +17,8 @@
 #include "lldb/Utility/Log.h"
 #include "lldb/Utility/StreamString.h"
 
+#include "llvm/Support/Error.h"
+
 #include "Plugins/DynamicLoader/FreeBSD-Kernel/DynamicLoaderFreeBSDKernel.h"
 #include "ProcessFreeBSDKernelCore.h"
 #include "ThreadFreeBSDKernelCore.h"
@@ -387,9 +389,11 @@ bool 
ProcessFreeBSDKernelCore::DoUpdateThreadList(ThreadList &old_thread_list,
       return false;
 
     std::vector<std::pair<lldb::addr_t, int32_t>> process_addrs;
-    for (lldb::addr_t proc = ReadPointerFromMemory(allproc_addr, error);
-         error.Success() && proc != 0 && proc != LLDB_INVALID_ADDRESS;
-         proc = ReadPointerFromMemory(proc + offset_p_list, error)) {
+    llvm::Expected<lldb::addr_t> proc_or_err =
+        ReadPointerFromMemory(allproc_addr);
+    for (; proc_or_err && *proc_or_err != 0;
+         proc_or_err = ReadPointerFromMemory(*proc_or_err + offset_p_list)) {
+      lldb::addr_t proc = *proc_or_err;
       int32_t pid =
           ReadSignedIntegerFromMemory(proc + offset_p_pid, 4, -1, error);
       if (error.Fail())
@@ -397,8 +401,10 @@ bool 
ProcessFreeBSDKernelCore::DoUpdateThreadList(ThreadList &old_thread_list,
       process_addrs.emplace_back(proc, pid);
     }
 
-    if (error.Fail())
+    if (!proc_or_err) {
+      llvm::consumeError(proc_or_err.takeError());
       return false;
+    }
 
     std::sort(process_addrs.begin(), process_addrs.end(),
               [](const auto &a, const auto &b) { return a.second < b.second; 
});
@@ -414,19 +420,23 @@ bool 
ProcessFreeBSDKernelCore::DoUpdateThreadList(ThreadList &old_thread_list,
       // the initial thread is found in process' p_threads, subsequent
       // elements are linked via td_plist field.
       // If reading memory fails, skip to the next thread.
-      for (lldb::addr_t td =
-               ReadPointerFromMemory(proc + offset_p_threads, error);
-           error.Success() && td != 0;
-           td = ReadPointerFromMemory(td + offset_td_plist, error)) {
+      llvm::Expected<lldb::addr_t> td_or_err =
+          ReadPointerFromMemory(proc + offset_p_threads);
+      for (; td_or_err && *td_or_err != 0;
+           td_or_err = ReadPointerFromMemory(*td_or_err + offset_td_plist)) {
+        lldb::addr_t td = *td_or_err;
         int32_t tid =
             ReadSignedIntegerFromMemory(td + offset_td_tid, 4, -1, error);
         if (error.Fail())
           continue;
 
-        lldb::addr_t pcb_addr =
-            ReadPointerFromMemory(td + offset_td_pcb, error);
-        if (error.Fail())
+        llvm::Expected<lldb::addr_t> pcb_addr_or_err =
+            ReadPointerFromMemory(td + offset_td_pcb);
+        if (!pcb_addr_or_err) {
+          llvm::consumeError(pcb_addr_or_err.takeError());
           continue;
+        }
+        lldb::addr_t pcb_addr = *pcb_addr_or_err;
 
         // whether process was on CPU (-1 if not, otherwise CPU number)
         int32_t oncpu =
@@ -494,8 +504,10 @@ bool 
ProcessFreeBSDKernelCore::DoUpdateThreadList(ThreadList &old_thread_list,
       }
 
       // If reading thread list has failed, return with false.
-      if (error.Fail())
+      if (!td_or_err) {
+        llvm::consumeError(td_or_err.takeError());
         return false;
+      }
     }
   } else {
     const uint32_t num_threads = old_thread_list.GetSize(false);
@@ -560,9 +572,13 @@ void ProcessFreeBSDKernelCore::PrintUnreadMessage() {
     return;
 
   // Read the pointer value
-  lldb::addr_t msgbufp = ReadPointerFromMemory(msgbufp_addr, error);
-  if (error.Fail() || msgbufp == LLDB_INVALID_ADDRESS)
+  llvm::Expected<lldb::addr_t> msgbufp_or_err =
+      ReadPointerFromMemory(msgbufp_addr);
+  if (!msgbufp_or_err) {
+    llvm::consumeError(msgbufp_or_err.takeError());
     return;
+  }
+  lldb::addr_t msgbufp = *msgbufp_or_err;
 
   // Get the type information for struct msgbuf from DWARF
   TypeQuery query("msgbuf");
@@ -625,9 +641,13 @@ void ProcessFreeBSDKernelCore::PrintUnreadMessage() {
   }
 
   // Read struct msgbuf fields
-  lldb::addr_t bufp = ReadPointerFromMemory(msgbufp + offset_msg_ptr, error);
-  if (error.Fail() || bufp == LLDB_INVALID_ADDRESS)
+  llvm::Expected<lldb::addr_t> bufp_or_err =
+      ReadPointerFromMemory(msgbufp + offset_msg_ptr);
+  if (!bufp_or_err) {
+    llvm::consumeError(bufp_or_err.takeError());
     return;
+  }
+  lldb::addr_t bufp = *bufp_or_err;
 
   uint32_t size =
       ReadUnsignedIntegerFromMemory(msgbufp + offset_msg_size, 4, 0, error);
diff --git a/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp 
b/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp
index 728239230a6fb..aed3f28089ab2 100644
--- a/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp
+++ b/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp
@@ -28,6 +28,8 @@
 #include "lldb/Utility/Log.h"
 #include "lldb/Utility/StreamString.h"
 
+#include "llvm/Support/Error.h"
+
 #include "AbortWithPayloadFrameRecognizer.h"
 #include "SystemRuntimeMacOSX.h"
 
@@ -130,33 +132,38 @@ 
SystemRuntimeMacOSX::GetQueueNameFromThreadQAddress(addr_t dispatch_qaddr) {
     // dispatch_qaddr is from a thread_info(THREAD_IDENTIFIER_INFO) call for a
     // thread - deref it to get the address of the dispatch_queue_t structure
     // for this thread's queue.
-    Status error;
-    addr_t dispatch_queue_addr =
-        m_process->ReadPointerFromMemory(dispatch_qaddr, error);
-    if (error.Success()) {
-      if (m_libdispatch_offsets.dqo_version >= 4) {
-        // libdispatch versions 4+, pointer to dispatch name is in the queue
-        // structure.
-        addr_t pointer_to_label_address =
-            dispatch_queue_addr + m_libdispatch_offsets.dqo_label;
-        addr_t label_addr =
-            m_process->ReadPointerFromMemory(pointer_to_label_address, error);
-        if (error.Success()) {
-          m_process->ReadCStringFromMemory(label_addr, dispatch_queue_name,
-                                           error);
-        }
+    llvm::Expected<lldb::addr_t> dispatch_queue_addr =
+        m_process->ReadPointerFromMemory(dispatch_qaddr);
+    if (!dispatch_queue_addr) {
+      llvm::consumeError(dispatch_queue_addr.takeError());
+      return dispatch_queue_name;
+    }
+    if (m_libdispatch_offsets.dqo_version >= 4) {
+      // libdispatch versions 4+, pointer to dispatch name is in the queue
+      // structure.
+      addr_t pointer_to_label_address =
+          *dispatch_queue_addr + m_libdispatch_offsets.dqo_label;
+      llvm::Expected<lldb::addr_t> label_addr =
+          m_process->ReadPointerFromMemory(pointer_to_label_address);
+      if (label_addr) {
+        Status error;
+        m_process->ReadCStringFromMemory(*label_addr, dispatch_queue_name,
+                                         error);
       } else {
-        // libdispatch versions 1-3, dispatch name is a fixed width char array
-        // in the queue structure.
-        addr_t label_addr =
-            dispatch_queue_addr + m_libdispatch_offsets.dqo_label;
-        dispatch_queue_name.resize(m_libdispatch_offsets.dqo_label_size, '\0');
-        size_t bytes_read =
-            m_process->ReadMemory(label_addr, &dispatch_queue_name[0],
-                                  m_libdispatch_offsets.dqo_label_size, error);
-        if (bytes_read < m_libdispatch_offsets.dqo_label_size)
-          dispatch_queue_name.erase(bytes_read);
+        llvm::consumeError(label_addr.takeError());
       }
+    } else {
+      // libdispatch versions 1-3, dispatch name is a fixed width char array
+      // in the queue structure.
+      addr_t label_addr =
+          *dispatch_queue_addr + m_libdispatch_offsets.dqo_label;
+      dispatch_queue_name.resize(m_libdispatch_offsets.dqo_label_size, '\0');
+      Status error;
+      size_t bytes_read =
+          m_process->ReadMemory(label_addr, &dispatch_queue_name[0],
+                                m_libdispatch_offsets.dqo_label_size, error);
+      if (bytes_read < m_libdispatch_offsets.dqo_label_size)
+        dispatch_queue_name.erase(bytes_read);
     }
   }
   return dispatch_queue_name;
@@ -164,14 +171,9 @@ SystemRuntimeMacOSX::GetQueueNameFromThreadQAddress(addr_t 
dispatch_qaddr) {
 
 lldb::addr_t SystemRuntimeMacOSX::GetLibdispatchQueueAddressFromThreadQAddress(
     addr_t dispatch_qaddr) {
-  addr_t libdispatch_queue_t_address = LLDB_INVALID_ADDRESS;
-  Status error;
-  libdispatch_queue_t_address =
-      m_process->ReadPointerFromMemory(dispatch_qaddr, error);
-  if (!error.Success()) {
-    libdispatch_queue_t_address = LLDB_INVALID_ADDRESS;
-  }
-  return libdispatch_queue_t_address;
+  return llvm::expectedToOptional(
+             m_process->ReadPointerFromMemory(dispatch_qaddr))
+      .value_or(LLDB_INVALID_ADDRESS);
 }
 
 lldb::QueueKind SystemRuntimeMacOSX::GetQueueKind(addr_t dispatch_queue_addr) {
@@ -251,17 +253,19 @@ 
SystemRuntimeMacOSX::GetQueueIDFromThreadQAddress(lldb::addr_t dispatch_qaddr) {
     // thread - deref it to get the address of the dispatch_queue_t structure
     // for this thread's queue.
     Status error;
-    uint64_t dispatch_queue_addr =
-        m_process->ReadPointerFromMemory(dispatch_qaddr, error);
+    llvm::Expected<lldb::addr_t> dispatch_queue_addr =
+        m_process->ReadPointerFromMemory(dispatch_qaddr);
+    if (!dispatch_queue_addr) {
+      llvm::consumeError(dispatch_queue_addr.takeError());
+      return queue_id;
+    }
+    addr_t serialnum_address =
+        *dispatch_queue_addr + m_libdispatch_offsets.dqo_serialnum;
+    queue_id_t serialnum = m_process->ReadUnsignedIntegerFromMemory(
+        serialnum_address, m_libdispatch_offsets.dqo_serialnum_size,
+        LLDB_INVALID_QUEUE_ID, error);
     if (error.Success()) {
-      addr_t serialnum_address =
-          dispatch_queue_addr + m_libdispatch_offsets.dqo_serialnum;
-      queue_id_t serialnum = m_process->ReadUnsignedIntegerFromMemory(
-          serialnum_address, m_libdispatch_offsets.dqo_serialnum_size,
-          LLDB_INVALID_QUEUE_ID, error);
-      if (error.Success()) {
-        queue_id = serialnum;
-      }
+      queue_id = serialnum;
     }
   }
 
diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp 
b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
index 51018c1922c4d..092921643a46f 100644
--- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
+++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
@@ -243,8 +243,13 @@ static lldb::addr_t GetVTableAddress(Process &process,
 
     vbtable_ptr_addr += vbtable_ptr_offset;
 
-    Status err;
-    return process.ReadPointerFromMemory(vbtable_ptr_addr, err);
+    llvm::Expected<lldb::addr_t> vbtable_ptr_addr_or_err =
+        process.ReadPointerFromMemory(vbtable_ptr_addr);
+    if (!vbtable_ptr_addr_or_err) {
+      llvm::consumeError(vbtable_ptr_addr_or_err.takeError());
+      return LLDB_INVALID_ADDRESS;
+    }
+    return *vbtable_ptr_addr_or_err;
   }
 
   // We have an object already read from process memory,
diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp
index 1d7e413603c82..f0a8d5fa7863f 100644
--- a/lldb/source/Target/Process.cpp
+++ b/lldb/source/Target/Process.cpp
@@ -2516,12 +2516,19 @@ int64_t 
Process::ReadSignedIntegerFromMemory(lldb::addr_t vm_addr,
   return fail_value;
 }
 
-addr_t Process::ReadPointerFromMemory(lldb::addr_t vm_addr, Status &error) {
+llvm::Expected<addr_t> Process::ReadPointerFromMemory(lldb::addr_t vm_addr) {
   Scalar scalar;
+  Status error;
   if (ReadScalarIntegerFromMemory(vm_addr, GetAddressByteSize(), false, scalar,
-                                  error))
-    return scalar.ULongLong(LLDB_INVALID_ADDRESS);
-  return LLDB_INVALID_ADDRESS;
+                                  error)) {
+    assert(scalar.GetType() == Scalar::e_int &&
+           "a successful read always yields an integer");
+    return scalar.ULongLong();
+  }
+  if (error.Fail())
+    return error.ToError();
+  return llvm::createStringError(
+      "failed to read pointer from memory at 0x%" PRIx64, vm_addr);
 }
 
 llvm::SmallVector<std::optional<addr_t>>
diff --git a/lldb/source/Target/RegisterContextUnwind.cpp 
b/lldb/source/Target/RegisterContextUnwind.cpp
index 1cf207b33c776..354bfddaa47ce 100644
--- a/lldb/source/Target/RegisterContextUnwind.cpp
+++ b/lldb/source/Target/RegisterContextUnwind.cpp
@@ -37,6 +37,7 @@
 #include "lldb/Utility/RegisterValue.h"
 #include "lldb/Utility/VASPrintf.h"
 #include "lldb/lldb-private.h"
+#include "llvm/Support/Error.h"
 #include "llvm/Support/FormatAdapters.h"
 #include <cassert>
 #include <memory>
@@ -2222,18 +2223,18 @@ bool RegisterContextUnwind::ReadFrameAddress(
       return false;
     const unsigned max_iterations = 256;
     for (unsigned i = 0; i < max_iterations; ++i) {
-      Status st;
       lldb::addr_t candidate_addr =
           return_address_hint + i * process.GetAddressByteSize();
-      lldb::addr_t candidate =
-          process.ReadPointerFromMemory(candidate_addr, st);
-      if (st.Fail()) {
-        UNWIND_LOG(log, "Cannot read memory at {0:x}: {1}", candidate_addr, 
st);
+      llvm::Expected<lldb::addr_t> candidate =
+          process.ReadPointerFromMemory(candidate_addr);
+      if (!candidate) {
+        LLDB_LOG_ERROR(log, candidate.takeError(),
+                       "Cannot read memory at {1:x}: {0}", candidate_addr);
         return false;
       }
       Address addr;
       uint32_t permissions;
-      if (process.GetLoadAddressPermissions(candidate, permissions) &&
+      if (process.GetLoadAddressPermissions(*candidate, permissions) &&
           permissions & lldb::ePermissionsExecutable) {
         address = candidate_addr;
         UNWIND_LOG(log, "Heuristically found CFA: {0:x}", address);
diff --git a/lldb/source/ValueObject/ValueObjectVTable.cpp 
b/lldb/source/ValueObject/ValueObjectVTable.cpp
index 297ae4ba47446..22564a76d4829 100644
--- a/lldb/source/ValueObject/ValueObjectVTable.cpp
+++ b/lldb/source/ValueObject/ValueObjectVTable.cpp
@@ -17,6 +17,8 @@
 #include "lldb/lldb-forward.h"
 #include "lldb/lldb-private-enumerations.h"
 
+#include "llvm/Support/Error.h"
+
 using namespace lldb;
 using namespace lldb_private;
 
@@ -77,14 +79,16 @@ class ValueObjectVTableChild : public ValueObject {
 
     // Each `vtable_entry_addr` points to the function pointer.
     addr_t vtable_entry_addr = parent_addr + m_func_idx * m_addr_size;
-    addr_t vfunc_ptr =
-        process_sp->ReadPointerFromMemory(vtable_entry_addr, m_error);
-    if (m_error.Fail()) {
+    llvm::Expected<lldb::addr_t> vfunc_ptr_or_err =
+        process_sp->ReadPointerFromMemory(vtable_entry_addr);
+    if (!vfunc_ptr_or_err) {
+      llvm::consumeError(vfunc_ptr_or_err.takeError());
       m_error = Status::FromErrorStringWithFormat(
           "failed to read virtual function entry 0x%16.16" PRIx64,
           vtable_entry_addr);
       return false;
     }
+    addr_t vfunc_ptr = *vfunc_ptr_or_err;
 
     vfunc_ptr = process_sp->FixCodeAddress(vfunc_ptr);
 

_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to