The new ReadStringFromMemory() API does not work correctly with NSStrings that have an explicit length and no NULL terminator
This checkin reverts NSString to the old behavior when appropriate, and cleans up the syntax to call the UTF Reader&Dumper function
Incidentally, add a "-d" command-line flag to redo.py with the same semantics as "-d" in dotest.py
llvm-svn: 180141
diff --git a/lldb/source/DataFormatters/CXXFormatterFunctions.cpp b/lldb/source/DataFormatters/CXXFormatterFunctions.cpp
index f74b4de..0357604 100644
--- a/lldb/source/DataFormatters/CXXFormatterFunctions.cpp
+++ b/lldb/source/DataFormatters/CXXFormatterFunctions.cpp
@@ -216,9 +216,9 @@
if (ConvertFunction)
{
- utf8_data_buffer_sp.reset(new DataBufferHeap(bufferSPSize,0));
+ utf8_data_buffer_sp.reset(new DataBufferHeap(4*bufferSPSize,0));
utf8_data_ptr = (UTF8*)utf8_data_buffer_sp->GetBytes();
- utf8_data_end_ptr = utf8_data_ptr + bufferSPSize;
+ utf8_data_end_ptr = utf8_data_ptr + utf8_data_buffer_sp->GetByteSize();
ConvertFunction ( (const SourceDataType**)&data_ptr, data_end_ptr, &utf8_data_ptr, utf8_data_end_ptr, lenientConversion );
utf8_data_ptr = (UTF8*)utf8_data_buffer_sp->GetBytes(); // needed because the ConvertFunction will change the value of the data_ptr
}
@@ -246,21 +246,151 @@
}
template<typename SourceDataType>
-static bool
-ReadUTFBufferAndDumpToStream (ConversionResult (*ConvertFunction) (const SourceDataType**,
- const SourceDataType*,
- UTF8**,
- UTF8*,
- ConversionFlags),
- uint64_t location,
- const ProcessSP& process_sp,
- Stream& stream,
- char prefix_token = '@',
- char quote = '"',
- uint32_t sourceSize = 0)
+class ReadUTFBufferAndDumpToStreamOptions
{
- if (location == 0 || location == LLDB_INVALID_ADDRESS)
+public:
+ typedef ConversionResult (*ConvertFunctionType) (const SourceDataType**,
+ const SourceDataType*,
+ UTF8**,
+ UTF8*,
+ ConversionFlags);
+
+ ReadUTFBufferAndDumpToStreamOptions () :
+ m_conversion_function(NULL),
+ m_location(0),
+ m_process_sp(),
+ m_stream(NULL),
+ m_prefix_token('@'),
+ m_quote('"'),
+ m_source_size(0),
+ m_needs_zero_termination(true)
+ {
+ }
+
+ ReadUTFBufferAndDumpToStreamOptions&
+ SetConversionFunction (ConvertFunctionType f)
+ {
+ m_conversion_function = f;
+ return *this;
+ }
+
+ ConvertFunctionType
+ GetConversionFunction () const
+ {
+ return m_conversion_function;
+ }
+
+ ReadUTFBufferAndDumpToStreamOptions&
+ SetLocation (uint64_t l)
+ {
+ m_location = l;
+ return *this;
+ }
+
+ uint64_t
+ GetLocation () const
+ {
+ return m_location;
+ }
+
+ ReadUTFBufferAndDumpToStreamOptions&
+ SetProcessSP (ProcessSP p)
+ {
+ m_process_sp = p;
+ return *this;
+ }
+
+ ProcessSP
+ GetProcessSP () const
+ {
+ return m_process_sp;
+ }
+
+ ReadUTFBufferAndDumpToStreamOptions&
+ SetStream (Stream* s)
+ {
+ m_stream = s;
+ return *this;
+ }
+
+ Stream*
+ GetStream () const
+ {
+ return m_stream;
+ }
+
+ ReadUTFBufferAndDumpToStreamOptions&
+ SetPrefixToken (char p)
+ {
+ m_prefix_token = p;
+ return *this;
+ }
+
+ char
+ GetPrefixToken () const
+ {
+ return m_prefix_token;
+ }
+
+ ReadUTFBufferAndDumpToStreamOptions&
+ SetQuote (char q)
+ {
+ m_quote = q;
+ return *this;
+ }
+
+ char
+ GetQuote () const
+ {
+ return m_quote;
+ }
+
+ ReadUTFBufferAndDumpToStreamOptions&
+ SetSourceSize (uint32_t s)
+ {
+ m_source_size = s;
+ return *this;
+ }
+
+ uint32_t
+ GetSourceSize () const
+ {
+ return m_source_size;
+ }
+
+ ReadUTFBufferAndDumpToStreamOptions&
+ SetNeedsZeroTermination (bool z)
+ {
+ m_needs_zero_termination = z;
+ return *this;
+ }
+
+ bool
+ GetNeedsZeroTermination () const
+ {
+ return m_needs_zero_termination;
+ }
+
+private:
+ ConvertFunctionType m_conversion_function;
+ uint64_t m_location;
+ ProcessSP m_process_sp;
+ Stream* m_stream;
+ char m_prefix_token;
+ char m_quote;
+ uint32_t m_source_size;
+ bool m_needs_zero_termination;
+};
+
+template<typename SourceDataType>
+static bool
+ReadUTFBufferAndDumpToStream (const ReadUTFBufferAndDumpToStreamOptions<SourceDataType>& options)
+{
+ if (options.GetLocation() == 0 || options.GetLocation() == LLDB_INVALID_ADDRESS)
return false;
+
+ ProcessSP process_sp(options.GetProcessSP());
+
if (!process_sp)
return false;
@@ -269,11 +399,20 @@
if (origin_encoding != 8 && origin_encoding != 16 && origin_encoding != 32)
return false;
// if not UTF8, I need a conversion function to return proper UTF8
- if (origin_encoding != 8 && !ConvertFunction)
+ if (origin_encoding != 8 && !options.GetConversionFunction())
+ return false;
+
+ if (!options.GetStream())
return false;
+ uint32_t sourceSize = options.GetSourceSize();
+ bool needs_zero_terminator = options.GetNeedsZeroTermination();
+
if (!sourceSize)
+ {
sourceSize = process_sp->GetTarget().GetMaximumSizeOfStringSummary();
+ needs_zero_terminator = true;
+ }
else
sourceSize = std::min(sourceSize,process_sp->GetTarget().GetMaximumSizeOfStringSummary());
@@ -287,16 +426,21 @@
Error error;
char *buffer = reinterpret_cast<char *>(buffer_sp->GetBytes());
- size_t data_read = process_sp->ReadStringFromMemory(location, buffer, bufferSPSize, error, type_width);
+ size_t data_read = 0;
+ if (needs_zero_terminator)
+ data_read = process_sp->ReadStringFromMemory(options.GetLocation(), buffer, bufferSPSize, error, type_width);
+ else
+ data_read = process_sp->ReadMemoryFromInferior(options.GetLocation(), (char*)buffer_sp->GetBytes(), bufferSPSize, error);
+
if (error.Fail() || data_read == 0)
{
- stream.Printf("unable to read data");
+ options.GetStream()->Printf("unable to read data");
return true;
}
DataExtractor data(buffer_sp, process_sp->GetByteOrder(), process_sp->GetAddressByteSize());
- return DumpUTFBufferToStream(ConvertFunction, data, stream, prefix_token, quote, sourceSize);
+ return DumpUTFBufferToStream(options.GetConversionFunction(), data, *options.GetStream(), options.GetPrefixToken(), options.GetQuote(), sourceSize);
}
bool
@@ -311,10 +455,14 @@
if (!valobj_addr)
return false;
- if (!ReadUTFBufferAndDumpToStream<UTF16>(ConvertUTF16toUTF8,valobj_addr,
- process_sp,
- stream,
- 'u'))
+ ReadUTFBufferAndDumpToStreamOptions<UTF16> options;
+ options.SetLocation(valobj_addr);
+ options.SetConversionFunction(ConvertUTF16toUTF8);
+ options.SetProcessSP(process_sp);
+ options.SetStream(&stream);
+ options.SetPrefixToken('u');
+
+ if (!ReadUTFBufferAndDumpToStream(options))
{
stream.Printf("Summary Unavailable");
return true;
@@ -335,10 +483,14 @@
if (!valobj_addr)
return false;
- if (!ReadUTFBufferAndDumpToStream<UTF32>(ConvertUTF32toUTF8,valobj_addr,
- process_sp,
- stream,
- 'U'))
+ ReadUTFBufferAndDumpToStreamOptions<UTF32> options;
+ options.SetLocation(valobj_addr);
+ options.SetConversionFunction(ConvertUTF32toUTF8);
+ options.SetProcessSP(process_sp);
+ options.SetStream(&stream);
+ options.SetPrefixToken('u');
+
+ if (!ReadUTFBufferAndDumpToStream(options))
{
stream.Printf("Summary Unavailable");
return true;
@@ -374,23 +526,42 @@
switch (wchar_size)
{
case 8:
+ {
// utf 8
- return ReadUTFBufferAndDumpToStream<UTF8>(nullptr, data_addr,
- process_sp,
- stream,
- 'L');
+
+ ReadUTFBufferAndDumpToStreamOptions<UTF8> options;
+ options.SetLocation(data_addr);
+ options.SetConversionFunction(nullptr);
+ options.SetProcessSP(process_sp);
+ options.SetStream(&stream);
+ options.SetPrefixToken('L');
+
+ return ReadUTFBufferAndDumpToStream(options);
+ }
case 16:
+ {
// utf 16
- return ReadUTFBufferAndDumpToStream<UTF16>(ConvertUTF16toUTF8, data_addr,
- process_sp,
- stream,
- 'L');
+ ReadUTFBufferAndDumpToStreamOptions<UTF16> options;
+ options.SetLocation(data_addr);
+ options.SetConversionFunction(ConvertUTF16toUTF8);
+ options.SetProcessSP(process_sp);
+ options.SetStream(&stream);
+ options.SetPrefixToken('L');
+
+ return ReadUTFBufferAndDumpToStream(options);
+ }
case 32:
+ {
// utf 32
- return ReadUTFBufferAndDumpToStream<UTF32>(ConvertUTF32toUTF8, data_addr,
- process_sp,
- stream,
- 'L');
+ ReadUTFBufferAndDumpToStreamOptions<UTF32> options;
+ options.SetLocation(data_addr);
+ options.SetConversionFunction(ConvertUTF32toUTF8);
+ options.SetProcessSP(process_sp);
+ options.SetStream(&stream);
+ options.SetPrefixToken('L');
+
+ return ReadUTFBufferAndDumpToStream(options);
+ }
default:
stream.Printf("size for wchar_t is not valid");
return true;
@@ -825,7 +996,7 @@
#endif
void* contentsAllocator = %p
}
- } variants;
+ } variants; ==> (M:%dI:%dL:%zuU:%dS:%dN:%d)
};\n)",
my_string_data._cfisa,
my_string_data._cfinfo[0],my_string_data._cfinfo[1],my_string_data._cfinfo[2],my_string_data._cfinfo[3],
@@ -845,7 +1016,13 @@
my_string_data.variants.notInlineMutable.capacityProvidedExternally,
my_string_data.variants.notInlineMutable.desiredCapacity,
my_string_data.variants.notInlineMutable.desiredCapacity,
- my_string_data.variants.notInlineMutable.contentsAllocator);
+ my_string_data.variants.notInlineMutable.contentsAllocator,
+ is_mutable,
+ is_inline,
+ explicit_length,
+ is_unicode,
+ is_special,
+ has_null);
#endif
if (strcmp(class_name,"NSString") &&
@@ -862,16 +1039,6 @@
return true;
}
-#ifdef WANT_DEEP_PRNT
- stream.Printf("(M:%dI:%dL:%zuU:%dS:%dN:%d) ",
- is_mutable,
- is_inline,
- explicit_length,
- is_unicode,
- is_special,
- has_null);
-#endif
-
if (is_mutable)
{
uint64_t location = 2 * ptr_size + valobj_addr;
@@ -879,7 +1046,18 @@
if (error.Fail())
return false;
if (has_explicit_length and is_unicode)
- return ReadUTFBufferAndDumpToStream<UTF16> (ConvertUTF16toUTF8,location, process_sp, stream, '@', '"', explicit_length);
+ {
+ ReadUTFBufferAndDumpToStreamOptions<UTF16> options;
+ options.SetConversionFunction(ConvertUTF16toUTF8);
+ options.SetLocation(location);
+ options.SetProcessSP(process_sp);
+ options.SetStream(&stream);
+ options.SetPrefixToken('@');
+ options.SetQuote('"');
+ options.SetSourceSize(explicit_length);
+ options.SetNeedsZeroTermination(false);
+ return ReadUTFBufferAndDumpToStream (options);
+ }
else
return ReadAsciiBufferAndDumpToStream(location+1,process_sp,stream, explicit_length);
}
@@ -900,19 +1078,37 @@
}
else
location += ptr_size;
- }
+ }
else
{
location = process_sp->ReadPointerFromMemory(location, error);
if (error.Fail())
return false;
}
- return ReadUTFBufferAndDumpToStream<UTF16> (ConvertUTF16toUTF8, location, process_sp, stream, '@', '"', explicit_length);
+ ReadUTFBufferAndDumpToStreamOptions<UTF16> options;
+ options.SetConversionFunction(ConvertUTF16toUTF8);
+ options.SetLocation(location);
+ options.SetProcessSP(process_sp);
+ options.SetStream(&stream);
+ options.SetPrefixToken('@');
+ options.SetQuote('"');
+ options.SetSourceSize(explicit_length);
+ options.SetNeedsZeroTermination(has_explicit_length == false);
+ return ReadUTFBufferAndDumpToStream (options);
}
else if (is_special)
{
uint64_t location = valobj_addr + (ptr_size == 8 ? 12 : 8);
- return ReadUTFBufferAndDumpToStream<UTF16> (ConvertUTF16toUTF8, location, process_sp, stream, '@', '"', explicit_length);
+ ReadUTFBufferAndDumpToStreamOptions<UTF16> options;
+ options.SetConversionFunction(ConvertUTF16toUTF8);
+ options.SetLocation(location);
+ options.SetProcessSP(process_sp);
+ options.SetStream(&stream);
+ options.SetPrefixToken('@');
+ options.SetQuote('"');
+ options.SetSourceSize(explicit_length);
+ options.SetNeedsZeroTermination(has_explicit_length == false);
+ return ReadUTFBufferAndDumpToStream (options);
}
else if (is_inline)
{