From e9fad0e91c49ca0f2669989dbad95664cbc9cbf3 Mon Sep 17 00:00:00 2001 From: Pavel Labath Date: Mon, 2 Jun 2025 09:39:56 +0200 Subject: [lldb] Refactor away UB in SBValue::GetLoadAddress (#141799) The problem was in calling GetLoadAddress on a value in the error state, where `ValueObject::GetLoadAddress` could end up accessing the uninitialized "address type" by-ref return value from `GetAddressOf`. This probably happened because each function expected the other to initialize it. We can guarantee initialization by turning this into a proper return value. I've added a test, but it only (reliably) crashes if lldb is built with ubsan. --- lldb/source/Commands/CommandObjectWatchpoint.cpp | 25 +++++++++++------------- 1 file changed, 11 insertions(+), 14 deletions(-) (limited to 'lldb/source/Commands/CommandObjectWatchpoint.cpp') diff --git a/lldb/source/Commands/CommandObjectWatchpoint.cpp b/lldb/source/Commands/CommandObjectWatchpoint.cpp index 20f4b91..e79c3b8 100644 --- a/lldb/source/Commands/CommandObjectWatchpoint.cpp +++ b/lldb/source/Commands/CommandObjectWatchpoint.cpp @@ -822,7 +822,6 @@ protected: // We passed the sanity check for the command. Proceed to set the // watchpoint now. - lldb::addr_t addr = 0; size_t size = 0; VariableSP var_sp; @@ -861,19 +860,7 @@ protected: CompilerType compiler_type; - if (valobj_sp) { - AddressType addr_type; - addr = valobj_sp->GetAddressOf(false, &addr_type); - if (addr_type == eAddressTypeLoad) { - // We're in business. - // Find out the size of this variable. - size = - m_option_watchpoint.watch_size.GetCurrentValue() == 0 - ? llvm::expectedToOptional(valobj_sp->GetByteSize()).value_or(0) - : m_option_watchpoint.watch_size.GetCurrentValue(); - } - compiler_type = valobj_sp->GetCompilerType(); - } else { + if (!valobj_sp) { const char *error_cstr = error.AsCString(nullptr); if (error_cstr) result.AppendError(error_cstr); @@ -883,6 +870,16 @@ protected: command.GetArgumentAtIndex(0)); return; } + auto [addr, addr_type] = valobj_sp->GetAddressOf(false); + if (addr_type == eAddressTypeLoad) { + // We're in business. + // Find out the size of this variable. + size = + m_option_watchpoint.watch_size.GetCurrentValue() == 0 + ? llvm::expectedToOptional(valobj_sp->GetByteSize()).value_or(0) + : m_option_watchpoint.watch_size.GetCurrentValue(); + } + compiler_type = valobj_sp->GetCompilerType(); // Now it's time to create the watchpoint. uint32_t watch_type = 0; -- cgit v1.1