vsk updated this revision to Diff 239753.
vsk edited the summary of this revision.
This revision is now accepted and ready to land.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D73148/new/
https://reviews.llvm.org/D73148
Files:
lldb/packages/Python/lldbsuite/test/functionalities/dw_op_piece/Makefile
lldb/packages/Python/lldbsuite/test/functionalities/dw_op_piece/TestDW_OP_piece.py
lldb/packages/Python/lldbsuite/test/functionalities/dw_op_piece/main.cpp
lldb/source/Core/Value.cpp
lldb/unittests/Expression/DWARFExpressionTest.cpp
Index: lldb/unittests/Expression/DWARFExpressionTest.cpp
===================================================================
--- lldb/unittests/Expression/DWARFExpressionTest.cpp
+++ lldb/unittests/Expression/DWARFExpressionTest.cpp
@@ -360,4 +360,27 @@
// Note that the "00" should really be "undef", but we can't
// represent that yet.
llvm::HasValue(GetScalar(16, 0xff00, true)));
+
+ for (unsigned char ByteSize = 1; ByteSize <= 8; ++ByteSize) {
+ llvm::Expected<Scalar> empty = Evaluate({DW_OP_piece, ByteSize});
+ // Note that the "0" should really be "undef", but we can't
+ // represent that yet.
+ EXPECT_THAT_EXPECTED(empty,
+ llvm::HasValue(GetScalar(ByteSize * 8, 0, true)));
+
+ Value pieces;
+ ASSERT_EQ(pieces.AppendDataToHostBuffer(empty.get()), ByteSize);
+ ASSERT_EQ(pieces.GetValueByteSize(nullptr, nullptr), ByteSize);
+ }
+
+ // When CommandObjectFrameVariable constructs an empty Value, check that
+ // we do not successfully report its size as 0. A CompilerType is needed to
+ // get the size in this special case.
+ {
+ Value empty;
+ empty.ResizeData(0);
+ Status error;
+ ASSERT_EQ(empty.GetValueByteSize(&error, nullptr), 0);
+ ASSERT_TRUE(error.Fail());
+ }
}
Index: lldb/source/Core/Value.cpp
===================================================================
--- lldb/source/Core/Value.cpp
+++ lldb/source/Core/Value.cpp
@@ -222,6 +222,12 @@
case eContextTypeLLDBType: // Type *
case eContextTypeVariable: // Variable *
{
+ // The size of this Value may be less than the size of the type of its
+ // source variable due to truncating operations such as DW_OP_piece.
+ if (m_value_type == eValueTypeHostAddress)
+ if (uint64_t buffer_size = GetBuffer().GetByteSize())
+ return buffer_size;
+
auto *scope = exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr;
if (llvm::Optional<uint64_t> size = GetCompilerType().GetByteSize(scope)) {
if (error_ptr)
Index: lldb/packages/Python/lldbsuite/test/functionalities/dw_op_piece/main.cpp
===================================================================
--- /dev/null
+++ lldb/packages/Python/lldbsuite/test/functionalities/dw_op_piece/main.cpp
@@ -0,0 +1,62 @@
+// The point of this test is to exercise lldb's DW_OP_piece evaluation logic.
+// The CHECK lines in the test depend on aspects of the optimizer's behavior
+// that aren't guaranteed. If the test fails after a compiler change, run it in
+// trace mode (./bin/lldb-dotest -t ...): this should print out the new location
+// expressions.
+
+__attribute__((noinline, optnone)) int use(int x) { return x; }
+
+volatile int sink;
+
+struct S1 {
+ int f1;
+ int *f2;
+};
+
+struct S2 {
+ char a, b;
+ int pad;
+ S2(int x) {
+ a = x & 0xff;
+ b = x & 0xff00;
+ }
+};
+
+int main() {
+ S1 v1;
+ v1.f1 = sink;
+ v1.f2 = nullptr;
+
+ // 1) Check that "v1" is described by 3 pieces (one each for "f1" and "f2"
+ // (in registers), and a third for padding (a literal)).
+ //
+ //% self.filecheck("image lookup -va $pc", "main.cpp", "-check-prefix=INFO-V1")
+ // INFO-V1: name = "v1", type = "S1", location = DW_OP_reg0 RAX, DW_OP_piece 0x4, DW_OP_piece 0x4, DW_OP_lit0, DW_OP_stack_value, DW_OP_piece 0x8, decl
+ sink++;
+
+ // 2) Check that lldb displays "v1" correctly.
+ //
+ //% self.filecheck("frame variable v1", "main.cpp", "-check-prefix=SHOW-V1")
+ // SHOW-V1: (S1) v1 = {
+ // SHOW-V1-NEXT: f1 = 0
+ // SHOW-V1-NEXT: f2 = 0x{{0+$}}
+ // SHOW-V1-NEXT: }
+
+ S2 v2(v1.f1);
+
+ // 3) Check that "v2" is described by 2 pieces (one each for "a" and "b").
+ // Note that a piece for "pad" is left out: this is crucial, as it means that
+ // DWARFExpression::Evaluate() will produce a 2-byte Value. We want to test
+ // that lldb can handle the Value without smashing memory (this is a
+ // regression test for a bug found by ASan).
+ sink += use(v2.a);
+ //% self.filecheck("image lookup -va $pc", "main.cpp", "-check-prefix=INFO-V2")
+ // INFO-V2: name = "v2", type = "S2", location = DW_OP_piece 0x1, DW_OP_lit0, DW_OP_stack_value, DW_OP_piece 0x1, decl
+
+ // 4) Check that lldb displays "v2" correctly.
+ sink += use(v2.pad);
+ //% self.filecheck("frame variable v2", "main.cpp", "-check-prefix=SHOW-V2")
+ // SHOW-V2: (S2) v2 = (a = '\0', b = '\0', pad = {{.*}})
+
+ return 0;
+}
Index: lldb/packages/Python/lldbsuite/test/functionalities/dw_op_piece/TestDW_OP_piece.py
===================================================================
--- /dev/null
+++ lldb/packages/Python/lldbsuite/test/functionalities/dw_op_piece/TestDW_OP_piece.py
@@ -0,0 +1,5 @@
+from lldbsuite.test import lldbinline
+from lldbsuite.test import decorators
+
+lldbinline.MakeInlineTest(__file__, globals(),
+ [decorators.skipUnlessArch('x86_64')])
Index: lldb/packages/Python/lldbsuite/test/functionalities/dw_op_piece/Makefile
===================================================================
--- /dev/null
+++ lldb/packages/Python/lldbsuite/test/functionalities/dw_op_piece/Makefile
@@ -0,0 +1,3 @@
+CXX_SOURCES := main.cpp
+CXXFLAGS_EXTRAS := -O2
+include Makefile.rules
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits