vsk updated this revision to Diff 241602.
vsk retitled this revision from "[lldb/Value] Report size of Value as size of 
underlying data buffer" to "[lldb/Value] Avoid reading more data than the host 
has available".
vsk edited the summary of this revision.
vsk added a comment.

Address review feedback:

- Add a test that doesn't depend on the compiler.
- Convert the old test into a simpler regression test.
- Based on feedback from Jim, don't try to change the definition of a Value's 
size, as the expectation that the type is correct is baked in deeply.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D73148/new/

https://reviews.llvm.org/D73148

Files:
  lldb/packages/Python/lldbsuite/test/functionalities/optimized_code/Makefile
  
lldb/packages/Python/lldbsuite/test/functionalities/optimized_code/TestNoASanExceptionAfterEvalOP_piece.py
  lldb/packages/Python/lldbsuite/test/functionalities/optimized_code/main.cpp
  lldb/source/Core/Value.cpp
  lldb/test/Shell/SymbolFile/DWARF/DW_OP_piece-smaller-than-struct.s

Index: lldb/test/Shell/SymbolFile/DWARF/DW_OP_piece-smaller-than-struct.s
===================================================================
--- /dev/null
+++ lldb/test/Shell/SymbolFile/DWARF/DW_OP_piece-smaller-than-struct.s
@@ -0,0 +1,110 @@
+# RUN: llvm-mc -filetype=obj -o %t -triple x86_64-pc-linux %s
+# RUN: %lldb %t -o "target variable reset" -b | FileCheck %s
+
+# CHECK: (lldb) target variable reset
+# CHECK: (auto_reset) reset = {
+# CHECK:   ptr = 0x{{0+$}}
+# Note: We need to find some way to represent "prev" as unknown/undefined.
+# CHECK:   prev = false
+# CHECK: }
+
+        .section        .debug_abbrev,"",@progbits
+        .byte   1                       # Abbreviation Code
+        .byte   17                      # DW_TAG_compile_unit
+        .byte   1                       # DW_CHILDREN_yes
+        .byte   0                       # EOM(1)
+        .byte   0                       # EOM(2)
+        .byte   2                       # Abbreviation Code
+        .byte   52                      # DW_TAG_variable
+        .byte   0                       # DW_CHILDREN_no
+        .byte   3                       # DW_AT_name
+        .byte   8                       # DW_FORM_string
+        .byte   73                      # DW_AT_type
+        .byte   19                      # DW_FORM_ref4
+        .byte   2                       # DW_AT_location
+        .byte   24                      # DW_FORM_exprloc
+        .byte   0                       # EOM(1)
+        .byte   0                       # EOM(2)
+        .byte   3                       # Abbreviation Code
+        .byte   36                      # DW_TAG_base_type
+        .byte   0                       # DW_CHILDREN_no
+        .byte   3                       # DW_AT_name
+        .byte   8                       # DW_FORM_string
+        .byte   62                      # DW_AT_encoding
+        .byte   11                      # DW_FORM_data1
+        .byte   11                      # DW_AT_byte_size
+        .byte   11                      # DW_FORM_data1
+        .byte   0                       # EOM(1)
+        .byte   0                       # EOM(2)
+        .byte   4                       # Abbreviation Code
+        .byte   19                      # DW_TAG_structure_type
+        .byte   1                       # DW_CHILDREN_yes
+        .byte   3                       # DW_AT_name
+        .byte   8                       # DW_FORM_string
+        .byte   11                      # DW_AT_byte_size
+        .byte   11                      # DW_FORM_data1
+        .byte   0                       # EOM(1)
+        .byte   0                       # EOM(2)
+        .byte   5                       # Abbreviation Code
+        .byte   13                      # DW_TAG_member
+        .byte   0                       # DW_CHILDREN_no
+        .byte   3                       # DW_AT_name
+        .byte   8                       # DW_FORM_string
+        .byte   73                      # DW_AT_type
+        .byte   19                      # DW_FORM_ref4
+        .byte   56                      # DW_AT_data_member_location
+        .byte   11                      # DW_FORM_data1
+        .byte   0                       # EOM(1)
+        .byte   0                       # EOM(2)
+        .byte   6                       # Abbreviation Code
+        .byte   15                      # DW_TAG_pointer_type
+        .byte   0                       # DW_CHILDREN_no
+        .byte   73                      # DW_AT_type
+        .byte   19                      # DW_FORM_ref4
+        .byte   0                       # EOM(1)
+        .byte   0                       # EOM(2)
+        .byte   0                       # EOM(3)
+
+        .section        .debug_info,"",@progbits
+.Lcu_begin0:
+        .long   .Lcu_end-.Lcu_start     # Length of Unit
+.Lcu_start:
+        .short  4                       # DWARF version number
+        .long   .debug_abbrev           # Offset Into Abbrev. Section
+        .byte   8                       # Address Size (in bytes)
+        .byte   1                       # Abbrev [1] 0xb:0x6c DW_TAG_compile_unit
+.Lbool:
+        .byte   3                       # Abbrev [3] 0x33:0x7 DW_TAG_base_type
+        .asciz  "bool"                  # DW_AT_name
+        .byte   2                       # DW_AT_encoding
+        .byte   1                       # DW_AT_byte_size
+        .byte   2                       # Abbrev [2] 0x3a:0x15 DW_TAG_variable
+        .asciz  "reset"                 # DW_AT_name
+        .long   .Lstruct                # DW_AT_type
+        .byte   2f-1f                   # DW_AT_location
+1:
+        .byte   0xe                     # DW_OP_constu
+        .quad   0xdeadbeefbaadf00d
+        .byte   0x9f                    # DW_OP_stack_value
+        .byte   0x93                    # DW_OP_piece
+        .uleb128 8
+        # Note: Only the first 8 bytes of the struct are described.
+2:
+.Lstruct:
+        .byte   4                       # Abbrev [4] 0x4f:0x22 DW_TAG_structure_type
+        .asciz  "auto_reset"            # DW_AT_name
+        .byte   16                      # DW_AT_byte_size
+        .byte   5                       # Abbrev [5] 0x58:0xc DW_TAG_member
+        .asciz  "ptr"                   # DW_AT_name
+        .long   .Lbool_ptr              # DW_AT_type
+        .byte   0                       # DW_AT_data_member_location
+        .byte   5                       # Abbrev [5] 0x64:0xc DW_TAG_member
+        .asciz  "prev"                  # DW_AT_name
+        .long   .Lbool                  # DW_AT_type
+        .byte   8                       # DW_AT_data_member_location
+        .byte   0                       # End Of Children Mark
+.Lbool_ptr:
+        .byte   6                       # Abbrev [6] 0x71:0x5 DW_TAG_pointer_type
+        .long   .Lbool                  # DW_AT_type
+        .byte   0                       # End Of Children Mark
+.Lcu_end:
Index: lldb/source/Core/Value.cpp
===================================================================
--- lldb/source/Core/Value.cpp
+++ lldb/source/Core/Value.cpp
@@ -533,13 +533,24 @@
   uint8_t *dst = const_cast<uint8_t *>(data.PeekData(0, byte_size));
   if (dst != nullptr) {
     if (address_type == eAddressTypeHost) {
+      // Don't read more of the Value than what the host has been able to
+      // actually evaluate. The buffer size may be less than the size prescribed
+      // by the type. E.g. this can happen when an expression containing
+      // DW_OP_piece doesn't describe the whole object.
+      byte_size = GetBuffer().GetByteSize();
+
       // The address is an address in this process, so just copy it.
       if (address == 0) {
         error.SetErrorStringWithFormat(
             "trying to read from host address of 0.");
         return error;
       }
-      memcpy(dst, reinterpret_cast<uint8_t *>(address), byte_size);
+
+      // Only copy if we have something to copy: otherwise, we still want to
+      // return a buffer of the appropriate size. Note that we ought to find a
+      // way to represent undefined bits and use that instead of printing 0's.
+      if (byte_size)
+        memcpy(dst, reinterpret_cast<uint8_t *>(address), byte_size);
     } else if ((address_type == eAddressTypeLoad) ||
                (address_type == eAddressTypeFile)) {
       if (file_so_addr.IsValid()) {
Index: lldb/packages/Python/lldbsuite/test/functionalities/optimized_code/main.cpp
===================================================================
--- /dev/null
+++ lldb/packages/Python/lldbsuite/test/functionalities/optimized_code/main.cpp
@@ -0,0 +1,31 @@
+// This is a regression test that checks whether lldb can inspect the variables
+// in this program without triggering an ASan exception.
+
+__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;
+  sink++; //% self.expect("frame variable v1", substrs=["S1"])
+  S2 v2(v1.f1);
+  sink += use(v2.a); //% self.expect("frame variable v2", substrs=["S2"])
+  sink += use(v2.pad); //% self.expect("frame variable v2", substrs=["S2"])
+  return 0;
+}
Index: lldb/packages/Python/lldbsuite/test/functionalities/optimized_code/TestNoASanExceptionAfterEvalOP_piece.py
===================================================================
--- /dev/null
+++ lldb/packages/Python/lldbsuite/test/functionalities/optimized_code/TestNoASanExceptionAfterEvalOP_piece.py
@@ -0,0 +1,4 @@
+from lldbsuite.test import lldbinline
+from lldbsuite.test import decorators
+
+lldbinline.MakeInlineTest(__file__, globals())
Index: lldb/packages/Python/lldbsuite/test/functionalities/optimized_code/Makefile
===================================================================
--- /dev/null
+++ lldb/packages/Python/lldbsuite/test/functionalities/optimized_code/Makefile
@@ -0,0 +1,3 @@
+CXX_SOURCES := main.cpp
+CXXFLAGS_EXTRAS := -O2
+include Makefile.rules
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to