Skip to content

Commit bf25180

Browse files
Sterling-Augustinetstellar
authored andcommitted
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 55b7061)
1 parent cf3e126 commit bf25180

File tree

3 files changed

+21
-11
lines changed

3 files changed

+21
-11
lines changed

libcxx/test/libcxx/gdb/gdb_pretty_printer_test.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ def invoke(self, arg, from_tty):
4545
# Ignore the convenience variable name and newline
4646
value = value_str[value_str.find("= ") + 2:-1]
4747
gdb.newest_frame().select()
48-
4948
expectation_val = compare_frame.read_var("expectation")
5049
check_literal = expectation_val.string(encoding="utf-8")
5150
if "PrettyPrintToRegex" in compare_frame.name():

libcxx/test/libcxx/gdb/gdb_pretty_printer_test.sh.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -608,25 +608,27 @@ void shared_ptr_test() {
608608
// due to which there is one more count for the pointer. Hence, all the
609609
// following tests are testing with expected count plus 1.
610610
std::shared_ptr<const int> test0 = std::make_shared<const int>(5);
611+
// The python regular expression matcher treats newlines as significant, so
612+
// these regular expressions should be on one line.
611613
ComparePrettyPrintToRegex(
612614
test0,
613-
R"(std::shared_ptr<int> count 2, weak 0 containing = {__ptr_ = 0x[a-f0-9]+})");
615+
R"(std::shared_ptr<int> count [2\?], weak [0\?]( \(libc\+\+ missing debug info\))? containing = {__ptr_ = 0x[a-f0-9]+})");
614616

615617
std::shared_ptr<const int> test1(test0);
616618
ComparePrettyPrintToRegex(
617619
test1,
618-
R"(std::shared_ptr<int> count 3, weak 0 containing = {__ptr_ = 0x[a-f0-9]+})");
620+
R"(std::shared_ptr<int> count [3\?], weak [0\?]( \(libc\+\+ missing debug info\))? containing = {__ptr_ = 0x[a-f0-9]+})");
619621

620622
{
621623
std::weak_ptr<const int> test2 = test1;
622624
ComparePrettyPrintToRegex(
623625
test0,
624-
R"(std::shared_ptr<int> count 3, weak 1 containing = {__ptr_ = 0x[a-f0-9]+})");
626+
R"(std::shared_ptr<int> count [3\?], weak [1\?]( \(libc\+\+ missing debug info\))? containing = {__ptr_ = 0x[a-f0-9]+})");
625627
}
626628

627629
ComparePrettyPrintToRegex(
628630
test0,
629-
R"(std::shared_ptr<int> count 3, weak 0 containing = {__ptr_ = 0x[a-f0-9]+})");
631+
R"(std::shared_ptr<int> count [3\?], weak [0\?]( \(libc\+\+ missing debug info\))? containing = {__ptr_ = 0x[a-f0-9]+})");
630632

631633
std::shared_ptr<const int> test3;
632634
ComparePrettyPrintToChars(test3, "std::shared_ptr is nullptr");

libcxx/utils/gdb/libcxx/printers.py

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -312,12 +312,21 @@ def to_string(self):
312312
return "%s is nullptr" % typename
313313
refcount = self.val["__cntrl_"]
314314
if refcount != 0:
315-
usecount = refcount["__shared_owners_"] + 1
316-
weakcount = refcount["__shared_weak_owners_"]
317-
if usecount == 0:
318-
state = "expired, weak %d" % weakcount
319-
else:
320-
state = "count %d, weak %d" % (usecount, weakcount)
315+
try:
316+
usecount = refcount["__shared_owners_"] + 1
317+
weakcount = refcount["__shared_weak_owners_"]
318+
if usecount == 0:
319+
state = "expired, weak %d" % weakcount
320+
else:
321+
state = "count %d, weak %d" % (usecount, weakcount)
322+
except:
323+
# Debug info for a class with virtual functions is emitted
324+
# in the same place as its key function. That means that
325+
# for std::shared_ptr, __shared_owners_ is emitted into
326+
# into libcxx.[so|a] itself, rather than into the shared_ptr
327+
# instantiation point. So if libcxx.so was built without
328+
# debug info, these fields will be missing.
329+
state = "count ?, weak ? (libc++ missing debug info)"
321330
return "%s<%s> %s containing" % (typename, pointee_type, state)
322331

323332
def __iter__(self):

0 commit comments

Comments
 (0)