[Lldb-commits] [lldb] [lldb] Trim and show embedded zeros in `charN_t` arrays (PR #195514)
via lldb-commits
lldb-commits at lists.llvm.org
Wed May 6 04:01:11 PDT 2026
https://github.com/Nerixyz updated https://github.com/llvm/llvm-project/pull/195514
>From ebfa459e47829347f3ec926d95e918004d25638a Mon Sep 17 00:00:00 2001
From: Nerixyz <nerixdev at outlook.de>
Date: Sun, 3 May 2026 11:55:47 +0200
Subject: [PATCH 1/4] [lldb] Trim and show embedded zeros in `char*_t` arrays
---
.../lldb/DataFormatters/StringPrinter.h | 7 +++++++
lldb/source/DataFormatters/StringPrinter.cpp | 12 +++++++++++
.../Language/CPlusPlus/CxxStringTypes.cpp | 20 +++++++++++++++++++
.../API/lang/cpp/char1632_t/TestChar1632T.py | 6 ++++++
lldb/test/API/lang/cpp/char1632_t/main.cpp | 8 +++++++-
.../API/lang/cpp/char8_t/TestCxxChar8_t.py | 12 +++++++++++
lldb/test/API/lang/cpp/char8_t/main.cpp | 3 +++
.../API/lang/cpp/wchar_t/TestCxxWCharT.py | 3 +++
lldb/test/API/lang/cpp/wchar_t/main.cpp | 9 +++++++--
9 files changed, 77 insertions(+), 3 deletions(-)
diff --git a/lldb/include/lldb/DataFormatters/StringPrinter.h b/lldb/include/lldb/DataFormatters/StringPrinter.h
index 4169f53e63f38..0f013564c5999 100644
--- a/lldb/include/lldb/DataFormatters/StringPrinter.h
+++ b/lldb/include/lldb/DataFormatters/StringPrinter.h
@@ -62,6 +62,10 @@ class StringPrinter {
bool GetBinaryZeroIsTerminator() const { return m_zero_is_terminator; }
+ void SetTrimTrailingZeros(bool v) { m_trim_trailing_zeros = v; }
+
+ bool GetTrimTrailingZeros() const { return m_trim_trailing_zeros; }
+
void SetEscapeNonPrintables(bool e) { m_escape_non_printables = e; }
bool GetEscapeNonPrintables() const { return m_escape_non_printables; }
@@ -95,6 +99,9 @@ class StringPrinter {
/// True iff a zero bytes ('\0') should terminate the memory region that
/// is being dumped.
bool m_zero_is_terminator = true;
+ /// True iff trailing zero bytes should be stripped from the string.
+ /// Mutually exclusive with `m_zero_is_terminator`.
+ bool m_trim_trailing_zeros = false;
/// The language-specific style for escaping special characters.
EscapeStyle m_escape_style = EscapeStyle::CXX;
};
diff --git a/lldb/source/DataFormatters/StringPrinter.cpp b/lldb/source/DataFormatters/StringPrinter.cpp
index 60cb0fc5d6876..a61042b34d29b 100644
--- a/lldb/source/DataFormatters/StringPrinter.cpp
+++ b/lldb/source/DataFormatters/StringPrinter.cpp
@@ -280,6 +280,11 @@ static bool DumpEncodedBufferToStream(
const SourceDataType *data_end_ptr = data_ptr + source_size;
const bool zero_is_terminator = dump_options.GetBinaryZeroIsTerminator();
+ const bool trim_trailing_zeros = dump_options.GetTrimTrailingZeros();
+
+ assert((!zero_is_terminator || !trim_trailing_zeros) &&
+ "BinaryZeroIsTerminator and "
+ "TrimTrailingZeros are mutually exclusive");
if (zero_is_terminator) {
while (data_ptr < data_end_ptr) {
@@ -291,6 +296,12 @@ static bool DumpEncodedBufferToStream(
}
data_ptr = (const SourceDataType *)data.GetDataStart();
+ } else if (trim_trailing_zeros) {
+ while (data_end_ptr != data_ptr) {
+ if (*(data_end_ptr - 1))
+ break;
+ data_end_ptr--;
+ }
}
lldb::WritableDataBufferSP utf8_data_buffer_sp;
@@ -385,6 +396,7 @@ lldb_private::formatters::StringPrinter::ReadBufferAndDumpToStreamOptions::
SetQuote(options.GetQuote());
SetEscapeNonPrintables(options.GetEscapeNonPrintables());
SetBinaryZeroIsTerminator(options.GetBinaryZeroIsTerminator());
+ SetTrimTrailingZeros(options.GetTrimTrailingZeros());
SetEscapeStyle(options.GetEscapeStyle());
}
diff --git a/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp b/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp
index bf8c393445908..f78613861424b 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp
@@ -60,6 +60,16 @@ static bool CharStringSummaryProvider(ValueObject &valobj, Stream &stream) {
options.SetStream(&stream);
options.SetPrefixToken(getElementTraits(ElemType).first);
+ CompilerType ty = valobj.GetCompilerType();
+ uint64_t size = 0;
+ if (ty.IsArrayType(nullptr, &size) && size > 0) {
+ options.SetSourceSize(size);
+ options.SetHasSourceSize(true);
+ options.SetBinaryZeroIsTerminator(false);
+ options.SetNeedsZeroTermination(false);
+ options.SetTrimTrailingZeros(true);
+ }
+
if (!StringPrinter::ReadStringAndDumpToStream<ElemType>(options))
stream.Printf("Summary Unavailable");
@@ -127,6 +137,16 @@ bool lldb_private::formatters::WCharStringSummaryProvider(
options.SetStream(&stream);
options.SetPrefixToken("L");
+ CompilerType ty = valobj.GetCompilerType();
+ uint64_t arr_size = 0;
+ if (ty.IsArrayType(nullptr, &arr_size) && arr_size > 0) {
+ options.SetSourceSize(arr_size);
+ options.SetHasSourceSize(true);
+ options.SetBinaryZeroIsTerminator(false);
+ options.SetNeedsZeroTermination(false);
+ options.SetTrimTrailingZeros(true);
+ }
+
switch (wchar_size) {
case 1:
return StringPrinter::ReadStringAndDumpToStream<StringElementType::UTF8>(
diff --git a/lldb/test/API/lang/cpp/char1632_t/TestChar1632T.py b/lldb/test/API/lang/cpp/char1632_t/TestChar1632T.py
index e2521d88258bc..cd4dc9a406f5c 100644
--- a/lldb/test/API/lang/cpp/char1632_t/TestChar1632T.py
+++ b/lldb/test/API/lang/cpp/char1632_t/TestChar1632T.py
@@ -80,6 +80,12 @@ def test(self):
substrs=['u"ﺸﺵۻ"', 'U"ЕЙРГЖО"'],
)
+ # Check that embedded zeros show up in arrays
+ self.expect_var_path("aZero16", summary='u"I\\0have\\0zeros"')
+ self.expect_var_path("cZero16", summary='u"I"')
+ self.expect_var_path("aZero32", summary='U"I\\0have\\0zeros"')
+ self.expect_var_path("cZero32", summary='U"I"')
+
self.runCmd("next") # step to after the string is nullified
# check that we don't crash on NULL
diff --git a/lldb/test/API/lang/cpp/char1632_t/main.cpp b/lldb/test/API/lang/cpp/char1632_t/main.cpp
index dc37df27fceb5..e38188cf85dee 100644
--- a/lldb/test/API/lang/cpp/char1632_t/main.cpp
+++ b/lldb/test/API/lang/cpp/char1632_t/main.cpp
@@ -10,7 +10,7 @@ void copy_char_seq (T (&arr)[N], const T* src)
assert(src_len < N);
std::char_traits<T>::copy(arr, src, src_len);
- arr[src_len] = 0;
+ memset(&arr[src_len], 0, (N - src_len) * sizeof(T));
}
int main (int argc, char const *argv[])
@@ -25,6 +25,12 @@ int main (int argc, char const *argv[])
char32_t *s32 = (char32_t *)U"ЕЙРГЖО";
copy_char_seq(as16, s16);
copy_char_seq(as32, s32);
+
+ char16_t aZero16[32] = u"I\0have\0zeros";
+ const char16_t *cZero16 = u"I\0have\0zeros";
+ char32_t aZero32[32] = U"I\0have\0zeros";
+ const char32_t *cZero32 = U"I\0have\0zeros";
+
s32 = nullptr; // breakpoint1
s32 = (char32_t *)U"෴";
s16 = (char16_t *)u"色ハ匂ヘト散リヌルヲ";
diff --git a/lldb/test/API/lang/cpp/char8_t/TestCxxChar8_t.py b/lldb/test/API/lang/cpp/char8_t/TestCxxChar8_t.py
index 08f09b317b217..c727ae9cf6ab6 100644
--- a/lldb/test/API/lang/cpp/char8_t/TestCxxChar8_t.py
+++ b/lldb/test/API/lang/cpp/char8_t/TestCxxChar8_t.py
@@ -21,10 +21,18 @@ def test_without_process(self):
self.expect("target variable a", substrs=["char8_t", "0x61 u8'a'"])
self.expect("target variable ab", substrs=["const char8_t *", 'u8"你好"'])
self.expect("target variable abc", substrs=["char8_t[9]", 'u8"你好"'])
+ self.expect(
+ "target variable aZero", substrs=["char8_t[32]", 'u8"I\\0have\\0zeros"']
+ )
+ self.expect("target variable cZero", substrs=["const char8_t *", 'u8"I"'])
self.expect_expr("a", result_type="char8_t", result_summary="0x61 u8'a'")
self.expect_expr("ab", result_type="const char8_t *", result_summary='u8"你好"')
self.expect_expr("abc", result_type="char8_t[9]", result_summary='u8"你好"')
+ self.expect_expr(
+ "aZero", result_type="char8_t[32]", result_summary='u8"I\\0have\\0zeros"'
+ )
+ self.expect_expr("cZero", result_type="const char8_t *", result_summary='u8"I"')
@skipIf(compiler="clang", compiler_version=["<", "7.0"])
def test_with_process(self):
@@ -38,3 +46,7 @@ def test_with_process(self):
self.expect_expr("a", result_type="char8_t", result_summary="0x61 u8'a'")
self.expect_expr("ab", result_type="const char8_t *", result_summary='u8"你好"')
self.expect_expr("abc", result_type="char8_t[9]", result_summary='u8"你好"')
+ self.expect_expr(
+ "aZero", result_type="char8_t[32]", result_summary='u8"I\\0have\\0zeros"'
+ )
+ self.expect_expr("cZero", result_type="const char8_t *", result_summary='u8"I"')
diff --git a/lldb/test/API/lang/cpp/char8_t/main.cpp b/lldb/test/API/lang/cpp/char8_t/main.cpp
index d109751cc2314..36a2bbef95e2b 100644
--- a/lldb/test/API/lang/cpp/char8_t/main.cpp
+++ b/lldb/test/API/lang/cpp/char8_t/main.cpp
@@ -2,6 +2,9 @@ char8_t a = u8'a';
const char8_t* ab = u8"你好";
char8_t abc[9] = u8"你好";
+char8_t aZero[32] = u8"I\0have\0zeros";
+const char8_t *cZero = u8"I\0have\0zeros";
+
int main (int argc, char const *argv[]) {
return 0; // break here
}
diff --git a/lldb/test/API/lang/cpp/wchar_t/TestCxxWCharT.py b/lldb/test/API/lang/cpp/wchar_t/TestCxxWCharT.py
index 35cb512142ca0..f17d5a707c9e3 100644
--- a/lldb/test/API/lang/cpp/wchar_t/TestCxxWCharT.py
+++ b/lldb/test/API/lang/cpp/wchar_t/TestCxxWCharT.py
@@ -48,3 +48,6 @@ def test(self):
self.expect("frame variable wchar_zero", substrs=["L'\\0'"])
self.expect("expression wchar_zero", substrs=["L'\\0'"])
+
+ self.expect_var_path("aZero", summary='L"I\\0have\\0zeros"')
+ self.expect_var_path("cZero", summary='L"I"')
diff --git a/lldb/test/API/lang/cpp/wchar_t/main.cpp b/lldb/test/API/lang/cpp/wchar_t/main.cpp
index 778642e0133f0..f6031ae9f7b9d 100644
--- a/lldb/test/API/lang/cpp/wchar_t/main.cpp
+++ b/lldb/test/API/lang/cpp/wchar_t/main.cpp
@@ -19,8 +19,13 @@ int main (int argc, char const *argv[])
const wchar_t *mazeltov = L"מזל טוב";
wchar_t *ws_NULL = nullptr;
wchar_t *ws_empty = L"";
- wchar_t array[200], * array_source = L"Hey, I'm a super wchar_t string, éõñž";
+ wchar_t array[200],
+ *array_source = L"Hey, I'm a super wchar_t string, éõñž";
wchar_t wchar_zero = (wchar_t)0;
- memcpy(array, array_source, 39 * sizeof(wchar_t));
+ memcpy(array, array_source, 39 * sizeof(wchar_t));
+
+ wchar_t aZero[32] = L"I\0have\0zeros";
+ const wchar_t *cZero = L"I\0have\0zeros";
+
return 0; // break here
}
>From 036864574f81998e47192f12ef83191a8e72e0a6 Mon Sep 17 00:00:00 2001
From: Nerixyz <nerixdev at outlook.de>
Date: Tue, 5 May 2026 15:09:23 +0200
Subject: [PATCH 2/4] refactor: Use enum for zero-termination
---
.../lldb/DataFormatters/StringPrinter.h | 29 +++++++----------
lldb/source/DataFormatters/StringPrinter.cpp | 32 +++++++++++--------
.../Language/CPlusPlus/CxxStringTypes.cpp | 16 ++++------
.../source/Plugins/Language/ObjC/NSString.cpp | 24 ++++++++------
lldb/source/ValueObject/ValueObject.cpp | 8 ++++-
.../DataFormatter/StringPrinterTests.cpp | 2 +-
6 files changed, 59 insertions(+), 52 deletions(-)
diff --git a/lldb/include/lldb/DataFormatters/StringPrinter.h b/lldb/include/lldb/DataFormatters/StringPrinter.h
index 0f013564c5999..caba15273469c 100644
--- a/lldb/include/lldb/DataFormatters/StringPrinter.h
+++ b/lldb/include/lldb/DataFormatters/StringPrinter.h
@@ -26,6 +26,15 @@ class StringPrinter {
enum class EscapeStyle { CXX, Swift };
+ enum class ZeroTermination : uint8_t {
+ /// Don't look for a terminator - print the whole buffer.
+ Ignore,
+ /// Stop printing at the first zero terminator.
+ ZeroTerminate,
+ /// Print embedded zeros, but ignore zeros at the end of the buffer.
+ TrimTrailingZeros,
+ };
+
class DumpToStreamOptions {
public:
DumpToStreamOptions() = default;
@@ -54,17 +63,9 @@ class StringPrinter {
uint32_t GetSourceSize() const { return m_source_size; }
- void SetNeedsZeroTermination(bool z) { m_needs_zero_termination = z; }
-
- bool GetNeedsZeroTermination() const { return m_needs_zero_termination; }
-
- void SetBinaryZeroIsTerminator(bool e) { m_zero_is_terminator = e; }
-
- bool GetBinaryZeroIsTerminator() const { return m_zero_is_terminator; }
-
- void SetTrimTrailingZeros(bool v) { m_trim_trailing_zeros = v; }
+ void SetZeroTermination(ZeroTermination z) { m_zero_termination = z; }
- bool GetTrimTrailingZeros() const { return m_trim_trailing_zeros; }
+ ZeroTermination GetZeroTermination() const { return m_zero_termination; }
void SetEscapeNonPrintables(bool e) { m_escape_non_printables = e; }
@@ -89,21 +90,15 @@ class StringPrinter {
char m_quote = '"';
/// The length of the memory region that should be dumped in bytes.
uint32_t m_source_size = 0;
- bool m_needs_zero_termination = true;
/// True iff non-printable characters should be escaped when dumping
/// them to the stream.
bool m_escape_non_printables = true;
/// True iff the max-string-summary-length setting of the target should
/// be ignored.
bool m_ignore_max_length = false;
- /// True iff a zero bytes ('\0') should terminate the memory region that
- /// is being dumped.
- bool m_zero_is_terminator = true;
- /// True iff trailing zero bytes should be stripped from the string.
- /// Mutually exclusive with `m_zero_is_terminator`.
- bool m_trim_trailing_zeros = false;
/// The language-specific style for escaping special characters.
EscapeStyle m_escape_style = EscapeStyle::CXX;
+ ZeroTermination m_zero_termination = ZeroTermination::ZeroTerminate;
};
class ReadStringAndDumpToStreamOptions : public DumpToStreamOptions {
diff --git a/lldb/source/DataFormatters/StringPrinter.cpp b/lldb/source/DataFormatters/StringPrinter.cpp
index a61042b34d29b..81b81fffcf73a 100644
--- a/lldb/source/DataFormatters/StringPrinter.cpp
+++ b/lldb/source/DataFormatters/StringPrinter.cpp
@@ -279,14 +279,11 @@ static bool DumpEncodedBufferToStream(
(const SourceDataType *)data.GetDataStart();
const SourceDataType *data_end_ptr = data_ptr + source_size;
- const bool zero_is_terminator = dump_options.GetBinaryZeroIsTerminator();
- const bool trim_trailing_zeros = dump_options.GetTrimTrailingZeros();
+ switch (dump_options.GetZeroTermination()) {
+ case StringPrinter::ZeroTermination::Ignore:
+ break;
- assert((!zero_is_terminator || !trim_trailing_zeros) &&
- "BinaryZeroIsTerminator and "
- "TrimTrailingZeros are mutually exclusive");
-
- if (zero_is_terminator) {
+ case StringPrinter::ZeroTermination::ZeroTerminate: {
while (data_ptr < data_end_ptr) {
if (!*data_ptr) {
data_end_ptr = data_ptr;
@@ -296,13 +293,19 @@ static bool DumpEncodedBufferToStream(
}
data_ptr = (const SourceDataType *)data.GetDataStart();
- } else if (trim_trailing_zeros) {
+ } break;
+
+ case StringPrinter::ZeroTermination::TrimTrailingZeros: {
while (data_end_ptr != data_ptr) {
if (*(data_end_ptr - 1))
break;
data_end_ptr--;
}
+ } break;
}
+ const bool zero_is_terminator =
+ dump_options.GetZeroTermination() ==
+ StringPrinter::ZeroTermination::ZeroTerminate;
lldb::WritableDataBufferSP utf8_data_buffer_sp;
llvm::UTF8 *utf8_data_ptr = nullptr;
@@ -395,8 +398,7 @@ lldb_private::formatters::StringPrinter::ReadBufferAndDumpToStreamOptions::
SetSuffixToken(options.GetSuffixToken());
SetQuote(options.GetQuote());
SetEscapeNonPrintables(options.GetEscapeNonPrintables());
- SetBinaryZeroIsTerminator(options.GetBinaryZeroIsTerminator());
- SetTrimTrailingZeros(options.GetTrimTrailingZeros());
+ SetZeroTermination(options.GetZeroTermination());
SetEscapeStyle(options.GetEscapeStyle());
}
@@ -431,7 +433,8 @@ static bool ReadEncodedBufferAndDumpToStream(
if (origin_encoding != 8 && !ConvertFunction)
return false;
- bool needs_zero_terminator = options.GetNeedsZeroTermination();
+ bool needs_zero_terminator = options.GetZeroTermination() ==
+ StringPrinter::ZeroTermination::ZeroTerminate;
bool is_truncated = false;
const auto max_size = target_sp->GetMaximumSizeOfStringSummary();
@@ -491,9 +494,10 @@ static bool ReadEncodedBufferAndDumpToStream(
target_sp->GetArchitecture().GetAddressByteSize()));
dump_options.SetSourceSize(sourceSize);
dump_options.SetIsTruncated(is_truncated);
- dump_options.SetNeedsZeroTermination(needs_zero_terminator);
- if (needs_zero_terminator)
- dump_options.SetBinaryZeroIsTerminator(true);
+ if (needs_zero_terminator) {
+ dump_options.SetZeroTermination(
+ StringPrinter::ZeroTermination::ZeroTerminate);
+ }
GetPrintableElementType print_style = (elem_type == StringElementType::ASCII)
? GetPrintableElementType::ASCII
diff --git a/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp b/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp
index f78613861424b..347c108a9a72a 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp
@@ -65,9 +65,8 @@ static bool CharStringSummaryProvider(ValueObject &valobj, Stream &stream) {
if (ty.IsArrayType(nullptr, &size) && size > 0) {
options.SetSourceSize(size);
options.SetHasSourceSize(true);
- options.SetBinaryZeroIsTerminator(false);
- options.SetNeedsZeroTermination(false);
- options.SetTrimTrailingZeros(true);
+ options.SetZeroTermination(
+ StringPrinter::ZeroTermination::TrimTrailingZeros);
}
if (!StringPrinter::ReadStringAndDumpToStream<ElemType>(options))
@@ -99,7 +98,7 @@ static bool CharSummaryProvider(ValueObject &valobj, Stream &stream) {
options.SetPrefixToken(ElemTraits.first);
options.SetQuote('\'');
options.SetSourceSize(1);
- options.SetBinaryZeroIsTerminator(false);
+ options.SetZeroTermination(StringPrinter::ZeroTermination::Ignore);
return StringPrinter::ReadBufferAndDumpToStream<ElemType>(options);
}
@@ -142,9 +141,8 @@ bool lldb_private::formatters::WCharStringSummaryProvider(
if (ty.IsArrayType(nullptr, &arr_size) && arr_size > 0) {
options.SetSourceSize(arr_size);
options.SetHasSourceSize(true);
- options.SetBinaryZeroIsTerminator(false);
- options.SetNeedsZeroTermination(false);
- options.SetTrimTrailingZeros(true);
+ options.SetZeroTermination(
+ StringPrinter::ZeroTermination::TrimTrailingZeros);
}
switch (wchar_size) {
@@ -200,7 +198,7 @@ bool lldb_private::formatters::WCharSummaryProvider(
options.SetPrefixToken("L");
options.SetQuote('\'');
options.SetSourceSize(1);
- options.SetBinaryZeroIsTerminator(false);
+ options.SetZeroTermination(StringPrinter::ZeroTermination::Ignore);
switch (wchar_size) {
case 1:
@@ -267,7 +265,7 @@ bool lldb_private::formatters::StringBufferSummaryProvider(
options.SetPrefixToken(prefix_token);
options.SetQuote('"');
options.SetSourceSize(size);
- options.SetBinaryZeroIsTerminator(false);
+ options.SetZeroTermination(StringPrinter::ZeroTermination::Ignore);
return StringPrinter::ReadBufferAndDumpToStream<element_type>(options);
}
diff --git a/lldb/source/Plugins/Language/ObjC/NSString.cpp b/lldb/source/Plugins/Language/ObjC/NSString.cpp
index ce268ac7f3257..7a295119bd031 100644
--- a/lldb/source/Plugins/Language/ObjC/NSString.cpp
+++ b/lldb/source/Plugins/Language/ObjC/NSString.cpp
@@ -151,10 +151,9 @@ bool lldb_private::formatters::NSStringSummaryProvider(
options.SetQuote('"');
options.SetSourceSize(explicit_length);
options.SetHasSourceSize(has_explicit_length);
- options.SetNeedsZeroTermination(false);
+ options.SetZeroTermination(StringPrinter::ZeroTermination::Ignore);
options.SetIgnoreMaxLength(summary_options.GetCapping() ==
TypeSummaryCapping::eTypeSummaryUncapped);
- options.SetBinaryZeroIsTerminator(false);
return StringPrinter::ReadStringAndDumpToStream<
StringPrinter::StringElementType::UTF16>(options);
} else {
@@ -163,10 +162,9 @@ bool lldb_private::formatters::NSStringSummaryProvider(
options.SetStream(&stream);
options.SetSourceSize(explicit_length);
options.SetHasSourceSize(has_explicit_length);
- options.SetNeedsZeroTermination(false);
+ options.SetZeroTermination(StringPrinter::ZeroTermination::Ignore);
options.SetIgnoreMaxLength(summary_options.GetCapping() ==
TypeSummaryCapping::eTypeSummaryUncapped);
- options.SetBinaryZeroIsTerminator(false);
return StringPrinter::ReadStringAndDumpToStream<
StringPrinter::StringElementType::ASCII>(options);
}
@@ -202,10 +200,12 @@ bool lldb_private::formatters::NSStringSummaryProvider(
options.SetQuote('"');
options.SetSourceSize(explicit_length);
options.SetHasSourceSize(has_explicit_length);
- options.SetNeedsZeroTermination(!has_explicit_length);
+ if (has_explicit_length)
+ options.SetZeroTermination(StringPrinter::ZeroTermination::Ignore);
+ else
+ options.SetZeroTermination(StringPrinter::ZeroTermination::ZeroTerminate);
options.SetIgnoreMaxLength(summary_options.GetCapping() ==
TypeSummaryCapping::eTypeSummaryUncapped);
- options.SetBinaryZeroIsTerminator(!has_explicit_length);
return StringPrinter::ReadStringAndDumpToStream<
StringPrinter::StringElementType::UTF16>(options);
} else if (is_path_store) {
@@ -228,10 +228,12 @@ bool lldb_private::formatters::NSStringSummaryProvider(
options.SetQuote('"');
options.SetSourceSize(explicit_length);
options.SetHasSourceSize(has_explicit_length);
- options.SetNeedsZeroTermination(!has_explicit_length);
+ if (has_explicit_length)
+ options.SetZeroTermination(StringPrinter::ZeroTermination::Ignore);
+ else
+ options.SetZeroTermination(StringPrinter::ZeroTermination::ZeroTerminate);
options.SetIgnoreMaxLength(summary_options.GetCapping() ==
TypeSummaryCapping::eTypeSummaryUncapped);
- options.SetBinaryZeroIsTerminator(!has_explicit_length);
return StringPrinter::ReadStringAndDumpToStream<
StringPrinter::StringElementType::UTF16>(options);
} else if (is_inline) {
@@ -250,10 +252,12 @@ bool lldb_private::formatters::NSStringSummaryProvider(
options.SetStream(&stream);
options.SetSourceSize(explicit_length);
options.SetHasSourceSize(has_explicit_length);
- options.SetNeedsZeroTermination(!has_explicit_length);
+ if (has_explicit_length)
+ options.SetZeroTermination(StringPrinter::ZeroTermination::Ignore);
+ else
+ options.SetZeroTermination(StringPrinter::ZeroTermination::ZeroTerminate);
options.SetIgnoreMaxLength(summary_options.GetCapping() ==
TypeSummaryCapping::eTypeSummaryUncapped);
- options.SetBinaryZeroIsTerminator(!has_explicit_length);
if (has_explicit_length)
return StringPrinter::ReadStringAndDumpToStream<
StringPrinter::StringElementType::UTF8>(options);
diff --git a/lldb/source/ValueObject/ValueObject.cpp b/lldb/source/ValueObject/ValueObject.cpp
index 33f143bb4e3e2..9903356cf4726 100644
--- a/lldb/source/ValueObject/ValueObject.cpp
+++ b/lldb/source/ValueObject/ValueObject.cpp
@@ -1403,7 +1403,13 @@ bool ValueObject::DumpPrintableRepresentation(
options.SetQuote('"');
options.SetSourceSize(buffer_sp->GetByteSize());
options.SetIsTruncated(read_string.second);
- options.SetBinaryZeroIsTerminator(custom_format != eFormatVectorOfChar);
+ if (custom_format == eFormatVectorOfChar) {
+ options.SetZeroTermination(
+ formatters::StringPrinter::ZeroTermination::Ignore);
+ } else {
+ options.SetZeroTermination(
+ formatters::StringPrinter::ZeroTermination::ZeroTerminate);
+ }
formatters::StringPrinter::ReadBufferAndDumpToStream<
lldb_private::formatters::StringPrinter::StringElementType::ASCII>(
options);
diff --git a/lldb/unittests/DataFormatter/StringPrinterTests.cpp b/lldb/unittests/DataFormatter/StringPrinterTests.cpp
index ac4116139beb2..64789bccd3e87 100644
--- a/lldb/unittests/DataFormatter/StringPrinterTests.cpp
+++ b/lldb/unittests/DataFormatter/StringPrinterTests.cpp
@@ -32,7 +32,7 @@ format(StringRef input, StringPrinter::EscapeStyle escape_style) {
StringPrinter::ReadBufferAndDumpToStreamOptions opts;
opts.SetStream(&out);
opts.SetSourceSize(input.size());
- opts.SetNeedsZeroTermination(true);
+ opts.SetZeroTermination(StringPrinter::ZeroTermination::ZeroTerminate);
opts.SetEscapeNonPrintables(true);
opts.SetIgnoreMaxLength(false);
opts.SetEscapeStyle(escape_style);
>From 4f7616ffb9289197f0e5e06aa16a987e9a8c9381 Mon Sep 17 00:00:00 2001
From: Nerixyz <nerixdev at outlook.de>
Date: Wed, 6 May 2026 12:59:43 +0200
Subject: [PATCH 3/4] fix: enum size
---
lldb/include/lldb/DataFormatters/StringPrinter.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lldb/include/lldb/DataFormatters/StringPrinter.h b/lldb/include/lldb/DataFormatters/StringPrinter.h
index caba15273469c..0a674b9fb303e 100644
--- a/lldb/include/lldb/DataFormatters/StringPrinter.h
+++ b/lldb/include/lldb/DataFormatters/StringPrinter.h
@@ -26,7 +26,7 @@ class StringPrinter {
enum class EscapeStyle { CXX, Swift };
- enum class ZeroTermination : uint8_t {
+ enum class ZeroTermination {
/// Don't look for a terminator - print the whole buffer.
Ignore,
/// Stop printing at the first zero terminator.
>From 520c4a926c30fd4d899304defd31f5b88a18a439 Mon Sep 17 00:00:00 2001
From: Nerixyz <nerixdev at outlook.de>
Date: Wed, 6 May 2026 13:00:53 +0200
Subject: [PATCH 4/4] fix: update comments
---
lldb/source/DataFormatters/StringPrinter.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/lldb/source/DataFormatters/StringPrinter.cpp b/lldb/source/DataFormatters/StringPrinter.cpp
index 81b81fffcf73a..3a6a55e9d4e02 100644
--- a/lldb/source/DataFormatters/StringPrinter.cpp
+++ b/lldb/source/DataFormatters/StringPrinter.cpp
@@ -442,8 +442,8 @@ static bool ReadEncodedBufferAndDumpToStream(
uint32_t sourceSize;
if (elem_type == StringElementType::ASCII && !options.GetSourceSize()) {
// FIXME: The NSString formatter sets HasSourceSize(true) when the size is
- // actually unknown, as well as SetBinaryZeroIsTerminator(false). IIUC the
- // C++ formatter also sets SetBinaryZeroIsTerminator(false) when it doesn't
+ // actually unknown, as well as SetZeroTermination(Ignore). IIUC the
+ // C++ formatter also sets SetZeroTermination(Ignore) when it doesn't
// mean to. I don't see how this makes sense: we should fix the formatters.
//
// Until then, the behavior that's expected for ASCII strings with unknown
More information about the lldb-commits
mailing list