From d6fcaef28163fee7f8884fd187a7c10918901737 Mon Sep 17 00:00:00 2001 From: nerix Date: Fri, 22 Aug 2025 12:26:03 +0200 Subject: [PATCH] [LLDB][Value] Require type size when reading a scalar (#153386) When reading a value as a scalar, the type size is required. It's returned as a `std::optional`. This optional isn't checked for scalar values, where it is unconditionally accessed. This came up in the [Shell/Process/Windows/msstl_smoke.cpp](https://github.com/llvm/llvm-project/blob/4e10b62442e9edf1769b98406b0559f515d9791f/lldb/test/Shell/Process/Windows/msstl_smoke.cpp) test. There, LLDB breaks at the function entry, so all locals aren't initialized yet. Most values will contain garbage. The [`std::list` synthetic provider](https://github.com/llvm/llvm-project/blob/4e10b62442e9edf1769b98406b0559f515d9791f/lldb/source/Plugins/Language/CPlusPlus/GenericList.cpp#L517) tries to read the value using `GetData`. However, in [`ValueObject::GetData`](https://github.com/llvm/llvm-project/blob/4e10b62442e9edf1769b98406b0559f515d9791f/lldb/source/ValueObject/ValueObject.cpp#L766), [`ValueObjectChild::UpdateValue`](https://github.com/llvm/llvm-project/blob/88c993fbc5b87030b082aeb99d4db94cc885ed1d/lldb/source/ValueObject/ValueObjectChild.cpp#L102) fails because the parent already failed to read its data, so `m_value` won't have a compiler type, thus the size can't be read. --- lldb/source/Core/Value.cpp | 3 +++ lldb/unittests/Core/CMakeLists.txt | 1 + lldb/unittests/Core/Value.cpp | 39 ++++++++++++++++++++++++++++++ 3 files changed, 43 insertions(+) create mode 100644 lldb/unittests/Core/Value.cpp diff --git a/lldb/source/Core/Value.cpp b/lldb/source/Core/Value.cpp index 86327e3a5733..f9e65d397f05 100644 --- a/lldb/source/Core/Value.cpp +++ b/lldb/source/Core/Value.cpp @@ -347,6 +347,9 @@ Status Value::GetValueAsData(ExecutionContext *exe_ctx, DataExtractor &data, else data.SetAddressByteSize(sizeof(void *)); + if (!type_size) + return Status::FromErrorString("type does not have a size"); + uint32_t result_byte_size = *type_size; if (m_value.GetData(data, result_byte_size)) return error; // Success; diff --git a/lldb/unittests/Core/CMakeLists.txt b/lldb/unittests/Core/CMakeLists.txt index a6820bdc7d7f..6e609a63ad9b 100644 --- a/lldb/unittests/Core/CMakeLists.txt +++ b/lldb/unittests/Core/CMakeLists.txt @@ -15,6 +15,7 @@ add_lldb_unittest(LLDBCoreTests SourceManagerTest.cpp TelemetryTest.cpp UniqueCStringMapTest.cpp + Value.cpp LINK_COMPONENTS Support diff --git a/lldb/unittests/Core/Value.cpp b/lldb/unittests/Core/Value.cpp new file mode 100644 index 000000000000..d18a700c00ec --- /dev/null +++ b/lldb/unittests/Core/Value.cpp @@ -0,0 +1,39 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "lldb/Core/Value.h" +#include "Plugins/Platform/MacOSX/PlatformMacOSX.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" +#include "TestingSupport/SubsystemRAII.h" +#include "TestingSupport/Symbol/ClangTestUtils.h" + +#include "lldb/Utility/DataExtractor.h" + +#include "gtest/gtest.h" + +using namespace lldb_private; +using namespace lldb_private::clang_utils; + +TEST(ValueTest, GetValueAsData) { + SubsystemRAII subsystems; + auto holder = std::make_unique("test"); + auto *clang = holder->GetAST(); + + Value v(Scalar(42)); + DataExtractor extractor; + + // no compiler type + Status status = v.GetValueAsData(nullptr, extractor, nullptr); + ASSERT_TRUE(status.Fail()); + + // with compiler type + v.SetCompilerType(clang->GetBasicType(lldb::BasicType::eBasicTypeChar)); + + status = v.GetValueAsData(nullptr, extractor, nullptr); + ASSERT_TRUE(status.Success()); +}