Teach the NSString data formatter to handle embedded NULs in short ASCII strings
llvm-svn: 242559
diff --git a/lldb/source/DataFormatters/CXXFormatterFunctions.cpp b/lldb/source/DataFormatters/CXXFormatterFunctions.cpp
index e845d64..d3c6f8e 100644
--- a/lldb/source/DataFormatters/CXXFormatterFunctions.cpp
+++ b/lldb/source/DataFormatters/CXXFormatterFunctions.cpp
@@ -1008,15 +1008,30 @@
{
uint64_t location = valobj_addr + 2*ptr_size;
if (!has_explicit_length)
+ {
+ // in this kind of string, the byte before the string content is a length byte
+ // so let's try and use it to handle the embedded NUL case
+ Error error;
+ explicit_length = process_sp->ReadUnsignedIntegerFromMemory(location, 1, 0, error);
+ if (error.Fail() || explicit_length == 0)
+ has_explicit_length = false;
+ else
+ has_explicit_length = true;
location++;
+ }
ReadStringAndDumpToStreamOptions options(valobj);
options.SetLocation(location);
options.SetProcessSP(process_sp);
options.SetStream(&stream);
options.SetPrefixToken('@');
options.SetSourceSize(explicit_length);
+ options.SetNeedsZeroTermination(!has_explicit_length);
options.SetIgnoreMaxLength(summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryUncapped);
- return ReadStringAndDumpToStream<StringElementType::ASCII>(options);
+ options.SetBinaryZeroIsTerminator(!has_explicit_length);
+ if (has_explicit_length)
+ return ReadStringAndDumpToStream<StringElementType::UTF8>(options);
+ else
+ return ReadStringAndDumpToStream<StringElementType::ASCII>(options);
}
else
{
diff --git a/lldb/test/functionalities/data-formatter/data-formatter-objc/nsstring/TestDataFormatterNSString.py b/lldb/test/functionalities/data-formatter/data-formatter-objc/nsstring/TestDataFormatterNSString.py
index 73f9f5f..563ba5a 100644
--- a/lldb/test/functionalities/data-formatter/data-formatter-objc/nsstring/TestDataFormatterNSString.py
+++ b/lldb/test/functionalities/data-formatter/data-formatter-objc/nsstring/TestDataFormatterNSString.py
@@ -63,6 +63,19 @@
"""Check that Unicode characters come out of CFString summary correctly."""
self.appkit_tester_impl(self.buildDwarf,self.rdar11106605_commands)
+ @skipUnlessDarwin
+ @dsym_test
+ def test_nsstring_withNULs_with_dsym_and_run_command(self):
+ """Test formatters for NSString."""
+ self.appkit_tester_impl(self.buildDsym,self.nsstring_withNULs_commands)
+
+ @skipUnlessDarwin
+ @dwarf_test
+ def test_nsstring_withNULS_with_dwarf_and_run_command(self):
+ """Test formatters for NSString."""
+ self.appkit_tester_impl(self.buildDwarf,self.nsstring_withNULs_commands)
+
+
def setUp(self):
# Call super's setUp().
TestBase.setUp(self)
@@ -102,9 +115,15 @@
self.expect('expr -d run-target -- path',substrs = ['usr/blah/stuff'])
self.expect('frame variable path',substrs = ['usr/blah/stuff'])
+ def nsstring_withNULs_commands(self):
+ """Check that the NSString formatter supports embedded NULs in the text"""
self.expect('po strwithNULs', substrs=['a very much boring task to write'])
self.expect('expr [strwithNULs length]', substrs=['54'])
self.expect('frame variable strwithNULs', substrs=['@"a very much boring task to write\\0a string this way!!'])
+ self.expect('po strwithNULs2', substrs=['a very much boring task to write'])
+ self.expect('expr [strwithNULs2 length]', substrs=['52'])
+ self.expect('frame variable strwithNULs2', substrs=['@"a very much boring task to write\\0a string this way!!'])
+
if __name__ == '__main__':
import atexit
diff --git a/lldb/test/functionalities/data-formatter/data-formatter-objc/nsstring/main.m b/lldb/test/functionalities/data-formatter/data-formatter-objc/nsstring/main.m
index 14b9200..7b8c378 100644
--- a/lldb/test/functionalities/data-formatter/data-formatter-objc/nsstring/main.m
+++ b/lldb/test/functionalities/data-formatter/data-formatter-objc/nsstring/main.m
@@ -86,6 +86,13 @@
NSString *strwithNULs = [NSString stringWithCharacters: someOfTheseAreNUL
length: sizeof someOfTheseAreNUL / sizeof *someOfTheseAreNUL];
+ const unichar someOfTheseAreNUL2[] = {'a',' ', 'v','e','r','y',' ',
+ 'm','u','c','h',' ','b','o','r','i','n','g',' ','t','a','s','k',
+ ' ','t','o',' ','w','r','i','t','e', 0, 'a', ' ', 's', 't', 'r', 'i', 'n', 'g', ' ',
+ 't','h','i','s',' ','w','a','y','!','!'};
+ NSString *strwithNULs2 = [NSString stringWithCharacters: someOfTheseAreNUL2
+ length: sizeof someOfTheseAreNUL2 / sizeof *someOfTheseAreNUL2];
+
[pool drain]; // break here
return 0;
}