Also port the C string reading code in ValueObject over to using StringPrinter API
authorEnrico Granata <egranata@apple.com>
Thu, 30 Oct 2014 18:27:31 +0000 (18:27 +0000)
committerEnrico Granata <egranata@apple.com>
Thu, 30 Oct 2014 18:27:31 +0000 (18:27 +0000)
llvm-svn: 220917

lldb/include/lldb/Core/ValueObject.h
lldb/source/Core/ValueObject.cpp
lldb/source/DataFormatters/CXXFormatterFunctions.cpp
lldb/source/Target/Process.cpp

index 4a4318f..2ec379e 100644 (file)
@@ -812,7 +812,7 @@ public:
     IsCStringContainer (bool check_pointer = false);
     
     size_t
-    ReadPointedString (Stream& s,
+    ReadPointedString (lldb::DataBufferSP& buffer_sp,
                        Error& error,
                        uint32_t max_length = 0,
                        bool honor_array = true,
index d839c1a..b1adf0b 100644 (file)
@@ -34,6 +34,7 @@
 #include "lldb/Core/ValueObjectSyntheticFilter.h"
 
 #include "lldb/DataFormatters/DataVisualization.h"
+#include "lldb/DataFormatters/StringPrinter.h"
 #include "lldb/DataFormatters/ValueObjectPrinter.h"
 
 #include "lldb/Host/Endian.h"
@@ -1187,20 +1188,31 @@ strlen_or_inf (const char* str,
     return len;
 }
 
+static bool
+CopyStringDataToBufferSP(const StreamString& source,
+                         lldb::DataBufferSP& destination)
+{
+    destination.reset(new DataBufferHeap(source.GetSize()+1,0));
+    memcpy(destination->GetBytes(), source.GetString().c_str(), source.GetSize());
+    return true;
+}
+
 size_t
-ValueObject::ReadPointedString (Stream& s,
+ValueObject::ReadPointedString (lldb::DataBufferSP& buffer_sp,
                                 Error& error,
                                 uint32_t max_length,
                                 bool honor_array,
                                 Format item_format)
 {
+    StreamString s;
     ExecutionContext exe_ctx (GetExecutionContextRef());
     Target* target = exe_ctx.GetTargetPtr();
-
+    
     if (!target)
     {
         s << "<no target to read from>";
         error.SetErrorString("no target to read from");
+        CopyStringDataToBufferSP(s, buffer_sp);
         return 0;
     }
     
@@ -1246,9 +1258,10 @@ ValueObject::ReadPointedString (Stream& s,
         {
             s << "<invalid address>";
             error.SetErrorString("invalid address");
+            CopyStringDataToBufferSP(s, buffer_sp);
             return 0;
         }
-
+        
         Address cstr_so_addr (cstr_address);
         DataExtractor data;
         if (cstr_len > 0 && honor_array)
@@ -1256,30 +1269,21 @@ ValueObject::ReadPointedString (Stream& s,
             // I am using GetPointeeData() here to abstract the fact that some ValueObjects are actually frozen pointers in the host
             // but the pointed-to data lives in the debuggee, and GetPointeeData() automatically takes care of this
             GetPointeeData(data, 0, cstr_len);
-
+            
             if ((bytes_read = data.GetByteSize()) > 0)
             {
                 total_bytes_read = bytes_read;
-                s << '"';
-                data.Dump (&s,
-                           0,                 // Start offset in "data"
-                           item_format,
-                           1,                 // Size of item (1 byte for a char!)
-                           bytes_read,        // How many bytes to print?
-                           UINT32_MAX,        // num per line
-                           LLDB_INVALID_ADDRESS,// base address
-                           0,                 // bitfield bit size
-                           0);                // bitfield bit offset
+                for (size_t offset = 0; offset < bytes_read; offset++)
+                    s.Printf("%c", *data.PeekData(offset, 1));
                 if (capped_data)
                     s << "...";
-                s << '"';
             }
         }
         else
         {
             cstr_len = max_length;
             const size_t k_max_buf_size = 64;
-                                        
+            
             size_t offset = 0;
             
             int cstr_len_displayed = -1;
@@ -1293,12 +1297,10 @@ ValueObject::ReadPointedString (Stream& s,
                 size_t len = strlen_or_inf (cstr, k_max_buf_size, k_max_buf_size+1);
                 if (len > k_max_buf_size)
                     len = k_max_buf_size;
-                if (cstr && cstr_len_displayed < 0)
-                    s << '"';
-
+                
                 if (cstr_len_displayed < 0)
                     cstr_len_displayed = len;
-
+                
                 if (len == 0)
                     break;
                 cstr_len_displayed += len;
@@ -1307,15 +1309,8 @@ ValueObject::ReadPointedString (Stream& s,
                 if (len > cstr_len)
                     len = cstr_len;
                 
-                data.Dump (&s,
-                           0,                 // Start offset in "data"
-                           item_format,
-                           1,                 // Size of item (1 byte for a char!)
-                           len,               // How many bytes to print?
-                           UINT32_MAX,        // num per line
-                           LLDB_INVALID_ADDRESS,// base address
-                           0,                 // bitfield bit size
-                           0);                // bitfield bit offset
+                for (size_t offset = 0; offset < bytes_read; offset++)
+                    s.Printf("%c", *data.PeekData(offset, 1));
                 
                 if (len < k_max_buf_size)
                     break;
@@ -1325,14 +1320,13 @@ ValueObject::ReadPointedString (Stream& s,
                     capped_cstr = true;
                     break;
                 }
-
+                
                 cstr_len -= len;
                 offset += len;
             }
             
             if (cstr_len_displayed >= 0)
             {
-                s << '"';
                 if (capped_cstr)
                     s << "...";
             }
@@ -1343,6 +1337,7 @@ ValueObject::ReadPointedString (Stream& s,
         error.SetErrorString("not a string object");
         s << "<not a string object>";
     }
+    CopyStringDataToBufferSP(s, buffer_sp);
     return total_bytes_read;
 }
 
@@ -1590,11 +1585,20 @@ ValueObject::DumpPrintableRepresentation(Stream& s,
                  custom_format == eFormatVectorOfChar)) // print char[] & char* directly
             {
                 Error error;
-                ReadPointedString(s,
+                lldb::DataBufferSP buffer_sp;
+                ReadPointedString(buffer_sp,
                                   error,
                                   0,
                                   (custom_format == eFormatVectorOfChar) ||
                                   (custom_format == eFormatCharArray));
+                lldb_private::formatters::ReadBufferAndDumpToStreamOptions options;
+                options.SetData(DataExtractor(buffer_sp, lldb::eByteOrderInvalid, 8)); // none of this matters for a string - pass some defaults
+                options.SetStream(&s);
+                options.SetPrefixToken(0);
+                options.SetQuote('"');
+                options.SetSourceSize(buffer_sp->GetByteSize());
+                options.SetEscapeNonPrintables(true);
+                lldb_private::formatters::ReadBufferAndDumpToStream<lldb_private::formatters::StringElementType::ASCII>(options);
                 return !error.Fail();
             }
             
index 4d02ca4..2a0ea44 100644 (file)
@@ -464,22 +464,33 @@ lldb_private::formatters::LibcxxStringSummaryProvider (ValueObject& valobj, Stre
 {
     uint64_t size = 0;
     ValueObjectSP location_sp((ValueObject*)nullptr);
+    
     if (!ExtractLibcxxStringInfo(valobj, location_sp, size))
         return false;
+    
     if (size == 0)
     {
         stream.Printf("\"\"");
         return true;
     }
+    
     if (!location_sp)
         return false;
-    Error error;
-    if (location_sp->ReadPointedString(stream,
-                                       error,
-                                       0, // max length is decided by the settings
-                                       false) == 0) // do not honor array (terminates on first 0 byte even for a char[])
-        stream.Printf("\"\""); // if nothing was read, print an empty string
-    return error.Success();
+    
+    DataExtractor extractor;
+    size = std::min<decltype(size)>(size, valobj.GetTargetSP()->GetMaximumSizeOfStringSummary());
+    location_sp->GetPointeeData(extractor, 0, size);
+    
+    lldb_private::formatters::ReadBufferAndDumpToStreamOptions options;
+    options.SetData(extractor); // none of this matters for a string - pass some defaults
+    options.SetStream(&stream);
+    options.SetPrefixToken(0);
+    options.SetQuote('"');
+    options.SetSourceSize(size);
+    options.SetEscapeNonPrintables(true);
+    lldb_private::formatters::ReadBufferAndDumpToStream<lldb_private::formatters::StringElementType::ASCII>(options);
+    
+    return true;
 }
 
 bool
index 7bf75a6..0cc15e1 100644 (file)
@@ -1882,12 +1882,17 @@ Process::LoadImage (const FileSpec &image_spec, Error &error)
                                 {
                                     if (error_str_sp->IsCStringContainer(true))
                                     {
-                                        StreamString s;
-                                        size_t num_chars = error_str_sp->ReadPointedString (s, error);
+                                        DataBufferSP buffer_sp(new DataBufferHeap(10240,0));
+                                        size_t num_chars = error_str_sp->ReadPointedString (buffer_sp, error, 10240);
                                         if (error.Success() && num_chars > 0)
                                         {
                                             error.Clear();
-                                            error.SetErrorStringWithFormat("dlopen error: %s", s.GetData());
+                                            error.SetErrorStringWithFormat("dlopen error: %s", buffer_sp->GetBytes());
+                                        }
+                                        else
+                                        {
+                                            error.Clear();
+                                            error.SetErrorStringWithFormat("dlopen failed for unknown reasons.");
                                         }
                                     }
                                 }