[libcxx-commits] [libcxx] [libc++] Fix gdb pretty printer for strings (PR #176882)
Johan Bengtsson via libcxx-commits
libcxx-commits at lists.llvm.org
Tue Feb 3 05:54:33 PST 2026
https://github.com/JohanBengtssonIAR updated https://github.com/llvm/llvm-project/pull/176882
>From b590deba7b07afc027b764a2260c3ddd50ff800c Mon Sep 17 00:00:00 2001
From: Johan Bengtsson <johan.bengtsson at iar.com>
Date: Tue, 20 Jan 2026 10:40:40 +0100
Subject: [PATCH 1/4] [libc++] Fix gdb pretty printer for strings
The gdb pretty printer for strings reports an error when printing a string that
is small enough to fit inline in the string object. The problem is that the
lazy_string method can't be applied directly to an array value. The fix is to
cast the array to a pointer and apply lazy_string to that value.
---
libcxx/utils/gdb/libcxx/printers.py | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/libcxx/utils/gdb/libcxx/printers.py b/libcxx/utils/gdb/libcxx/printers.py
index 1c8ef6d7feb97..4c04894db7f5d 100644
--- a/libcxx/utils/gdb/libcxx/printers.py
+++ b/libcxx/utils/gdb/libcxx/printers.py
@@ -198,7 +198,8 @@ def to_string(self):
data = long_field["__data_"]
size = long_field["__size_"]
else:
- data = short_field["__data_"]
+ char_ptr = gdb.lookup_type("char").pointer()
+ data = short_field["__data_"].cast(char_ptr)
size = short_field["__size_"]
return data.lazy_string(length=size)
>From 7f3675e4b53866677db0c78383dcf5f730623ca8 Mon Sep 17 00:00:00 2001
From: Johan Bengtsson <johan.bengtsson at iar.com>
Date: Tue, 20 Jan 2026 11:07:06 +0100
Subject: [PATCH 2/4] Make string pointer type based on type of data field
Instead of hardcoding the type of the pointer to use for lazy string to char
the pointer type is derived from the type of the array elements. This fixes the
problem when the string has non-char content.
---
libcxx/utils/gdb/libcxx/printers.py | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/libcxx/utils/gdb/libcxx/printers.py b/libcxx/utils/gdb/libcxx/printers.py
index 4c04894db7f5d..ccaa6e9a019e8 100644
--- a/libcxx/utils/gdb/libcxx/printers.py
+++ b/libcxx/utils/gdb/libcxx/printers.py
@@ -198,8 +198,9 @@ def to_string(self):
data = long_field["__data_"]
size = long_field["__size_"]
else:
- char_ptr = gdb.lookup_type("char").pointer()
- data = short_field["__data_"].cast(char_ptr)
+ data = short_field["__data_"]
+ ptr_type = data.type.target().pointer()
+ data = data.cast(ptr_type)
size = short_field["__size_"]
return data.lazy_string(length=size)
>From c3cd29615f5caa8a5f1e7caffdd6f330812fbe15 Mon Sep 17 00:00:00 2001
From: Johan Bengtsson <johan.bengtsson at iar.com>
Date: Mon, 2 Feb 2026 18:47:57 +0100
Subject: [PATCH 3/4] Add regression tests for pretty printing of strings
It turns out that strings returned by gdb expressions are handled differently
from variables when it comes to pretty printing so two new cases are added.
---
.../libcxx/gdb/gdb_pretty_printer_test.sh.cpp | 22 ++++++++++++++++++-
1 file changed, 21 insertions(+), 1 deletion(-)
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 f5a878582666b..881f18bfe04cb 100644
--- a/libcxx/test/libcxx/gdb/gdb_pretty_printer_test.sh.cpp
+++ b/libcxx/test/libcxx/gdb/gdb_pretty_printer_test.sh.cpp
@@ -172,6 +172,19 @@ template <typename T> class UncompressibleAllocator : public std::allocator<T> {
};
};
+// Helper function to check pretty printing of short strings returned by
+// debugger-called functions.
+std::string return_short_string() {
+ return "abc";
+}
+
+// Helper function to check pretty printing of long strings returned by
+// debugger-called functions.
+std::basic_string<char, std::char_traits<char>, UncompressibleAllocator<char>>
+return_long_string() {
+ return "this is a string that is too long to fit in the string object";
+}
+
void string_test() {
std::string short_string("kdjflskdjf");
// The display_hint "string" adds quotes the printed result.
@@ -181,7 +194,14 @@ void string_test() {
long_string("mehmet bizim dostumuz agzi kirik testimiz");
ComparePrettyPrintToChars(long_string,
"\"mehmet bizim dostumuz agzi kirik testimiz\"");
-}
+
+ // GDB handles strings that are returned from a debugger called function or
+ // when stepping out of a function differently from string variables. These
+ // two tests check that pretty printing works also for this case.
+ CompareExpressionPrettyPrintToChars("return_short_string()", "\"abc\"");
+ CompareExpressionPrettyPrintToChars("return_long_string()",
+ "\"this is a string that is too long to fit in the string object\"");
+ }
namespace a_namespace {
// To test name-lookup in the presence of using inside a namespace. Inside this
>From 66e60b66aa4020769af55c992d15105e6de83201 Mon Sep 17 00:00:00 2001
From: Johan Bengtsson <johan.bengtsson at iar.com>
Date: Tue, 3 Feb 2026 14:40:14 +0100
Subject: [PATCH 4/4] Add regression tests for pretty printing of unicode
strings
This is to make sure prettu printing works also for strings with wider
encodings.
---
.../libcxx/gdb/gdb_pretty_printer_test.sh.cpp | 28 +++++++++++++++++++
1 file changed, 28 insertions(+)
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 881f18bfe04cb..638137f8d4c58 100644
--- a/libcxx/test/libcxx/gdb/gdb_pretty_printer_test.sh.cpp
+++ b/libcxx/test/libcxx/gdb/gdb_pretty_printer_test.sh.cpp
@@ -231,6 +231,14 @@ void string_view_test() {
}
}
+std::u16string return_short_u16string() {
+ return u"a";
+}
+
+std::u16string return_long_u16string() {
+ return u"this is a string that is too long to fit in the string object";
+}
+
void u16string_test() {
std::u16string test0 = u"Hello World";
ComparePrettyPrintToChars(test0, "u\"Hello World\"");
@@ -241,6 +249,20 @@ void u16string_test() {
std::u16string test3 = u"mehmet bizim dostumuz agzi kirik testimiz";
ComparePrettyPrintToChars(test3,
("u\"mehmet bizim dostumuz agzi kirik testimiz\""));
+ // GDB handles strings that are returned from a debugger called function or
+ // when stepping out of a function differently from string variables. These
+ // two tests check that pretty printing works also for this case.
+ CompareExpressionPrettyPrintToChars("return_short_u16string()", "u\"a\"");
+ CompareExpressionPrettyPrintToChars("return_long_u16string()",
+ "u\"this is a string that is too long to fit in the string object\"");
+}
+
+std::u32string return_short_u32string() {
+ return U"a";
+}
+
+std::u32string return_long_u32string() {
+ return U"this is a string that is too long to fit in the string object";
}
void u32string_test() {
@@ -255,6 +277,12 @@ void u32string_test() {
ComparePrettyPrintToChars(test2, ("U\"\U00004f60\U0000597d\""));
std::u32string test3 = U"mehmet bizim dostumuz agzi kirik testimiz";
ComparePrettyPrintToChars(test3, ("U\"mehmet bizim dostumuz agzi kirik testimiz\""));
+ // GDB handles strings that are returned from a debugger called function or
+ // when stepping out of a function differently from string variables. These
+ // two tests check that pretty printing works also for this case.
+ CompareExpressionPrettyPrintToChars("return_short_u32string()", "U\"a\"");
+ CompareExpressionPrettyPrintToChars("return_long_u32string()",
+ "U\"this is a string that is too long to fit in the string object\"");
}
void tuple_test() {
More information about the libcxx-commits
mailing list