[Lldb-commits] [lldb] [lldb][test] Reinforce formatter bytecode unit tests (PR #211042)
Dave Lee via lldb-commits
lldb-commits at lists.llvm.org
Tue Jul 21 15:53:34 PDT 2026
https://github.com/kastiglione updated https://github.com/llvm/llvm-project/pull/211042
>From 6e3b34d77976e1b30371e5d4401f9a034708f68e Mon Sep 17 00:00:00 2001
From: Dave Lee <davelee.com at gmail.com>
Date: Tue, 21 Jul 2026 09:35:27 -0700
Subject: [PATCH 1/2] [lldb][test] Reinforce formatter bytecode unit tests
---
.../DataFormatter/FormatterBytecodeTest.cpp | 58 +++++++++++++++++++
1 file changed, 58 insertions(+)
diff --git a/lldb/unittests/DataFormatter/FormatterBytecodeTest.cpp b/lldb/unittests/DataFormatter/FormatterBytecodeTest.cpp
index 20c90bfe6fb60..6c361db813bee 100644
--- a/lldb/unittests/DataFormatter/FormatterBytecodeTest.cpp
+++ b/lldb/unittests/DataFormatter/FormatterBytecodeTest.cpp
@@ -251,6 +251,64 @@ TEST_F(FormatterBytecodeTest, ArithOps) {
}
}
+TEST_F(FormatterBytecodeTest, OutOfBounds) {
+ {
+ // op_lit_uint's ULEB128 operand is truncated: the interpreter runs off
+ // the end of the buffer while decoding it.
+ DataStack data;
+ ASSERT_FALSE(Interpret({op_lit_uint}, data));
+ }
+ {
+ // op_begin claims a block that is longer than the remaining bytecode.
+ DataStack data;
+ ASSERT_FALSE(Interpret({op_begin, 5, op_lit_uint, 42}, data));
+ }
+ {
+ // The ULEB128 byte's continuation bit is set, but there is no
+ // terminating byte.
+ DataStack data;
+ ASSERT_FALSE(Interpret({op_lit_uint, 0x80}, data));
+ }
+ {
+ // Same as above, but for op_lit_int's SLEB128 operand.
+ DataStack data;
+ ASSERT_FALSE(Interpret({op_lit_int, 0x80}, data));
+ }
+ {
+ // The ULEB128 operand encodes a value that doesn't fit into a uint64_t:
+ // 9 continuation bytes (63 bits) followed by a final byte contributing
+ // more than the single remaining bit.
+ DataStack data;
+ ASSERT_FALSE(Interpret({op_lit_uint, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x02},
+ data));
+ }
+ {
+ // Same as above, but for op_lit_int's SLEB128 operand not fitting into
+ // an int64_t.
+ DataStack data;
+ ASSERT_FALSE(Interpret({op_lit_int, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x02},
+ data));
+ }
+}
+
+TEST_F(FormatterBytecodeTest, EmptyBytecode) {
+ DataStack data;
+ ASSERT_TRUE(Interpret({}, data));
+ ASSERT_EQ(data.size(), 0u);
+}
+
+TEST_F(FormatterBytecodeTest, UnknownSelector) {
+ DataStack data;
+ ASSERT_FALSE(Interpret({op_lit_selector, 0xff, op_call}, data));
+}
+
+TEST_F(FormatterBytecodeTest, UnknownOpcode) {
+ DataStack data;
+ ASSERT_FALSE(Interpret({0xaa}, data));
+}
+
TEST_F(FormatterBytecodeTest, CallOps) {
{
DataStack data;
>From 67ab2ad74dc87fff51afa5378a3ae64dddc5a292 Mon Sep 17 00:00:00 2001
From: Dave Lee <davelee.com at gmail.com>
Date: Tue, 21 Jul 2026 15:53:13 -0700
Subject: [PATCH 2/2] Assert error messages for failure cases
---
.../DataFormatter/FormatterBytecodeTest.cpp | 104 ++++++++++--------
1 file changed, 59 insertions(+), 45 deletions(-)
diff --git a/lldb/unittests/DataFormatter/FormatterBytecodeTest.cpp b/lldb/unittests/DataFormatter/FormatterBytecodeTest.cpp
index 6c361db813bee..b8675f92d1f30 100644
--- a/lldb/unittests/DataFormatter/FormatterBytecodeTest.cpp
+++ b/lldb/unittests/DataFormatter/FormatterBytecodeTest.cpp
@@ -1,17 +1,20 @@
#include "lldb/DataFormatters/FormatterBytecode.h"
#include "lldb/Utility/StreamString.h"
+#include "llvm/Testing/Support/Error.h"
#include "gtest/gtest.h"
using namespace lldb_private;
using namespace lldb;
using namespace FormatterBytecode;
+using llvm::FailedWithMessage;
using llvm::StringRef;
namespace {
class FormatterBytecodeTest : public ::testing::Test {};
+} // namespace
-bool Interpret(std::vector<uint8_t> code, DataStack &data) {
+static bool Interpret(std::vector<uint8_t> code, DataStack &data) {
auto buf =
StringRef(reinterpret_cast<const char *>(code.data()), code.size());
ControlStack control({buf});
@@ -26,7 +29,15 @@ bool Interpret(std::vector<uint8_t> code, DataStack &data) {
return true;
}
-} // namespace
+/// Like Interpret() above, but returns (instead of discarding) the Error,
+/// allowing tests to assert on the error message.
+static llvm::Error InterpretFail(std::vector<uint8_t> code) {
+ auto buf =
+ StringRef(reinterpret_cast<const char *>(code.data()), code.size());
+ ControlStack control({buf});
+ DataStack data;
+ return Interpret(control, data, sig_summary);
+}
TEST_F(FormatterBytecodeTest, StackOps) {
{
@@ -252,45 +263,48 @@ TEST_F(FormatterBytecodeTest, ArithOps) {
}
TEST_F(FormatterBytecodeTest, OutOfBounds) {
- {
- // op_lit_uint's ULEB128 operand is truncated: the interpreter runs off
- // the end of the buffer while decoding it.
- DataStack data;
- ASSERT_FALSE(Interpret({op_lit_uint}, data));
- }
- {
- // op_begin claims a block that is longer than the remaining bytecode.
- DataStack data;
- ASSERT_FALSE(Interpret({op_begin, 5, op_lit_uint, 42}, data));
- }
- {
- // The ULEB128 byte's continuation bit is set, but there is no
- // terminating byte.
- DataStack data;
- ASSERT_FALSE(Interpret({op_lit_uint, 0x80}, data));
- }
- {
- // Same as above, but for op_lit_int's SLEB128 operand.
- DataStack data;
- ASSERT_FALSE(Interpret({op_lit_int, 0x80}, data));
- }
- {
- // The ULEB128 operand encodes a value that doesn't fit into a uint64_t:
- // 9 continuation bytes (63 bits) followed by a final byte contributing
- // more than the single remaining bit.
- DataStack data;
- ASSERT_FALSE(Interpret({op_lit_uint, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x02},
- data));
- }
- {
- // Same as above, but for op_lit_int's SLEB128 operand not fitting into
- // an int64_t.
- DataStack data;
- ASSERT_FALSE(Interpret({op_lit_int, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x02},
- data));
- }
+ // op_lit_uint's ULEB128 operand is truncated: the interpreter runs off
+ // the end of the buffer while decoding it.
+ EXPECT_THAT_ERROR(
+ InterpretFail({op_lit_uint}),
+ FailedWithMessage("unable to decode LEB128 at offset 0x00000001: "
+ "malformed uleb128, extends past end"));
+
+ // op_begin claims a block that is longer than the remaining bytecode.
+ EXPECT_THAT_ERROR(
+ InterpretFail({op_begin, 5, op_lit_uint, 42}),
+ FailedWithMessage(
+ "unexpected end of data at offset 0x4 while reading [0x2, 0x7)"));
+
+ // The ULEB128 byte's continuation bit is set, but there is no
+ // terminating byte.
+ EXPECT_THAT_ERROR(
+ InterpretFail({op_lit_uint, 0x80}),
+ FailedWithMessage("unable to decode LEB128 at offset 0x00000001: "
+ "malformed uleb128, extends past end"));
+
+ // Same as above, but for op_lit_int's SLEB128 operand.
+ EXPECT_THAT_ERROR(
+ InterpretFail({op_lit_int, 0x80}),
+ FailedWithMessage("unable to decode LEB128 at offset 0x00000001: "
+ "malformed sleb128, extends past end"));
+
+ // The ULEB128 operand encodes a value that doesn't fit into a uint64_t:
+ // 9 continuation bytes (63 bits) followed by a final byte contributing
+ // more than the single remaining bit.
+ EXPECT_THAT_ERROR(
+ InterpretFail({op_lit_uint, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x02}),
+ FailedWithMessage("unable to decode LEB128 at offset 0x00000001: "
+ "uleb128 too big for uint64"));
+
+ // Same as above, but for op_lit_int's SLEB128 operand not fitting into
+ // an int64_t.
+ EXPECT_THAT_ERROR(
+ InterpretFail({op_lit_int, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x02}),
+ FailedWithMessage("unable to decode LEB128 at offset 0x00000001: "
+ "sleb128 too big for int64"));
}
TEST_F(FormatterBytecodeTest, EmptyBytecode) {
@@ -300,13 +314,13 @@ TEST_F(FormatterBytecodeTest, EmptyBytecode) {
}
TEST_F(FormatterBytecodeTest, UnknownSelector) {
- DataStack data;
- ASSERT_FALSE(Interpret({op_lit_selector, 0xff, op_call}, data));
+ EXPECT_THAT_ERROR(InterpretFail({op_lit_selector, 0xff, op_call}),
+ FailedWithMessage("{0} (opcode={1}, selector={2})"));
}
TEST_F(FormatterBytecodeTest, UnknownOpcode) {
- DataStack data;
- ASSERT_FALSE(Interpret({0xaa}, data));
+ EXPECT_THAT_ERROR(InterpretFail({0xaa}),
+ FailedWithMessage("opcode not implemented(opcode=170)"));
}
TEST_F(FormatterBytecodeTest, CallOps) {
More information about the lldb-commits
mailing list