[Lldb-commits] [lldb] r178577 - <rdar://problem/13415737>

Enrico Granata egranata at apple.com
Tue Apr 2 14:25:34 PDT 2013


Author: enrico
Date: Tue Apr  2 16:25:34 2013
New Revision: 178577

URL: http://llvm.org/viewvc/llvm-project?rev=178577&view=rev
Log:
<rdar://problem/13415737>

Fixing a bug where LLDB was not handling correctly CFStrings that have an explicit length but no NULL terminator
The data formatter was showing garbled data as part of the summary
The fix is to explicitly figure out the explicit length if we need to (bitfields tell us when that is the case) and use that as a size delimiter


Modified:
    lldb/trunk/source/DataFormatters/CXXFormatterFunctions.cpp

Modified: lldb/trunk/source/DataFormatters/CXXFormatterFunctions.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/DataFormatters/CXXFormatterFunctions.cpp?rev=178577&r1=178576&r2=178577&view=diff
==============================================================================
--- lldb/trunk/source/DataFormatters/CXXFormatterFunctions.cpp (original)
+++ lldb/trunk/source/DataFormatters/CXXFormatterFunctions.cpp Tue Apr  2 16:25:34 2013
@@ -7,8 +7,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "lldb/lldb-python.h"
-
 #include "lldb/DataFormatters/CXXFormatterFunctions.h"
 
 #include "llvm/Support/ConvertUTF.h"
@@ -23,6 +21,8 @@
 #include "lldb/Target/ObjCLanguageRuntime.h"
 #include "lldb/Target/Target.h"
 
+#include <algorithm>
+
 using namespace lldb;
 using namespace lldb_private;
 using namespace lldb_private::formatters;
@@ -180,7 +180,7 @@ DumpUTFBufferToStream (ConversionResult
                        Stream& stream,
                        char prefix_token = '@',
                        char quote = '"',
-                       int sourceSize = 0)
+                       uint32_t sourceSize = 0)
 {
     if (prefix_token != 0)
         stream.Printf("%c",prefix_token);
@@ -257,7 +257,7 @@ ReadUTFBufferAndDumpToStream (Conversion
                               Stream& stream,
                               char prefix_token = '@',
                               char quote = '"',
-                              int sourceSize = 0)
+                              uint32_t sourceSize = 0)
 {
     if (location == 0 || location == LLDB_INVALID_ADDRESS)
         return false;
@@ -271,8 +271,7 @@ ReadUTFBufferAndDumpToStream (Conversion
     if (origin_encoding != 8 && !ConvertFunction)
         return false;
 
-    if (sourceSize == 0)
-        sourceSize = process_sp->GetTarget().GetMaximumSizeOfStringSummary();
+    sourceSize = std::min(sourceSize,process_sp->GetTarget().GetMaximumSizeOfStringSummary());
     const int bufferSPSize = sourceSize * (origin_encoding >> 2);
 
     Error error;
@@ -644,7 +643,7 @@ static bool
 ReadAsciiBufferAndDumpToStream (lldb::addr_t location,
                                 lldb::ProcessSP& process_sp,
                                 Stream& dest,
-                                size_t size = 0,
+                                uint32_t size = 0,
                                 Error* error = NULL,
                                 size_t *data_read = NULL,
                                 char prefix_token = '@',
@@ -655,8 +654,7 @@ ReadAsciiBufferAndDumpToStream (lldb::ad
     if (!process_sp || location == 0)
         return false;
     
-    if (size == 0)
-        size = process_sp->GetTarget().GetMaximumSizeOfStringSummary();
+    size = std::min(size,process_sp->GetTarget().GetMaximumSizeOfStringSummary());
     
     lldb::DataBufferSP buffer_sp(new DataBufferHeap(size,0));
     
@@ -675,6 +673,45 @@ ReadAsciiBufferAndDumpToStream (lldb::ad
     return true;
 }
 
+#ifdef WANT_DEEP_PRINT
+struct lldb__notInlineMutable {
+    void *buffer;
+    signed long length;
+    signed long capacity;
+    unsigned int hasGap:1;
+    unsigned int isFixedCapacity:1;
+    unsigned int isExternalMutable:1;
+    unsigned int capacityProvidedExternally:1;
+#if __LP64__
+    unsigned long desiredCapacity:60;
+#else
+    unsigned long desiredCapacity:28;
+#endif
+    void* contentsAllocator;
+};
+
+struct lldb__CFString {
+    uintptr_t _cfisa;
+    uint8_t _cfinfo[4];
+    uint32_t _rc;
+    union {
+        struct __inline1 {
+            signed long length;
+        } inline1;
+        struct __notInlineImmutable1 {
+            void *buffer;
+            signed long length;
+            void* contentsDeallocator;
+        } notInlineImmutable1;
+        struct __notInlineImmutable2 {
+            void *buffer;
+            void* contentsDeallocator;
+        } notInlineImmutable2;
+        struct lldb__notInlineMutable notInlineMutable;
+    } variants;
+};
+#endif
+
 bool
 lldb_private::formatters::NSStringSummaryProvider (ValueObject& valobj, Stream& stream)
 {
@@ -719,6 +756,87 @@ lldb_private::formatters::NSStringSummar
     bool has_explicit_length = (info_bits & (1 | 4)) != 4;
     bool is_unicode = (info_bits & 0x10) == 0x10;
     bool is_special = strcmp(class_name,"NSPathStore2") == 0;
+    bool has_null = (info_bits & 8) == 8;
+    
+    size_t explicit_length = 0;
+    if (!has_null && has_explicit_length && !is_special)
+    {
+        lldb::addr_t explicit_length_offset = 2*ptr_size;
+        if (is_mutable and not is_inline)
+            explicit_length_offset = explicit_length_offset + ptr_size; //  notInlineMutable.length;
+        else if (is_inline)
+            explicit_length = explicit_length + 0; // inline1.length;
+        else if (not is_inline and not is_mutable)
+            explicit_length_offset = explicit_length_offset + ptr_size; // notInlineImmutable1.length;
+        else
+            explicit_length_offset = 0;
+
+        if (explicit_length_offset)
+        {
+            explicit_length_offset = valobj_addr + explicit_length_offset;
+            explicit_length = process_sp->ReadUnsignedIntegerFromMemory(explicit_length_offset, 4, 0, error);
+        }
+    }
+    
+#ifdef WANT_DEEP_PRINT
+    lldb__CFString my_string_data;
+    process_sp->ReadMemory(valobj_addr, &my_string_data, sizeof(lldb__CFString),error);
+    
+    printf(R"(
+           __CFString my_string_data = {
+           uintptr_t _cfisa = %lu
+           uint8_t _cfinfo[4] = %c%c%c%c
+           uint32_t _rc = %d
+           union {
+               struct __inline1 {
+                   signed long length = %ld
+               } inline1;
+               struct __notInlineImmutable1 {
+                   void *buffer = %p
+                   signed long length = %ld
+                   void* contentsDeallocator = %p
+               } notInlineImmutable1;
+               struct __notInlineImmutable2 {
+                   void *buffer = %p
+                   void* contentsDeallocator = %p
+               } notInlineImmutable2;
+               struct __notInlineMutable notInlineMutable {
+                   void *buffer = %p
+                   signed long length = %ld
+                   signed long capacity = %ld
+                   unsigned int hasGap:1 = %d
+                   unsigned int isFixedCapacity:1 = %d
+                   unsigned int isExternalMutable:1 = %d
+                   unsigned int capacityProvidedExternally:1 = %d
+#if __LP64__
+                   unsigned long desiredCapacity:60 = %lu
+#else
+                   unsigned long desiredCapacity:28 = %lu
+#endif
+                   void* contentsAllocator = %p
+               }
+           } variants;
+           };\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],
+    my_string_data._rc,
+    my_string_data.variants.inline1.length,
+    my_string_data.variants.notInlineImmutable1.buffer,
+    my_string_data.variants.notInlineImmutable1.length,
+    my_string_data.variants.notInlineImmutable1.contentsDeallocator,
+    my_string_data.variants.notInlineImmutable2.buffer,
+    my_string_data.variants.notInlineImmutable2.contentsDeallocator,
+    my_string_data.variants.notInlineMutable.buffer,
+    my_string_data.variants.notInlineMutable.length,
+    my_string_data.variants.notInlineMutable.capacity,
+    my_string_data.variants.notInlineMutable.hasGap,
+    my_string_data.variants.notInlineMutable.isFixedCapacity,
+    my_string_data.variants.notInlineMutable.isExternalMutable,
+    my_string_data.variants.notInlineMutable.capacityProvidedExternally,
+    my_string_data.variants.notInlineMutable.desiredCapacity,
+    my_string_data.variants.notInlineMutable.desiredCapacity,
+    my_string_data.variants.notInlineMutable.contentsAllocator);
+#endif
     
     if (strcmp(class_name,"NSString") &&
         strcmp(class_name,"CFStringRef") &&
@@ -734,6 +852,16 @@ lldb_private::formatters::NSStringSummar
         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;
@@ -741,14 +869,14 @@ lldb_private::formatters::NSStringSummar
         if (error.Fail())
             return false;
         if (has_explicit_length and is_unicode)
-            return ReadUTFBufferAndDumpToStream<UTF16> (ConvertUTF16toUTF8,location, process_sp, stream, '@');
+            return ReadUTFBufferAndDumpToStream<UTF16> (ConvertUTF16toUTF8,location, process_sp, stream, '@', '"', explicit_length);
         else
-            return ReadAsciiBufferAndDumpToStream(location+1,process_sp,stream);
+            return ReadAsciiBufferAndDumpToStream(location+1,process_sp,stream, explicit_length);
     }
     else if (is_inline && has_explicit_length && !is_unicode && !is_special && !is_mutable)
     {
         uint64_t location = 3 * ptr_size + valobj_addr;
-        return ReadAsciiBufferAndDumpToStream(location,process_sp,stream);
+        return ReadAsciiBufferAndDumpToStream(location,process_sp,stream,explicit_length);
     }
     else if (is_unicode)
     {
@@ -769,19 +897,19 @@ lldb_private::formatters::NSStringSummar
             if (error.Fail())
                 return false;
         }
-        return ReadUTFBufferAndDumpToStream<UTF16> (ConvertUTF16toUTF8, location, process_sp, stream, '@');
+        return ReadUTFBufferAndDumpToStream<UTF16> (ConvertUTF16toUTF8, location, process_sp, stream, '@', '"', explicit_length);
     }
     else if (is_special)
     {
         uint64_t location = valobj_addr + (ptr_size == 8 ? 12 : 8);
-        return ReadUTFBufferAndDumpToStream<UTF16> (ConvertUTF16toUTF8, location, process_sp, stream, '@');
+        return ReadUTFBufferAndDumpToStream<UTF16> (ConvertUTF16toUTF8, location, process_sp, stream, '@', '"', explicit_length);
     }
     else if (is_inline)
     {
         uint64_t location = valobj_addr + 2*ptr_size;
         if (!has_explicit_length)
             location++;
-        return ReadAsciiBufferAndDumpToStream(location,process_sp,stream);
+        return ReadAsciiBufferAndDumpToStream(location,process_sp,stream,explicit_length);
     }
     else
     {
@@ -789,7 +917,7 @@ lldb_private::formatters::NSStringSummar
         location = process_sp->ReadPointerFromMemory(location, error);
         if (error.Fail())
             return false;
-        return ReadAsciiBufferAndDumpToStream(location,process_sp,stream);
+        return ReadAsciiBufferAndDumpToStream(location,process_sp,stream,explicit_length);
     }
     
     stream.Printf("class name = %s",class_name);





More information about the lldb-commits mailing list