diff options
author | Pavel Labath <pavel@labath.sk> | 2025-06-02 09:39:56 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-06-02 09:39:56 +0200 |
commit | e9fad0e91c49ca0f2669989dbad95664cbc9cbf3 (patch) | |
tree | 334be0ec84d6ca6d6db42f670c01fa2622c4b884 /lldb/source/Commands/CommandObjectWatchpoint.cpp | |
parent | 246d5da7fedb39ba1ad838032f2946535606631d (diff) | |
download | llvm-e9fad0e91c49ca0f2669989dbad95664cbc9cbf3.zip llvm-e9fad0e91c49ca0f2669989dbad95664cbc9cbf3.tar.gz llvm-e9fad0e91c49ca0f2669989dbad95664cbc9cbf3.tar.bz2 |
[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.
Diffstat (limited to 'lldb/source/Commands/CommandObjectWatchpoint.cpp')
-rw-r--r-- | lldb/source/Commands/CommandObjectWatchpoint.cpp | 25 |
1 files changed, 11 insertions, 14 deletions
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; |