summaryrefslogtreecommitdiff
path: root/examples/python/diagnose_nsstring.py
diff options
context:
space:
mode:
Diffstat (limited to 'examples/python/diagnose_nsstring.py')
-rw-r--r--examples/python/diagnose_nsstring.py183
1 files changed, 0 insertions, 183 deletions
diff --git a/examples/python/diagnose_nsstring.py b/examples/python/diagnose_nsstring.py
deleted file mode 100644
index 0404f714f74a..000000000000
--- a/examples/python/diagnose_nsstring.py
+++ /dev/null
@@ -1,183 +0,0 @@
-# This implements the "diagnose-nsstring" command, usually installed in the debug session like
-# command script import lldb.diagnose
-# it is used when NSString summary formatter fails to replicate the logic that went into LLDB making the
-# decisions it did and providing some useful context information that can
-# be used for improving the formatter
-
-import lldb
-
-
-def read_memory(process, location, size):
- data = ""
- error = lldb.SBError()
- for x in range(0, size - 1):
- byte = process.ReadUnsignedFromMemory(x + location, 1, error)
- if error.fail:
- data = data + "err%s" % "" if x == size - 2 else ":"
- else:
- try:
- data = data + "0x%x" % byte
- if byte == 0:
- data = data + "(\\0)"
- elif byte == 0xa:
- data = data + "(\\a)"
- elif byte == 0xb:
- data = data + "(\\b)"
- elif byte == 0xc:
- data = data + "(\\c)"
- elif byte == '\n':
- data = data + "(\\n)"
- else:
- data = data + "(%s)" % chr(byte)
- if x < size - 2:
- data = data + ":"
- except Exception as e:
- print e
- return data
-
-
-def diagnose_nsstring_Command_Impl(debugger, command, result, internal_dict):
- """
- A command to diagnose the LLDB NSString data formatter
- invoke as
- (lldb) diagnose-nsstring <expr returning NSString>
- e.g.
- (lldb) diagnose-nsstring @"Hello world"
- """
- target = debugger.GetSelectedTarget()
- process = target.GetProcess()
- thread = process.GetSelectedThread()
- frame = thread.GetSelectedFrame()
- if not target.IsValid() or not process.IsValid():
- return "unable to get target/process - cannot proceed"
- options = lldb.SBExpressionOptions()
- options.SetFetchDynamicValue()
- error = lldb.SBError()
- if frame.IsValid():
- nsstring = frame.EvaluateExpression(command, options)
- else:
- nsstring = target.EvaluateExpression(command, options)
- print >>result, str(nsstring)
- nsstring_address = nsstring.GetValueAsUnsigned(0)
- if nsstring_address == 0:
- return "unable to obtain the string - cannot proceed"
- expression = "\
-struct $__lldb__notInlineMutable {\
- char* buffer;\
- signed long length;\
- signed long capacity;\
- unsigned int hasGap:1;\
- unsigned int isFixedCapacity:1;\
- unsigned int isExternalMutable:1;\
- unsigned int capacityProvidedExternally:1;\n\
-#if __LP64__\n\
- unsigned long desiredCapacity:60;\n\
-#else\n\
- unsigned long desiredCapacity:28;\n\
-#endif\n\
- void* contentsAllocator;\
-};\
-\
-struct $__lldb__CFString {\
- void* _cfisa;\
- uint8_t _cfinfo[4];\
- uint32_t _rc;\
- union {\
- struct __inline1 {\
- signed long length;\
- } inline1;\
- struct __notInlineImmutable1 {\
- char* buffer;\
- signed long length;\
- void* contentsDeallocator;\
- } notInlineImmutable1;\
- struct __notInlineImmutable2 {\
- char* buffer;\
- void* contentsDeallocator;\
- } notInlineImmutable2;\
- struct $__lldb__notInlineMutable notInlineMutable;\
- } variants;\
-};\
-"
-
- expression = expression + "*(($__lldb__CFString*) %d)" % nsstring_address
- # print expression
- dumped = target.EvaluateExpression(expression, options)
- print >>result, str(dumped)
-
- little_endian = (target.byte_order == lldb.eByteOrderLittle)
- ptr_size = target.addr_size
-
- info_bits = dumped.GetChildMemberWithName("_cfinfo").GetChildAtIndex(
- 0 if little_endian else 3).GetValueAsUnsigned(0)
- is_mutable = (info_bits & 1) == 1
- is_inline = (info_bits & 0x60) == 0
- has_explicit_length = (info_bits & (1 | 4)) != 4
- is_unicode = (info_bits & 0x10) == 0x10
- is_special = (
- nsstring.GetDynamicValue(
- lldb.eDynamicCanRunTarget).GetTypeName() == "NSPathStore2")
- has_null = (info_bits & 8) == 8
-
- print >>result, "\nInfo=%d\nMutable=%s\nInline=%s\nExplicit=%s\nUnicode=%s\nSpecial=%s\nNull=%s\n" % \
- (info_bits, "yes" if is_mutable else "no", "yes" if is_inline else "no", "yes" if has_explicit_length else "no", "yes" if is_unicode else "no", "yes" if is_special else "no", "yes" if has_null else "no")
-
- explicit_length_offset = 0
- if not has_null and has_explicit_length and not is_special:
- explicit_length_offset = 2 * ptr_size
- if is_mutable and not is_inline:
- explicit_length_offset = explicit_length_offset + ptr_size
- elif is_inline:
- pass
- elif not is_inline and not is_mutable:
- explicit_length_offset = explicit_length_offset + ptr_size
- else:
- explicit_length_offset = 0
-
- if explicit_length_offset == 0:
- print >>result, "There is no explicit length marker - skipping this step\n"
- else:
- explicit_length_offset = nsstring_address + explicit_length_offset
- explicit_length = process.ReadUnsignedFromMemory(
- explicit_length_offset, 4, error)
- print >>result, "Explicit length location is at 0x%x - read value is %d\n" % (
- explicit_length_offset, explicit_length)
-
- if is_mutable:
- location = 2 * ptr_size + nsstring_address
- location = process.ReadPointerFromMemory(location, error)
- elif is_inline and has_explicit_length and not is_unicode and not is_special and not is_mutable:
- location = 3 * ptr_size + nsstring_address
- elif is_unicode:
- location = 2 * ptr_size + nsstring_address
- if is_inline:
- if not has_explicit_length:
- print >>result, "Unicode & Inline & !Explicit is a new combo - no formula for it"
- else:
- location += ptr_size
- else:
- location = process.ReadPointerFromMemory(location, error)
- elif is_special:
- location = nsstring_address + ptr_size + 4
- elif is_inline:
- location = 2 * ptr_size + nsstring_address
- if not has_explicit_length:
- location += 1
- else:
- location = 2 * ptr_size + nsstring_address
- location = process.ReadPointerFromMemory(location, error)
- print >>result, "Expected data location: 0x%x\n" % (location)
- print >>result, "1K of data around location: %s\n" % read_memory(
- process, location, 1024)
- print >>result, "5K of data around string pointer: %s\n" % read_memory(
- process, nsstring_address, 1024 * 5)
-
-
-def __lldb_init_module(debugger, internal_dict):
- debugger.HandleCommand(
- "command script add -f %s.diagnose_nsstring_Command_Impl diagnose-nsstring" %
- __name__)
- print 'The "diagnose-nsstring" command has been installed, type "help diagnose-nsstring" for detailed help.'
-
-__lldb_init_module(lldb.debugger, None)
-__lldb_init_module = None