[llvm-branch-commits] [libcxx] bf25180 - Tolerate missing debug info in the shared_ptr pretty printer.

Tom Stellard via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Tue Jun 8 16:11:43 PDT 2021


Author: Sterling Augustine
Date: 2021-06-08T16:11:06-07:00
New Revision: bf25180e6727f53b916c73e53212b274fe64ded6

URL: https://github.com/llvm/llvm-project/commit/bf25180e6727f53b916c73e53212b274fe64ded6
DIFF: https://github.com/llvm/llvm-project/commit/bf25180e6727f53b916c73e53212b274fe64ded6.diff

LOG: Tolerate missing debug info in the shared_ptr pretty printer.

Certain fields of shared ptr have virtual functions and therefore
have their debug info homed in libc++. But if libc++ wasn't built
with debug info, the pretty printer would fail.

This patch makes the pretty printer tolerate such conditions and
updates the test harness.

This patch significantly reworks a previous attempt.

This addresses https://bugs.llvm.org/show_bug.cgi?id=48937

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

(cherry picked from commit 55b7061116b5f0f839bd4240c3c6fba63918b816)

Added: 
    

Modified: 
    libcxx/test/libcxx/gdb/gdb_pretty_printer_test.py
    libcxx/test/libcxx/gdb/gdb_pretty_printer_test.sh.cpp
    libcxx/utils/gdb/libcxx/printers.py

Removed: 
    


################################################################################
diff  --git a/libcxx/test/libcxx/gdb/gdb_pretty_printer_test.py b/libcxx/test/libcxx/gdb/gdb_pretty_printer_test.py
index 19e9a4a793bf8..b9d00371418e8 100644
--- a/libcxx/test/libcxx/gdb/gdb_pretty_printer_test.py
+++ b/libcxx/test/libcxx/gdb/gdb_pretty_printer_test.py
@@ -45,7 +45,6 @@ def invoke(self, arg, from_tty):
             # Ignore the convenience variable name and newline
             value = value_str[value_str.find("= ") + 2:-1]
             gdb.newest_frame().select()
-
             expectation_val = compare_frame.read_var("expectation")
             check_literal = expectation_val.string(encoding="utf-8")
             if "PrettyPrintToRegex" in compare_frame.name():

diff  --git a/libcxx/test/libcxx/gdb/gdb_pretty_printer_test.sh.cpp b/libcxx/test/libcxx/gdb/gdb_pretty_printer_test.sh.cpp
index d8a02a3845638..2d8e9620089a4 100644
--- a/libcxx/test/libcxx/gdb/gdb_pretty_printer_test.sh.cpp
+++ b/libcxx/test/libcxx/gdb/gdb_pretty_printer_test.sh.cpp
@@ -608,25 +608,27 @@ void shared_ptr_test() {
   // due to which there is one more count for the pointer. Hence, all the
   // following tests are testing with expected count plus 1.
   std::shared_ptr<const int> test0 = std::make_shared<const int>(5);
+  // The python regular expression matcher treats newlines as significant, so
+  // these regular expressions should be on one line.
   ComparePrettyPrintToRegex(
       test0,
-      R"(std::shared_ptr<int> count 2, weak 0 containing = {__ptr_ = 0x[a-f0-9]+})");
+      R"(std::shared_ptr<int> count [2\?], weak [0\?]( \(libc\+\+ missing debug info\))? containing = {__ptr_ = 0x[a-f0-9]+})");
 
   std::shared_ptr<const int> test1(test0);
   ComparePrettyPrintToRegex(
       test1,
-      R"(std::shared_ptr<int> count 3, weak 0 containing = {__ptr_ = 0x[a-f0-9]+})");
+      R"(std::shared_ptr<int> count [3\?], weak [0\?]( \(libc\+\+ missing debug info\))? containing = {__ptr_ = 0x[a-f0-9]+})");
 
   {
     std::weak_ptr<const int> test2 = test1;
     ComparePrettyPrintToRegex(
         test0,
-        R"(std::shared_ptr<int> count 3, weak 1 containing = {__ptr_ = 0x[a-f0-9]+})");
+        R"(std::shared_ptr<int> count [3\?], weak [1\?]( \(libc\+\+ missing debug info\))? containing = {__ptr_ = 0x[a-f0-9]+})");
   }
 
   ComparePrettyPrintToRegex(
       test0,
-      R"(std::shared_ptr<int> count 3, weak 0 containing = {__ptr_ = 0x[a-f0-9]+})");
+      R"(std::shared_ptr<int> count [3\?], weak [0\?]( \(libc\+\+ missing debug info\))? containing = {__ptr_ = 0x[a-f0-9]+})");
 
   std::shared_ptr<const int> test3;
   ComparePrettyPrintToChars(test3, "std::shared_ptr is nullptr");

diff  --git a/libcxx/utils/gdb/libcxx/printers.py b/libcxx/utils/gdb/libcxx/printers.py
index 9b413a86b1597..9d9a96a3e36f7 100644
--- a/libcxx/utils/gdb/libcxx/printers.py
+++ b/libcxx/utils/gdb/libcxx/printers.py
@@ -312,12 +312,21 @@ def to_string(self):
             return "%s is nullptr" % typename
         refcount = self.val["__cntrl_"]
         if refcount != 0:
-            usecount = refcount["__shared_owners_"] + 1
-            weakcount = refcount["__shared_weak_owners_"]
-            if usecount == 0:
-                state = "expired, weak %d" % weakcount
-            else:
-                state = "count %d, weak %d" % (usecount, weakcount)
+            try:
+                usecount = refcount["__shared_owners_"] + 1
+                weakcount = refcount["__shared_weak_owners_"]
+                if usecount == 0:
+                    state = "expired, weak %d" % weakcount
+                else:
+                    state = "count %d, weak %d" % (usecount, weakcount)
+            except:
+                # Debug info for a class with virtual functions is emitted
+                # in the same place as its key function. That means that
+                # for std::shared_ptr, __shared_owners_ is emitted into
+                # into libcxx.[so|a] itself, rather than into the shared_ptr
+                # instantiation point. So if libcxx.so was built without
+                # debug info, these fields will be missing.
+                state = "count ?, weak ? (libc++ missing debug info)"
         return "%s<%s> %s containing" % (typename, pointee_type, state)
 
     def __iter__(self):


        


More information about the llvm-branch-commits mailing list