[Lldb-commits] [lldb] r299249 - Do not dereference std::unique_ptr by default

Tamas Berghammer via lldb-commits lldb-commits at lists.llvm.org
Fri Mar 31 13:07:20 PDT 2017


Author: tberghammer
Date: Fri Mar 31 15:07:20 2017
New Revision: 299249

URL: http://llvm.org/viewvc/llvm-project?rev=299249&view=rev
Log:
Do not dereference std::unique_ptr by default

Summary:
Displaying the object pointed by the unique_ptr can cause an infinite
recursion when we have a pointer loop so this change stops that
behavior. Additionally it makes the unique_ptr act more like a class
containing a pointer (what is the underlying truth) instead of some
"magic" class.

Reviewers: labath, jingham

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

Modified:
    lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/unique_ptr/TestDataFormatterStdUniquePtr.py
    lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/unique_ptr/main.cpp
    lldb/trunk/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp

Modified: lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/unique_ptr/TestDataFormatterStdUniquePtr.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/unique_ptr/TestDataFormatterStdUniquePtr.py?rev=299249&r1=299248&r2=299249&view=diff
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/unique_ptr/TestDataFormatterStdUniquePtr.py (original)
+++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/unique_ptr/TestDataFormatterStdUniquePtr.py Fri Mar 31 15:07:20 2017
@@ -34,13 +34,13 @@ class StdUniquePtrDataFormatterTestCase(
         self.assertTrue(frame.IsValid())
 
         self.expect("frame variable nup", substrs=['nup = nullptr'])
-        self.expect("frame variable iup", substrs=['iup = 0x', 'object = 123'])
-        self.expect("frame variable sup", substrs=['sup = 0x', 'object = "foobar"'])
+        self.expect("frame variable iup", substrs=['iup = 0x'])
+        self.expect("frame variable sup", substrs=['sup = 0x'])
 
         self.expect("frame variable ndp", substrs=['ndp = nullptr'])
-        self.expect("frame variable idp", substrs=['idp = 0x', 'object = 456', 'deleter = ', 'a = 1', 'b = 2'])
-        self.expect("frame variable sdp", substrs=['sdp = 0x', 'object = "baz"', 'deleter = ', 'a = 3', 'b = 4'])
-        
+        self.expect("frame variable idp", substrs=['idp = 0x', 'deleter = ', 'a = 1', 'b = 2'])
+        self.expect("frame variable sdp", substrs=['sdp = 0x', 'deleter = ', 'a = 3', 'b = 4'])
+
         self.assertEqual(123, frame.GetValueForVariablePath("iup.object").GetValueAsUnsigned())
         self.assertFalse(frame.GetValueForVariablePath("iup.deleter").IsValid())
 
@@ -59,3 +59,32 @@ class StdUniquePtrDataFormatterTestCase(
         self.assertTrue(sdp_deleter.IsValid())
         self.assertEqual(3, sdp_deleter.GetChildMemberWithName("a").GetValueAsUnsigned())
         self.assertEqual(4, sdp_deleter.GetChildMemberWithName("b").GetValueAsUnsigned())
+
+    @skipIfFreeBSD
+    @skipIfWindows  # libstdcpp not ported to Windows
+    @skipIfDarwin  # doesn't compile on Darwin
+    def test_recursive_unique_ptr(self):
+        # Tests that LLDB can handle when we have a loop in the unique_ptr
+        # reference chain and that it correctly handles the different options
+        # for the frame variable command in this case.
+        self.build()
+        self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
+
+        lldbutil.run_break_set_by_source_regexp(
+            self, "Set break point at this line.")
+        self.runCmd("run", RUN_SUCCEEDED)
+        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+                    substrs=['stopped', 'stop reason = breakpoint'])
+
+        self.expect("frame variable f1->fp",
+                    substrs=['fp = 0x'])
+        self.expect("frame variable --ptr-depth=1 f1->fp",
+                    substrs=['data = 2', 'fp = 0x'])
+        self.expect("frame variable --ptr-depth=2 f1->fp",
+                    substrs=['data = 2', 'fp = 0x', 'data = 1'])
+
+        frame = self.frame()
+        self.assertTrue(frame.IsValid())
+        self.assertEqual(2, frame.GetValueForVariablePath("f1->fp.object.data").GetValueAsUnsigned())
+        self.assertEqual(1, frame.GetValueForVariablePath("f1->fp.object.fp.object.data").GetValueAsUnsigned())
+

Modified: lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/unique_ptr/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/unique_ptr/main.cpp?rev=299249&r1=299248&r2=299249&view=diff
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/unique_ptr/main.cpp (original)
+++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/unique_ptr/main.cpp Fri Mar 31 15:07:20 2017
@@ -8,6 +8,11 @@ struct Deleter {
   int b;
 };
 
+struct Foo {
+  int data;
+  std::unique_ptr<Foo> fp;
+};
+
 int main() {
   std::unique_ptr<char> nup;
   std::unique_ptr<int> iup(new int{123});
@@ -18,5 +23,13 @@ int main() {
   std::unique_ptr<std::string, Deleter> sdp(new std::string("baz"),
                                             Deleter{3, 4});
 
+  std::unique_ptr<Foo> fp(new Foo{3});
+
+  // Set up a structure where we have a loop in the unique_ptr chain.
+  Foo* f1 = new Foo{1};
+  Foo* f2 = new Foo{2};
+  f1->fp.reset(f2);
+  f2->fp.reset(f1);
+
   return 0; // Set break point at this line.
 }

Modified: lldb/trunk/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp?rev=299249&r1=299248&r2=299249&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp (original)
+++ lldb/trunk/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp Fri Mar 31 15:07:20 2017
@@ -94,29 +94,27 @@ bool LibStdcppUniquePtrSyntheticFrontEnd
 lldb::ValueObjectSP
 LibStdcppUniquePtrSyntheticFrontEnd::GetChildAtIndex(size_t idx) {
   if (idx == 0)
-    return m_obj_obj;
+    return m_ptr_obj;
   if (idx == 1)
     return m_del_obj;
   if (idx == 2)
-    return m_ptr_obj;
+    return m_obj_obj;
   return lldb::ValueObjectSP();
 }
 
 size_t LibStdcppUniquePtrSyntheticFrontEnd::CalculateNumChildren() {
   if (m_del_obj)
     return 2;
-  if (m_ptr_obj && m_ptr_obj->GetValueAsUnsigned(0) != 0)
-    return 1;
-  return 0;
+  return 1;
 }
 
 size_t LibStdcppUniquePtrSyntheticFrontEnd::GetIndexOfChildWithName(
     const ConstString &name) {
-  if (name == ConstString("obj") || name == ConstString("object"))
+  if (name == ConstString("ptr") || name == ConstString("pointer"))
     return 0;
   if (name == ConstString("del") || name == ConstString("deleter"))
     return 1;
-  if (name == ConstString("ptr") || name == ConstString("pointer"))
+  if (name == ConstString("obj") || name == ConstString("object"))
     return 2;
   return UINT32_MAX;
 }




More information about the lldb-commits mailing list