Fix a buffer-size bug when the first DW_OP_piece is undefined
authorAdrian Prantl <aprantl@apple.com>
Thu, 16 Jan 2020 22:21:17 +0000 (14:21 -0800)
committerAdrian Prantl <aprantl@apple.com>
Fri, 17 Jan 2020 00:47:59 +0000 (16:47 -0800)
and document the shortcomings of LLDB's partially defined DW_OP_piece
handling.

This would manifest as "DW_OP_piece for offset foo but top of stack is
of size bar".

rdar://problem/46262998

Differential Revision: https://reviews.llvm.org/D72880

lldb/source/Expression/DWARFExpression.cpp
lldb/unittests/Expression/DWARFExpressionTest.cpp

index 6af0f37..e09b1a5 100644 (file)
@@ -2071,6 +2071,10 @@ bool DWARFExpression::Evaluate(
           // not available. Fill with zeros for now by resizing the data and
           // appending it
           curr_piece.ResizeData(piece_byte_size);
+          // Note that "0" is not a correct value for the unknown bits.
+          // It would be better to also return a mask of valid bits together
+          // with the expression result, so the debugger can print missing
+          // members as "<optimized out>" or something.
           ::memset(curr_piece.GetBuffer().GetBytes(), 0, piece_byte_size);
           pieces.AppendDataToHostBuffer(curr_piece);
         } else {
@@ -2193,8 +2197,8 @@ bool DWARFExpression::Evaluate(
               return false;
             }
           }
-          op_piece_offset += piece_byte_size;
         }
+        op_piece_offset += piece_byte_size;
       }
     } break;
 
index fe5e9c9..4587615 100644 (file)
@@ -355,4 +355,9 @@ TEST(DWARFExpression, DW_OP_piece) {
   EXPECT_THAT_EXPECTED(Evaluate({DW_OP_const2u, 0x11, 0x22, DW_OP_piece, 2,
                                  DW_OP_const2u, 0x33, 0x44, DW_OP_piece, 2}),
                        llvm::HasValue(GetScalar(32, 0x44332211, true)));
+  EXPECT_THAT_EXPECTED(
+      Evaluate({DW_OP_piece, 1, DW_OP_const1u, 0xff, DW_OP_piece, 1}),
+      // Note that the "00" should really be "undef", but we can't
+      // represent that yet.
+      llvm::HasValue(GetScalar(16, 0xff00, true)));
 }