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
