[Lldb-commits] [lldb] [lldb][DataFormatter] Allow std::string formatters to match against custom allocators (PR #156050)
Michael Buch via lldb-commits
lldb-commits at lists.llvm.org
Thu Sep 4 05:21:52 PDT 2025
https://github.com/Michael137 updated https://github.com/llvm/llvm-project/pull/156050
>From 35999d8d509864795dd36565d12ddea425a98c22 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Fri, 29 Aug 2025 16:57:35 +0100
Subject: [PATCH 1/4] [lldb][DataFormatter] Allow std::string formatters to
match against custom allocators
This came up in https://github.com/llvm/llvm-project/issues/155691.
For `std::basic_string` our formatter matching logic required the
allocator template parameter to be a `std::allocator`. There is no
compelling reason (that I know of) why this would be required for us to
apply the existing formatter to the string. We don't check the
`allocator` parameter for other STL containers either. This meant that
`std::string` that used custom allocators wouldn't be formatted. This
patch relaxes the regex for `basic_string`.
---
.../Language/CPlusPlus/CPlusPlusLanguage.cpp | 15 ++++------
.../string/TestDataFormatterStdString.py | 6 ++++
.../generic/string/main.cpp | 30 +++++++++++++++++++
3 files changed, 41 insertions(+), 10 deletions(-)
diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
index c39b529f7305a..ad3c00a1132d4 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
@@ -749,31 +749,27 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
lldb_private::formatters::LibcxxStringSummaryProviderASCII,
"std::string summary provider",
"^std::__[[:alnum:]]+::basic_string<char, "
- "std::__[[:alnum:]]+::char_traits<char>, "
- "std::__[[:alnum:]]+::allocator<char> >$",
+ "std::__[[:alnum:]]+::char_traits<char>,.*>$",
stl_summary_flags, true);
AddCXXSummary(cpp_category_sp,
lldb_private::formatters::LibcxxStringSummaryProviderASCII,
"std::string summary provider",
"^std::__[[:alnum:]]+::basic_string<unsigned char, "
- "std::__[[:alnum:]]+::char_traits<unsigned char>, "
- "std::__[[:alnum:]]+::allocator<unsigned char> >$",
+ "std::__[[:alnum:]]+::char_traits<unsigned char>,.*>$",
stl_summary_flags, true);
AddCXXSummary(cpp_category_sp,
lldb_private::formatters::LibcxxStringSummaryProviderUTF16,
"std::u16string summary provider",
"^std::__[[:alnum:]]+::basic_string<char16_t, "
- "std::__[[:alnum:]]+::char_traits<char16_t>, "
- "std::__[[:alnum:]]+::allocator<char16_t> >$",
+ "std::__[[:alnum:]]+::char_traits<char16_t>,.*>$",
stl_summary_flags, true);
AddCXXSummary(cpp_category_sp,
lldb_private::formatters::LibcxxStringSummaryProviderUTF32,
"std::u32string summary provider",
"^std::__[[:alnum:]]+::basic_string<char32_t, "
- "std::__[[:alnum:]]+::char_traits<char32_t>, "
- "std::__[[:alnum:]]+::allocator<char32_t> >$",
+ "std::__[[:alnum:]]+::char_traits<char32_t>,.*>$",
stl_summary_flags, true);
AddCXXSummary(cpp_category_sp,
@@ -784,8 +780,7 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
lldb_private::formatters::LibcxxWStringSummaryProvider,
"std::wstring summary provider",
"^std::__[[:alnum:]]+::basic_string<wchar_t, "
- "std::__[[:alnum:]]+::char_traits<wchar_t>, "
- "std::__[[:alnum:]]+::allocator<wchar_t> >$",
+ "std::__[[:alnum:]]+::char_traits<wchar_t>,.*>$",
stl_summary_flags, true);
AddCXXSummary(cpp_category_sp,
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string/TestDataFormatterStdString.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string/TestDataFormatterStdString.py
index fec20bae997ef..6a27b5d2f0780 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string/TestDataFormatterStdString.py
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string/TestDataFormatterStdString.py
@@ -80,6 +80,8 @@ def cleanup():
'(%s::string) Q = "quite a long std::strin with lots of info inside it"'
% ns,
"(%s::string *) null_str = nullptr" % ns,
+ '(CustomString) custom_str = "hello!"',
+ '(CustomWString) custom_wstr = L"hello!"',
],
)
@@ -143,6 +145,10 @@ def do_test_multibyte(self):
'(%s::u16string) u16_empty = u""' % ns,
'(%s::u32string) u32_string = U"🍄🍅🍆🍌"' % ns,
'(%s::u32string) u32_empty = U""' % ns,
+ '(CustomStringU16) custom_u16 = u"ß水氶"',
+ '(CustomStringU16) custom_u16_empty = u""',
+ '(CustomStringU32) custom_u32 = U"🍄🍅🍆🍌"',
+ '(CustomStringU32) custom_u32_empty = U""',
],
)
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string/main.cpp b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string/main.cpp
index f22c890861d01..55f2de131b402 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string/main.cpp
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string/main.cpp
@@ -1,6 +1,29 @@
#include <stdint.h>
#include <string>
+template <typename T> struct CustomAlloc {
+ using value_type = T;
+ using pointer = value_type *;
+ using const_pointer = const value_type *;
+ using size_type = std::size_t;
+
+ pointer allocate(size_type) { return new T; }
+
+ void deallocate(pointer p, size_type) { delete p; }
+};
+
+using CustomString =
+ std::basic_string<char, std::char_traits<char>, CustomAlloc<char>>;
+
+using CustomWString =
+ std::basic_string<wchar_t, std::char_traits<wchar_t>, CustomAlloc<wchar_t>>;
+
+using CustomStringU16 = std::basic_string<char16_t, std::char_traits<char16_t>,
+ CustomAlloc<char16_t>>;
+
+using CustomStringU32 = std::basic_string<char32_t, std::char_traits<char32_t>,
+ CustomAlloc<char32_t>>;
+
size_t touch_string(std::string &in_str) {
return in_str.size(); // Break here to look at bad string
}
@@ -99,6 +122,13 @@ int main() {
std::string *pq = &q;
std::string *pQ = &Q;
+ CustomString custom_str("hello!");
+ CustomWString custom_wstr(L"hello!");
+ CustomStringU16 custom_u16(u16_string);
+ CustomStringU16 custom_u16_empty(u"");
+ CustomStringU32 custom_u32(u32_string);
+ CustomStringU32 custom_u32_empty(U"");
+
S.assign(L"!!!!!"); // Set break point at this line.
std::string *not_a_string = (std::string *)0x0;
touch_string(*not_a_string);
>From af0f77f235d3544add4f494365fa0075e63fe5a2 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Mon, 1 Sep 2025 11:06:28 +0100
Subject: [PATCH 2/4] fixup! fix test compilation with libstdc++
---
.../data-formatter/data-formatter-stl/generic/string/main.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string/main.cpp b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string/main.cpp
index 55f2de131b402..720601261056d 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string/main.cpp
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string/main.cpp
@@ -124,9 +124,9 @@ int main() {
CustomString custom_str("hello!");
CustomWString custom_wstr(L"hello!");
- CustomStringU16 custom_u16(u16_string);
+ CustomStringU16 custom_u16(u16_string.c_str());
CustomStringU16 custom_u16_empty(u"");
- CustomStringU32 custom_u32(u32_string);
+ CustomStringU32 custom_u32(u32_string.c_str());
CustomStringU32 custom_u32_empty(U"");
S.assign(L"!!!!!"); // Set break point at this line.
>From 1649ecec94ae836467725a35c3e61823edefa2dc Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Wed, 3 Sep 2025 16:14:01 +0100
Subject: [PATCH 3/4] TEMPORARY: debugging CI failures
---
.../generic/string/TestDataFormatterStdString.py | 6 ------
.../data-formatter-stl/generic/string/main.cpp | 7 ++++---
2 files changed, 4 insertions(+), 9 deletions(-)
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string/TestDataFormatterStdString.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string/TestDataFormatterStdString.py
index 6a27b5d2f0780..fec20bae997ef 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string/TestDataFormatterStdString.py
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string/TestDataFormatterStdString.py
@@ -80,8 +80,6 @@ def cleanup():
'(%s::string) Q = "quite a long std::strin with lots of info inside it"'
% ns,
"(%s::string *) null_str = nullptr" % ns,
- '(CustomString) custom_str = "hello!"',
- '(CustomWString) custom_wstr = L"hello!"',
],
)
@@ -145,10 +143,6 @@ def do_test_multibyte(self):
'(%s::u16string) u16_empty = u""' % ns,
'(%s::u32string) u32_string = U"🍄🍅🍆🍌"' % ns,
'(%s::u32string) u32_empty = U""' % ns,
- '(CustomStringU16) custom_u16 = u"ß水氶"',
- '(CustomStringU16) custom_u16_empty = u""',
- '(CustomStringU32) custom_u32 = U"🍄🍅🍆🍌"',
- '(CustomStringU32) custom_u32_empty = U""',
],
)
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string/main.cpp b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string/main.cpp
index 720601261056d..d25767322e1ea 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string/main.cpp
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string/main.cpp
@@ -122,6 +122,10 @@ int main() {
std::string *pq = &q;
std::string *pQ = &Q;
+ S.assign(L"!!!!!"); // Set break point at this line.
+ std::string *not_a_string = (std::string *)0x0;
+ touch_string(*not_a_string);
+
CustomString custom_str("hello!");
CustomWString custom_wstr(L"hello!");
CustomStringU16 custom_u16(u16_string.c_str());
@@ -129,8 +133,5 @@ int main() {
CustomStringU32 custom_u32(u32_string.c_str());
CustomStringU32 custom_u32_empty(U"");
- S.assign(L"!!!!!"); // Set break point at this line.
- std::string *not_a_string = (std::string *)0x0;
- touch_string(*not_a_string);
return 0;
}
>From 990b38321cf9b979b9baa26501fe68ab08ea9eba Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Thu, 4 Sep 2025 13:21:37 +0100
Subject: [PATCH 4/4] TEMPORARY: bisect which local var is causing issues
---
.../data-formatter-stl/generic/string/main.cpp | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string/main.cpp b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string/main.cpp
index d25767322e1ea..13476c67eb539 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string/main.cpp
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string/main.cpp
@@ -122,16 +122,16 @@ int main() {
std::string *pq = &q;
std::string *pQ = &Q;
+ CustomString custom_str("hello!");
+ CustomWString custom_wstr(L"hello!");
+ //CustomStringU16 custom_u16(u16_string.c_str());
+ //CustomStringU16 custom_u16_empty(u"");
+ //CustomStringU32 custom_u32(u32_string.c_str());
+ //CustomStringU32 custom_u32_empty(U"");
+
S.assign(L"!!!!!"); // Set break point at this line.
std::string *not_a_string = (std::string *)0x0;
touch_string(*not_a_string);
- CustomString custom_str("hello!");
- CustomWString custom_wstr(L"hello!");
- CustomStringU16 custom_u16(u16_string.c_str());
- CustomStringU16 custom_u16_empty(u"");
- CustomStringU32 custom_u32(u32_string.c_str());
- CustomStringU32 custom_u32_empty(U"");
-
return 0;
}
More information about the lldb-commits
mailing list