aboutsummaryrefslogtreecommitdiff
path: root/examples/summaries
diff options
context:
space:
mode:
Diffstat (limited to 'examples/summaries')
-rw-r--r--examples/summaries/cocoa/CFArray.py345
-rw-r--r--examples/summaries/cocoa/CFBag.py241
-rw-r--r--examples/summaries/cocoa/CFBinaryHeap.py235
-rw-r--r--examples/summaries/cocoa/CFBitVector.py301
-rw-r--r--examples/summaries/cocoa/CFDictionary.py421
-rw-r--r--examples/summaries/cocoa/CFString.py646
-rw-r--r--examples/summaries/cocoa/Class.py19
-rw-r--r--examples/summaries/cocoa/Logger.py207
-rw-r--r--examples/summaries/cocoa/NSBundle.py208
-rw-r--r--examples/summaries/cocoa/NSData.py283
-rw-r--r--examples/summaries/cocoa/NSDate.py462
-rw-r--r--examples/summaries/cocoa/NSException.py196
-rw-r--r--examples/summaries/cocoa/NSIndexSet.py264
-rw-r--r--examples/summaries/cocoa/NSMachPort.py196
-rw-r--r--examples/summaries/cocoa/NSNotification.py174
-rw-r--r--examples/summaries/cocoa/NSNumber.py430
-rw-r--r--examples/summaries/cocoa/NSSet.py476
-rw-r--r--examples/summaries/cocoa/NSURL.py222
-rw-r--r--examples/summaries/cocoa/Selector.py13
-rw-r--r--examples/summaries/cocoa/attrib_fromdict.py64
-rw-r--r--examples/summaries/cocoa/cache.py43
-rw-r--r--examples/summaries/cocoa/metrics.py168
-rw-r--r--examples/summaries/cocoa/objc_runtime.py1560
-rw-r--r--examples/summaries/objc.py25
-rw-r--r--examples/summaries/pysummary.py32
-rw-r--r--examples/summaries/sp_cp.py119
-rw-r--r--examples/summaries/synth.py66
-rw-r--r--examples/summaries/unicode_strings.py73
28 files changed, 4067 insertions, 3422 deletions
diff --git a/examples/summaries/cocoa/CFArray.py b/examples/summaries/cocoa/CFArray.py
index 5068875b5b38..6fc97081bad5 100644
--- a/examples/summaries/cocoa/CFArray.py
+++ b/examples/summaries/cocoa/CFArray.py
@@ -22,183 +22,212 @@ statistics.add_metric('code_notrun')
# much less functional than the other two cases below
# just runs code to get to the count and then returns
# no children
+
+
class NSArrayKVC_SynthProvider:
- def adjust_for_architecture(self):
- pass
+ def adjust_for_architecture(self):
+ pass
- def __init__(self, valobj, dict, params):
- logger = lldb.formatters.Logger.Logger()
- self.valobj = valobj;
- self.update()
+ def __init__(self, valobj, dict, params):
+ logger = lldb.formatters.Logger.Logger()
+ self.valobj = valobj
+ self.update()
- def update(self):
- logger = lldb.formatters.Logger.Logger()
- self.adjust_for_architecture();
+ def update(self):
+ logger = lldb.formatters.Logger.Logger()
+ self.adjust_for_architecture()
- def num_children(self):
- logger = lldb.formatters.Logger.Logger()
- stream = lldb.SBStream()
- self.valobj.GetExpressionPath(stream)
- num_children_vo = self.valobj.CreateValueFromExpression("count","(int)[" + stream.GetData() + " count]");
- if num_children_vo.IsValid():
- return num_children_vo.GetValueAsUnsigned(0)
- return "<variable is not NSArray>"
+ def num_children(self):
+ logger = lldb.formatters.Logger.Logger()
+ stream = lldb.SBStream()
+ self.valobj.GetExpressionPath(stream)
+ num_children_vo = self.valobj.CreateValueFromExpression(
+ "count", "(int)[" + stream.GetData() + " count]")
+ if num_children_vo.IsValid():
+ return num_children_vo.GetValueAsUnsigned(0)
+ return "<variable is not NSArray>"
# much less functional than the other two cases below
# just runs code to get to the count and then returns
# no children
+
+
class NSArrayCF_SynthProvider:
- def adjust_for_architecture(self):
- pass
+ def adjust_for_architecture(self):
+ pass
- def __init__(self, valobj, dict, params):
- logger = lldb.formatters.Logger.Logger()
- self.valobj = valobj;
- self.sys_params = params
- if not (self.sys_params.types_cache.ulong):
- self.sys_params.types_cache.ulong = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong)
- self.update()
+ def __init__(self, valobj, dict, params):
+ logger = lldb.formatters.Logger.Logger()
+ self.valobj = valobj
+ self.sys_params = params
+ if not (self.sys_params.types_cache.ulong):
+ self.sys_params.types_cache.ulong = self.valobj.GetType(
+ ).GetBasicType(lldb.eBasicTypeUnsignedLong)
+ self.update()
- def update(self):
- logger = lldb.formatters.Logger.Logger()
- self.adjust_for_architecture();
+ def update(self):
+ logger = lldb.formatters.Logger.Logger()
+ self.adjust_for_architecture()
+
+ def num_children(self):
+ logger = lldb.formatters.Logger.Logger()
+ num_children_vo = self.valobj.CreateChildAtOffset(
+ "count", self.sys_params.cfruntime_size, self.sys_params.types_cache.ulong)
+ return num_children_vo.GetValueAsUnsigned(0)
- def num_children(self):
- logger = lldb.formatters.Logger.Logger()
- num_children_vo = self.valobj.CreateChildAtOffset("count",
- self.sys_params.cfruntime_size,
- self.sys_params.types_cache.ulong)
- return num_children_vo.GetValueAsUnsigned(0)
class NSArrayI_SynthProvider:
- def adjust_for_architecture(self):
- pass
-
- def __init__(self, valobj, dict, params):
- logger = lldb.formatters.Logger.Logger()
- self.valobj = valobj;
- self.sys_params = params
- if not(self.sys_params.types_cache.long):
- self.sys_params.types_cache.long = self.valobj.GetType().GetBasicType(lldb.eBasicTypeLong)
- self.update()
-
- def update(self):
- logger = lldb.formatters.Logger.Logger()
- self.adjust_for_architecture();
-
- # skip the isa pointer and get at the size
- def num_children(self):
- logger = lldb.formatters.Logger.Logger()
- count = self.valobj.CreateChildAtOffset("count",
- self.sys_params.pointer_size,
- self.sys_params.types_cache.long);
- return count.GetValueAsUnsigned(0)
+
+ def adjust_for_architecture(self):
+ pass
+
+ def __init__(self, valobj, dict, params):
+ logger = lldb.formatters.Logger.Logger()
+ self.valobj = valobj
+ self.sys_params = params
+ if not(self.sys_params.types_cache.long):
+ self.sys_params.types_cache.long = self.valobj.GetType(
+ ).GetBasicType(lldb.eBasicTypeLong)
+ self.update()
+
+ def update(self):
+ logger = lldb.formatters.Logger.Logger()
+ self.adjust_for_architecture()
+
+ # skip the isa pointer and get at the size
+ def num_children(self):
+ logger = lldb.formatters.Logger.Logger()
+ count = self.valobj.CreateChildAtOffset(
+ "count",
+ self.sys_params.pointer_size,
+ self.sys_params.types_cache.long)
+ return count.GetValueAsUnsigned(0)
+
class NSArrayM_SynthProvider:
- def adjust_for_architecture(self):
- pass
-
- def __init__(self, valobj, dict, params):
- logger = lldb.formatters.Logger.Logger()
- self.valobj = valobj;
- self.sys_params = params
- if not(self.sys_params.types_cache.long):
- self.sys_params.types_cache.long = self.valobj.GetType().GetBasicType(lldb.eBasicTypeLong)
- self.update()
-
- def update(self):
- logger = lldb.formatters.Logger.Logger()
- self.adjust_for_architecture();
-
- # skip the isa pointer and get at the size
- def num_children(self):
- logger = lldb.formatters.Logger.Logger()
- count = self.valobj.CreateChildAtOffset("count",
- self.sys_params.pointer_size,
- self.sys_params.types_cache.long);
- return count.GetValueAsUnsigned(0)
+
+ def adjust_for_architecture(self):
+ pass
+
+ def __init__(self, valobj, dict, params):
+ logger = lldb.formatters.Logger.Logger()
+ self.valobj = valobj
+ self.sys_params = params
+ if not(self.sys_params.types_cache.long):
+ self.sys_params.types_cache.long = self.valobj.GetType(
+ ).GetBasicType(lldb.eBasicTypeLong)
+ self.update()
+
+ def update(self):
+ logger = lldb.formatters.Logger.Logger()
+ self.adjust_for_architecture()
+
+ # skip the isa pointer and get at the size
+ def num_children(self):
+ logger = lldb.formatters.Logger.Logger()
+ count = self.valobj.CreateChildAtOffset(
+ "count",
+ self.sys_params.pointer_size,
+ self.sys_params.types_cache.long)
+ return count.GetValueAsUnsigned(0)
# this is the actual synth provider, but is just a wrapper that checks
# whether valobj is an instance of __NSArrayI or __NSArrayM and sets up an
-# appropriate backend layer to do the computations
+# appropriate backend layer to do the computations
+
+
class NSArray_SynthProvider:
- def adjust_for_architecture(self):
- pass
-
- def __init__(self, valobj, dict):
- logger = lldb.formatters.Logger.Logger()
- self.valobj = valobj;
- self.adjust_for_architecture()
- self.error = False
- self.wrapper = self.make_wrapper()
- self.invalid = (self.wrapper == None)
-
- def num_children(self):
- logger = lldb.formatters.Logger.Logger()
- if self.wrapper == None:
- return 0;
- return self.wrapper.num_children()
-
- def update(self):
- logger = lldb.formatters.Logger.Logger()
- if self.wrapper == None:
- return
- self.wrapper.update()
-
- # this code acts as our defense against NULL and uninitialized
- # NSArray pointers, which makes it much longer than it would be otherwise
- def make_wrapper(self):
- logger = lldb.formatters.Logger.Logger()
- if self.valobj.GetValueAsUnsigned() == 0:
- self.error = True
- return lldb.runtime.objc.objc_runtime.InvalidPointer_Description(True)
- else:
- global statistics
- class_data,wrapper =lldb.runtime.objc.objc_runtime.Utilities.prepare_class_detection(self.valobj,statistics)
- if wrapper:
- self.error = True
- return wrapper
-
- name_string = class_data.class_name()
-
- logger >> "Class name is " + str(name_string)
-
- if name_string == '__NSArrayI':
- wrapper = NSArrayI_SynthProvider(self.valobj, dict, class_data.sys_params)
- statistics.metric_hit('code_notrun',self.valobj.GetName())
- elif name_string == '__NSArrayM':
- wrapper = NSArrayM_SynthProvider(self.valobj, dict, class_data.sys_params)
- statistics.metric_hit('code_notrun',self.valobj.GetName())
- elif name_string == '__NSCFArray':
- wrapper = NSArrayCF_SynthProvider(self.valobj, dict, class_data.sys_params)
- statistics.metric_hit('code_notrun',self.valobj.GetName())
- else:
- wrapper = NSArrayKVC_SynthProvider(self.valobj, dict, class_data.sys_params)
- statistics.metric_hit('unknown_class',str(self.valobj.GetName()) + " seen as " + name_string)
- return wrapper;
-
-def CFArray_SummaryProvider (valobj,dict):
- logger = lldb.formatters.Logger.Logger()
- provider = NSArray_SynthProvider(valobj,dict);
- if provider.invalid == False:
- if provider.error == True:
- return provider.wrapper.message()
- try:
- summary = int(provider.num_children());
- except:
- summary = None
- logger >> "provider gave me " + str(summary)
- if summary == None:
- summary = '<variable is not NSArray>'
- elif isinstance(summary,basestring):
- pass
- else:
- # we format it like it were a CFString to make it look the same as the summary from Xcode
- summary = '@"' + str(summary) + (" objects" if summary != 1 else " object") + '"'
- return summary
- return 'Summary Unavailable'
-
-def __lldb_init_module(debugger,dict):
- debugger.HandleCommand("type summary add -F CFArray.CFArray_SummaryProvider NSArray CFArrayRef CFMutableArrayRef")
+
+ def adjust_for_architecture(self):
+ pass
+
+ def __init__(self, valobj, dict):
+ logger = lldb.formatters.Logger.Logger()
+ self.valobj = valobj
+ self.adjust_for_architecture()
+ self.error = False
+ self.wrapper = self.make_wrapper()
+ self.invalid = (self.wrapper is None)
+
+ def num_children(self):
+ logger = lldb.formatters.Logger.Logger()
+ if self.wrapper is None:
+ return 0
+ return self.wrapper.num_children()
+
+ def update(self):
+ logger = lldb.formatters.Logger.Logger()
+ if self.wrapper is None:
+ return
+ self.wrapper.update()
+
+ # this code acts as our defense against NULL and uninitialized
+ # NSArray pointers, which makes it much longer than it would be otherwise
+ def make_wrapper(self):
+ logger = lldb.formatters.Logger.Logger()
+ if self.valobj.GetValueAsUnsigned() == 0:
+ self.error = True
+ return lldb.runtime.objc.objc_runtime.InvalidPointer_Description(
+ True)
+ else:
+ global statistics
+ class_data, wrapper = lldb.runtime.objc.objc_runtime.Utilities.prepare_class_detection(
+ self.valobj, statistics)
+ if wrapper:
+ self.error = True
+ return wrapper
+
+ name_string = class_data.class_name()
+
+ logger >> "Class name is " + str(name_string)
+
+ if name_string == '__NSArrayI':
+ wrapper = NSArrayI_SynthProvider(
+ self.valobj, dict, class_data.sys_params)
+ statistics.metric_hit('code_notrun', self.valobj.GetName())
+ elif name_string == '__NSArrayM':
+ wrapper = NSArrayM_SynthProvider(
+ self.valobj, dict, class_data.sys_params)
+ statistics.metric_hit('code_notrun', self.valobj.GetName())
+ elif name_string == '__NSCFArray':
+ wrapper = NSArrayCF_SynthProvider(
+ self.valobj, dict, class_data.sys_params)
+ statistics.metric_hit('code_notrun', self.valobj.GetName())
+ else:
+ wrapper = NSArrayKVC_SynthProvider(
+ self.valobj, dict, class_data.sys_params)
+ statistics.metric_hit(
+ 'unknown_class', str(
+ self.valobj.GetName()) + " seen as " + name_string)
+ return wrapper
+
+
+def CFArray_SummaryProvider(valobj, dict):
+ logger = lldb.formatters.Logger.Logger()
+ provider = NSArray_SynthProvider(valobj, dict)
+ if not provider.invalid:
+ if provider.error:
+ return provider.wrapper.message()
+ try:
+ summary = int(provider.num_children())
+ except:
+ summary = None
+ logger >> "provider gave me " + str(summary)
+ if summary is None:
+ summary = '<variable is not NSArray>'
+ elif isinstance(summary, basestring):
+ pass
+ else:
+ # we format it like it were a CFString to make it look the same as
+ # the summary from Xcode
+ summary = '@"' + str(summary) + \
+ (" objects" if summary != 1 else " object") + '"'
+ return summary
+ return 'Summary Unavailable'
+
+
+def __lldb_init_module(debugger, dict):
+ debugger.HandleCommand(
+ "type summary add -F CFArray.CFArray_SummaryProvider NSArray CFArrayRef CFMutableArrayRef")
diff --git a/examples/summaries/cocoa/CFBag.py b/examples/summaries/cocoa/CFBag.py
index 37d14a432d52..d9a18996e78b 100644
--- a/examples/summaries/cocoa/CFBag.py
+++ b/examples/summaries/cocoa/CFBag.py
@@ -22,125 +22,142 @@ statistics.add_metric('code_notrun')
# despite the similary to synthetic children providers, these classes are not
# trying to provide anything but the length for an CFBag, so they need not
# obey the interface specification for synthetic children providers
+
+
class CFBagRef_SummaryProvider:
- def adjust_for_architecture(self):
- pass
-
- def __init__(self, valobj, params):
- logger = lldb.formatters.Logger.Logger()
- self.valobj = valobj;
- self.sys_params = params
- if not(self.sys_params.types_cache.NSUInteger):
- if self.sys_params.is_64_bit:
- self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong)
- else:
- self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt)
- self.update();
-
- def update(self):
- logger = lldb.formatters.Logger.Logger()
- self.adjust_for_architecture();
-
- # 12 bytes on i386
- # 20 bytes on x64
- # most probably 2 pointers and 4 bytes of data
- def offset(self):
- logger = lldb.formatters.Logger.Logger()
- if self.sys_params.is_64_bit:
- return 20
- else:
- return 12
-
- def length(self):
- logger = lldb.formatters.Logger.Logger()
- size = self.valobj.CreateChildAtOffset("count",
- self.offset(),
- self.sys_params.types_cache.NSUInteger)
- return size.GetValueAsUnsigned(0)
+
+ def adjust_for_architecture(self):
+ pass
+
+ def __init__(self, valobj, params):
+ logger = lldb.formatters.Logger.Logger()
+ self.valobj = valobj
+ self.sys_params = params
+ if not(self.sys_params.types_cache.NSUInteger):
+ if self.sys_params.is_64_bit:
+ self.sys_params.types_cache.NSUInteger = self.valobj.GetType(
+ ).GetBasicType(lldb.eBasicTypeUnsignedLong)
+ else:
+ self.sys_params.types_cache.NSUInteger = self.valobj.GetType(
+ ).GetBasicType(lldb.eBasicTypeUnsignedInt)
+ self.update()
+
+ def update(self):
+ logger = lldb.formatters.Logger.Logger()
+ self.adjust_for_architecture()
+
+ # 12 bytes on i386
+ # 20 bytes on x64
+ # most probably 2 pointers and 4 bytes of data
+ def offset(self):
+ logger = lldb.formatters.Logger.Logger()
+ if self.sys_params.is_64_bit:
+ return 20
+ else:
+ return 12
+
+ def length(self):
+ logger = lldb.formatters.Logger.Logger()
+ size = self.valobj.CreateChildAtOffset(
+ "count", self.offset(), self.sys_params.types_cache.NSUInteger)
+ return size.GetValueAsUnsigned(0)
class CFBagUnknown_SummaryProvider:
- def adjust_for_architecture(self):
- pass
- def __init__(self, valobj, params):
- logger = lldb.formatters.Logger.Logger()
- self.valobj = valobj;
- self.sys_params = params
- self.update();
+ def adjust_for_architecture(self):
+ pass
+
+ def __init__(self, valobj, params):
+ logger = lldb.formatters.Logger.Logger()
+ self.valobj = valobj
+ self.sys_params = params
+ self.update()
- def update(self):
- logger = lldb.formatters.Logger.Logger()
- self.adjust_for_architecture();
+ def update(self):
+ logger = lldb.formatters.Logger.Logger()
+ self.adjust_for_architecture()
- def length(self):
- logger = lldb.formatters.Logger.Logger()
- stream = lldb.SBStream()
- self.valobj.GetExpressionPath(stream)
- num_children_vo = self.valobj.CreateValueFromExpression("count","(int)CFBagGetCount(" + stream.GetData() + " )")
- if num_children_vo.IsValid():
- return num_children_vo.GetValueAsUnsigned(0)
- return "<variable is not CFBag>"
+ def length(self):
+ logger = lldb.formatters.Logger.Logger()
+ stream = lldb.SBStream()
+ self.valobj.GetExpressionPath(stream)
+ num_children_vo = self.valobj.CreateValueFromExpression(
+ "count", "(int)CFBagGetCount(" + stream.GetData() + " )")
+ if num_children_vo.IsValid():
+ return num_children_vo.GetValueAsUnsigned(0)
+ return "<variable is not CFBag>"
def GetSummary_Impl(valobj):
- logger = lldb.formatters.Logger.Logger()
- global statistics
- class_data,wrapper =lldb.runtime.objc.objc_runtime.Utilities.prepare_class_detection(valobj,statistics)
- if wrapper:
- return wrapper
-
- name_string = class_data.class_name()
- actual_name = name_string
-
- logger >> "name string got was " + str(name_string) + " but actual name is " + str(actual_name)
-
- if class_data.is_cftype():
- # CFBag does not expose an actual NSWrapper type, so we have to check that this is
- # an NSCFType and then check we are a pointer-to __CFBag
- valobj_type = valobj.GetType()
- if valobj_type.IsValid() and valobj_type.IsPointerType():
- valobj_type = valobj_type.GetPointeeType()
- if valobj_type.IsValid():
- actual_name = valobj_type.GetName()
- if actual_name == '__CFBag' or \
- actual_name == 'const struct __CFBag':
- wrapper = CFBagRef_SummaryProvider(valobj, class_data.sys_params)
- statistics.metric_hit('code_notrun',valobj)
- return wrapper
- wrapper = CFBagUnknown_SummaryProvider(valobj, class_data.sys_params)
- statistics.metric_hit('unknown_class',valobj.GetName() + " seen as " + actual_name)
- return wrapper;
-
-def CFBag_SummaryProvider (valobj,dict):
- logger = lldb.formatters.Logger.Logger()
- provider = GetSummary_Impl(valobj);
- if provider != None:
- if isinstance(provider,lldb.runtime.objc.objc_runtime.SpecialSituation_Description):
- return provider.message()
- try:
- summary = provider.length();
- except:
- summary = None
- logger >> "summary got from provider: " + str(summary)
- # for some reason, one needs to clear some bits for the count
- # to be correct when using CF(Mutable)BagRef on x64
- # the bit mask was derived through experimentation
- # (if counts start looking weird, then most probably
- # the mask needs to be changed)
- if summary == None:
- summary = '<variable is not CFBag>'
- elif isinstance(summary,basestring):
- pass
- else:
- if provider.sys_params.is_64_bit:
- summary = summary & ~0x1fff000000000000
- if summary == 1:
- summary = '@"1 value"'
- else:
- summary = '@"' + str(summary) + ' values"'
- return summary
- return 'Summary Unavailable'
-
-def __lldb_init_module(debugger,dict):
- debugger.HandleCommand("type summary add -F CFBag.CFBag_SummaryProvider CFBagRef CFMutableBagRef")
+ logger = lldb.formatters.Logger.Logger()
+ global statistics
+ class_data, wrapper = lldb.runtime.objc.objc_runtime.Utilities.prepare_class_detection(
+ valobj, statistics)
+ if wrapper:
+ return wrapper
+
+ name_string = class_data.class_name()
+ actual_name = name_string
+
+ logger >> "name string got was " + \
+ str(name_string) + " but actual name is " + str(actual_name)
+
+ if class_data.is_cftype():
+ # CFBag does not expose an actual NSWrapper type, so we have to check that this is
+ # an NSCFType and then check we are a pointer-to __CFBag
+ valobj_type = valobj.GetType()
+ if valobj_type.IsValid() and valobj_type.IsPointerType():
+ valobj_type = valobj_type.GetPointeeType()
+ if valobj_type.IsValid():
+ actual_name = valobj_type.GetName()
+ if actual_name == '__CFBag' or \
+ actual_name == 'const struct __CFBag':
+ wrapper = CFBagRef_SummaryProvider(valobj, class_data.sys_params)
+ statistics.metric_hit('code_notrun', valobj)
+ return wrapper
+ wrapper = CFBagUnknown_SummaryProvider(valobj, class_data.sys_params)
+ statistics.metric_hit(
+ 'unknown_class',
+ valobj.GetName() +
+ " seen as " +
+ actual_name)
+ return wrapper
+
+
+def CFBag_SummaryProvider(valobj, dict):
+ logger = lldb.formatters.Logger.Logger()
+ provider = GetSummary_Impl(valobj)
+ if provider is not None:
+ if isinstance(
+ provider,
+ lldb.runtime.objc.objc_runtime.SpecialSituation_Description):
+ return provider.message()
+ try:
+ summary = provider.length()
+ except:
+ summary = None
+ logger >> "summary got from provider: " + str(summary)
+ # for some reason, one needs to clear some bits for the count
+ # to be correct when using CF(Mutable)BagRef on x64
+ # the bit mask was derived through experimentation
+ # (if counts start looking weird, then most probably
+ # the mask needs to be changed)
+ if summary is None:
+ summary = '<variable is not CFBag>'
+ elif isinstance(summary, basestring):
+ pass
+ else:
+ if provider.sys_params.is_64_bit:
+ summary = summary & ~0x1fff000000000000
+ if summary == 1:
+ summary = '@"1 value"'
+ else:
+ summary = '@"' + str(summary) + ' values"'
+ return summary
+ return 'Summary Unavailable'
+
+
+def __lldb_init_module(debugger, dict):
+ debugger.HandleCommand(
+ "type summary add -F CFBag.CFBag_SummaryProvider CFBagRef CFMutableBagRef")
diff --git a/examples/summaries/cocoa/CFBinaryHeap.py b/examples/summaries/cocoa/CFBinaryHeap.py
index 2348a8971815..b22f2c5d4f7c 100644
--- a/examples/summaries/cocoa/CFBinaryHeap.py
+++ b/examples/summaries/cocoa/CFBinaryHeap.py
@@ -22,121 +22,140 @@ statistics.add_metric('code_notrun')
# despite the similary to synthetic children providers, these classes are not
# trying to provide anything but the length for an CFBinaryHeap, so they need not
# obey the interface specification for synthetic children providers
+
+
class CFBinaryHeapRef_SummaryProvider:
- def adjust_for_architecture(self):
- pass
-
- def __init__(self, valobj, params):
- logger = lldb.formatters.Logger.Logger()
- self.valobj = valobj;
- self.sys_params = params
- if not(self.sys_params.types_cache.NSUInteger):
- if self.sys_params.is_64_bit:
- self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong)
- else:
- self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt)
- self.update();
-
- def update(self):
- logger = lldb.formatters.Logger.Logger()
- self.adjust_for_architecture();
-
- # 8 bytes on i386
- # 16 bytes on x64
- # most probably 2 pointers
- def offset(self):
- logger = lldb.formatters.Logger.Logger()
- return 2 * self.sys_params.pointer_size
-
- def length(self):
- logger = lldb.formatters.Logger.Logger()
- size = self.valobj.CreateChildAtOffset("count",
- self.offset(),
- self.sys_params.types_cache.NSUInteger)
- return size.GetValueAsUnsigned(0)
+
+ def adjust_for_architecture(self):
+ pass
+
+ def __init__(self, valobj, params):
+ logger = lldb.formatters.Logger.Logger()
+ self.valobj = valobj
+ self.sys_params = params
+ if not(self.sys_params.types_cache.NSUInteger):
+ if self.sys_params.is_64_bit:
+ self.sys_params.types_cache.NSUInteger = self.valobj.GetType(
+ ).GetBasicType(lldb.eBasicTypeUnsignedLong)
+ else:
+ self.sys_params.types_cache.NSUInteger = self.valobj.GetType(
+ ).GetBasicType(lldb.eBasicTypeUnsignedInt)
+ self.update()
+
+ def update(self):
+ logger = lldb.formatters.Logger.Logger()
+ self.adjust_for_architecture()
+
+ # 8 bytes on i386
+ # 16 bytes on x64
+ # most probably 2 pointers
+ def offset(self):
+ logger = lldb.formatters.Logger.Logger()
+ return 2 * self.sys_params.pointer_size
+
+ def length(self):
+ logger = lldb.formatters.Logger.Logger()
+ size = self.valobj.CreateChildAtOffset(
+ "count", self.offset(), self.sys_params.types_cache.NSUInteger)
+ return size.GetValueAsUnsigned(0)
class CFBinaryHeapUnknown_SummaryProvider:
- def adjust_for_architecture(self):
- pass
- def __init__(self, valobj, params):
- logger = lldb.formatters.Logger.Logger()
- self.valobj = valobj;
- self.sys_params = params
- self.update();
+ def adjust_for_architecture(self):
+ pass
+
+ def __init__(self, valobj, params):
+ logger = lldb.formatters.Logger.Logger()
+ self.valobj = valobj
+ self.sys_params = params
+ self.update()
- def update(self):
- logger = lldb.formatters.Logger.Logger()
- self.adjust_for_architecture();
+ def update(self):
+ logger = lldb.formatters.Logger.Logger()
+ self.adjust_for_architecture()
- def length(self):
- logger = lldb.formatters.Logger.Logger()
- stream = lldb.SBStream()
- self.valobj.GetExpressionPath(stream)
- num_children_vo = self.valobj.CreateValueFromExpression("count","(int)CFBinaryHeapGetCount(" + stream.GetData() + " )");
- if num_children_vo.IsValid():
- return num_children_vo.GetValueAsUnsigned(0)
- return '<variable is not CFBinaryHeap>'
+ def length(self):
+ logger = lldb.formatters.Logger.Logger()
+ stream = lldb.SBStream()
+ self.valobj.GetExpressionPath(stream)
+ num_children_vo = self.valobj.CreateValueFromExpression(
+ "count", "(int)CFBinaryHeapGetCount(" + stream.GetData() + " )")
+ if num_children_vo.IsValid():
+ return num_children_vo.GetValueAsUnsigned(0)
+ return '<variable is not CFBinaryHeap>'
def GetSummary_Impl(valobj):
- logger = lldb.formatters.Logger.Logger()
- global statistics
- class_data,wrapper =lldb.runtime.objc.objc_runtime.Utilities.prepare_class_detection(valobj,statistics)
- if wrapper:
- return wrapper
-
- name_string = class_data.class_name()
- actual_name = class_data.class_name()
-
- logger >> "name string got was " + str(name_string) + " but actual name is " + str(actual_name)
-
- if class_data.is_cftype():
- # CFBinaryHeap does not expose an actual NSWrapper type, so we have to check that this is
- # an NSCFType and then check we are a pointer-to CFBinaryHeap
- valobj_type = valobj.GetType()
- if valobj_type.IsValid() and valobj_type.IsPointerType():
- valobj_type = valobj_type.GetPointeeType()
- if valobj_type.IsValid():
- actual_name = valobj_type.GetName()
- if actual_name == '__CFBinaryHeap':
- wrapper = CFBinaryHeapRef_SummaryProvider(valobj, class_data.sys_params)
- statistics.metric_hit('code_notrun',valobj)
- return wrapper
- wrapper = CFBinaryHeapUnknown_SummaryProvider(valobj, class_data.sys_params)
- statistics.metric_hit('unknown_class',valobj.GetName() + " seen as " + name_string)
- return wrapper;
-
-def CFBinaryHeap_SummaryProvider (valobj,dict):
- logger = lldb.formatters.Logger.Logger()
- provider = GetSummary_Impl(valobj);
- if provider != None:
- if isinstance(provider,lldb.runtime.objc.objc_runtime.SpecialSituation_Description):
- return provider.message()
- try:
- summary = provider.length();
- except:
- summary = None
- logger >> "summary got from provider: " + str(summary)
- # for some reason, one needs to clear some bits for the count
- # to be correct when using CF(Mutable)BagRef on x64
- # the bit mask was derived through experimentation
- # (if counts start looking weird, then most probably
- # the mask needs to be changed)
- if summary == None:
- summary = '<variable is not CFBinaryHeap>'
- elif isinstance(summary,basestring):
- pass
- else:
- if provider.sys_params.is_64_bit:
- summary = summary & ~0x1fff000000000000
- if summary == 1:
- return '@"1 item"'
- else:
- summary = '@"' + str(summary) + ' items"'
- return summary
- return 'Summary Unavailable'
-
-def __lldb_init_module(debugger,dict):
- debugger.HandleCommand("type summary add -F CFBinaryHeap.CFBinaryHeap_SummaryProvider CFBinaryHeapRef")
+ logger = lldb.formatters.Logger.Logger()
+ global statistics
+ class_data, wrapper = lldb.runtime.objc.objc_runtime.Utilities.prepare_class_detection(
+ valobj, statistics)
+ if wrapper:
+ return wrapper
+
+ name_string = class_data.class_name()
+ actual_name = class_data.class_name()
+
+ logger >> "name string got was " + \
+ str(name_string) + " but actual name is " + str(actual_name)
+
+ if class_data.is_cftype():
+ # CFBinaryHeap does not expose an actual NSWrapper type, so we have to check that this is
+ # an NSCFType and then check we are a pointer-to CFBinaryHeap
+ valobj_type = valobj.GetType()
+ if valobj_type.IsValid() and valobj_type.IsPointerType():
+ valobj_type = valobj_type.GetPointeeType()
+ if valobj_type.IsValid():
+ actual_name = valobj_type.GetName()
+ if actual_name == '__CFBinaryHeap':
+ wrapper = CFBinaryHeapRef_SummaryProvider(
+ valobj, class_data.sys_params)
+ statistics.metric_hit('code_notrun', valobj)
+ return wrapper
+ wrapper = CFBinaryHeapUnknown_SummaryProvider(
+ valobj, class_data.sys_params)
+ statistics.metric_hit(
+ 'unknown_class',
+ valobj.GetName() +
+ " seen as " +
+ name_string)
+ return wrapper
+
+
+def CFBinaryHeap_SummaryProvider(valobj, dict):
+ logger = lldb.formatters.Logger.Logger()
+ provider = GetSummary_Impl(valobj)
+ if provider is not None:
+ if isinstance(
+ provider,
+ lldb.runtime.objc.objc_runtime.SpecialSituation_Description):
+ return provider.message()
+ try:
+ summary = provider.length()
+ except:
+ summary = None
+ logger >> "summary got from provider: " + str(summary)
+ # for some reason, one needs to clear some bits for the count
+ # to be correct when using CF(Mutable)BagRef on x64
+ # the bit mask was derived through experimentation
+ # (if counts start looking weird, then most probably
+ # the mask needs to be changed)
+ if summary is None:
+ summary = '<variable is not CFBinaryHeap>'
+ elif isinstance(summary, basestring):
+ pass
+ else:
+ if provider.sys_params.is_64_bit:
+ summary = summary & ~0x1fff000000000000
+ if summary == 1:
+ return '@"1 item"'
+ else:
+ summary = '@"' + str(summary) + ' items"'
+ return summary
+ return 'Summary Unavailable'
+
+
+def __lldb_init_module(debugger, dict):
+ debugger.HandleCommand(
+ "type summary add -F CFBinaryHeap.CFBinaryHeap_SummaryProvider CFBinaryHeapRef")
diff --git a/examples/summaries/cocoa/CFBitVector.py b/examples/summaries/cocoa/CFBitVector.py
index b0c9e7912106..e788e625b0d8 100644
--- a/examples/summaries/cocoa/CFBitVector.py
+++ b/examples/summaries/cocoa/CFBitVector.py
@@ -13,23 +13,28 @@ import lldb.formatters.metrics
import lldb.formatters.Logger
# first define some utility functions
+
+
def byte_index(abs_pos):
- logger = lldb.formatters.Logger.Logger()
- return abs_pos/8
+ logger = lldb.formatters.Logger.Logger()
+ return abs_pos / 8
+
def bit_index(abs_pos):
- logger = lldb.formatters.Logger.Logger()
- return abs_pos & 7
+ logger = lldb.formatters.Logger.Logger()
+ return abs_pos & 7
+
+
+def get_bit(byte, index):
+ logger = lldb.formatters.Logger.Logger()
+ if index < 0 or index > 7:
+ return None
+ return (byte >> (7 - index)) & 1
-def get_bit(byte,index):
- logger = lldb.formatters.Logger.Logger()
- if index < 0 or index > 7:
- return None
- return (byte >> (7-index)) & 1
-def grab_array_item_data(pointer,index):
- logger = lldb.formatters.Logger.Logger()
- return pointer.GetPointeeData(index,1)
+def grab_array_item_data(pointer, index):
+ logger = lldb.formatters.Logger.Logger()
+ return pointer.GetPointeeData(index, 1)
statistics = lldb.formatters.metrics.Metrics()
statistics.add_metric('invalid_isa')
@@ -40,136 +45,162 @@ statistics.add_metric('code_notrun')
# despite the similary to synthetic children providers, these classes are not
# trying to provide anything but a summary for a CF*BitVector, so they need not
# obey the interface specification for synthetic children providers
+
+
class CFBitVectorKnown_SummaryProvider:
- def adjust_for_architecture(self):
- logger = lldb.formatters.Logger.Logger()
- self.uiint_size = self.sys_params.types_cache.NSUInteger.GetByteSize()
- pass
-
- def __init__(self, valobj, params):
- logger = lldb.formatters.Logger.Logger()
- self.valobj = valobj;
- self.sys_params = params
- if not(self.sys_params.types_cache.NSUInteger):
- if self.sys_params.is_64_bit:
- self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong)
- else:
- self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt)
- if not(self.sys_params.types_cache.charptr):
- self.sys_params.types_cache.charptr = self.valobj.GetType().GetBasicType(lldb.eBasicTypeChar).GetPointerType()
- self.update();
-
- def update(self):
- logger = lldb.formatters.Logger.Logger()
- self.adjust_for_architecture();
-
- # we skip the CFRuntimeBase
- # then the next CFIndex is the count
- # then we skip another CFIndex and then we get at a byte array
- # that wraps the individual bits
-
- def contents(self):
- logger = lldb.formatters.Logger.Logger()
- count_vo = self.valobj.CreateChildAtOffset("count",self.sys_params.cfruntime_size,
- self.sys_params.types_cache.NSUInteger)
- count = count_vo.GetValueAsUnsigned(0)
- if count == 0:
- return '(empty)'
-
- array_vo = self.valobj.CreateChildAtOffset("data",
- self.sys_params.cfruntime_size+2*self.uiint_size,
- self.sys_params.types_cache.charptr)
-
- data_list = []
- cur_byte_pos = None
- for i in range(0,count):
- if cur_byte_pos == None:
- cur_byte_pos = byte_index(i)
- cur_byte = grab_array_item_data(array_vo,cur_byte_pos)
- cur_byte_val = cur_byte.uint8[0]
- else:
- byte_pos = byte_index(i)
- # do not fetch the pointee data every single time through
- if byte_pos != cur_byte_pos:
- cur_byte_pos = byte_pos
- cur_byte = grab_array_item_data(array_vo,cur_byte_pos)
- cur_byte_val = cur_byte.uint8[0]
- bit = get_bit(cur_byte_val,bit_index(i))
- if (i % 4) == 0:
- data_list.append(' ')
- if bit == 1:
- data_list.append('1')
- else:
- data_list.append('0')
- return ''.join(data_list)
+
+ def adjust_for_architecture(self):
+ logger = lldb.formatters.Logger.Logger()
+ self.uiint_size = self.sys_params.types_cache.NSUInteger.GetByteSize()
+ pass
+
+ def __init__(self, valobj, params):
+ logger = lldb.formatters.Logger.Logger()
+ self.valobj = valobj
+ self.sys_params = params
+ if not(self.sys_params.types_cache.NSUInteger):
+ if self.sys_params.is_64_bit:
+ self.sys_params.types_cache.NSUInteger = self.valobj.GetType(
+ ).GetBasicType(lldb.eBasicTypeUnsignedLong)
+ else:
+ self.sys_params.types_cache.NSUInteger = self.valobj.GetType(
+ ).GetBasicType(lldb.eBasicTypeUnsignedInt)
+ if not(self.sys_params.types_cache.charptr):
+ self.sys_params.types_cache.charptr = self.valobj.GetType(
+ ).GetBasicType(lldb.eBasicTypeChar).GetPointerType()
+ self.update()
+
+ def update(self):
+ logger = lldb.formatters.Logger.Logger()
+ self.adjust_for_architecture()
+
+ # we skip the CFRuntimeBase
+ # then the next CFIndex is the count
+ # then we skip another CFIndex and then we get at a byte array
+ # that wraps the individual bits
+
+ def contents(self):
+ logger = lldb.formatters.Logger.Logger()
+ count_vo = self.valobj.CreateChildAtOffset(
+ "count",
+ self.sys_params.cfruntime_size,
+ self.sys_params.types_cache.NSUInteger)
+ count = count_vo.GetValueAsUnsigned(0)
+ if count == 0:
+ return '(empty)'
+
+ array_vo = self.valobj.CreateChildAtOffset(
+ "data",
+ self.sys_params.cfruntime_size +
+ 2 *
+ self.uiint_size,
+ self.sys_params.types_cache.charptr)
+
+ data_list = []
+ cur_byte_pos = None
+ for i in range(0, count):
+ if cur_byte_pos is None:
+ cur_byte_pos = byte_index(i)
+ cur_byte = grab_array_item_data(array_vo, cur_byte_pos)
+ cur_byte_val = cur_byte.uint8[0]
+ else:
+ byte_pos = byte_index(i)
+ # do not fetch the pointee data every single time through
+ if byte_pos != cur_byte_pos:
+ cur_byte_pos = byte_pos
+ cur_byte = grab_array_item_data(array_vo, cur_byte_pos)
+ cur_byte_val = cur_byte.uint8[0]
+ bit = get_bit(cur_byte_val, bit_index(i))
+ if (i % 4) == 0:
+ data_list.append(' ')
+ if bit == 1:
+ data_list.append('1')
+ else:
+ data_list.append('0')
+ return ''.join(data_list)
class CFBitVectorUnknown_SummaryProvider:
- def adjust_for_architecture(self):
- pass
- def __init__(self, valobj, params):
- logger = lldb.formatters.Logger.Logger()
- self.valobj = valobj;
- self.sys_params = params
- self.update();
+ def adjust_for_architecture(self):
+ pass
+
+ def __init__(self, valobj, params):
+ logger = lldb.formatters.Logger.Logger()
+ self.valobj = valobj
+ self.sys_params = params
+ self.update()
- def update(self):
- logger = lldb.formatters.Logger.Logger()
- self.adjust_for_architecture();
+ def update(self):
+ logger = lldb.formatters.Logger.Logger()
+ self.adjust_for_architecture()
- def contents(self):
- logger = lldb.formatters.Logger.Logger()
- return '<unable to summarize this CFBitVector>'
+ def contents(self):
+ logger = lldb.formatters.Logger.Logger()
+ return '<unable to summarize this CFBitVector>'
def GetSummary_Impl(valobj):
- logger = lldb.formatters.Logger.Logger()
- global statistics
- class_data,wrapper =lldb.runtime.objc.objc_runtime.Utilities.prepare_class_detection(valobj,statistics)
- if wrapper:
- return wrapper
-
- name_string = class_data.class_name()
- actual_name = name_string
-
- logger >> "name string got was " + str(name_string) + " but actual name is " + str(actual_name)
-
- if class_data.is_cftype():
- # CFBitVectorRef does not expose an actual NSWrapper type, so we have to check that this is
- # an NSCFType and then check we are a pointer-to CFBitVectorRef
- valobj_type = valobj.GetType()
- if valobj_type.IsValid() and valobj_type.IsPointerType():
- valobj_type = valobj_type.GetPointeeType()
- if valobj_type.IsValid():
- actual_name = valobj_type.GetName()
- if actual_name == '__CFBitVector' or actual_name == '__CFMutableBitVector':
- wrapper = CFBitVectorKnown_SummaryProvider(valobj, class_data.sys_params)
- statistics.metric_hit('code_notrun',valobj)
- else:
- wrapper = CFBitVectorUnknown_SummaryProvider(valobj, class_data.sys_params)
- print actual_name
- else:
- wrapper = CFBitVectorUnknown_SummaryProvider(valobj, class_data.sys_params)
- print name_string
- statistics.metric_hit('unknown_class',valobj.GetName() + " seen as " + name_string)
- return wrapper;
-
-def CFBitVector_SummaryProvider (valobj,dict):
- logger = lldb.formatters.Logger.Logger()
- provider = GetSummary_Impl(valobj);
- if provider != None:
- if isinstance(provider,lldb.runtime.objc.objc_runtime.SpecialSituation_Description):
- return provider.message()
- try:
- summary = provider.contents();
- except:
- summary = None
- logger >> "summary got from provider: " + str(summary)
- if summary == None or summary == '':
- summary = '<variable is not CFBitVector>'
- return summary
- return 'Summary Unavailable'
-
-def __lldb_init_module(debugger,dict):
- debugger.HandleCommand("type summary add -F CFBitVector.CFBitVector_SummaryProvider CFBitVectorRef CFMutableBitVectorRef")
+ logger = lldb.formatters.Logger.Logger()
+ global statistics
+ class_data, wrapper = lldb.runtime.objc.objc_runtime.Utilities.prepare_class_detection(
+ valobj, statistics)
+ if wrapper:
+ return wrapper
+
+ name_string = class_data.class_name()
+ actual_name = name_string
+
+ logger >> "name string got was " + \
+ str(name_string) + " but actual name is " + str(actual_name)
+
+ if class_data.is_cftype():
+ # CFBitVectorRef does not expose an actual NSWrapper type, so we have to check that this is
+ # an NSCFType and then check we are a pointer-to CFBitVectorRef
+ valobj_type = valobj.GetType()
+ if valobj_type.IsValid() and valobj_type.IsPointerType():
+ valobj_type = valobj_type.GetPointeeType()
+ if valobj_type.IsValid():
+ actual_name = valobj_type.GetName()
+ if actual_name == '__CFBitVector' or actual_name == '__CFMutableBitVector':
+ wrapper = CFBitVectorKnown_SummaryProvider(
+ valobj, class_data.sys_params)
+ statistics.metric_hit('code_notrun', valobj)
+ else:
+ wrapper = CFBitVectorUnknown_SummaryProvider(
+ valobj, class_data.sys_params)
+ print actual_name
+ else:
+ wrapper = CFBitVectorUnknown_SummaryProvider(
+ valobj, class_data.sys_params)
+ print name_string
+ statistics.metric_hit(
+ 'unknown_class',
+ valobj.GetName() +
+ " seen as " +
+ name_string)
+ return wrapper
+
+
+def CFBitVector_SummaryProvider(valobj, dict):
+ logger = lldb.formatters.Logger.Logger()
+ provider = GetSummary_Impl(valobj)
+ if provider is not None:
+ if isinstance(
+ provider,
+ lldb.runtime.objc.objc_runtime.SpecialSituation_Description):
+ return provider.message()
+ try:
+ summary = provider.contents()
+ except:
+ summary = None
+ logger >> "summary got from provider: " + str(summary)
+ if summary is None or summary == '':
+ summary = '<variable is not CFBitVector>'
+ return summary
+ return 'Summary Unavailable'
+
+
+def __lldb_init_module(debugger, dict):
+ debugger.HandleCommand(
+ "type summary add -F CFBitVector.CFBitVector_SummaryProvider CFBitVectorRef CFMutableBitVectorRef")
diff --git a/examples/summaries/cocoa/CFDictionary.py b/examples/summaries/cocoa/CFDictionary.py
index 061f5c56f9d6..92d8048470c0 100644
--- a/examples/summaries/cocoa/CFDictionary.py
+++ b/examples/summaries/cocoa/CFDictionary.py
@@ -22,213 +22,242 @@ statistics.add_metric('code_notrun')
# despite the similary to synthetic children providers, these classes are not
# trying to provide anything but the count for an NSDictionary, so they need not
# obey the interface specification for synthetic children providers
+
+
class NSCFDictionary_SummaryProvider:
- def adjust_for_architecture(self):
- pass
-
- def __init__(self, valobj, params):
- logger = lldb.formatters.Logger.Logger()
- self.valobj = valobj;
- self.sys_params = params
- if not(self.sys_params.types_cache.NSUInteger):
- if self.sys_params.is_64_bit:
- self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong)
- else:
- self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt)
- self.update();
-
- def update(self):
- logger = lldb.formatters.Logger.Logger()
- self.adjust_for_architecture();
-
- # empirically determined on both 32 and 64bit desktop Mac OS X
- # probably boils down to 2 pointers and 4 bytes of data, but
- # the description of __CFDictionary is not readily available so most
- # of this is guesswork, plain and simple
- def offset(self):
- logger = lldb.formatters.Logger.Logger()
- if self.sys_params.is_64_bit:
- return 20
- else:
- return 12
-
- def num_children(self):
- logger = lldb.formatters.Logger.Logger()
- num_children_vo = self.valobj.CreateChildAtOffset("count",
- self.offset(),
- self.sys_params.types_cache.NSUInteger)
- return num_children_vo.GetValueAsUnsigned(0)
+
+ def adjust_for_architecture(self):
+ pass
+
+ def __init__(self, valobj, params):
+ logger = lldb.formatters.Logger.Logger()
+ self.valobj = valobj
+ self.sys_params = params
+ if not(self.sys_params.types_cache.NSUInteger):
+ if self.sys_params.is_64_bit:
+ self.sys_params.types_cache.NSUInteger = self.valobj.GetType(
+ ).GetBasicType(lldb.eBasicTypeUnsignedLong)
+ else:
+ self.sys_params.types_cache.NSUInteger = self.valobj.GetType(
+ ).GetBasicType(lldb.eBasicTypeUnsignedInt)
+ self.update()
+
+ def update(self):
+ logger = lldb.formatters.Logger.Logger()
+ self.adjust_for_architecture()
+
+ # empirically determined on both 32 and 64bit desktop Mac OS X
+ # probably boils down to 2 pointers and 4 bytes of data, but
+ # the description of __CFDictionary is not readily available so most
+ # of this is guesswork, plain and simple
+ def offset(self):
+ logger = lldb.formatters.Logger.Logger()
+ if self.sys_params.is_64_bit:
+ return 20
+ else:
+ return 12
+
+ def num_children(self):
+ logger = lldb.formatters.Logger.Logger()
+ num_children_vo = self.valobj.CreateChildAtOffset(
+ "count", self.offset(), self.sys_params.types_cache.NSUInteger)
+ return num_children_vo.GetValueAsUnsigned(0)
class NSDictionaryI_SummaryProvider:
- def adjust_for_architecture(self):
- pass
-
- def __init__(self, valobj, params):
- logger = lldb.formatters.Logger.Logger()
- self.valobj = valobj;
- self.sys_params = params
- if not(self.sys_params.types_cache.NSUInteger):
- if self.sys_params.is_64_bit:
- self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong)
- else:
- self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt)
- self.update();
-
- def update(self):
- logger = lldb.formatters.Logger.Logger()
- self.adjust_for_architecture();
-
- # we just need to skip the ISA and the count immediately follows
- def offset(self):
- logger = lldb.formatters.Logger.Logger()
- return self.sys_params.pointer_size
-
- def num_children(self):
- logger = lldb.formatters.Logger.Logger()
- num_children_vo = self.valobj.CreateChildAtOffset("count",
- self.offset(),
- self.sys_params.types_cache.NSUInteger)
- value = num_children_vo.GetValueAsUnsigned(0)
- if value != None:
- # the MS6bits on immutable dictionaries seem to be taken by the LSB of capacity
- # not sure if it is a bug or some weird sort of feature, but masking that out
- # gets the count right
- if self.sys_params.is_64_bit:
- value = value & ~0xFC00000000000000
- else:
- value = value & ~0xFC000000
- return value
+
+ def adjust_for_architecture(self):
+ pass
+
+ def __init__(self, valobj, params):
+ logger = lldb.formatters.Logger.Logger()
+ self.valobj = valobj
+ self.sys_params = params
+ if not(self.sys_params.types_cache.NSUInteger):
+ if self.sys_params.is_64_bit:
+ self.sys_params.types_cache.NSUInteger = self.valobj.GetType(
+ ).GetBasicType(lldb.eBasicTypeUnsignedLong)
+ else:
+ self.sys_params.types_cache.NSUInteger = self.valobj.GetType(
+ ).GetBasicType(lldb.eBasicTypeUnsignedInt)
+ self.update()
+
+ def update(self):
+ logger = lldb.formatters.Logger.Logger()
+ self.adjust_for_architecture()
+
+ # we just need to skip the ISA and the count immediately follows
+ def offset(self):
+ logger = lldb.formatters.Logger.Logger()
+ return self.sys_params.pointer_size
+
+ def num_children(self):
+ logger = lldb.formatters.Logger.Logger()
+ num_children_vo = self.valobj.CreateChildAtOffset(
+ "count", self.offset(), self.sys_params.types_cache.NSUInteger)
+ value = num_children_vo.GetValueAsUnsigned(0)
+ if value is not None:
+ # the MS6bits on immutable dictionaries seem to be taken by the LSB of capacity
+ # not sure if it is a bug or some weird sort of feature, but masking that out
+ # gets the count right
+ if self.sys_params.is_64_bit:
+ value = value & ~0xFC00000000000000
+ else:
+ value = value & ~0xFC000000
+ return value
+
class NSDictionaryM_SummaryProvider:
- def adjust_for_architecture(self):
- pass
-
- def __init__(self, valobj, params):
- logger = lldb.formatters.Logger.Logger()
- self.valobj = valobj;
- self.sys_params = params
- if not(self.sys_params.types_cache.NSUInteger):
- if self.sys_params.is_64_bit:
- self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong)
- else:
- self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt)
- self.update();
-
- def update(self):
- logger = lldb.formatters.Logger.Logger()
- self.adjust_for_architecture();
-
- # we just need to skip the ISA and the count immediately follows
- def offset(self):
- return self.sys_params.pointer_size
-
- def num_children(self):
- logger = lldb.formatters.Logger.Logger()
- num_children_vo = self.valobj.CreateChildAtOffset("count",
- self.offset(),
- self.sys_params.types_cache.NSUInteger)
- value = num_children_vo.GetValueAsUnsigned(0)
- if value != None:
- # the MS6bits on immutable dictionaries seem to be taken by the LSB of capacity
- # not sure if it is a bug or some weird sort of feature, but masking that out
- # gets the count right
- if self.sys_params.is_64_bit:
- value = value & ~0xFC00000000000000
- else:
- value = value & ~0xFC000000
- return value
+
+ def adjust_for_architecture(self):
+ pass
+
+ def __init__(self, valobj, params):
+ logger = lldb.formatters.Logger.Logger()
+ self.valobj = valobj
+ self.sys_params = params
+ if not(self.sys_params.types_cache.NSUInteger):
+ if self.sys_params.is_64_bit:
+ self.sys_params.types_cache.NSUInteger = self.valobj.GetType(
+ ).GetBasicType(lldb.eBasicTypeUnsignedLong)
+ else:
+ self.sys_params.types_cache.NSUInteger = self.valobj.GetType(
+ ).GetBasicType(lldb.eBasicTypeUnsignedInt)
+ self.update()
+
+ def update(self):
+ logger = lldb.formatters.Logger.Logger()
+ self.adjust_for_architecture()
+
+ # we just need to skip the ISA and the count immediately follows
+ def offset(self):
+ return self.sys_params.pointer_size
+
+ def num_children(self):
+ logger = lldb.formatters.Logger.Logger()
+ num_children_vo = self.valobj.CreateChildAtOffset(
+ "count", self.offset(), self.sys_params.types_cache.NSUInteger)
+ value = num_children_vo.GetValueAsUnsigned(0)
+ if value is not None:
+ # the MS6bits on immutable dictionaries seem to be taken by the LSB of capacity
+ # not sure if it is a bug or some weird sort of feature, but masking that out
+ # gets the count right
+ if self.sys_params.is_64_bit:
+ value = value & ~0xFC00000000000000
+ else:
+ value = value & ~0xFC000000
+ return value
+
class NSDictionaryUnknown_SummaryProvider:
- def adjust_for_architecture(self):
- pass
- def __init__(self, valobj, params):
- logger = lldb.formatters.Logger.Logger()
- self.valobj = valobj;
- self.sys_params = params
- self.update();
+ def adjust_for_architecture(self):
+ pass
- def update(self):
- logger = lldb.formatters.Logger.Logger()
- self.adjust_for_architecture();
+ def __init__(self, valobj, params):
+ logger = lldb.formatters.Logger.Logger()
+ self.valobj = valobj
+ self.sys_params = params
+ self.update()
- def num_children(self):
- logger = lldb.formatters.Logger.Logger()
- stream = lldb.SBStream()
- self.valobj.GetExpressionPath(stream)
- num_children_vo = self.valobj.CreateValueFromExpression("count","(int)[" + stream.GetData() + " count]");
- if num_children_vo.IsValid():
- return num_children_vo.GetValueAsUnsigned(0)
- return '<variable is not NSDictionary>'
+ def update(self):
+ logger = lldb.formatters.Logger.Logger()
+ self.adjust_for_architecture()
+
+ def num_children(self):
+ logger = lldb.formatters.Logger.Logger()
+ stream = lldb.SBStream()
+ self.valobj.GetExpressionPath(stream)
+ num_children_vo = self.valobj.CreateValueFromExpression(
+ "count", "(int)[" + stream.GetData() + " count]")
+ if num_children_vo.IsValid():
+ return num_children_vo.GetValueAsUnsigned(0)
+ return '<variable is not NSDictionary>'
def GetSummary_Impl(valobj):
- logger = lldb.formatters.Logger.Logger()
- global statistics
- class_data,wrapper =lldb.runtime.objc.objc_runtime.Utilities.prepare_class_detection(valobj,statistics)
- if wrapper:
- return wrapper
-
- name_string = class_data.class_name()
-
- logger >> "class name is: " + str(name_string)
-
- if name_string == '__NSCFDictionary':
- wrapper = NSCFDictionary_SummaryProvider(valobj, class_data.sys_params)
- statistics.metric_hit('code_notrun',valobj)
- elif name_string == '__NSDictionaryI':
- wrapper = NSDictionaryI_SummaryProvider(valobj, class_data.sys_params)
- statistics.metric_hit('code_notrun',valobj)
- elif name_string == '__NSDictionaryM':
- wrapper = NSDictionaryM_SummaryProvider(valobj, class_data.sys_params)
- statistics.metric_hit('code_notrun',valobj)
- else:
- wrapper = NSDictionaryUnknown_SummaryProvider(valobj, class_data.sys_params)
- statistics.metric_hit('unknown_class',valobj.GetName() + " seen as " + name_string)
- return wrapper;
-
-def CFDictionary_SummaryProvider (valobj,dict):
- logger = lldb.formatters.Logger.Logger()
- provider = GetSummary_Impl(valobj);
- if provider != None:
- if isinstance(provider,lldb.runtime.objc.objc_runtime.SpecialSituation_Description):
- return provider.message()
- try:
- summary = provider.num_children();
- except:
- summary = None
- logger >> "got summary " + str(summary)
- if summary == None:
- return '<variable is not NSDictionary>'
- if isinstance(summary,basestring):
- return summary
- return str(summary) + (" key/value pairs" if summary != 1 else " key/value pair")
- return 'Summary Unavailable'
-
-def CFDictionary_SummaryProvider2 (valobj,dict):
- logger = lldb.formatters.Logger.Logger()
- provider = GetSummary_Impl(valobj);
- if provider != None:
- if isinstance(provider,lldb.runtime.objc.objc_runtime.SpecialSituation_Description):
- return provider.message()
- try:
- summary = provider.num_children();
- except:
- summary = None
- logger >> "got summary " + str(summary)
- if summary == None:
- summary = '<variable is not CFDictionary>'
- if isinstance(summary,basestring):
- return summary
- else:
- # needed on OSX Mountain Lion
- if provider.sys_params.is_64_bit:
- summary = summary & ~0x0f1f000000000000
- summary = '@"' + str(summary) + (' entries"' if summary != 1 else ' entry"')
- return summary
- return 'Summary Unavailable'
-
-def __lldb_init_module(debugger,dict):
- debugger.HandleCommand("type summary add -F CFDictionary.CFDictionary_SummaryProvider NSDictionary")
- debugger.HandleCommand("type summary add -F CFDictionary.CFDictionary_SummaryProvider2 CFDictionaryRef CFMutableDictionaryRef")
+ logger = lldb.formatters.Logger.Logger()
+ global statistics
+ class_data, wrapper = lldb.runtime.objc.objc_runtime.Utilities.prepare_class_detection(
+ valobj, statistics)
+ if wrapper:
+ return wrapper
+
+ name_string = class_data.class_name()
+
+ logger >> "class name is: " + str(name_string)
+
+ if name_string == '__NSCFDictionary':
+ wrapper = NSCFDictionary_SummaryProvider(valobj, class_data.sys_params)
+ statistics.metric_hit('code_notrun', valobj)
+ elif name_string == '__NSDictionaryI':
+ wrapper = NSDictionaryI_SummaryProvider(valobj, class_data.sys_params)
+ statistics.metric_hit('code_notrun', valobj)
+ elif name_string == '__NSDictionaryM':
+ wrapper = NSDictionaryM_SummaryProvider(valobj, class_data.sys_params)
+ statistics.metric_hit('code_notrun', valobj)
+ else:
+ wrapper = NSDictionaryUnknown_SummaryProvider(
+ valobj, class_data.sys_params)
+ statistics.metric_hit(
+ 'unknown_class',
+ valobj.GetName() +
+ " seen as " +
+ name_string)
+ return wrapper
+
+
+def CFDictionary_SummaryProvider(valobj, dict):
+ logger = lldb.formatters.Logger.Logger()
+ provider = GetSummary_Impl(valobj)
+ if provider is not None:
+ if isinstance(
+ provider,
+ lldb.runtime.objc.objc_runtime.SpecialSituation_Description):
+ return provider.message()
+ try:
+ summary = provider.num_children()
+ except:
+ summary = None
+ logger >> "got summary " + str(summary)
+ if summary is None:
+ return '<variable is not NSDictionary>'
+ if isinstance(summary, basestring):
+ return summary
+ return str(summary) + (" key/value pairs" if summary !=
+ 1 else " key/value pair")
+ return 'Summary Unavailable'
+
+
+def CFDictionary_SummaryProvider2(valobj, dict):
+ logger = lldb.formatters.Logger.Logger()
+ provider = GetSummary_Impl(valobj)
+ if provider is not None:
+ if isinstance(
+ provider,
+ lldb.runtime.objc.objc_runtime.SpecialSituation_Description):
+ return provider.message()
+ try:
+ summary = provider.num_children()
+ except:
+ summary = None
+ logger >> "got summary " + str(summary)
+ if summary is None:
+ summary = '<variable is not CFDictionary>'
+ if isinstance(summary, basestring):
+ return summary
+ else:
+ # needed on OSX Mountain Lion
+ if provider.sys_params.is_64_bit:
+ summary = summary & ~0x0f1f000000000000
+ summary = '@"' + str(summary) + \
+ (' entries"' if summary != 1 else ' entry"')
+ return summary
+ return 'Summary Unavailable'
+
+
+def __lldb_init_module(debugger, dict):
+ debugger.HandleCommand(
+ "type summary add -F CFDictionary.CFDictionary_SummaryProvider NSDictionary")
+ debugger.HandleCommand(
+ "type summary add -F CFDictionary.CFDictionary_SummaryProvider2 CFDictionaryRef CFMutableDictionaryRef")
diff --git a/examples/summaries/cocoa/CFString.py b/examples/summaries/cocoa/CFString.py
index 570fd8280e0c..109d918a9de2 100644
--- a/examples/summaries/cocoa/CFString.py
+++ b/examples/summaries/cocoa/CFString.py
@@ -11,315 +11,341 @@ import lldb
import lldb.runtime.objc.objc_runtime
import lldb.formatters.Logger
-def CFString_SummaryProvider (valobj,dict):
- logger = lldb.formatters.Logger.Logger()
- provider = CFStringSynthProvider(valobj,dict);
- if provider.invalid == False:
- try:
- summary = provider.get_child_at_index(provider.get_child_index("content"))
- if type(summary) == lldb.SBValue:
- summary = summary.GetSummary()
- else:
- summary = '"' + summary + '"'
- except:
- summary = None
- if summary == None:
- summary = '<variable is not NSString>'
- return '@'+summary
- return ''
-
-def CFAttributedString_SummaryProvider (valobj,dict):
- logger = lldb.formatters.Logger.Logger()
- offset = valobj.GetTarget().GetProcess().GetAddressByteSize()
- pointee = valobj.GetValueAsUnsigned(0)
- summary = '<variable is not NSAttributedString>'
- if pointee != None and pointee != 0:
- pointee = pointee + offset
- child_ptr = valobj.CreateValueFromAddress("string_ptr",pointee,valobj.GetType())
- child = child_ptr.CreateValueFromAddress("string_data",child_ptr.GetValueAsUnsigned(),valobj.GetType()).AddressOf()
- provider = CFStringSynthProvider(child,dict);
- if provider.invalid == False:
- try:
- summary = provider.get_child_at_index(provider.get_child_index("content")).GetSummary();
- except:
- summary = '<variable is not NSAttributedString>'
- if summary == None:
- summary = '<variable is not NSAttributedString>'
- return '@'+summary
-
-
-def __lldb_init_module(debugger,dict):
- debugger.HandleCommand("type summary add -F CFString.CFString_SummaryProvider NSString CFStringRef CFMutableStringRef")
- debugger.HandleCommand("type summary add -F CFString.CFAttributedString_SummaryProvider NSAttributedString")
+
+def CFString_SummaryProvider(valobj, dict):
+ logger = lldb.formatters.Logger.Logger()
+ provider = CFStringSynthProvider(valobj, dict)
+ if not provider.invalid:
+ try:
+ summary = provider.get_child_at_index(
+ provider.get_child_index("content"))
+ if isinstance(summary, lldb.SBValue):
+ summary = summary.GetSummary()
+ else:
+ summary = '"' + summary + '"'
+ except:
+ summary = None
+ if summary is None:
+ summary = '<variable is not NSString>'
+ return '@' + summary
+ return ''
+
+
+def CFAttributedString_SummaryProvider(valobj, dict):
+ logger = lldb.formatters.Logger.Logger()
+ offset = valobj.GetTarget().GetProcess().GetAddressByteSize()
+ pointee = valobj.GetValueAsUnsigned(0)
+ summary = '<variable is not NSAttributedString>'
+ if pointee is not None and pointee != 0:
+ pointee = pointee + offset
+ child_ptr = valobj.CreateValueFromAddress(
+ "string_ptr", pointee, valobj.GetType())
+ child = child_ptr.CreateValueFromAddress(
+ "string_data",
+ child_ptr.GetValueAsUnsigned(),
+ valobj.GetType()).AddressOf()
+ provider = CFStringSynthProvider(child, dict)
+ if not provider.invalid:
+ try:
+ summary = provider.get_child_at_index(
+ provider.get_child_index("content")).GetSummary()
+ except:
+ summary = '<variable is not NSAttributedString>'
+ if summary is None:
+ summary = '<variable is not NSAttributedString>'
+ return '@' + summary
+
+
+def __lldb_init_module(debugger, dict):
+ debugger.HandleCommand(
+ "type summary add -F CFString.CFString_SummaryProvider NSString CFStringRef CFMutableStringRef")
+ debugger.HandleCommand(
+ "type summary add -F CFString.CFAttributedString_SummaryProvider NSAttributedString")
+
class CFStringSynthProvider:
- def __init__(self,valobj,dict):
- logger = lldb.formatters.Logger.Logger()
- self.valobj = valobj;
- self.update()
-
- # children other than "content" are for debugging only and must not be used in production code
- def num_children(self):
- logger = lldb.formatters.Logger.Logger()
- if self.invalid:
- return 0;
- return 6;
-
- def read_unicode(self, pointer,max_len=2048):
- logger = lldb.formatters.Logger.Logger()
- process = self.valobj.GetTarget().GetProcess()
- error = lldb.SBError()
- pystr = u''
- # cannot do the read at once because the length value has
- # a weird encoding. better play it safe here
- while max_len > 0:
- content = process.ReadMemory(pointer, 2, error)
- new_bytes = bytearray(content)
- b0 = new_bytes[0]
- b1 = new_bytes[1]
- pointer = pointer + 2
- if b0 == 0 and b1 == 0:
- break
- # rearrange bytes depending on endianness
- # (do we really need this or is Cocoa going to
- # use Windows-compatible little-endian even
- # if the target is big endian?)
- if self.is_little:
- value = b1 * 256 + b0
- else:
- value = b0 * 256 + b1
- pystr = pystr + unichr(value)
- # read max_len unicode values, not max_len bytes
- max_len = max_len - 1
- return pystr
-
- # handle the special case strings
- # only use the custom code for the tested LP64 case
- def handle_special(self):
- logger = lldb.formatters.Logger.Logger()
- if self.is_64_bit == False:
- # for 32bit targets, use safe ObjC code
- return self.handle_unicode_string_safe()
- offset = 12
- pointer = self.valobj.GetValueAsUnsigned(0) + offset
- pystr = self.read_unicode(pointer)
- return self.valobj.CreateValueFromExpression("content",
- "(char*)\"" + pystr.encode('utf-8') + "\"")
-
- # last resort call, use ObjC code to read; the final aim is to
- # be able to strip this call away entirely and only do the read
- # ourselves
- def handle_unicode_string_safe(self):
- return self.valobj.CreateValueFromExpression("content",
- "(char*)\"" + self.valobj.GetObjectDescription() + "\"");
-
- def handle_unicode_string(self):
- logger = lldb.formatters.Logger.Logger()
- # step 1: find offset
- if self.inline:
- pointer = self.valobj.GetValueAsUnsigned(0) + self.size_of_cfruntime_base();
- if self.explicit == False:
- # untested, use the safe code path
- return self.handle_unicode_string_safe();
- else:
- # a full pointer is skipped here before getting to the live data
- pointer = pointer + self.pointer_size
- else:
- pointer = self.valobj.GetValueAsUnsigned(0) + self.size_of_cfruntime_base()
- # read 8 bytes here and make an address out of them
- try:
- char_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeChar).GetPointerType()
- vopointer = self.valobj.CreateValueFromAddress("dummy",pointer,char_type);
- pointer = vopointer.GetValueAsUnsigned(0)
- except:
- return self.valobj.CreateValueFromExpression("content",
- '(char*)"@\"invalid NSString\""')
- # step 2: read Unicode data at pointer
- pystr = self.read_unicode(pointer)
- # step 3: return it
- return pystr.encode('utf-8')
-
- def handle_inline_explicit(self):
- logger = lldb.formatters.Logger.Logger()
- offset = 3*self.pointer_size
- offset = offset + self.valobj.GetValueAsUnsigned(0)
- return self.valobj.CreateValueFromExpression("content",
- "(char*)(" + str(offset) + ")")
-
- def handle_mutable_string(self):
- logger = lldb.formatters.Logger.Logger()
- offset = 2 * self.pointer_size
- data = self.valobj.CreateChildAtOffset("content",
- offset, self.valobj.GetType().GetBasicType(lldb.eBasicTypeChar).GetPointerType());
- data_value = data.GetValueAsUnsigned(0)
- if self.explicit and self.unicode:
- return self.read_unicode(data_value).encode('utf-8')
- else:
- data_value = data_value + 1
- return self.valobj.CreateValueFromExpression("content", "(char*)(" + str(data_value) + ")")
-
- def handle_UTF8_inline(self):
- logger = lldb.formatters.Logger.Logger()
- offset = self.valobj.GetValueAsUnsigned(0) + self.size_of_cfruntime_base();
- if self.explicit == False:
- offset = offset + 1;
- return self.valobj.CreateValueFromAddress("content",
- offset, self.valobj.GetType().GetBasicType(lldb.eBasicTypeChar)).AddressOf();
-
- def handle_UTF8_not_inline(self):
- logger = lldb.formatters.Logger.Logger()
- offset = self.size_of_cfruntime_base();
- return self.valobj.CreateChildAtOffset("content",
- offset,self.valobj.GetType().GetBasicType(lldb.eBasicTypeChar).GetPointerType());
-
- def get_child_at_index(self,index):
- logger = lldb.formatters.Logger.Logger()
- logger >> "Querying for child [" + str(index) + "]"
- if index == 0:
- return self.valobj.CreateValueFromExpression("mutable",
- str(int(self.mutable)));
- if index == 1:
- return self.valobj.CreateValueFromExpression("inline",
- str(int(self.inline)));
- if index == 2:
- return self.valobj.CreateValueFromExpression("explicit",
- str(int(self.explicit)));
- if index == 3:
- return self.valobj.CreateValueFromExpression("unicode",
- str(int(self.unicode)));
- if index == 4:
- return self.valobj.CreateValueFromExpression("special",
- str(int(self.special)));
- if index == 5:
- # we are handling the several possible combinations of flags.
- # for each known combination we have a function that knows how to
- # go fetch the data from memory instead of running code. if a string is not
- # correctly displayed, one should start by finding a combination of flags that
- # makes it different from these known cases, and provide a new reader function
- # if this is not possible, a new flag might have to be made up (like the "special" flag
- # below, which is not a real flag in CFString), or alternatively one might need to use
- # the ObjC runtime helper to detect the new class and deal with it accordingly
- #print 'mutable = ' + str(self.mutable)
- #print 'inline = ' + str(self.inline)
- #print 'explicit = ' + str(self.explicit)
- #print 'unicode = ' + str(self.unicode)
- #print 'special = ' + str(self.special)
- if self.mutable == True:
- return self.handle_mutable_string()
- elif self.inline == True and self.explicit == True and \
- self.unicode == False and self.special == False and \
- self.mutable == False:
- return self.handle_inline_explicit()
- elif self.unicode == True:
- return self.handle_unicode_string();
- elif self.special == True:
- return self.handle_special();
- elif self.inline == True:
- return self.handle_UTF8_inline();
- else:
- return self.handle_UTF8_not_inline();
-
- def get_child_index(self,name):
- logger = lldb.formatters.Logger.Logger()
- logger >> "Querying for child ['" + str(name) + "']"
- if name == "content":
- return self.num_children() - 1;
- if name == "mutable":
- return 0;
- if name == "inline":
- return 1;
- if name == "explicit":
- return 2;
- if name == "unicode":
- return 3;
- if name == "special":
- return 4;
-
- # CFRuntimeBase is defined as having an additional
- # 4 bytes (padding?) on LP64 architectures
- # to get its size we add up sizeof(pointer)+4
- # and then add 4 more bytes if we are on a 64bit system
- def size_of_cfruntime_base(self):
- logger = lldb.formatters.Logger.Logger()
- return self.pointer_size+4+(4 if self.is_64_bit else 0)
-
- # the info bits are part of the CFRuntimeBase structure
- # to get at them we have to skip a uintptr_t and then get
- # at the least-significant byte of a 4 byte array. If we are
- # on big-endian this means going to byte 3, if we are on
- # little endian (OSX & iOS), this means reading byte 0
- def offset_of_info_bits(self):
- logger = lldb.formatters.Logger.Logger()
- offset = self.pointer_size
- if self.is_little == False:
- offset = offset + 3;
- return offset;
-
- def read_info_bits(self):
- logger = lldb.formatters.Logger.Logger()
- cfinfo = self.valobj.CreateChildAtOffset("cfinfo",
- self.offset_of_info_bits(),
- self.valobj.GetType().GetBasicType(lldb.eBasicTypeChar));
- cfinfo.SetFormat(11)
- info = cfinfo.GetValue();
- if info != None:
- self.invalid = False;
- return int(info,0);
- else:
- self.invalid = True;
- return None;
-
- # calculating internal flag bits of the CFString object
- # this stuff is defined and discussed in CFString.c
- def is_mutable(self):
- logger = lldb.formatters.Logger.Logger()
- return (self.info_bits & 1) == 1;
-
- def is_inline(self):
- logger = lldb.formatters.Logger.Logger()
- return (self.info_bits & 0x60) == 0;
-
- # this flag's name is ambiguous, it turns out
- # we must skip a length byte to get at the data
- # when this flag is False
- def has_explicit_length(self):
- logger = lldb.formatters.Logger.Logger()
- return (self.info_bits & (1 | 4)) != 4;
-
- # probably a subclass of NSString. obtained this from [str pathExtension]
- # here info_bits = 0 and Unicode data at the start of the padding word
- # in the long run using the isa value might be safer as a way to identify this
- # instead of reading the info_bits
- def is_special_case(self):
- logger = lldb.formatters.Logger.Logger()
- return self.info_bits == 0;
-
- def is_unicode(self):
- logger = lldb.formatters.Logger.Logger()
- return (self.info_bits & 0x10) == 0x10;
-
- # preparing ourselves to read into memory
- # by adjusting architecture-specific info
- def adjust_for_architecture(self):
- logger = lldb.formatters.Logger.Logger()
- self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize()
- self.is_64_bit = self.pointer_size == 8
- self.is_little = self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle
-
- # reading info bits out of the CFString and computing
- # useful values to get at the real data
- def compute_flags(self):
- logger = lldb.formatters.Logger.Logger()
- self.info_bits = self.read_info_bits();
- if self.info_bits == None:
- return;
- self.mutable = self.is_mutable();
- self.inline = self.is_inline();
- self.explicit = self.has_explicit_length();
- self.unicode = self.is_unicode();
- self.special = self.is_special_case();
-
- def update(self):
- logger = lldb.formatters.Logger.Logger()
- self.adjust_for_architecture();
- self.compute_flags();
+
+ def __init__(self, valobj, dict):
+ logger = lldb.formatters.Logger.Logger()
+ self.valobj = valobj
+ self.update()
+
+ # children other than "content" are for debugging only and must not be
+ # used in production code
+ def num_children(self):
+ logger = lldb.formatters.Logger.Logger()
+ if self.invalid:
+ return 0
+ return 6
+
+ def read_unicode(self, pointer, max_len=2048):
+ logger = lldb.formatters.Logger.Logger()
+ process = self.valobj.GetTarget().GetProcess()
+ error = lldb.SBError()
+ pystr = u''
+ # cannot do the read at once because the length value has
+ # a weird encoding. better play it safe here
+ while max_len > 0:
+ content = process.ReadMemory(pointer, 2, error)
+ new_bytes = bytearray(content)
+ b0 = new_bytes[0]
+ b1 = new_bytes[1]
+ pointer = pointer + 2
+ if b0 == 0 and b1 == 0:
+ break
+ # rearrange bytes depending on endianness
+ # (do we really need this or is Cocoa going to
+ # use Windows-compatible little-endian even
+ # if the target is big endian?)
+ if self.is_little:
+ value = b1 * 256 + b0
+ else:
+ value = b0 * 256 + b1
+ pystr = pystr + unichr(value)
+ # read max_len unicode values, not max_len bytes
+ max_len = max_len - 1
+ return pystr
+
+ # handle the special case strings
+ # only use the custom code for the tested LP64 case
+ def handle_special(self):
+ logger = lldb.formatters.Logger.Logger()
+ if not self.is_64_bit:
+ # for 32bit targets, use safe ObjC code
+ return self.handle_unicode_string_safe()
+ offset = 12
+ pointer = self.valobj.GetValueAsUnsigned(0) + offset
+ pystr = self.read_unicode(pointer)
+ return self.valobj.CreateValueFromExpression(
+ "content", "(char*)\"" + pystr.encode('utf-8') + "\"")
+
+ # last resort call, use ObjC code to read; the final aim is to
+ # be able to strip this call away entirely and only do the read
+ # ourselves
+ def handle_unicode_string_safe(self):
+ return self.valobj.CreateValueFromExpression(
+ "content", "(char*)\"" + self.valobj.GetObjectDescription() + "\"")
+
+ def handle_unicode_string(self):
+ logger = lldb.formatters.Logger.Logger()
+ # step 1: find offset
+ if self.inline:
+ pointer = self.valobj.GetValueAsUnsigned(
+ 0) + self.size_of_cfruntime_base()
+ if not self.explicit:
+ # untested, use the safe code path
+ return self.handle_unicode_string_safe()
+ else:
+ # a full pointer is skipped here before getting to the live
+ # data
+ pointer = pointer + self.pointer_size
+ else:
+ pointer = self.valobj.GetValueAsUnsigned(
+ 0) + self.size_of_cfruntime_base()
+ # read 8 bytes here and make an address out of them
+ try:
+ char_type = self.valobj.GetType().GetBasicType(
+ lldb.eBasicTypeChar).GetPointerType()
+ vopointer = self.valobj.CreateValueFromAddress(
+ "dummy", pointer, char_type)
+ pointer = vopointer.GetValueAsUnsigned(0)
+ except:
+ return self.valobj.CreateValueFromExpression(
+ "content", '(char*)"@\"invalid NSString\""')
+ # step 2: read Unicode data at pointer
+ pystr = self.read_unicode(pointer)
+ # step 3: return it
+ return pystr.encode('utf-8')
+
+ def handle_inline_explicit(self):
+ logger = lldb.formatters.Logger.Logger()
+ offset = 3 * self.pointer_size
+ offset = offset + self.valobj.GetValueAsUnsigned(0)
+ return self.valobj.CreateValueFromExpression(
+ "content", "(char*)(" + str(offset) + ")")
+
+ def handle_mutable_string(self):
+ logger = lldb.formatters.Logger.Logger()
+ offset = 2 * self.pointer_size
+ data = self.valobj.CreateChildAtOffset(
+ "content", offset, self.valobj.GetType().GetBasicType(
+ lldb.eBasicTypeChar).GetPointerType())
+ data_value = data.GetValueAsUnsigned(0)
+ if self.explicit and self.unicode:
+ return self.read_unicode(data_value).encode('utf-8')
+ else:
+ data_value = data_value + 1
+ return self.valobj.CreateValueFromExpression(
+ "content", "(char*)(" + str(data_value) + ")")
+
+ def handle_UTF8_inline(self):
+ logger = lldb.formatters.Logger.Logger()
+ offset = self.valobj.GetValueAsUnsigned(
+ 0) + self.size_of_cfruntime_base()
+ if not self.explicit:
+ offset = offset + 1
+ return self.valobj.CreateValueFromAddress(
+ "content", offset, self.valobj.GetType().GetBasicType(
+ lldb.eBasicTypeChar)).AddressOf()
+
+ def handle_UTF8_not_inline(self):
+ logger = lldb.formatters.Logger.Logger()
+ offset = self.size_of_cfruntime_base()
+ return self.valobj.CreateChildAtOffset(
+ "content", offset, self.valobj.GetType().GetBasicType(
+ lldb.eBasicTypeChar).GetPointerType())
+
+ def get_child_at_index(self, index):
+ logger = lldb.formatters.Logger.Logger()
+ logger >> "Querying for child [" + str(index) + "]"
+ if index == 0:
+ return self.valobj.CreateValueFromExpression(
+ "mutable", str(int(self.mutable)))
+ if index == 1:
+ return self.valobj.CreateValueFromExpression("inline",
+ str(int(self.inline)))
+ if index == 2:
+ return self.valobj.CreateValueFromExpression(
+ "explicit", str(int(self.explicit)))
+ if index == 3:
+ return self.valobj.CreateValueFromExpression(
+ "unicode", str(int(self.unicode)))
+ if index == 4:
+ return self.valobj.CreateValueFromExpression(
+ "special", str(int(self.special)))
+ if index == 5:
+ # we are handling the several possible combinations of flags.
+ # for each known combination we have a function that knows how to
+ # go fetch the data from memory instead of running code. if a string is not
+ # correctly displayed, one should start by finding a combination of flags that
+ # makes it different from these known cases, and provide a new reader function
+ # if this is not possible, a new flag might have to be made up (like the "special" flag
+ # below, which is not a real flag in CFString), or alternatively one might need to use
+ # the ObjC runtime helper to detect the new class and deal with it accordingly
+ # print 'mutable = ' + str(self.mutable)
+ # print 'inline = ' + str(self.inline)
+ # print 'explicit = ' + str(self.explicit)
+ # print 'unicode = ' + str(self.unicode)
+ # print 'special = ' + str(self.special)
+ if self.mutable:
+ return self.handle_mutable_string()
+ elif self.inline and self.explicit and \
+ self.unicode == False and self.special == False and \
+ self.mutable == False:
+ return self.handle_inline_explicit()
+ elif self.unicode:
+ return self.handle_unicode_string()
+ elif self.special:
+ return self.handle_special()
+ elif self.inline:
+ return self.handle_UTF8_inline()
+ else:
+ return self.handle_UTF8_not_inline()
+
+ def get_child_index(self, name):
+ logger = lldb.formatters.Logger.Logger()
+ logger >> "Querying for child ['" + str(name) + "']"
+ if name == "content":
+ return self.num_children() - 1
+ if name == "mutable":
+ return 0
+ if name == "inline":
+ return 1
+ if name == "explicit":
+ return 2
+ if name == "unicode":
+ return 3
+ if name == "special":
+ return 4
+
+ # CFRuntimeBase is defined as having an additional
+ # 4 bytes (padding?) on LP64 architectures
+ # to get its size we add up sizeof(pointer)+4
+ # and then add 4 more bytes if we are on a 64bit system
+ def size_of_cfruntime_base(self):
+ logger = lldb.formatters.Logger.Logger()
+ return self.pointer_size + 4 + (4 if self.is_64_bit else 0)
+
+ # the info bits are part of the CFRuntimeBase structure
+ # to get at them we have to skip a uintptr_t and then get
+ # at the least-significant byte of a 4 byte array. If we are
+ # on big-endian this means going to byte 3, if we are on
+ # little endian (OSX & iOS), this means reading byte 0
+ def offset_of_info_bits(self):
+ logger = lldb.formatters.Logger.Logger()
+ offset = self.pointer_size
+ if not self.is_little:
+ offset = offset + 3
+ return offset
+
+ def read_info_bits(self):
+ logger = lldb.formatters.Logger.Logger()
+ cfinfo = self.valobj.CreateChildAtOffset(
+ "cfinfo",
+ self.offset_of_info_bits(),
+ self.valobj.GetType().GetBasicType(
+ lldb.eBasicTypeChar))
+ cfinfo.SetFormat(11)
+ info = cfinfo.GetValue()
+ if info is not None:
+ self.invalid = False
+ return int(info, 0)
+ else:
+ self.invalid = True
+ return None
+
+ # calculating internal flag bits of the CFString object
+ # this stuff is defined and discussed in CFString.c
+ def is_mutable(self):
+ logger = lldb.formatters.Logger.Logger()
+ return (self.info_bits & 1) == 1
+
+ def is_inline(self):
+ logger = lldb.formatters.Logger.Logger()
+ return (self.info_bits & 0x60) == 0
+
+ # this flag's name is ambiguous, it turns out
+ # we must skip a length byte to get at the data
+ # when this flag is False
+ def has_explicit_length(self):
+ logger = lldb.formatters.Logger.Logger()
+ return (self.info_bits & (1 | 4)) != 4
+
+ # probably a subclass of NSString. obtained this from [str pathExtension]
+ # here info_bits = 0 and Unicode data at the start of the padding word
+ # in the long run using the isa value might be safer as a way to identify this
+ # instead of reading the info_bits
+ def is_special_case(self):
+ logger = lldb.formatters.Logger.Logger()
+ return self.info_bits == 0
+
+ def is_unicode(self):
+ logger = lldb.formatters.Logger.Logger()
+ return (self.info_bits & 0x10) == 0x10
+
+ # preparing ourselves to read into memory
+ # by adjusting architecture-specific info
+ def adjust_for_architecture(self):
+ logger = lldb.formatters.Logger.Logger()
+ self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize()
+ self.is_64_bit = self.pointer_size == 8
+ self.is_little = self.valobj.GetTarget().GetProcess(
+ ).GetByteOrder() == lldb.eByteOrderLittle
+
+ # reading info bits out of the CFString and computing
+ # useful values to get at the real data
+ def compute_flags(self):
+ logger = lldb.formatters.Logger.Logger()
+ self.info_bits = self.read_info_bits()
+ if self.info_bits is None:
+ return
+ self.mutable = self.is_mutable()
+ self.inline = self.is_inline()
+ self.explicit = self.has_explicit_length()
+ self.unicode = self.is_unicode()
+ self.special = self.is_special_case()
+
+ def update(self):
+ logger = lldb.formatters.Logger.Logger()
+ self.adjust_for_architecture()
+ self.compute_flags()
diff --git a/examples/summaries/cocoa/Class.py b/examples/summaries/cocoa/Class.py
index 9c9dda858ac1..1c97ed8965f5 100644
--- a/examples/summaries/cocoa/Class.py
+++ b/examples/summaries/cocoa/Class.py
@@ -9,13 +9,14 @@ import lldb
import lldb.runtime.objc.objc_runtime
import lldb.formatters.Logger
-def Class_Summary(valobj,dict):
- logger = lldb.formatters.Logger.Logger()
- runtime =lldb.runtime.objc.objc_runtime.ObjCRuntime.runtime_from_isa(valobj)
- if runtime == None or not runtime.is_valid():
- return '<error: unknown Class>'
- class_data = runtime.read_class_data()
- if class_data == None or not class_data.is_valid():
- return '<error: unknown Class>'
- return class_data.class_name()
+def Class_Summary(valobj, dict):
+ logger = lldb.formatters.Logger.Logger()
+ runtime = lldb.runtime.objc.objc_runtime.ObjCRuntime.runtime_from_isa(
+ valobj)
+ if runtime is None or not runtime.is_valid():
+ return '<error: unknown Class>'
+ class_data = runtime.read_class_data()
+ if class_data is None or not class_data.is_valid():
+ return '<error: unknown Class>'
+ return class_data.class_name()
diff --git a/examples/summaries/cocoa/Logger.py b/examples/summaries/cocoa/Logger.py
index 91d503c31210..e518b75b20ce 100644
--- a/examples/summaries/cocoa/Logger.py
+++ b/examples/summaries/cocoa/Logger.py
@@ -3,120 +3,131 @@ import sys
import os.path
import inspect
+
class NopLogger:
- def __init__(self):
- pass
- def write(self,data):
- pass
+ def __init__(self):
+ pass
+
+ def write(self, data):
+ pass
- def flush(self):
- pass
+ def flush(self):
+ pass
- def close(self):
- pass
+ def close(self):
+ pass
class StdoutLogger:
- def __init__(self):
- pass
- def write(self,data):
- print(data)
+ def __init__(self):
+ pass
+
+ def write(self, data):
+ print(data)
+
+ def flush(self):
+ pass
- def flush(self):
- pass
+ def close(self):
+ pass
- def close(self):
- pass
class FileLogger:
- def __init__(self, name):
- self.file = None
- try:
- name = os.path.abspath(name)
- self.file = open(name,'a')
- except:
- try:
- self.file = open('formatters.log','a')
- except:
- pass
-
- def write(self,data):
- if self.file != None:
- print(data,file=self.file)
- else:
- print(data)
-
- def flush(self):
- if self.file != None:
- self.file.flush()
-
- def close(self):
- if self.file != None:
- self.file.close()
- self.file = None
+
+ def __init__(self, name):
+ self.file = None
+ try:
+ name = os.path.abspath(name)
+ self.file = open(name, 'a')
+ except:
+ try:
+ self.file = open('formatters.log', 'a')
+ except:
+ pass
+
+ def write(self, data):
+ if self.file is not None:
+ print(data, file=self.file)
+ else:
+ print(data)
+
+ def flush(self):
+ if self.file is not None:
+ self.file.flush()
+
+ def close(self):
+ if self.file is not None:
+ self.file.close()
+ self.file = None
# to enable logging:
# define lldb.formatters.Logger._lldb_formatters_debug_level to any number greater than 0
# if you define it to any value greater than 1, the log will be automatically flushed after each write (slower but should make sure most of the stuff makes it to the log even if we crash)
# if you define it to any value greater than 2, the calling function's details will automatically be logged (even slower, but provides additional details)
-# if you need the log to go to a file instead of on screen, define lldb.formatters.Logger._lldb_formatters_debug_filename to a valid filename
+# if you need the log to go to a file instead of on screen, define
+# lldb.formatters.Logger._lldb_formatters_debug_filename to a valid
+# filename
+
+
class Logger:
- def __init__(self,autoflush=False,logcaller=False):
- global _lldb_formatters_debug_level
- global _lldb_formatters_debug_filename
- self.autoflush = autoflush
- want_log = False
- try:
- want_log = (_lldb_formatters_debug_level > 0)
- except:
- pass
- if not (want_log):
- self.impl = NopLogger()
- return
- want_file = False
- try:
- want_file = (_lldb_formatters_debug_filename != None and _lldb_formatters_debug_filename != '' and _lldb_formatters_debug_filename != 0)
- except:
- pass
- if want_file:
- self.impl = FileLogger(_lldb_formatters_debug_filename)
- else:
- self.impl = StdoutLogger()
- try:
- self.autoflush = (_lldb_formatters_debug_level > 1)
- except:
- self.autoflush = autoflush
- want_caller_info = False
- try:
- want_caller_info = (_lldb_formatters_debug_level > 2)
- except:
- pass
- if want_caller_info:
- self._log_caller()
-
- def _log_caller(self):
- caller = inspect.stack()[2]
- try:
- if caller != None and len(caller) > 3:
- self.write('Logging from function ' + str(caller))
- else:
- self.write('Caller info not available - Required caller logging not possible')
- finally:
- del caller # needed per Python docs to avoid keeping objects alive longer than we care
-
- def write(self,data):
- self.impl.write(data)
- if self.autoflush:
- self.flush()
-
- def __rshift__(self,data):
- self.write(data)
-
- def flush(self):
- self.impl.flush()
-
- def close(self):
- self.impl.close()
+ def __init__(self, autoflush=False, logcaller=False):
+ global _lldb_formatters_debug_level
+ global _lldb_formatters_debug_filename
+ self.autoflush = autoflush
+ want_log = False
+ try:
+ want_log = (_lldb_formatters_debug_level > 0)
+ except:
+ pass
+ if not (want_log):
+ self.impl = NopLogger()
+ return
+ want_file = False
+ try:
+ want_file = (_lldb_formatters_debug_filename is not None and _lldb_formatters_debug_filename !=
+ '' and _lldb_formatters_debug_filename != 0)
+ except:
+ pass
+ if want_file:
+ self.impl = FileLogger(_lldb_formatters_debug_filename)
+ else:
+ self.impl = StdoutLogger()
+ try:
+ self.autoflush = (_lldb_formatters_debug_level > 1)
+ except:
+ self.autoflush = autoflush
+ want_caller_info = False
+ try:
+ want_caller_info = (_lldb_formatters_debug_level > 2)
+ except:
+ pass
+ if want_caller_info:
+ self._log_caller()
+
+ def _log_caller(self):
+ caller = inspect.stack()[2]
+ try:
+ if caller is not None and len(caller) > 3:
+ self.write('Logging from function ' + str(caller))
+ else:
+ self.write(
+ 'Caller info not available - Required caller logging not possible')
+ finally:
+ del caller # needed per Python docs to avoid keeping objects alive longer than we care
+
+ def write(self, data):
+ self.impl.write(data)
+ if self.autoflush:
+ self.flush()
+
+ def __rshift__(self, data):
+ self.write(data)
+
+ def flush(self):
+ self.impl.flush()
+
+ def close(self):
+ self.impl.close()
diff --git a/examples/summaries/cocoa/NSBundle.py b/examples/summaries/cocoa/NSBundle.py
index 5fd83f8e89f1..298150e6cc0a 100644
--- a/examples/summaries/cocoa/NSBundle.py
+++ b/examples/summaries/cocoa/NSBundle.py
@@ -23,105 +23,123 @@ statistics.add_metric('code_notrun')
# despite the similary to synthetic children providers, these classes are not
# trying to provide anything but a summary for an NSURL, so they need not
# obey the interface specification for synthetic children providers
+
+
class NSBundleKnown_SummaryProvider:
- def adjust_for_architecture(self):
- pass
-
- def __init__(self, valobj, params):
- logger = lldb.formatters.Logger.Logger()
- self.valobj = valobj;
- self.sys_params = params
- if not(self.sys_params.types_cache.NSString):
- self.sys_params.types_cache.NSString = self.valobj.GetTarget().FindFirstType('NSString').GetPointerType()
- self.update();
-
- def update(self):
- logger = lldb.formatters.Logger.Logger()
- self.adjust_for_architecture();
-
- # we need to skip the ISA, plus four other values
- # that are luckily each a pointer in size
- # which makes our computation trivial :-)
- def offset(self):
- logger = lldb.formatters.Logger.Logger()
- return 5 * self.sys_params.pointer_size
-
- def url_text(self):
- logger = lldb.formatters.Logger.Logger()
- global statistics
- text = self.valobj.CreateChildAtOffset("text",
- self.offset(),
- self.sys_params.types_cache.NSString)
- my_string = text.GetSummary()
- if (my_string == None) or (my_string == ''):
- statistics.metric_hit('unknown_class',str(self.valobj.GetName()) + " triggered unknown pointer location")
- return NSBundleUnknown_SummaryProvider(self.valobj, self.sys_params).url_text()
- else:
- statistics.metric_hit('code_notrun',self.valobj)
- return my_string
+
+ def adjust_for_architecture(self):
+ pass
+
+ def __init__(self, valobj, params):
+ logger = lldb.formatters.Logger.Logger()
+ self.valobj = valobj
+ self.sys_params = params
+ if not(self.sys_params.types_cache.NSString):
+ self.sys_params.types_cache.NSString = self.valobj.GetTarget(
+ ).FindFirstType('NSString').GetPointerType()
+ self.update()
+
+ def update(self):
+ logger = lldb.formatters.Logger.Logger()
+ self.adjust_for_architecture()
+
+ # we need to skip the ISA, plus four other values
+ # that are luckily each a pointer in size
+ # which makes our computation trivial :-)
+ def offset(self):
+ logger = lldb.formatters.Logger.Logger()
+ return 5 * self.sys_params.pointer_size
+
+ def url_text(self):
+ logger = lldb.formatters.Logger.Logger()
+ global statistics
+ text = self.valobj.CreateChildAtOffset(
+ "text", self.offset(), self.sys_params.types_cache.NSString)
+ my_string = text.GetSummary()
+ if (my_string is None) or (my_string == ''):
+ statistics.metric_hit(
+ 'unknown_class', str(
+ self.valobj.GetName()) + " triggered unknown pointer location")
+ return NSBundleUnknown_SummaryProvider(
+ self.valobj, self.sys_params).url_text()
+ else:
+ statistics.metric_hit('code_notrun', self.valobj)
+ return my_string
class NSBundleUnknown_SummaryProvider:
- def adjust_for_architecture(self):
- pass
-
- def __init__(self, valobj, params):
- logger = lldb.formatters.Logger.Logger()
- self.valobj = valobj;
- self.sys_params = params
- self.update()
-
- def update(self):
- logger = lldb.formatters.Logger.Logger()
- self.adjust_for_architecture();
-
- def url_text(self):
- logger = lldb.formatters.Logger.Logger()
- stream = lldb.SBStream()
- self.valobj.GetExpressionPath(stream)
- expr = "(NSString*)[" + stream.GetData() + " bundlePath]"
- url_text_vo = self.valobj.CreateValueFromExpression("path",expr);
- if url_text_vo.IsValid():
- return url_text_vo.GetSummary()
- return '<variable is not NSBundle>'
+
+ def adjust_for_architecture(self):
+ pass
+
+ def __init__(self, valobj, params):
+ logger = lldb.formatters.Logger.Logger()
+ self.valobj = valobj
+ self.sys_params = params
+ self.update()
+
+ def update(self):
+ logger = lldb.formatters.Logger.Logger()
+ self.adjust_for_architecture()
+
+ def url_text(self):
+ logger = lldb.formatters.Logger.Logger()
+ stream = lldb.SBStream()
+ self.valobj.GetExpressionPath(stream)
+ expr = "(NSString*)[" + stream.GetData() + " bundlePath]"
+ url_text_vo = self.valobj.CreateValueFromExpression("path", expr)
+ if url_text_vo.IsValid():
+ return url_text_vo.GetSummary()
+ return '<variable is not NSBundle>'
def GetSummary_Impl(valobj):
- logger = lldb.formatters.Logger.Logger()
- global statistics
- class_data,wrapper =lldb.runtime.objc.objc_runtime.Utilities.prepare_class_detection(valobj,statistics)
- if wrapper:
- return wrapper
-
- name_string = class_data.class_name()
- logger >> "class name is: " + str(name_string)
-
- if name_string == 'NSBundle':
- wrapper = NSBundleKnown_SummaryProvider(valobj, class_data.sys_params)
- # [NSBundle mainBundle] does return an object that is
- # not correctly filled out for our purposes, so we still
- # end up having to run code in that case
- #statistics.metric_hit('code_notrun',valobj)
- else:
- wrapper = NSBundleUnknown_SummaryProvider(valobj, class_data.sys_params)
- statistics.metric_hit('unknown_class',valobj.GetName() + " seen as " + name_string)
- return wrapper;
-
-def NSBundle_SummaryProvider (valobj,dict):
- logger = lldb.formatters.Logger.Logger()
- provider = GetSummary_Impl(valobj);
- if provider != None:
- if isinstance(provider,lldb.runtime.objc.objc_runtime.SpecialSituation_Description):
- return provider.message()
- try:
- summary = provider.url_text();
- except:
- summary = None
- logger >> "got summary " + str(summary)
- if summary == None or summary == '':
- summary = '<variable is not NSBundle>'
- return summary
- return 'Summary Unavailable'
-
-def __lldb_init_module(debugger,dict):
- debugger.HandleCommand("type summary add -F NSBundle.NSBundle_SummaryProvider NSBundle")
+ logger = lldb.formatters.Logger.Logger()
+ global statistics
+ class_data, wrapper = lldb.runtime.objc.objc_runtime.Utilities.prepare_class_detection(
+ valobj, statistics)
+ if wrapper:
+ return wrapper
+
+ name_string = class_data.class_name()
+ logger >> "class name is: " + str(name_string)
+
+ if name_string == 'NSBundle':
+ wrapper = NSBundleKnown_SummaryProvider(valobj, class_data.sys_params)
+ # [NSBundle mainBundle] does return an object that is
+ # not correctly filled out for our purposes, so we still
+ # end up having to run code in that case
+ # statistics.metric_hit('code_notrun',valobj)
+ else:
+ wrapper = NSBundleUnknown_SummaryProvider(
+ valobj, class_data.sys_params)
+ statistics.metric_hit(
+ 'unknown_class',
+ valobj.GetName() +
+ " seen as " +
+ name_string)
+ return wrapper
+
+
+def NSBundle_SummaryProvider(valobj, dict):
+ logger = lldb.formatters.Logger.Logger()
+ provider = GetSummary_Impl(valobj)
+ if provider is not None:
+ if isinstance(
+ provider,
+ lldb.runtime.objc.objc_runtime.SpecialSituation_Description):
+ return provider.message()
+ try:
+ summary = provider.url_text()
+ except:
+ summary = None
+ logger >> "got summary " + str(summary)
+ if summary is None or summary == '':
+ summary = '<variable is not NSBundle>'
+ return summary
+ return 'Summary Unavailable'
+
+
+def __lldb_init_module(debugger, dict):
+ debugger.HandleCommand(
+ "type summary add -F NSBundle.NSBundle_SummaryProvider NSBundle")
diff --git a/examples/summaries/cocoa/NSData.py b/examples/summaries/cocoa/NSData.py
index 3aa30b29f54b..bf4f2c6bbb7c 100644
--- a/examples/summaries/cocoa/NSData.py
+++ b/examples/summaries/cocoa/NSData.py
@@ -22,142 +22,161 @@ statistics.add_metric('code_notrun')
# despite the similary to synthetic children providers, these classes are not
# trying to provide anything but the length for an NSData, so they need not
# obey the interface specification for synthetic children providers
+
+
class NSConcreteData_SummaryProvider:
- def adjust_for_architecture(self):
- pass
-
- def __init__(self, valobj, params):
- logger = lldb.formatters.Logger.Logger()
- logger >> "NSConcreteData_SummaryProvider __init__"
- self.valobj = valobj;
- self.sys_params = params
- if not(self.sys_params.types_cache.NSUInteger):
- if self.sys_params.is_64_bit:
- self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong)
- else:
- self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt)
- self.update();
-
- def update(self):
- self.adjust_for_architecture();
-
- # one pointer is the ISA
- # then there are 32 bit worth of flags and other data
- # however, on 64bit systems these are padded to be a full
- # machine word long, which means we actually have two pointers
- # worth of data to skip
- def offset(self):
- return 2 * self.sys_params.pointer_size
-
- def length(self):
- logger = lldb.formatters.Logger.Logger()
- logger >> "NSConcreteData_SummaryProvider length"
- size = self.valobj.CreateChildAtOffset("count",
- self.offset(),
- self.sys_params.types_cache.NSUInteger)
- logger >> str(size)
- logger >> str(size.GetValueAsUnsigned(0))
- return size.GetValueAsUnsigned(0)
+
+ def adjust_for_architecture(self):
+ pass
+
+ def __init__(self, valobj, params):
+ logger = lldb.formatters.Logger.Logger()
+ logger >> "NSConcreteData_SummaryProvider __init__"
+ self.valobj = valobj
+ self.sys_params = params
+ if not(self.sys_params.types_cache.NSUInteger):
+ if self.sys_params.is_64_bit:
+ self.sys_params.types_cache.NSUInteger = self.valobj.GetType(
+ ).GetBasicType(lldb.eBasicTypeUnsignedLong)
+ else:
+ self.sys_params.types_cache.NSUInteger = self.valobj.GetType(
+ ).GetBasicType(lldb.eBasicTypeUnsignedInt)
+ self.update()
+
+ def update(self):
+ self.adjust_for_architecture()
+
+ # one pointer is the ISA
+ # then there are 32 bit worth of flags and other data
+ # however, on 64bit systems these are padded to be a full
+ # machine word long, which means we actually have two pointers
+ # worth of data to skip
+ def offset(self):
+ return 2 * self.sys_params.pointer_size
+
+ def length(self):
+ logger = lldb.formatters.Logger.Logger()
+ logger >> "NSConcreteData_SummaryProvider length"
+ size = self.valobj.CreateChildAtOffset(
+ "count", self.offset(), self.sys_params.types_cache.NSUInteger)
+ logger >> str(size)
+ logger >> str(size.GetValueAsUnsigned(0))
+ return size.GetValueAsUnsigned(0)
class NSDataUnknown_SummaryProvider:
- def adjust_for_architecture(self):
- pass
-
- def __init__(self, valobj, params):
- logger = lldb.formatters.Logger.Logger()
- logger >> "NSDataUnknown_SummaryProvider __init__"
- self.valobj = valobj;
- self.sys_params = params
- self.update();
-
- def update(self):
- self.adjust_for_architecture();
-
- def length(self):
- logger = lldb.formatters.Logger.Logger()
- logger >> "NSDataUnknown_SummaryProvider length"
- stream = lldb.SBStream()
- self.valobj.GetExpressionPath(stream)
- logger >> stream.GetData()
- num_children_vo = self.valobj.CreateValueFromExpression("count","(int)[" + stream.GetData() + " length]");
- logger >> "still in after expression: " + str(num_children_vo)
- if num_children_vo.IsValid():
- logger >> "wow - expr output is valid: " + str(num_children_vo.GetValueAsUnsigned())
- return num_children_vo.GetValueAsUnsigned(0)
- logger >> "invalid expr output - too bad"
- return '<variable is not NSData>'
+
+ def adjust_for_architecture(self):
+ pass
+
+ def __init__(self, valobj, params):
+ logger = lldb.formatters.Logger.Logger()
+ logger >> "NSDataUnknown_SummaryProvider __init__"
+ self.valobj = valobj
+ self.sys_params = params
+ self.update()
+
+ def update(self):
+ self.adjust_for_architecture()
+
+ def length(self):
+ logger = lldb.formatters.Logger.Logger()
+ logger >> "NSDataUnknown_SummaryProvider length"
+ stream = lldb.SBStream()
+ self.valobj.GetExpressionPath(stream)
+ logger >> stream.GetData()
+ num_children_vo = self.valobj.CreateValueFromExpression(
+ "count", "(int)[" + stream.GetData() + " length]")
+ logger >> "still in after expression: " + str(num_children_vo)
+ if num_children_vo.IsValid():
+ logger >> "wow - expr output is valid: " + \
+ str(num_children_vo.GetValueAsUnsigned())
+ return num_children_vo.GetValueAsUnsigned(0)
+ logger >> "invalid expr output - too bad"
+ return '<variable is not NSData>'
def GetSummary_Impl(valobj):
- global statistics
- logger = lldb.formatters.Logger.Logger()
- logger >> "NSData GetSummary_Impl"
- class_data,wrapper =lldb.runtime.objc.objc_runtime.Utilities.prepare_class_detection(valobj,statistics)
- if wrapper:
- logger >> "got a wrapper summary - using it"
- return wrapper
-
- name_string = class_data.class_name()
- logger >> "class name: " + name_string
- if name_string == 'NSConcreteData' or \
- name_string == 'NSConcreteMutableData' or \
- name_string == '__NSCFData':
- wrapper = NSConcreteData_SummaryProvider(valobj, class_data.sys_params)
- statistics.metric_hit('code_notrun',valobj)
- else:
- wrapper = NSDataUnknown_SummaryProvider(valobj, class_data.sys_params)
- statistics.metric_hit('unknown_class',valobj.GetName() + " seen as " + name_string)
- return wrapper;
-
-def NSData_SummaryProvider (valobj,dict):
- logger = lldb.formatters.Logger.Logger()
- logger >> "NSData_SummaryProvider"
- provider = GetSummary_Impl(valobj);
- logger >> "found a summary provider, it is: " + str(provider)
- if provider != None:
- try:
- summary = provider.length();
- except:
- summary = None
- logger >> "got a summary: it is " + str(summary)
- if summary == None:
- summary = '<variable is not NSData>'
- elif isinstance(summary,basestring):
- pass
- else:
- if summary == 1:
- summary = '1 byte'
- else:
- summary = str(summary) + ' bytes'
- return summary
- return 'Summary Unavailable'
-
-def NSData_SummaryProvider2 (valobj,dict):
- logger = lldb.formatters.Logger.Logger()
- logger >> "NSData_SummaryProvider2"
- provider = GetSummary_Impl(valobj);
- logger >> "found a summary provider, it is: " + str(provider)
- if provider != None:
- if isinstance(provider,lldb.runtime.objc.objc_runtime.SpecialSituation_Description):
- return provider.message()
- try:
- summary = provider.length();
- except:
- summary = None
- logger >> "got a summary: it is " + str(summary)
- if summary == None:
- summary = '<variable is not CFData>'
- elif isinstance(summary,basestring):
- pass
- else:
- if summary == 1:
- summary = '@"1 byte"'
- else:
- summary = '@"' + str(summary) + ' bytes"'
- return summary
- return 'Summary Unavailable'
-
-def __lldb_init_module(debugger,dict):
- debugger.HandleCommand("type summary add -F NSData.NSData_SummaryProvider NSData")
- debugger.HandleCommand("type summary add -F NSData.NSData_SummaryProvider2 CFDataRef CFMutableDataRef")
+ global statistics
+ logger = lldb.formatters.Logger.Logger()
+ logger >> "NSData GetSummary_Impl"
+ class_data, wrapper = lldb.runtime.objc.objc_runtime.Utilities.prepare_class_detection(
+ valobj, statistics)
+ if wrapper:
+ logger >> "got a wrapper summary - using it"
+ return wrapper
+
+ name_string = class_data.class_name()
+ logger >> "class name: " + name_string
+ if name_string == 'NSConcreteData' or \
+ name_string == 'NSConcreteMutableData' or \
+ name_string == '__NSCFData':
+ wrapper = NSConcreteData_SummaryProvider(valobj, class_data.sys_params)
+ statistics.metric_hit('code_notrun', valobj)
+ else:
+ wrapper = NSDataUnknown_SummaryProvider(valobj, class_data.sys_params)
+ statistics.metric_hit(
+ 'unknown_class',
+ valobj.GetName() +
+ " seen as " +
+ name_string)
+ return wrapper
+
+
+def NSData_SummaryProvider(valobj, dict):
+ logger = lldb.formatters.Logger.Logger()
+ logger >> "NSData_SummaryProvider"
+ provider = GetSummary_Impl(valobj)
+ logger >> "found a summary provider, it is: " + str(provider)
+ if provider is not None:
+ try:
+ summary = provider.length()
+ except:
+ summary = None
+ logger >> "got a summary: it is " + str(summary)
+ if summary is None:
+ summary = '<variable is not NSData>'
+ elif isinstance(summary, basestring):
+ pass
+ else:
+ if summary == 1:
+ summary = '1 byte'
+ else:
+ summary = str(summary) + ' bytes'
+ return summary
+ return 'Summary Unavailable'
+
+
+def NSData_SummaryProvider2(valobj, dict):
+ logger = lldb.formatters.Logger.Logger()
+ logger >> "NSData_SummaryProvider2"
+ provider = GetSummary_Impl(valobj)
+ logger >> "found a summary provider, it is: " + str(provider)
+ if provider is not None:
+ if isinstance(
+ provider,
+ lldb.runtime.objc.objc_runtime.SpecialSituation_Description):
+ return provider.message()
+ try:
+ summary = provider.length()
+ except:
+ summary = None
+ logger >> "got a summary: it is " + str(summary)
+ if summary is None:
+ summary = '<variable is not CFData>'
+ elif isinstance(summary, basestring):
+ pass
+ else:
+ if summary == 1:
+ summary = '@"1 byte"'
+ else:
+ summary = '@"' + str(summary) + ' bytes"'
+ return summary
+ return 'Summary Unavailable'
+
+
+def __lldb_init_module(debugger, dict):
+ debugger.HandleCommand(
+ "type summary add -F NSData.NSData_SummaryProvider NSData")
+ debugger.HandleCommand(
+ "type summary add -F NSData.NSData_SummaryProvider2 CFDataRef CFMutableDataRef")
diff --git a/examples/summaries/cocoa/NSDate.py b/examples/summaries/cocoa/NSDate.py
index 4dd63b4a5c32..4efe76eca598 100644
--- a/examples/summaries/cocoa/NSDate.py
+++ b/examples/summaries/cocoa/NSDate.py
@@ -27,243 +27,281 @@ statistics.add_metric('code_notrun')
# hence, all we need to know is the epoch year
python_epoch = time.gmtime(0).tm_year
-osx_epoch = datetime.date(2001,1,1).timetuple()
+osx_epoch = datetime.date(2001, 1, 1).timetuple()
+
def mkgmtime(t):
- logger = lldb.formatters.Logger.Logger()
- return time.mktime(t)-time.timezone
+ logger = lldb.formatters.Logger.Logger()
+ return time.mktime(t) - time.timezone
osx_epoch = mkgmtime(osx_epoch)
+
def osx_to_python_time(osx):
- logger = lldb.formatters.Logger.Logger()
- if python_epoch <= 2001:
- return osx + osx_epoch
- else:
- return osx - osx_epoch
+ logger = lldb.formatters.Logger.Logger()
+ if python_epoch <= 2001:
+ return osx + osx_epoch
+ else:
+ return osx - osx_epoch
# represent a struct_time as a string in the format used by Xcode
+
+
def xcode_format_time(X):
- logger = lldb.formatters.Logger.Logger()
- return time.strftime('%Y-%m-%d %H:%M:%S %Z',X)
+ logger = lldb.formatters.Logger.Logger()
+ return time.strftime('%Y-%m-%d %H:%M:%S %Z', X)
# represent a count-since-epoch as a string in the format used by Xcode
+
+
def xcode_format_count(X):
- logger = lldb.formatters.Logger.Logger()
- return xcode_format_time(time.localtime(X))
+ logger = lldb.formatters.Logger.Logger()
+ return xcode_format_time(time.localtime(X))
# despite the similary to synthetic children providers, these classes are not
# trying to provide anything but the summary for NSDate, so they need not
# obey the interface specification for synthetic children providers
+
+
class NSTaggedDate_SummaryProvider:
- def adjust_for_architecture(self):
- pass
-
- def __init__(self, valobj, info_bits, data, params):
- logger = lldb.formatters.Logger.Logger()
- self.valobj = valobj;
- self.sys_params = params
- self.update();
- # NSDate is not using its info_bits for info like NSNumber is
- # so we need to regroup info_bits and data
- self.data = ((data << 8) | (info_bits << 4))
-
- def update(self):
- logger = lldb.formatters.Logger.Logger()
- self.adjust_for_architecture();
-
- def value(self):
- logger = lldb.formatters.Logger.Logger()
- # the value of the date-time object is wrapped into the pointer value
- # unfortunately, it is made as a time-delta after Jan 1 2001 midnight GMT
- # while all Python knows about is the "epoch", which is a platform-dependent
- # year (1970 of *nix) whose Jan 1 at midnight is taken as reference
- value_double = struct.unpack('d', struct.pack('Q', self.data))[0]
- if value_double == -63114076800.0:
- return '0001-12-30 00:00:00 +0000'
- return xcode_format_count(osx_to_python_time(value_double))
+
+ def adjust_for_architecture(self):
+ pass
+
+ def __init__(self, valobj, info_bits, data, params):
+ logger = lldb.formatters.Logger.Logger()
+ self.valobj = valobj
+ self.sys_params = params
+ self.update()
+ # NSDate is not using its info_bits for info like NSNumber is
+ # so we need to regroup info_bits and data
+ self.data = ((data << 8) | (info_bits << 4))
+
+ def update(self):
+ logger = lldb.formatters.Logger.Logger()
+ self.adjust_for_architecture()
+
+ def value(self):
+ logger = lldb.formatters.Logger.Logger()
+ # the value of the date-time object is wrapped into the pointer value
+ # unfortunately, it is made as a time-delta after Jan 1 2001 midnight GMT
+ # while all Python knows about is the "epoch", which is a platform-dependent
+ # year (1970 of *nix) whose Jan 1 at midnight is taken as reference
+ value_double = struct.unpack('d', struct.pack('Q', self.data))[0]
+ if value_double == -63114076800.0:
+ return '0001-12-30 00:00:00 +0000'
+ return xcode_format_count(osx_to_python_time(value_double))
class NSUntaggedDate_SummaryProvider:
- def adjust_for_architecture(self):
- pass
-
- def __init__(self, valobj, params):
- logger = lldb.formatters.Logger.Logger()
- self.valobj = valobj;
- self.sys_params = params
- if not (self.sys_params.types_cache.double):
- self.sys_params.types_cache.double = self.valobj.GetType().GetBasicType(lldb.eBasicTypeDouble)
- self.update()
-
- def update(self):
- logger = lldb.formatters.Logger.Logger()
- self.adjust_for_architecture();
-
- def offset(self):
- logger = lldb.formatters.Logger.Logger()
- return self.sys_params.pointer_size
-
- def value(self):
- logger = lldb.formatters.Logger.Logger()
- value = self.valobj.CreateChildAtOffset("value",
- self.offset(),
- self.sys_params.types_cache.double)
- value_double = struct.unpack('d', struct.pack('Q', value.GetData().uint64[0]))[0]
- if value_double == -63114076800.0:
- return '0001-12-30 00:00:00 +0000'
- return xcode_format_count(osx_to_python_time(value_double))
+
+ def adjust_for_architecture(self):
+ pass
+
+ def __init__(self, valobj, params):
+ logger = lldb.formatters.Logger.Logger()
+ self.valobj = valobj
+ self.sys_params = params
+ if not (self.sys_params.types_cache.double):
+ self.sys_params.types_cache.double = self.valobj.GetType(
+ ).GetBasicType(lldb.eBasicTypeDouble)
+ self.update()
+
+ def update(self):
+ logger = lldb.formatters.Logger.Logger()
+ self.adjust_for_architecture()
+
+ def offset(self):
+ logger = lldb.formatters.Logger.Logger()
+ return self.sys_params.pointer_size
+
+ def value(self):
+ logger = lldb.formatters.Logger.Logger()
+ value = self.valobj.CreateChildAtOffset(
+ "value", self.offset(), self.sys_params.types_cache.double)
+ value_double = struct.unpack(
+ 'd', struct.pack(
+ 'Q', value.GetData().uint64[0]))[0]
+ if value_double == -63114076800.0:
+ return '0001-12-30 00:00:00 +0000'
+ return xcode_format_count(osx_to_python_time(value_double))
+
class NSCalendarDate_SummaryProvider:
- def adjust_for_architecture(self):
- pass
-
- def __init__(self, valobj, params):
- logger = lldb.formatters.Logger.Logger()
- self.valobj = valobj;
- self.sys_params = params
- if not (self.sys_params.types_cache.double):
- self.sys_params.types_cache.double = self.valobj.GetType().GetBasicType(lldb.eBasicTypeDouble)
- self.update()
-
- def update(self):
- logger = lldb.formatters.Logger.Logger()
- self.adjust_for_architecture();
-
- def offset(self):
- logger = lldb.formatters.Logger.Logger()
- return 2*self.sys_params.pointer_size
-
- def value(self):
- logger = lldb.formatters.Logger.Logger()
- value = self.valobj.CreateChildAtOffset("value",
- self.offset(),
- self.sys_params.types_cache.double)
- value_double = struct.unpack('d', struct.pack('Q', value.GetData().uint64[0]))[0]
- return xcode_format_count(osx_to_python_time(value_double))
+
+ def adjust_for_architecture(self):
+ pass
+
+ def __init__(self, valobj, params):
+ logger = lldb.formatters.Logger.Logger()
+ self.valobj = valobj
+ self.sys_params = params
+ if not (self.sys_params.types_cache.double):
+ self.sys_params.types_cache.double = self.valobj.GetType(
+ ).GetBasicType(lldb.eBasicTypeDouble)
+ self.update()
+
+ def update(self):
+ logger = lldb.formatters.Logger.Logger()
+ self.adjust_for_architecture()
+
+ def offset(self):
+ logger = lldb.formatters.Logger.Logger()
+ return 2 * self.sys_params.pointer_size
+
+ def value(self):
+ logger = lldb.formatters.Logger.Logger()
+ value = self.valobj.CreateChildAtOffset(
+ "value", self.offset(), self.sys_params.types_cache.double)
+ value_double = struct.unpack(
+ 'd', struct.pack(
+ 'Q', value.GetData().uint64[0]))[0]
+ return xcode_format_count(osx_to_python_time(value_double))
+
class NSTimeZoneClass_SummaryProvider:
- def adjust_for_architecture(self):
- pass
-
- def __init__(self, valobj, params):
- logger = lldb.formatters.Logger.Logger()
- self.valobj = valobj;
- self.sys_params = params
- if not (self.sys_params.types_cache.voidptr):
- self.sys_params.types_cache.voidptr = self.valobj.GetType().GetBasicType(lldb.eBasicTypeVoid).GetPointerType()
- self.update()
-
- def update(self):
- logger = lldb.formatters.Logger.Logger()
- self.adjust_for_architecture();
-
- def offset(self):
- logger = lldb.formatters.Logger.Logger()
- return self.sys_params.pointer_size
-
- def timezone(self):
- logger = lldb.formatters.Logger.Logger()
- tz_string = self.valobj.CreateChildAtOffset("tz_name",
- self.offset(),
- self.sys_params.types_cache.voidptr)
- return CFString.CFString_SummaryProvider(tz_string,None)
+
+ def adjust_for_architecture(self):
+ pass
+
+ def __init__(self, valobj, params):
+ logger = lldb.formatters.Logger.Logger()
+ self.valobj = valobj
+ self.sys_params = params
+ if not (self.sys_params.types_cache.voidptr):
+ self.sys_params.types_cache.voidptr = self.valobj.GetType(
+ ).GetBasicType(lldb.eBasicTypeVoid).GetPointerType()
+ self.update()
+
+ def update(self):
+ logger = lldb.formatters.Logger.Logger()
+ self.adjust_for_architecture()
+
+ def offset(self):
+ logger = lldb.formatters.Logger.Logger()
+ return self.sys_params.pointer_size
+
+ def timezone(self):
+ logger = lldb.formatters.Logger.Logger()
+ tz_string = self.valobj.CreateChildAtOffset(
+ "tz_name", self.offset(), self.sys_params.types_cache.voidptr)
+ return CFString.CFString_SummaryProvider(tz_string, None)
+
class NSUnknownDate_SummaryProvider:
- def adjust_for_architecture(self):
- pass
-
- def __init__(self, valobj):
- logger = lldb.formatters.Logger.Logger()
- self.valobj = valobj;
- self.update()
-
- def update(self):
- logger = lldb.formatters.Logger.Logger()
- self.adjust_for_architecture();
-
- def value(self):
- logger = lldb.formatters.Logger.Logger()
- stream = lldb.SBStream()
- self.valobj.GetExpressionPath(stream)
- expr = "(NSString*)[" + stream.GetData() + " description]"
- num_children_vo = self.valobj.CreateValueFromExpression("str",expr);
- if num_children_vo.IsValid():
- return num_children_vo.GetSummary()
- return '<variable is not NSDate>'
-def GetSummary_Impl(valobj):
- logger = lldb.formatters.Logger.Logger()
- global statistics
- class_data,wrapper =lldb.runtime.objc.objc_runtime.Utilities.prepare_class_detection(valobj,statistics)
- if wrapper:
- return wrapper
-
- name_string = class_data.class_name()
- logger >> "class name is: " + str(name_string)
-
- if name_string == 'NSDate' or name_string == '__NSDate' or name_string == '__NSTaggedDate':
- if class_data.is_tagged():
- wrapper = NSTaggedDate_SummaryProvider(valobj,class_data.info_bits(),class_data.value(), class_data.sys_params)
- statistics.metric_hit('code_notrun',valobj)
- else:
- wrapper = NSUntaggedDate_SummaryProvider(valobj, class_data.sys_params)
- statistics.metric_hit('code_notrun',valobj)
- elif name_string == 'NSCalendarDate':
- wrapper = NSCalendarDate_SummaryProvider(valobj, class_data.sys_params)
- statistics.metric_hit('code_notrun',valobj)
- elif name_string == '__NSTimeZone':
- wrapper = NSTimeZoneClass_SummaryProvider(valobj, class_data.sys_params)
- statistics.metric_hit('code_notrun',valobj)
- else:
- wrapper = NSUnknownDate_SummaryProvider(valobj)
- statistics.metric_hit('unknown_class',valobj.GetName() + " seen as " + name_string)
- return wrapper;
-
-
-def NSDate_SummaryProvider (valobj,dict):
- logger = lldb.formatters.Logger.Logger()
- provider = GetSummary_Impl(valobj);
- if provider != None:
- if isinstance(provider,lldb.runtime.objc.objc_runtime.SpecialSituation_Description):
- return provider.message()
- try:
- summary = provider.value();
- except:
- summary = None
- if summary == None:
- summary = '<variable is not NSDate>'
- return str(summary)
- return 'Summary Unavailable'
-
-def NSTimeZone_SummaryProvider (valobj,dict):
- logger = lldb.formatters.Logger.Logger()
- provider = GetSummary_Impl(valobj);
- if provider != None:
- if isinstance(provider,lldb.runtime.objc.objc_runtime.SpecialSituation_Description):
- return provider.message()
- try:
- summary = provider.timezone();
- except:
- summary = None
- logger >> "got summary " + str(summary)
- if summary == None:
- summary = '<variable is not NSTimeZone>'
- return str(summary)
- return 'Summary Unavailable'
-
-
-def CFAbsoluteTime_SummaryProvider (valobj,dict):
- logger = lldb.formatters.Logger.Logger()
- try:
- value_double = struct.unpack('d', struct.pack('Q', valobj.GetData().uint64[0]))[0]
- return xcode_format_count(osx_to_python_time(value_double))
- except:
- return 'Summary Unavailable'
-
-
-def __lldb_init_module(debugger,dict):
- debugger.HandleCommand("type summary add -F NSDate.NSDate_SummaryProvider NSDate")
- debugger.HandleCommand("type summary add -F NSDate.CFAbsoluteTime_SummaryProvider CFAbsoluteTime")
- debugger.HandleCommand("type summary add -F NSDate.NSTimeZone_SummaryProvider NSTimeZone CFTimeZoneRef")
+ def adjust_for_architecture(self):
+ pass
+
+ def __init__(self, valobj):
+ logger = lldb.formatters.Logger.Logger()
+ self.valobj = valobj
+ self.update()
+
+ def update(self):
+ logger = lldb.formatters.Logger.Logger()
+ self.adjust_for_architecture()
+ def value(self):
+ logger = lldb.formatters.Logger.Logger()
+ stream = lldb.SBStream()
+ self.valobj.GetExpressionPath(stream)
+ expr = "(NSString*)[" + stream.GetData() + " description]"
+ num_children_vo = self.valobj.CreateValueFromExpression("str", expr)
+ if num_children_vo.IsValid():
+ return num_children_vo.GetSummary()
+ return '<variable is not NSDate>'
+
+
+def GetSummary_Impl(valobj):
+ logger = lldb.formatters.Logger.Logger()
+ global statistics
+ class_data, wrapper = lldb.runtime.objc.objc_runtime.Utilities.prepare_class_detection(
+ valobj, statistics)
+ if wrapper:
+ return wrapper
+
+ name_string = class_data.class_name()
+ logger >> "class name is: " + str(name_string)
+
+ if name_string == 'NSDate' or name_string == '__NSDate' or name_string == '__NSTaggedDate':
+ if class_data.is_tagged():
+ wrapper = NSTaggedDate_SummaryProvider(
+ valobj, class_data.info_bits(), class_data.value(), class_data.sys_params)
+ statistics.metric_hit('code_notrun', valobj)
+ else:
+ wrapper = NSUntaggedDate_SummaryProvider(
+ valobj, class_data.sys_params)
+ statistics.metric_hit('code_notrun', valobj)
+ elif name_string == 'NSCalendarDate':
+ wrapper = NSCalendarDate_SummaryProvider(valobj, class_data.sys_params)
+ statistics.metric_hit('code_notrun', valobj)
+ elif name_string == '__NSTimeZone':
+ wrapper = NSTimeZoneClass_SummaryProvider(
+ valobj, class_data.sys_params)
+ statistics.metric_hit('code_notrun', valobj)
+ else:
+ wrapper = NSUnknownDate_SummaryProvider(valobj)
+ statistics.metric_hit(
+ 'unknown_class',
+ valobj.GetName() +
+ " seen as " +
+ name_string)
+ return wrapper
+
+
+def NSDate_SummaryProvider(valobj, dict):
+ logger = lldb.formatters.Logger.Logger()
+ provider = GetSummary_Impl(valobj)
+ if provider is not None:
+ if isinstance(
+ provider,
+ lldb.runtime.objc.objc_runtime.SpecialSituation_Description):
+ return provider.message()
+ try:
+ summary = provider.value()
+ except:
+ summary = None
+ if summary is None:
+ summary = '<variable is not NSDate>'
+ return str(summary)
+ return 'Summary Unavailable'
+
+
+def NSTimeZone_SummaryProvider(valobj, dict):
+ logger = lldb.formatters.Logger.Logger()
+ provider = GetSummary_Impl(valobj)
+ if provider is not None:
+ if isinstance(
+ provider,
+ lldb.runtime.objc.objc_runtime.SpecialSituation_Description):
+ return provider.message()
+ try:
+ summary = provider.timezone()
+ except:
+ summary = None
+ logger >> "got summary " + str(summary)
+ if summary is None:
+ summary = '<variable is not NSTimeZone>'
+ return str(summary)
+ return 'Summary Unavailable'
+
+
+def CFAbsoluteTime_SummaryProvider(valobj, dict):
+ logger = lldb.formatters.Logger.Logger()
+ try:
+ value_double = struct.unpack(
+ 'd', struct.pack(
+ 'Q', valobj.GetData().uint64[0]))[0]
+ return xcode_format_count(osx_to_python_time(value_double))
+ except:
+ return 'Summary Unavailable'
+
+
+def __lldb_init_module(debugger, dict):
+ debugger.HandleCommand(
+ "type summary add -F NSDate.NSDate_SummaryProvider NSDate")
+ debugger.HandleCommand(
+ "type summary add -F NSDate.CFAbsoluteTime_SummaryProvider CFAbsoluteTime")
+ debugger.HandleCommand(
+ "type summary add -F NSDate.NSTimeZone_SummaryProvider NSTimeZone CFTimeZoneRef")
diff --git a/examples/summaries/cocoa/NSException.py b/examples/summaries/cocoa/NSException.py
index 72bf895bdbc3..826871d70c21 100644
--- a/examples/summaries/cocoa/NSException.py
+++ b/examples/summaries/cocoa/NSException.py
@@ -18,97 +18,117 @@ statistics.add_metric('invalid_pointer')
statistics.add_metric('unknown_class')
statistics.add_metric('code_notrun')
+
class NSKnownException_SummaryProvider:
- def adjust_for_architecture(self):
- pass
-
- def __init__(self, valobj, params):
- logger = lldb.formatters.Logger.Logger()
- self.valobj = valobj;
- self.sys_params = params
- if not (self.sys_params.types_cache.id):
- self.sys_params.types_cache.id = self.valobj.GetType().GetBasicType(lldb.eBasicTypeObjCID)
- self.update();
-
- def update(self):
- logger = lldb.formatters.Logger.Logger()
- self.adjust_for_architecture();
-
- def offset_name(self):
- logger = lldb.formatters.Logger.Logger()
- return self.sys_params.pointer_size
- def offset_reason(self):
- logger = lldb.formatters.Logger.Logger()
- return 2*self.sys_params.pointer_size
-
- def description(self):
- logger = lldb.formatters.Logger.Logger()
- name_ptr = self.valobj.CreateChildAtOffset("name",
- self.offset_name(),
- self.sys_params.types_cache.id)
- reason_ptr = self.valobj.CreateChildAtOffset("reason",
- self.offset_reason(),
- self.sys_params.types_cache.id)
- return 'name:' + CFString.CFString_SummaryProvider(name_ptr,None) + ' reason:' + CFString.CFString_SummaryProvider(reason_ptr,None)
+
+ def adjust_for_architecture(self):
+ pass
+
+ def __init__(self, valobj, params):
+ logger = lldb.formatters.Logger.Logger()
+ self.valobj = valobj
+ self.sys_params = params
+ if not (self.sys_params.types_cache.id):
+ self.sys_params.types_cache.id = self.valobj.GetType(
+ ).GetBasicType(lldb.eBasicTypeObjCID)
+ self.update()
+
+ def update(self):
+ logger = lldb.formatters.Logger.Logger()
+ self.adjust_for_architecture()
+
+ def offset_name(self):
+ logger = lldb.formatters.Logger.Logger()
+ return self.sys_params.pointer_size
+
+ def offset_reason(self):
+ logger = lldb.formatters.Logger.Logger()
+ return 2 * self.sys_params.pointer_size
+
+ def description(self):
+ logger = lldb.formatters.Logger.Logger()
+ name_ptr = self.valobj.CreateChildAtOffset(
+ "name", self.offset_name(), self.sys_params.types_cache.id)
+ reason_ptr = self.valobj.CreateChildAtOffset(
+ "reason", self.offset_reason(), self.sys_params.types_cache.id)
+ return 'name:' + CFString.CFString_SummaryProvider(
+ name_ptr, None) + ' reason:' + CFString.CFString_SummaryProvider(reason_ptr, None)
+
class NSUnknownException_SummaryProvider:
- def adjust_for_architecture(self):
- pass
-
- def __init__(self, valobj, params):
- logger = lldb.formatters.Logger.Logger()
- self.valobj = valobj;
- self.sys_params = params
- self.update();
-
- def update(self):
- logger = lldb.formatters.Logger.Logger()
- self.adjust_for_architecture();
-
- def description(self):
- logger = lldb.formatters.Logger.Logger()
- stream = lldb.SBStream()
- self.valobj.GetExpressionPath(stream)
- name_vo = self.valobj.CreateValueFromExpression("name","(NSString*)[" + stream.GetData() + " name]");
- reason_vo = self.valobj.CreateValueFromExpression("reason","(NSString*)[" + stream.GetData() + " reason]");
- if name_vo.IsValid() and reason_vo.IsValid():
- return CFString.CFString_SummaryProvider(name_vo,None) + ' ' + CFString.CFString_SummaryProvider(reason_vo,None)
- return '<variable is not NSException>'
+
+ def adjust_for_architecture(self):
+ pass
+
+ def __init__(self, valobj, params):
+ logger = lldb.formatters.Logger.Logger()
+ self.valobj = valobj
+ self.sys_params = params
+ self.update()
+
+ def update(self):
+ logger = lldb.formatters.Logger.Logger()
+ self.adjust_for_architecture()
+
+ def description(self):
+ logger = lldb.formatters.Logger.Logger()
+ stream = lldb.SBStream()
+ self.valobj.GetExpressionPath(stream)
+ name_vo = self.valobj.CreateValueFromExpression(
+ "name", "(NSString*)[" + stream.GetData() + " name]")
+ reason_vo = self.valobj.CreateValueFromExpression(
+ "reason", "(NSString*)[" + stream.GetData() + " reason]")
+ if name_vo.IsValid() and reason_vo.IsValid():
+ return CFString.CFString_SummaryProvider(
+ name_vo, None) + ' ' + CFString.CFString_SummaryProvider(reason_vo, None)
+ return '<variable is not NSException>'
def GetSummary_Impl(valobj):
- logger = lldb.formatters.Logger.Logger()
- global statistics
- class_data,wrapper =lldb.runtime.objc.objc_runtime.Utilities.prepare_class_detection(valobj,statistics)
- if wrapper:
- return wrapper
-
- name_string = class_data.class_name()
- logger >> "class name is: " + str(name_string)
-
- if name_string == 'NSException':
- wrapper = NSKnownException_SummaryProvider(valobj, class_data.sys_params)
- statistics.metric_hit('code_notrun',valobj)
- else:
- wrapper = NSUnknownException_SummaryProvider(valobj, class_data.sys_params)
- statistics.metric_hit('unknown_class',valobj.GetName() + " seen as " + name_string)
- return wrapper;
-
-def NSException_SummaryProvider (valobj,dict):
- logger = lldb.formatters.Logger.Logger()
- provider = GetSummary_Impl(valobj);
- if provider != None:
- if isinstance(provider,lldb.runtime.objc.objc_runtime.SpecialSituation_Description):
- return provider.message()
- try:
- summary = provider.description();
- except:
- summary = None
- logger >> "got summary " + str(summary)
- if summary == None:
- summary = '<variable is not NSException>'
- return str(summary)
- return 'Summary Unavailable'
-
-def __lldb_init_module(debugger,dict):
- debugger.HandleCommand("type summary add -F NSException.NSException_SummaryProvider NSException")
+ logger = lldb.formatters.Logger.Logger()
+ global statistics
+ class_data, wrapper = lldb.runtime.objc.objc_runtime.Utilities.prepare_class_detection(
+ valobj, statistics)
+ if wrapper:
+ return wrapper
+
+ name_string = class_data.class_name()
+ logger >> "class name is: " + str(name_string)
+
+ if name_string == 'NSException':
+ wrapper = NSKnownException_SummaryProvider(
+ valobj, class_data.sys_params)
+ statistics.metric_hit('code_notrun', valobj)
+ else:
+ wrapper = NSUnknownException_SummaryProvider(
+ valobj, class_data.sys_params)
+ statistics.metric_hit(
+ 'unknown_class',
+ valobj.GetName() +
+ " seen as " +
+ name_string)
+ return wrapper
+
+
+def NSException_SummaryProvider(valobj, dict):
+ logger = lldb.formatters.Logger.Logger()
+ provider = GetSummary_Impl(valobj)
+ if provider is not None:
+ if isinstance(
+ provider,
+ lldb.runtime.objc.objc_runtime.SpecialSituation_Description):
+ return provider.message()
+ try:
+ summary = provider.description()
+ except:
+ summary = None
+ logger >> "got summary " + str(summary)
+ if summary is None:
+ summary = '<variable is not NSException>'
+ return str(summary)
+ return 'Summary Unavailable'
+
+
+def __lldb_init_module(debugger, dict):
+ debugger.HandleCommand(
+ "type summary add -F NSException.NSException_SummaryProvider NSException")
diff --git a/examples/summaries/cocoa/NSIndexSet.py b/examples/summaries/cocoa/NSIndexSet.py
index 011d58dd773d..ca9906158a90 100644
--- a/examples/summaries/cocoa/NSIndexSet.py
+++ b/examples/summaries/cocoa/NSIndexSet.py
@@ -22,129 +22,155 @@ statistics.add_metric('code_notrun')
# despite the similary to synthetic children providers, these classes are not
# trying to provide anything but the count of values for an NSIndexSet, so they need not
# obey the interface specification for synthetic children providers
+
+
class NSIndexSetClass_SummaryProvider:
- def adjust_for_architecture(self):
- pass
-
- def __init__(self, valobj, params):
- logger = lldb.formatters.Logger.Logger()
- self.valobj = valobj;
- self.sys_params = params
- if not(self.sys_params.types_cache.NSUInteger):
- if self.sys_params.is_64_bit:
- self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong)
- self.sys_params.types_cache.uint32 = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt)
- else:
- self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt)
- self.sys_params.types_cache.uint32 = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt)
- if not(self.sys_params.types_cache.uint32):
- self.sys_params.types_cache.uint32 = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt)
- self.update();
-
- def update(self):
- logger = lldb.formatters.Logger.Logger()
- self.adjust_for_architecture();
-
- # NS(Mutable)IndexSet works in one of two modes: when having a compact block of data (e.g. a Range)
- # the count is stored in the set itself, 3 pointers into it
- # otherwise, it will store a pointer to an additional data structure (2 pointers into itself) and this
- # additional structure will contain the count two pointers deep
- # a bunch of flags allow us to detect an empty set, vs. a one-range set, vs. a multi-range set
- def count(self):
- logger = lldb.formatters.Logger.Logger()
- mode_chooser_vo = self.valobj.CreateChildAtOffset("mode_chooser",
- self.sys_params.pointer_size,
- self.sys_params.types_cache.uint32)
- mode_chooser = mode_chooser_vo.GetValueAsUnsigned(0)
- if self.sys_params.is_64_bit:
- mode_chooser = mode_chooser & 0x00000000FFFFFFFF
- # empty set
- if mode_chooser & 0x01 == 1:
- return 0
- # single range
- if mode_chooser & 0x02 == 2:
- mode = 1
- # multi range
- else:
- mode = 2
- if mode == 1:
- count_vo = self.valobj.CreateChildAtOffset("count",
- 3*self.sys_params.pointer_size,
- self.sys_params.types_cache.NSUInteger)
- else:
- count_ptr = self.valobj.CreateChildAtOffset("count_ptr",
- 2*self.sys_params.pointer_size,
- self.sys_params.types_cache.NSUInteger)
- count_vo = self.valobj.CreateValueFromAddress("count",
- count_ptr.GetValueAsUnsigned()+2*self.sys_params.pointer_size,
- self.sys_params.types_cache.NSUInteger)
- return count_vo.GetValueAsUnsigned(0)
+
+ def adjust_for_architecture(self):
+ pass
+
+ def __init__(self, valobj, params):
+ logger = lldb.formatters.Logger.Logger()
+ self.valobj = valobj
+ self.sys_params = params
+ if not(self.sys_params.types_cache.NSUInteger):
+ if self.sys_params.is_64_bit:
+ self.sys_params.types_cache.NSUInteger = self.valobj.GetType(
+ ).GetBasicType(lldb.eBasicTypeUnsignedLong)
+ self.sys_params.types_cache.uint32 = self.valobj.GetType(
+ ).GetBasicType(lldb.eBasicTypeUnsignedInt)
+ else:
+ self.sys_params.types_cache.NSUInteger = self.valobj.GetType(
+ ).GetBasicType(lldb.eBasicTypeUnsignedInt)
+ self.sys_params.types_cache.uint32 = self.valobj.GetType(
+ ).GetBasicType(lldb.eBasicTypeUnsignedInt)
+ if not(self.sys_params.types_cache.uint32):
+ self.sys_params.types_cache.uint32 = self.valobj.GetType(
+ ).GetBasicType(lldb.eBasicTypeUnsignedInt)
+ self.update()
+
+ def update(self):
+ logger = lldb.formatters.Logger.Logger()
+ self.adjust_for_architecture()
+
+ # NS(Mutable)IndexSet works in one of two modes: when having a compact block of data (e.g. a Range)
+ # the count is stored in the set itself, 3 pointers into it
+ # otherwise, it will store a pointer to an additional data structure (2 pointers into itself) and this
+ # additional structure will contain the count two pointers deep
+ # a bunch of flags allow us to detect an empty set, vs. a one-range set,
+ # vs. a multi-range set
+ def count(self):
+ logger = lldb.formatters.Logger.Logger()
+ mode_chooser_vo = self.valobj.CreateChildAtOffset(
+ "mode_chooser",
+ self.sys_params.pointer_size,
+ self.sys_params.types_cache.uint32)
+ mode_chooser = mode_chooser_vo.GetValueAsUnsigned(0)
+ if self.sys_params.is_64_bit:
+ mode_chooser = mode_chooser & 0x00000000FFFFFFFF
+ # empty set
+ if mode_chooser & 0x01 == 1:
+ return 0
+ # single range
+ if mode_chooser & 0x02 == 2:
+ mode = 1
+ # multi range
+ else:
+ mode = 2
+ if mode == 1:
+ count_vo = self.valobj.CreateChildAtOffset(
+ "count",
+ 3 * self.sys_params.pointer_size,
+ self.sys_params.types_cache.NSUInteger)
+ else:
+ count_ptr = self.valobj.CreateChildAtOffset(
+ "count_ptr",
+ 2 * self.sys_params.pointer_size,
+ self.sys_params.types_cache.NSUInteger)
+ count_vo = self.valobj.CreateValueFromAddress(
+ "count",
+ count_ptr.GetValueAsUnsigned() +
+ 2 *
+ self.sys_params.pointer_size,
+ self.sys_params.types_cache.NSUInteger)
+ return count_vo.GetValueAsUnsigned(0)
class NSIndexSetUnknown_SummaryProvider:
- def adjust_for_architecture(self):
- pass
-
- def __init__(self, valobj, params):
- logger = lldb.formatters.Logger.Logger()
- self.valobj = valobj;
- self.sys_params = params
- self.update();
-
- def update(self):
- logger = lldb.formatters.Logger.Logger()
- self.adjust_for_architecture();
-
- def count(self):
- logger = lldb.formatters.Logger.Logger()
- stream = lldb.SBStream()
- self.valobj.GetExpressionPath(stream)
- expr = "(int)[" + stream.GetData() + " count]"
- num_children_vo = self.valobj.CreateValueFromExpression("count",expr)
- if num_children_vo.IsValid():
- return num_children_vo.GetValueAsUnsigned(0)
- return '<variable is not NSIndexSet>'
+
+ def adjust_for_architecture(self):
+ pass
+
+ def __init__(self, valobj, params):
+ logger = lldb.formatters.Logger.Logger()
+ self.valobj = valobj
+ self.sys_params = params
+ self.update()
+
+ def update(self):
+ logger = lldb.formatters.Logger.Logger()
+ self.adjust_for_architecture()
+
+ def count(self):
+ logger = lldb.formatters.Logger.Logger()
+ stream = lldb.SBStream()
+ self.valobj.GetExpressionPath(stream)
+ expr = "(int)[" + stream.GetData() + " count]"
+ num_children_vo = self.valobj.CreateValueFromExpression("count", expr)
+ if num_children_vo.IsValid():
+ return num_children_vo.GetValueAsUnsigned(0)
+ return '<variable is not NSIndexSet>'
def GetSummary_Impl(valobj):
- logger = lldb.formatters.Logger.Logger()
- global statistics
- class_data,wrapper =lldb.runtime.objc.objc_runtime.Utilities.prepare_class_detection(valobj,statistics)
- if wrapper:
- return wrapper
-
- name_string = class_data.class_name()
- logger >> "class name is: " + str(name_string)
-
- if name_string == 'NSIndexSet' or name_string == 'NSMutableIndexSet':
- wrapper = NSIndexSetClass_SummaryProvider(valobj, class_data.sys_params)
- statistics.metric_hit('code_notrun',valobj)
- else:
- wrapper = NSIndexSetUnknown_SummaryProvider(valobj, class_data.sys_params)
- statistics.metric_hit('unknown_class',valobj.GetName() + " seen as " + name_string)
- return wrapper;
-
-
-def NSIndexSet_SummaryProvider (valobj,dict):
- logger = lldb.formatters.Logger.Logger()
- provider = GetSummary_Impl(valobj);
- if provider != None:
- if isinstance(provider,lldb.runtime.objc.objc_runtime.SpecialSituation_Description):
- return provider.message()
- try:
- summary = provider.count();
- except:
- summary = None
- logger >> "got summary " + str(summary)
- if summary == None:
- summary = '<variable is not NSIndexSet>'
- if isinstance(summary, basestring):
- return summary
- else:
- summary = str(summary) + (' indexes' if summary != 1 else ' index')
- return summary
- return 'Summary Unavailable'
-
-
-def __lldb_init_module(debugger,dict):
- debugger.HandleCommand("type summary add -F NSIndexSet.NSIndexSet_SummaryProvider NSIndexSet NSMutableIndexSet")
+ logger = lldb.formatters.Logger.Logger()
+ global statistics
+ class_data, wrapper = lldb.runtime.objc.objc_runtime.Utilities.prepare_class_detection(
+ valobj, statistics)
+ if wrapper:
+ return wrapper
+
+ name_string = class_data.class_name()
+ logger >> "class name is: " + str(name_string)
+
+ if name_string == 'NSIndexSet' or name_string == 'NSMutableIndexSet':
+ wrapper = NSIndexSetClass_SummaryProvider(
+ valobj, class_data.sys_params)
+ statistics.metric_hit('code_notrun', valobj)
+ else:
+ wrapper = NSIndexSetUnknown_SummaryProvider(
+ valobj, class_data.sys_params)
+ statistics.metric_hit(
+ 'unknown_class',
+ valobj.GetName() +
+ " seen as " +
+ name_string)
+ return wrapper
+
+
+def NSIndexSet_SummaryProvider(valobj, dict):
+ logger = lldb.formatters.Logger.Logger()
+ provider = GetSummary_Impl(valobj)
+ if provider is not None:
+ if isinstance(
+ provider,
+ lldb.runtime.objc.objc_runtime.SpecialSituation_Description):
+ return provider.message()
+ try:
+ summary = provider.count()
+ except:
+ summary = None
+ logger >> "got summary " + str(summary)
+ if summary is None:
+ summary = '<variable is not NSIndexSet>'
+ if isinstance(summary, basestring):
+ return summary
+ else:
+ summary = str(summary) + (' indexes' if summary != 1 else ' index')
+ return summary
+ return 'Summary Unavailable'
+
+
+def __lldb_init_module(debugger, dict):
+ debugger.HandleCommand(
+ "type summary add -F NSIndexSet.NSIndexSet_SummaryProvider NSIndexSet NSMutableIndexSet")
diff --git a/examples/summaries/cocoa/NSMachPort.py b/examples/summaries/cocoa/NSMachPort.py
index 554d2ca7785a..6eea6ca66816 100644
--- a/examples/summaries/cocoa/NSMachPort.py
+++ b/examples/summaries/cocoa/NSMachPort.py
@@ -22,102 +22,120 @@ statistics.add_metric('code_notrun')
# despite the similary to synthetic children providers, these classes are not
# trying to provide anything but the port number of an NSMachPort, so they need not
# obey the interface specification for synthetic children providers
+
+
class NSMachPortKnown_SummaryProvider:
- def adjust_for_architecture(self):
- pass
-
- def __init__(self, valobj, params):
- logger = lldb.formatters.Logger.Logger()
- self.valobj = valobj;
- self.sys_params = params
- if not(self.sys_params.types_cache.NSUInteger):
- if self.sys_params.is_64_bit:
- self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong)
- else:
- self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt)
- self.update();
-
- def update(self):
- logger = lldb.formatters.Logger.Logger()
- self.adjust_for_architecture();
-
- # one pointer is the ISA
- # then we have one other internal pointer, plus
- # 4 bytes worth of flags. hence, these values
- def offset(self):
- logger = lldb.formatters.Logger.Logger()
- if self.sys_params.is_64_bit:
- return 20
- else:
- return 12
-
- def port(self):
- logger = lldb.formatters.Logger.Logger()
- vport = self.valobj.CreateChildAtOffset("port",
- self.offset(),
- self.sys_params.types_cache.NSUInteger)
- return vport.GetValueAsUnsigned(0)
+
+ def adjust_for_architecture(self):
+ pass
+
+ def __init__(self, valobj, params):
+ logger = lldb.formatters.Logger.Logger()
+ self.valobj = valobj
+ self.sys_params = params
+ if not(self.sys_params.types_cache.NSUInteger):
+ if self.sys_params.is_64_bit:
+ self.sys_params.types_cache.NSUInteger = self.valobj.GetType(
+ ).GetBasicType(lldb.eBasicTypeUnsignedLong)
+ else:
+ self.sys_params.types_cache.NSUInteger = self.valobj.GetType(
+ ).GetBasicType(lldb.eBasicTypeUnsignedInt)
+ self.update()
+
+ def update(self):
+ logger = lldb.formatters.Logger.Logger()
+ self.adjust_for_architecture()
+
+ # one pointer is the ISA
+ # then we have one other internal pointer, plus
+ # 4 bytes worth of flags. hence, these values
+ def offset(self):
+ logger = lldb.formatters.Logger.Logger()
+ if self.sys_params.is_64_bit:
+ return 20
+ else:
+ return 12
+
+ def port(self):
+ logger = lldb.formatters.Logger.Logger()
+ vport = self.valobj.CreateChildAtOffset(
+ "port", self.offset(), self.sys_params.types_cache.NSUInteger)
+ return vport.GetValueAsUnsigned(0)
class NSMachPortUnknown_SummaryProvider:
- def adjust_for_architecture(self):
- pass
- def __init__(self, valobj, params):
- logger = lldb.formatters.Logger.Logger()
- self.valobj = valobj;
- self.sys_params = params
- self.update();
+ def adjust_for_architecture(self):
+ pass
+
+ def __init__(self, valobj, params):
+ logger = lldb.formatters.Logger.Logger()
+ self.valobj = valobj
+ self.sys_params = params
+ self.update()
- def update(self):
- logger = lldb.formatters.Logger.Logger()
- self.adjust_for_architecture();
+ def update(self):
+ logger = lldb.formatters.Logger.Logger()
+ self.adjust_for_architecture()
- def port(self):
- logger = lldb.formatters.Logger.Logger()
- stream = lldb.SBStream()
- self.valobj.GetExpressionPath(stream)
- num_children_vo = self.valobj.CreateValueFromExpression("port","(int)[" + stream.GetData() + " machPort]")
- if num_children_vo.IsValid():
- return num_children_vo.GetValueAsUnsigned(0)
- return '<variable is not NSMachPort>'
+ def port(self):
+ logger = lldb.formatters.Logger.Logger()
+ stream = lldb.SBStream()
+ self.valobj.GetExpressionPath(stream)
+ num_children_vo = self.valobj.CreateValueFromExpression(
+ "port", "(int)[" + stream.GetData() + " machPort]")
+ if num_children_vo.IsValid():
+ return num_children_vo.GetValueAsUnsigned(0)
+ return '<variable is not NSMachPort>'
def GetSummary_Impl(valobj):
- logger = lldb.formatters.Logger.Logger()
- global statistics
- class_data,wrapper =lldb.runtime.objc.objc_runtime.Utilities.prepare_class_detection(valobj,statistics)
- if wrapper:
- return wrapper
-
- name_string = class_data.class_name()
- logger >> "class name is: " + str(name_string)
-
- if name_string == 'NSMachPort':
- wrapper = NSMachPortKnown_SummaryProvider(valobj, class_data.sys_params)
- statistics.metric_hit('code_notrun',valobj)
- else:
- wrapper = NSMachPortUnknown_SummaryProvider(valobj, class_data.sys_params)
- statistics.metric_hit('unknown_class',valobj.GetName() + " seen as " + name_string)
- return wrapper;
-
-def NSMachPort_SummaryProvider (valobj,dict):
- logger = lldb.formatters.Logger.Logger()
- provider = GetSummary_Impl(valobj);
- if provider != None:
- if isinstance(provider,lldb.runtime.objc.objc_runtime.SpecialSituation_Description):
- return provider.message()
- try:
- summary = provider.port();
- except:
- summary = None
- logger >> "got summary " + str(summary)
- if summary == None:
- summary = '<variable is not NSMachPort>'
- if isinstance(summary, basestring):
- return summay
- return 'mach port: ' + str(summary)
- return 'Summary Unavailable'
-
-def __lldb_init_module(debugger,dict):
- debugger.HandleCommand("type summary add -F NSMachPort.NSMachPort_SummaryProvider NSMachPort")
+ logger = lldb.formatters.Logger.Logger()
+ global statistics
+ class_data, wrapper = lldb.runtime.objc.objc_runtime.Utilities.prepare_class_detection(
+ valobj, statistics)
+ if wrapper:
+ return wrapper
+
+ name_string = class_data.class_name()
+ logger >> "class name is: " + str(name_string)
+
+ if name_string == 'NSMachPort':
+ wrapper = NSMachPortKnown_SummaryProvider(
+ valobj, class_data.sys_params)
+ statistics.metric_hit('code_notrun', valobj)
+ else:
+ wrapper = NSMachPortUnknown_SummaryProvider(
+ valobj, class_data.sys_params)
+ statistics.metric_hit(
+ 'unknown_class',
+ valobj.GetName() +
+ " seen as " +
+ name_string)
+ return wrapper
+
+
+def NSMachPort_SummaryProvider(valobj, dict):
+ logger = lldb.formatters.Logger.Logger()
+ provider = GetSummary_Impl(valobj)
+ if provider is not None:
+ if isinstance(
+ provider,
+ lldb.runtime.objc.objc_runtime.SpecialSituation_Description):
+ return provider.message()
+ try:
+ summary = provider.port()
+ except:
+ summary = None
+ logger >> "got summary " + str(summary)
+ if summary is None:
+ summary = '<variable is not NSMachPort>'
+ if isinstance(summary, basestring):
+ return summay
+ return 'mach port: ' + str(summary)
+ return 'Summary Unavailable'
+
+
+def __lldb_init_module(debugger, dict):
+ debugger.HandleCommand(
+ "type summary add -F NSMachPort.NSMachPort_SummaryProvider NSMachPort")
diff --git a/examples/summaries/cocoa/NSNotification.py b/examples/summaries/cocoa/NSNotification.py
index 33c20065346f..319d7561e552 100644
--- a/examples/summaries/cocoa/NSNotification.py
+++ b/examples/summaries/cocoa/NSNotification.py
@@ -19,92 +19,108 @@ statistics.add_metric('invalid_pointer')
statistics.add_metric('unknown_class')
statistics.add_metric('code_notrun')
+
class NSConcreteNotification_SummaryProvider:
- def adjust_for_architecture(self):
- pass
-
- def __init__(self, valobj, params):
- logger = lldb.formatters.Logger.Logger()
- self.valobj = valobj;
- self.sys_params = params
- if not (self.sys_params.types_cache.id):
- self.sys_params.types_cache.id = self.valobj.GetType().GetBasicType(lldb.eBasicTypeObjCID)
- self.update();
-
- def update(self):
- logger = lldb.formatters.Logger.Logger()
- self.adjust_for_architecture();
-
- # skip the ISA and go to the name pointer
- def offset(self):
- logger = lldb.formatters.Logger.Logger()
- return self.sys_params.pointer_size
-
- def name(self):
- logger = lldb.formatters.Logger.Logger()
- string_ptr = self.valobj.CreateChildAtOffset("name",
- self.offset(),
- self.sys_params.types_cache.id)
- return CFString.CFString_SummaryProvider(string_ptr,None)
+
+ def adjust_for_architecture(self):
+ pass
+
+ def __init__(self, valobj, params):
+ logger = lldb.formatters.Logger.Logger()
+ self.valobj = valobj
+ self.sys_params = params
+ if not (self.sys_params.types_cache.id):
+ self.sys_params.types_cache.id = self.valobj.GetType(
+ ).GetBasicType(lldb.eBasicTypeObjCID)
+ self.update()
+
+ def update(self):
+ logger = lldb.formatters.Logger.Logger()
+ self.adjust_for_architecture()
+
+ # skip the ISA and go to the name pointer
+ def offset(self):
+ logger = lldb.formatters.Logger.Logger()
+ return self.sys_params.pointer_size
+
+ def name(self):
+ logger = lldb.formatters.Logger.Logger()
+ string_ptr = self.valobj.CreateChildAtOffset(
+ "name", self.offset(), self.sys_params.types_cache.id)
+ return CFString.CFString_SummaryProvider(string_ptr, None)
class NSNotificationUnknown_SummaryProvider:
- def adjust_for_architecture(self):
- pass
- def __init__(self, valobj, params):
- logger = lldb.formatters.Logger.Logger()
- self.valobj = valobj;
- self.sys_params = params
- self.update()
+ def adjust_for_architecture(self):
+ pass
+
+ def __init__(self, valobj, params):
+ logger = lldb.formatters.Logger.Logger()
+ self.valobj = valobj
+ self.sys_params = params
+ self.update()
- def update(self):
- logger = lldb.formatters.Logger.Logger()
- self.adjust_for_architecture();
+ def update(self):
+ logger = lldb.formatters.Logger.Logger()
+ self.adjust_for_architecture()
- def name(self):
- logger = lldb.formatters.Logger.Logger()
- stream = lldb.SBStream()
- self.valobj.GetExpressionPath(stream)
- name_vo = self.valobj.CreateValueFromExpression("name","(NSString*)[" + stream.GetData() + " name]")
- if name_vo.IsValid():
- return CFString.CFString_SummaryProvider(name_vo,None)
- return '<variable is not NSNotification>'
+ def name(self):
+ logger = lldb.formatters.Logger.Logger()
+ stream = lldb.SBStream()
+ self.valobj.GetExpressionPath(stream)
+ name_vo = self.valobj.CreateValueFromExpression(
+ "name", "(NSString*)[" + stream.GetData() + " name]")
+ if name_vo.IsValid():
+ return CFString.CFString_SummaryProvider(name_vo, None)
+ return '<variable is not NSNotification>'
def GetSummary_Impl(valobj):
- logger = lldb.formatters.Logger.Logger()
- global statistics
- class_data,wrapper =lldb.runtime.objc.objc_runtime.Utilities.prepare_class_detection(valobj,statistics)
- if wrapper:
- return wrapper
-
- name_string = class_data.class_name()
- logger >> "class name is: " + str(name_string)
-
- if name_string == 'NSConcreteNotification':
- wrapper = NSConcreteNotification_SummaryProvider(valobj, class_data.sys_params)
- statistics.metric_hit('code_notrun',valobj)
- else:
- wrapper = NSNotificationUnknown_SummaryProvider(valobj, class_data.sys_params)
- statistics.metric_hit('unknown_class',valobj.GetName() + " seen as " + name_string)
- return wrapper;
-
-def NSNotification_SummaryProvider (valobj,dict):
- logger = lldb.formatters.Logger.Logger()
- provider = GetSummary_Impl(valobj);
- if provider != None:
- if isinstance(provider,lldb.runtime.objc.objc_runtime.SpecialSituation_Description):
- return provider.message()
- try:
- summary = provider.name();
- except:
- summary = None
- logger >> "got summary " + str(summary)
- if summary == None:
- summary = '<variable is not NSNotification>'
- return str(summary)
- return 'Summary Unavailable'
-
-def __lldb_init_module(debugger,dict):
- debugger.HandleCommand("type summary add -F NSNotification.NSNotification_SummaryProvider NSNotification")
+ logger = lldb.formatters.Logger.Logger()
+ global statistics
+ class_data, wrapper = lldb.runtime.objc.objc_runtime.Utilities.prepare_class_detection(
+ valobj, statistics)
+ if wrapper:
+ return wrapper
+
+ name_string = class_data.class_name()
+ logger >> "class name is: " + str(name_string)
+
+ if name_string == 'NSConcreteNotification':
+ wrapper = NSConcreteNotification_SummaryProvider(
+ valobj, class_data.sys_params)
+ statistics.metric_hit('code_notrun', valobj)
+ else:
+ wrapper = NSNotificationUnknown_SummaryProvider(
+ valobj, class_data.sys_params)
+ statistics.metric_hit(
+ 'unknown_class',
+ valobj.GetName() +
+ " seen as " +
+ name_string)
+ return wrapper
+
+
+def NSNotification_SummaryProvider(valobj, dict):
+ logger = lldb.formatters.Logger.Logger()
+ provider = GetSummary_Impl(valobj)
+ if provider is not None:
+ if isinstance(
+ provider,
+ lldb.runtime.objc.objc_runtime.SpecialSituation_Description):
+ return provider.message()
+ try:
+ summary = provider.name()
+ except:
+ summary = None
+ logger >> "got summary " + str(summary)
+ if summary is None:
+ summary = '<variable is not NSNotification>'
+ return str(summary)
+ return 'Summary Unavailable'
+
+
+def __lldb_init_module(debugger, dict):
+ debugger.HandleCommand(
+ "type summary add -F NSNotification.NSNotification_SummaryProvider NSNotification")
diff --git a/examples/summaries/cocoa/NSNumber.py b/examples/summaries/cocoa/NSNumber.py
index 7edd33803f9c..3225ea95ded6 100644
--- a/examples/summaries/cocoa/NSNumber.py
+++ b/examples/summaries/cocoa/NSNumber.py
@@ -23,213 +23,247 @@ statistics.add_metric('code_notrun')
# despite the similary to synthetic children providers, these classes are not
# trying to provide anything but the port number of an NSNumber, so they need not
# obey the interface specification for synthetic children providers
+
+
class NSTaggedNumber_SummaryProvider:
- def adjust_for_architecture(self):
- pass
-
- def __init__(self, valobj, info_bits, data, params):
- logger = lldb.formatters.Logger.Logger()
- self.valobj = valobj;
- self.sys_params = params
- self.info_bits = info_bits
- self.data = data
- self.update();
-
- def update(self):
- logger = lldb.formatters.Logger.Logger()
- self.adjust_for_architecture();
-
- def value(self):
- logger = lldb.formatters.Logger.Logger()
- # in spite of the plenty of types made available by the public NSNumber API
- # only a bunch of these are actually used in the internal implementation
- # unfortunately, the original type information appears to be lost
- # so we try to at least recover the proper magnitude of the data
- if self.info_bits == 0:
- return '(char)' + str(ord(ctypes.c_char(chr(self.data % 256)).value))
- if self.info_bits == 4:
- return '(short)' + str(ctypes.c_short(self.data % (256*256)).value)
- if self.info_bits == 8:
- return '(int)' + str(ctypes.c_int(self.data % (256*256*256*256)).value)
- if self.info_bits == 12:
- return '(long)' + str(ctypes.c_long(self.data).value)
- else:
- return 'unexpected value:(info=' + str(self.info_bits) + ", value = " + str(self.data) + ')'
+
+ def adjust_for_architecture(self):
+ pass
+
+ def __init__(self, valobj, info_bits, data, params):
+ logger = lldb.formatters.Logger.Logger()
+ self.valobj = valobj
+ self.sys_params = params
+ self.info_bits = info_bits
+ self.data = data
+ self.update()
+
+ def update(self):
+ logger = lldb.formatters.Logger.Logger()
+ self.adjust_for_architecture()
+
+ def value(self):
+ logger = lldb.formatters.Logger.Logger()
+ # in spite of the plenty of types made available by the public NSNumber API
+ # only a bunch of these are actually used in the internal implementation
+ # unfortunately, the original type information appears to be lost
+ # so we try to at least recover the proper magnitude of the data
+ if self.info_bits == 0:
+ return '(char)' + \
+ str(ord(ctypes.c_char(chr(self.data % 256)).value))
+ if self.info_bits == 4:
+ return '(short)' + \
+ str(ctypes.c_short(self.data % (256 * 256)).value)
+ if self.info_bits == 8:
+ return '(int)' + str(ctypes.c_int(self.data %
+ (256 * 256 * 256 * 256)).value)
+ if self.info_bits == 12:
+ return '(long)' + str(ctypes.c_long(self.data).value)
+ else:
+ return 'unexpected value:(info=' + str(self.info_bits) + \
+ ", value = " + str(self.data) + ')'
class NSUntaggedNumber_SummaryProvider:
- def adjust_for_architecture(self):
- pass
-
- def __init__(self, valobj, params):
- logger = lldb.formatters.Logger.Logger()
- self.valobj = valobj;
- self.sys_params = params
- if not(self.sys_params.types_cache.char):
- self.sys_params.types_cache.char = self.valobj.GetType().GetBasicType(lldb.eBasicTypeChar)
- if not(self.sys_params.types_cache.short):
- self.sys_params.types_cache.short = self.valobj.GetType().GetBasicType(lldb.eBasicTypeShort)
- if not(self.sys_params.types_cache.ushort):
- self.sys_params.types_cache.ushort = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedShort)
- if not(self.sys_params.types_cache.int):
- self.sys_params.types_cache.int = self.valobj.GetType().GetBasicType(lldb.eBasicTypeInt)
- if not(self.sys_params.types_cache.long):
- self.sys_params.types_cache.long = self.valobj.GetType().GetBasicType(lldb.eBasicTypeLong)
- if not(self.sys_params.types_cache.ulong):
- self.sys_params.types_cache.ulong = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong)
- if not(self.sys_params.types_cache.longlong):
- self.sys_params.types_cache.longlong = self.valobj.GetType().GetBasicType(lldb.eBasicTypeLongLong)
- if not(self.sys_params.types_cache.ulonglong):
- self.sys_params.types_cache.ulonglong = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLongLong)
- if not(self.sys_params.types_cache.float):
- self.sys_params.types_cache.float = self.valobj.GetType().GetBasicType(lldb.eBasicTypeFloat)
- if not(self.sys_params.types_cache.double):
- self.sys_params.types_cache.double = self.valobj.GetType().GetBasicType(lldb.eBasicTypeDouble)
- self.update();
-
- def update(self):
- logger = lldb.formatters.Logger.Logger()
- self.adjust_for_architecture();
-
- def value(self):
- logger = lldb.formatters.Logger.Logger()
- global statistics
- # we need to skip the ISA, then the next byte tells us what to read
- # we then skip one other full pointer worth of data and then fetch the contents
- # if we are fetching an int64 value, one more pointer must be skipped to get at our data
- data_type_vo = self.valobj.CreateChildAtOffset("dt",
- self.sys_params.pointer_size,
- self.sys_params.types_cache.char)
- data_type = ((data_type_vo.GetValueAsUnsigned(0) % 256) & 0x1F)
- data_offset = 2 * self.sys_params.pointer_size
- if data_type == 0B00001:
- data_vo = self.valobj.CreateChildAtOffset("data",
- data_offset,
- self.sys_params.types_cache.char)
- statistics.metric_hit('code_notrun',self.valobj)
- return '(char)' + str(ord(ctypes.c_char(chr(data_vo.GetValueAsUnsigned(0))).value))
- elif data_type == 0B0010:
- data_vo = self.valobj.CreateChildAtOffset("data",
- data_offset,
- self.sys_params.types_cache.short)
- statistics.metric_hit('code_notrun',self.valobj)
- return '(short)' + str(ctypes.c_short(data_vo.GetValueAsUnsigned(0) % (256*256)).value)
- # IF tagged pointers are possible on 32bit+v2 runtime
- # (of which the only existing instance should be iOS)
- # then values of this type might be tagged
- elif data_type == 0B0011:
- data_vo = self.valobj.CreateChildAtOffset("data",
- data_offset,
- self.sys_params.types_cache.int)
- statistics.metric_hit('code_notrun',self.valobj)
- return '(int)' + str(ctypes.c_int(data_vo.GetValueAsUnsigned(0)% (256*256*256*256)).value)
- # apparently, on is_64_bit architectures, these are the only values that will ever
- # be represented by a non tagged pointers
- elif data_type == 0B10001:
- data_offset = data_offset + 8 # 8 is needed even if we are on 32bit
- data_vo = self.valobj.CreateChildAtOffset("data",
- data_offset,
- self.sys_params.types_cache.longlong)
- statistics.metric_hit('code_notrun',self.valobj)
- return '(long)' + str(ctypes.c_long(data_vo.GetValueAsUnsigned(0)).value)
- elif data_type == 0B0100:
- if self.sys_params.is_64_bit:
- data_offset = data_offset + self.sys_params.pointer_size
- data_vo = self.valobj.CreateChildAtOffset("data",
- data_offset,
- self.sys_params.types_cache.longlong)
- statistics.metric_hit('code_notrun',self.valobj)
- return '(long)' + str(ctypes.c_long(data_vo.GetValueAsUnsigned(0)).value)
- elif data_type == 0B0101:
- data_vo = self.valobj.CreateChildAtOffset("data",
- data_offset,
- self.sys_params.types_cache.longlong)
- data_plain = int(str(data_vo.GetValueAsUnsigned(0) & 0x00000000FFFFFFFF))
- packed = struct.pack('I', data_plain)
- data_float = struct.unpack('f', packed)[0]
- statistics.metric_hit('code_notrun',self.valobj)
- return '(float)' + str(data_float)
- elif data_type == 0B0110:
- data_vo = self.valobj.CreateChildAtOffset("data",
- data_offset,
- self.sys_params.types_cache.longlong)
- data_plain = data_vo.GetValueAsUnsigned(0)
- data_double = struct.unpack('d', struct.pack('Q', data_plain))[0]
- statistics.metric_hit('code_notrun',self.valobj)
- return '(double)' + str(data_double)
- statistics.metric_hit('unknown_class',str(valobj.GetName()) + " had unknown data_type " + str(data_type))
- return 'unexpected: dt = ' + str(data_type)
+
+ def adjust_for_architecture(self):
+ pass
+
+ def __init__(self, valobj, params):
+ logger = lldb.formatters.Logger.Logger()
+ self.valobj = valobj
+ self.sys_params = params
+ if not(self.sys_params.types_cache.char):
+ self.sys_params.types_cache.char = self.valobj.GetType(
+ ).GetBasicType(lldb.eBasicTypeChar)
+ if not(self.sys_params.types_cache.short):
+ self.sys_params.types_cache.short = self.valobj.GetType(
+ ).GetBasicType(lldb.eBasicTypeShort)
+ if not(self.sys_params.types_cache.ushort):
+ self.sys_params.types_cache.ushort = self.valobj.GetType(
+ ).GetBasicType(lldb.eBasicTypeUnsignedShort)
+ if not(self.sys_params.types_cache.int):
+ self.sys_params.types_cache.int = self.valobj.GetType().GetBasicType(lldb.eBasicTypeInt)
+ if not(self.sys_params.types_cache.long):
+ self.sys_params.types_cache.long = self.valobj.GetType(
+ ).GetBasicType(lldb.eBasicTypeLong)
+ if not(self.sys_params.types_cache.ulong):
+ self.sys_params.types_cache.ulong = self.valobj.GetType(
+ ).GetBasicType(lldb.eBasicTypeUnsignedLong)
+ if not(self.sys_params.types_cache.longlong):
+ self.sys_params.types_cache.longlong = self.valobj.GetType(
+ ).GetBasicType(lldb.eBasicTypeLongLong)
+ if not(self.sys_params.types_cache.ulonglong):
+ self.sys_params.types_cache.ulonglong = self.valobj.GetType(
+ ).GetBasicType(lldb.eBasicTypeUnsignedLongLong)
+ if not(self.sys_params.types_cache.float):
+ self.sys_params.types_cache.float = self.valobj.GetType(
+ ).GetBasicType(lldb.eBasicTypeFloat)
+ if not(self.sys_params.types_cache.double):
+ self.sys_params.types_cache.double = self.valobj.GetType(
+ ).GetBasicType(lldb.eBasicTypeDouble)
+ self.update()
+
+ def update(self):
+ logger = lldb.formatters.Logger.Logger()
+ self.adjust_for_architecture()
+
+ def value(self):
+ logger = lldb.formatters.Logger.Logger()
+ global statistics
+ # we need to skip the ISA, then the next byte tells us what to read
+ # we then skip one other full pointer worth of data and then fetch the contents
+ # if we are fetching an int64 value, one more pointer must be skipped
+ # to get at our data
+ data_type_vo = self.valobj.CreateChildAtOffset(
+ "dt", self.sys_params.pointer_size, self.sys_params.types_cache.char)
+ data_type = ((data_type_vo.GetValueAsUnsigned(0) % 256) & 0x1F)
+ data_offset = 2 * self.sys_params.pointer_size
+ if data_type == 0B00001:
+ data_vo = self.valobj.CreateChildAtOffset(
+ "data", data_offset, self.sys_params.types_cache.char)
+ statistics.metric_hit('code_notrun', self.valobj)
+ return '(char)' + \
+ str(ord(ctypes.c_char(chr(data_vo.GetValueAsUnsigned(0))).value))
+ elif data_type == 0B0010:
+ data_vo = self.valobj.CreateChildAtOffset(
+ "data", data_offset, self.sys_params.types_cache.short)
+ statistics.metric_hit('code_notrun', self.valobj)
+ return '(short)' + str(
+ ctypes.c_short(
+ data_vo.GetValueAsUnsigned(0) %
+ (256 * 256)).value)
+ # IF tagged pointers are possible on 32bit+v2 runtime
+ # (of which the only existing instance should be iOS)
+ # then values of this type might be tagged
+ elif data_type == 0B0011:
+ data_vo = self.valobj.CreateChildAtOffset(
+ "data", data_offset, self.sys_params.types_cache.int)
+ statistics.metric_hit('code_notrun', self.valobj)
+ return '(int)' + str(ctypes.c_int(data_vo.GetValueAsUnsigned(0) %
+ (256 * 256 * 256 * 256)).value)
+ # apparently, on is_64_bit architectures, these are the only values that will ever
+ # be represented by a non tagged pointers
+ elif data_type == 0B10001:
+ data_offset = data_offset + 8 # 8 is needed even if we are on 32bit
+ data_vo = self.valobj.CreateChildAtOffset(
+ "data", data_offset, self.sys_params.types_cache.longlong)
+ statistics.metric_hit('code_notrun', self.valobj)
+ return '(long)' + \
+ str(ctypes.c_long(data_vo.GetValueAsUnsigned(0)).value)
+ elif data_type == 0B0100:
+ if self.sys_params.is_64_bit:
+ data_offset = data_offset + self.sys_params.pointer_size
+ data_vo = self.valobj.CreateChildAtOffset(
+ "data", data_offset, self.sys_params.types_cache.longlong)
+ statistics.metric_hit('code_notrun', self.valobj)
+ return '(long)' + \
+ str(ctypes.c_long(data_vo.GetValueAsUnsigned(0)).value)
+ elif data_type == 0B0101:
+ data_vo = self.valobj.CreateChildAtOffset(
+ "data", data_offset, self.sys_params.types_cache.longlong)
+ data_plain = int(
+ str(data_vo.GetValueAsUnsigned(0) & 0x00000000FFFFFFFF))
+ packed = struct.pack('I', data_plain)
+ data_float = struct.unpack('f', packed)[0]
+ statistics.metric_hit('code_notrun', self.valobj)
+ return '(float)' + str(data_float)
+ elif data_type == 0B0110:
+ data_vo = self.valobj.CreateChildAtOffset(
+ "data", data_offset, self.sys_params.types_cache.longlong)
+ data_plain = data_vo.GetValueAsUnsigned(0)
+ data_double = struct.unpack('d', struct.pack('Q', data_plain))[0]
+ statistics.metric_hit('code_notrun', self.valobj)
+ return '(double)' + str(data_double)
+ statistics.metric_hit(
+ 'unknown_class', str(
+ valobj.GetName()) + " had unknown data_type " + str(data_type))
+ return 'unexpected: dt = ' + str(data_type)
class NSUnknownNumber_SummaryProvider:
- def adjust_for_architecture(self):
- pass
-
- def __init__(self, valobj, params):
- logger = lldb.formatters.Logger.Logger()
- self.valobj = valobj;
- self.sys_params = params
- self.update();
-
- def update(self):
- logger = lldb.formatters.Logger.Logger()
- self.adjust_for_architecture();
-
- def value(self):
- logger = lldb.formatters.Logger.Logger()
- stream = lldb.SBStream()
- self.valobj.GetExpressionPath(stream)
- expr = "(NSString*)[" + stream.GetData() + " stringValue]"
- num_children_vo = self.valobj.CreateValueFromExpression("str",expr)
- if num_children_vo.IsValid():
- return num_children_vo.GetSummary()
- return '<variable is not NSNumber>'
+
+ def adjust_for_architecture(self):
+ pass
+
+ def __init__(self, valobj, params):
+ logger = lldb.formatters.Logger.Logger()
+ self.valobj = valobj
+ self.sys_params = params
+ self.update()
+
+ def update(self):
+ logger = lldb.formatters.Logger.Logger()
+ self.adjust_for_architecture()
+
+ def value(self):
+ logger = lldb.formatters.Logger.Logger()
+ stream = lldb.SBStream()
+ self.valobj.GetExpressionPath(stream)
+ expr = "(NSString*)[" + stream.GetData() + " stringValue]"
+ num_children_vo = self.valobj.CreateValueFromExpression("str", expr)
+ if num_children_vo.IsValid():
+ return num_children_vo.GetSummary()
+ return '<variable is not NSNumber>'
+
def GetSummary_Impl(valobj):
- logger = lldb.formatters.Logger.Logger()
- global statistics
- class_data,wrapper =lldb.runtime.objc.objc_runtime.Utilities.prepare_class_detection(valobj,statistics)
- if wrapper:
- return wrapper
-
- name_string = class_data.class_name()
- logger >> "class name is: " + str(name_string)
-
- if name_string == 'NSNumber' or name_string == '__NSCFNumber':
- if class_data.is_tagged():
- wrapper = NSTaggedNumber_SummaryProvider(valobj,class_data.info_bits(),class_data.value(), class_data.sys_params)
- statistics.metric_hit('code_notrun',valobj)
- else:
- # the wrapper might be unable to decipher what is into the NSNumber
- # and then have to run code on it
- wrapper = NSUntaggedNumber_SummaryProvider(valobj, class_data.sys_params)
- else:
- wrapper = NSUnknownNumber_SummaryProvider(valobj, class_data.sys_params)
- statistics.metric_hit('unknown_class',valobj.GetName() + " seen as " + name_string)
- return wrapper;
-
-
-def NSNumber_SummaryProvider (valobj,dict):
- logger = lldb.formatters.Logger.Logger()
- provider = GetSummary_Impl(valobj);
- if provider != None:
- if isinstance(provider,lldb.runtime.objc.objc_runtime.SpecialSituation_Description):
- return provider.message()
- try:
- summary = provider.value();
- except Exception as foo:
- print foo
-# except:
- summary = None
- logger >> "got summary " + str(summary)
- if summary == None:
- summary = '<variable is not NSNumber>'
- return str(summary)
- return 'Summary Unavailable'
+ logger = lldb.formatters.Logger.Logger()
+ global statistics
+ class_data, wrapper = lldb.runtime.objc.objc_runtime.Utilities.prepare_class_detection(
+ valobj, statistics)
+ if wrapper:
+ return wrapper
+
+ name_string = class_data.class_name()
+ logger >> "class name is: " + str(name_string)
+
+ if name_string == 'NSNumber' or name_string == '__NSCFNumber':
+ if class_data.is_tagged():
+ wrapper = NSTaggedNumber_SummaryProvider(
+ valobj, class_data.info_bits(), class_data.value(), class_data.sys_params)
+ statistics.metric_hit('code_notrun', valobj)
+ else:
+ # the wrapper might be unable to decipher what is into the NSNumber
+ # and then have to run code on it
+ wrapper = NSUntaggedNumber_SummaryProvider(
+ valobj, class_data.sys_params)
+ else:
+ wrapper = NSUnknownNumber_SummaryProvider(
+ valobj, class_data.sys_params)
+ statistics.metric_hit(
+ 'unknown_class',
+ valobj.GetName() +
+ " seen as " +
+ name_string)
+ return wrapper
-def __lldb_init_module(debugger,dict):
- debugger.HandleCommand("type summary add -F NSNumber.NSNumber_SummaryProvider NSNumber")
- debugger.HandleCommand("type summary add -F NSNumber.NSNumber_SummaryProvider __NSCFBoolean")
- debugger.HandleCommand("type summary add -F NSNumber.NSNumber_SummaryProvider __NSCFNumber")
+def NSNumber_SummaryProvider(valobj, dict):
+ logger = lldb.formatters.Logger.Logger()
+ provider = GetSummary_Impl(valobj)
+ if provider is not None:
+ if isinstance(
+ provider,
+ lldb.runtime.objc.objc_runtime.SpecialSituation_Description):
+ return provider.message()
+ try:
+ summary = provider.value()
+ except Exception as foo:
+ print foo
+# except:
+ summary = None
+ logger >> "got summary " + str(summary)
+ if summary is None:
+ summary = '<variable is not NSNumber>'
+ return str(summary)
+ return 'Summary Unavailable'
+
+def __lldb_init_module(debugger, dict):
+ debugger.HandleCommand(
+ "type summary add -F NSNumber.NSNumber_SummaryProvider NSNumber")
+ debugger.HandleCommand(
+ "type summary add -F NSNumber.NSNumber_SummaryProvider __NSCFBoolean")
+ debugger.HandleCommand(
+ "type summary add -F NSNumber.NSNumber_SummaryProvider __NSCFNumber")
diff --git a/examples/summaries/cocoa/NSSet.py b/examples/summaries/cocoa/NSSet.py
index 71665dbc9f79..a6c7768671aa 100644
--- a/examples/summaries/cocoa/NSSet.py
+++ b/examples/summaries/cocoa/NSSet.py
@@ -22,242 +22,268 @@ statistics.add_metric('code_notrun')
# despite the similary to synthetic children providers, these classes are not
# trying to provide anything but the port number of an NSMachPort, so they need not
# obey the interface specification for synthetic children providers
+
+
class NSCFSet_SummaryProvider:
- def adjust_for_architecture(self):
- pass
-
- def __init__(self, valobj, params):
- logger = lldb.formatters.Logger.Logger()
- self.valobj = valobj;
- self.sys_params = params
- if not(self.sys_params.types_cache.NSUInteger):
- if self.sys_params.is_64_bit:
- self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong)
- else:
- self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt)
- self.update();
-
- def update(self):
- logger = lldb.formatters.Logger.Logger()
- self.adjust_for_architecture();
-
- # one pointer is the ISA
- # then we have one other internal pointer, plus
- # 4 bytes worth of flags. hence, these values
- def offset(self):
- logger = lldb.formatters.Logger.Logger()
- if self.sys_params.is_64_bit:
- return 20
- else:
- return 12
-
- def count(self):
- logger = lldb.formatters.Logger.Logger()
- vcount = self.valobj.CreateChildAtOffset("count",
- self.offset(),
- self.sys_params.types_cache.NSUInteger)
- return vcount.GetValueAsUnsigned(0)
+
+ def adjust_for_architecture(self):
+ pass
+
+ def __init__(self, valobj, params):
+ logger = lldb.formatters.Logger.Logger()
+ self.valobj = valobj
+ self.sys_params = params
+ if not(self.sys_params.types_cache.NSUInteger):
+ if self.sys_params.is_64_bit:
+ self.sys_params.types_cache.NSUInteger = self.valobj.GetType(
+ ).GetBasicType(lldb.eBasicTypeUnsignedLong)
+ else:
+ self.sys_params.types_cache.NSUInteger = self.valobj.GetType(
+ ).GetBasicType(lldb.eBasicTypeUnsignedInt)
+ self.update()
+
+ def update(self):
+ logger = lldb.formatters.Logger.Logger()
+ self.adjust_for_architecture()
+
+ # one pointer is the ISA
+ # then we have one other internal pointer, plus
+ # 4 bytes worth of flags. hence, these values
+ def offset(self):
+ logger = lldb.formatters.Logger.Logger()
+ if self.sys_params.is_64_bit:
+ return 20
+ else:
+ return 12
+
+ def count(self):
+ logger = lldb.formatters.Logger.Logger()
+ vcount = self.valobj.CreateChildAtOffset(
+ "count", self.offset(), self.sys_params.types_cache.NSUInteger)
+ return vcount.GetValueAsUnsigned(0)
class NSSetUnknown_SummaryProvider:
- def adjust_for_architecture(self):
- pass
-
- def __init__(self, valobj, params):
- logger = lldb.formatters.Logger.Logger()
- self.valobj = valobj;
- self.sys_params = params
- self.update();
-
- def update(self):
- logger = lldb.formatters.Logger.Logger()
- self.adjust_for_architecture();
-
- def count(self):
- logger = lldb.formatters.Logger.Logger()
- stream = lldb.SBStream()
- self.valobj.GetExpressionPath(stream)
- expr = "(int)[" + stream.GetData() + " count]"
- num_children_vo = self.valobj.CreateValueFromExpression("count",expr)
- if num_children_vo.IsValid():
- return num_children_vo.GetValueAsUnsigned(0)
- return '<variable is not NSSet>'
+
+ def adjust_for_architecture(self):
+ pass
+
+ def __init__(self, valobj, params):
+ logger = lldb.formatters.Logger.Logger()
+ self.valobj = valobj
+ self.sys_params = params
+ self.update()
+
+ def update(self):
+ logger = lldb.formatters.Logger.Logger()
+ self.adjust_for_architecture()
+
+ def count(self):
+ logger = lldb.formatters.Logger.Logger()
+ stream = lldb.SBStream()
+ self.valobj.GetExpressionPath(stream)
+ expr = "(int)[" + stream.GetData() + " count]"
+ num_children_vo = self.valobj.CreateValueFromExpression("count", expr)
+ if num_children_vo.IsValid():
+ return num_children_vo.GetValueAsUnsigned(0)
+ return '<variable is not NSSet>'
+
class NSSetI_SummaryProvider:
- def adjust_for_architecture(self):
- pass
-
- def __init__(self, valobj, params):
- logger = lldb.formatters.Logger.Logger()
- self.valobj = valobj;
- self.sys_params = params
- if not(self.sys_params.types_cache.NSUInteger):
- if self.sys_params.is_64_bit:
- self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong)
- else:
- self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt)
- self.update();
-
- def update(self):
- logger = lldb.formatters.Logger.Logger()
- self.adjust_for_architecture();
-
- # we just need to skip the ISA and the count immediately follows
- def offset(self):
- logger = lldb.formatters.Logger.Logger()
- return self.sys_params.pointer_size
-
- def count(self):
- logger = lldb.formatters.Logger.Logger()
- num_children_vo = self.valobj.CreateChildAtOffset("count",
- self.offset(),
- self.sys_params.types_cache.NSUInteger)
- value = num_children_vo.GetValueAsUnsigned(0)
- if value != None:
- # the MSB on immutable sets seems to be taken by some other data
- # not sure if it is a bug or some weird sort of feature, but masking it out
- # gets the count right (unless, of course, someone's dictionaries grow
- # too large - but I have not tested this)
- if self.sys_params.is_64_bit:
- value = value & ~0xFF00000000000000
- else:
- value = value & ~0xFF000000
- return value
+
+ def adjust_for_architecture(self):
+ pass
+
+ def __init__(self, valobj, params):
+ logger = lldb.formatters.Logger.Logger()
+ self.valobj = valobj
+ self.sys_params = params
+ if not(self.sys_params.types_cache.NSUInteger):
+ if self.sys_params.is_64_bit:
+ self.sys_params.types_cache.NSUInteger = self.valobj.GetType(
+ ).GetBasicType(lldb.eBasicTypeUnsignedLong)
+ else:
+ self.sys_params.types_cache.NSUInteger = self.valobj.GetType(
+ ).GetBasicType(lldb.eBasicTypeUnsignedInt)
+ self.update()
+
+ def update(self):
+ logger = lldb.formatters.Logger.Logger()
+ self.adjust_for_architecture()
+
+ # we just need to skip the ISA and the count immediately follows
+ def offset(self):
+ logger = lldb.formatters.Logger.Logger()
+ return self.sys_params.pointer_size
+
+ def count(self):
+ logger = lldb.formatters.Logger.Logger()
+ num_children_vo = self.valobj.CreateChildAtOffset(
+ "count", self.offset(), self.sys_params.types_cache.NSUInteger)
+ value = num_children_vo.GetValueAsUnsigned(0)
+ if value is not None:
+ # the MSB on immutable sets seems to be taken by some other data
+ # not sure if it is a bug or some weird sort of feature, but masking it out
+ # gets the count right (unless, of course, someone's dictionaries grow
+ # too large - but I have not tested this)
+ if self.sys_params.is_64_bit:
+ value = value & ~0xFF00000000000000
+ else:
+ value = value & ~0xFF000000
+ return value
+
class NSSetM_SummaryProvider:
- def adjust_for_architecture(self):
- pass
-
- def __init__(self, valobj, params):
- logger = lldb.formatters.Logger.Logger()
- self.valobj = valobj;
- self.sys_params = params
- if not(self.sys_params.types_cache.NSUInteger):
- if self.sys_params.is_64_bit:
- self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong)
- else:
- self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt)
- self.update();
-
- def update(self):
- logger = lldb.formatters.Logger.Logger()
- self.adjust_for_architecture();
-
- # we just need to skip the ISA and the count immediately follows
- def offset(self):
- logger = lldb.formatters.Logger.Logger()
- return self.sys_params.pointer_size
-
- def count(self):
- logger = lldb.formatters.Logger.Logger()
- num_children_vo = self.valobj.CreateChildAtOffset("count",
- self.offset(),
- self.sys_params.types_cache.NSUInteger)
- return num_children_vo.GetValueAsUnsigned(0)
+
+ def adjust_for_architecture(self):
+ pass
+
+ def __init__(self, valobj, params):
+ logger = lldb.formatters.Logger.Logger()
+ self.valobj = valobj
+ self.sys_params = params
+ if not(self.sys_params.types_cache.NSUInteger):
+ if self.sys_params.is_64_bit:
+ self.sys_params.types_cache.NSUInteger = self.valobj.GetType(
+ ).GetBasicType(lldb.eBasicTypeUnsignedLong)
+ else:
+ self.sys_params.types_cache.NSUInteger = self.valobj.GetType(
+ ).GetBasicType(lldb.eBasicTypeUnsignedInt)
+ self.update()
+
+ def update(self):
+ logger = lldb.formatters.Logger.Logger()
+ self.adjust_for_architecture()
+
+ # we just need to skip the ISA and the count immediately follows
+ def offset(self):
+ logger = lldb.formatters.Logger.Logger()
+ return self.sys_params.pointer_size
+
+ def count(self):
+ logger = lldb.formatters.Logger.Logger()
+ num_children_vo = self.valobj.CreateChildAtOffset(
+ "count", self.offset(), self.sys_params.types_cache.NSUInteger)
+ return num_children_vo.GetValueAsUnsigned(0)
class NSCountedSet_SummaryProvider:
- def adjust_for_architecture(self):
- pass
-
- def __init__(self, valobj, params):
- logger = lldb.formatters.Logger.Logger()
- self.valobj = valobj;
- self.sys_params = params
- if not (self.sys_params.types_cache.voidptr):
- self.sys_params.types_cache.voidptr = self.valobj.GetType().GetBasicType(lldb.eBasicTypeVoid).GetPointerType()
- self.update();
-
- def update(self):
- logger = lldb.formatters.Logger.Logger()
- self.adjust_for_architecture();
-
- # an NSCountedSet is implemented using a CFBag whose pointer just follows the ISA
- def offset(self):
- logger = lldb.formatters.Logger.Logger()
- return self.sys_params.pointer_size
-
- def count(self):
- logger = lldb.formatters.Logger.Logger()
- cfbag_vo = self.valobj.CreateChildAtOffset("bag_impl",
- self.offset(),
- self.sys_params.types_cache.voidptr)
- return CFBag.CFBagRef_SummaryProvider(cfbag_vo,self.sys_params).length()
+
+ def adjust_for_architecture(self):
+ pass
+
+ def __init__(self, valobj, params):
+ logger = lldb.formatters.Logger.Logger()
+ self.valobj = valobj
+ self.sys_params = params
+ if not (self.sys_params.types_cache.voidptr):
+ self.sys_params.types_cache.voidptr = self.valobj.GetType(
+ ).GetBasicType(lldb.eBasicTypeVoid).GetPointerType()
+ self.update()
+
+ def update(self):
+ logger = lldb.formatters.Logger.Logger()
+ self.adjust_for_architecture()
+
+ # an NSCountedSet is implemented using a CFBag whose pointer just follows
+ # the ISA
+ def offset(self):
+ logger = lldb.formatters.Logger.Logger()
+ return self.sys_params.pointer_size
+
+ def count(self):
+ logger = lldb.formatters.Logger.Logger()
+ cfbag_vo = self.valobj.CreateChildAtOffset(
+ "bag_impl", self.offset(), self.sys_params.types_cache.voidptr)
+ return CFBag.CFBagRef_SummaryProvider(
+ cfbag_vo, self.sys_params).length()
def GetSummary_Impl(valobj):
- logger = lldb.formatters.Logger.Logger()
- global statistics
- class_data,wrapper =lldb.runtime.objc.objc_runtime.Utilities.prepare_class_detection(valobj,statistics)
- if wrapper:
- return wrapper
-
- name_string = class_data.class_name()
- logger >> "class name is: " + str(name_string)
-
- if name_string == '__NSCFSet':
- wrapper = NSCFSet_SummaryProvider(valobj, class_data.sys_params)
- statistics.metric_hit('code_notrun',valobj)
- elif name_string == '__NSSetI':
- wrapper = NSSetI_SummaryProvider(valobj, class_data.sys_params)
- statistics.metric_hit('code_notrun',valobj)
- elif name_string == '__NSSetM':
- wrapper = NSSetM_SummaryProvider(valobj, class_data.sys_params)
- statistics.metric_hit('code_notrun',valobj)
- elif name_string == 'NSCountedSet':
- wrapper = NSCountedSet_SummaryProvider(valobj, class_data.sys_params)
- statistics.metric_hit('code_notrun',valobj)
- else:
- wrapper = NSSetUnknown_SummaryProvider(valobj, class_data.sys_params)
- statistics.metric_hit('unknown_class',valobj.GetName() + " seen as " + name_string)
- return wrapper;
-
-
-def NSSet_SummaryProvider (valobj,dict):
- logger = lldb.formatters.Logger.Logger()
- provider = GetSummary_Impl(valobj);
- if provider != None:
- try:
- summary = provider.count();
- except:
- summary = None
- if summary == None:
- summary = '<variable is not NSSet>'
- if isinstance(summary, basestring):
- return summary
- else:
- summary = str(summary) + (' objects' if summary != 1 else ' object')
- return summary
- return 'Summary Unavailable'
-
-def NSSet_SummaryProvider2 (valobj,dict):
- logger = lldb.formatters.Logger.Logger()
- provider = GetSummary_Impl(valobj);
- if provider != None:
- if isinstance(provider,lldb.runtime.objc.objc_runtime.SpecialSituation_Description):
- return provider.message()
- try:
- summary = provider.count();
- except:
- summary = None
- logger >> "got summary " + str(summary)
- # for some reason, one needs to clear some bits for the count returned
- # to be correct when using directly CF*SetRef as compared to NS*Set
- # this only happens on 64bit, and the bit mask was derived through
- # experimentation (if counts start looking weird, then most probably
- # the mask needs to be changed)
- if summary == None:
- summary = '<variable is not CFSet>'
- if isinstance(summary, basestring):
- return summary
- else:
- if provider.sys_params.is_64_bit:
- summary = summary & ~0x1fff000000000000
- summary = '@"' + str(summary) + (' values"' if summary != 1 else ' value"')
- return summary
- return 'Summary Unavailable'
-
-
-def __lldb_init_module(debugger,dict):
- debugger.HandleCommand("type summary add -F NSSet.NSSet_SummaryProvider NSSet")
- debugger.HandleCommand("type summary add -F NSSet.NSSet_SummaryProvider2 CFSetRef CFMutableSetRef")
+ logger = lldb.formatters.Logger.Logger()
+ global statistics
+ class_data, wrapper = lldb.runtime.objc.objc_runtime.Utilities.prepare_class_detection(
+ valobj, statistics)
+ if wrapper:
+ return wrapper
+
+ name_string = class_data.class_name()
+ logger >> "class name is: " + str(name_string)
+
+ if name_string == '__NSCFSet':
+ wrapper = NSCFSet_SummaryProvider(valobj, class_data.sys_params)
+ statistics.metric_hit('code_notrun', valobj)
+ elif name_string == '__NSSetI':
+ wrapper = NSSetI_SummaryProvider(valobj, class_data.sys_params)
+ statistics.metric_hit('code_notrun', valobj)
+ elif name_string == '__NSSetM':
+ wrapper = NSSetM_SummaryProvider(valobj, class_data.sys_params)
+ statistics.metric_hit('code_notrun', valobj)
+ elif name_string == 'NSCountedSet':
+ wrapper = NSCountedSet_SummaryProvider(valobj, class_data.sys_params)
+ statistics.metric_hit('code_notrun', valobj)
+ else:
+ wrapper = NSSetUnknown_SummaryProvider(valobj, class_data.sys_params)
+ statistics.metric_hit(
+ 'unknown_class',
+ valobj.GetName() +
+ " seen as " +
+ name_string)
+ return wrapper
+
+
+def NSSet_SummaryProvider(valobj, dict):
+ logger = lldb.formatters.Logger.Logger()
+ provider = GetSummary_Impl(valobj)
+ if provider is not None:
+ try:
+ summary = provider.count()
+ except:
+ summary = None
+ if summary is None:
+ summary = '<variable is not NSSet>'
+ if isinstance(summary, basestring):
+ return summary
+ else:
+ summary = str(summary) + \
+ (' objects' if summary != 1 else ' object')
+ return summary
+ return 'Summary Unavailable'
+
+
+def NSSet_SummaryProvider2(valobj, dict):
+ logger = lldb.formatters.Logger.Logger()
+ provider = GetSummary_Impl(valobj)
+ if provider is not None:
+ if isinstance(
+ provider,
+ lldb.runtime.objc.objc_runtime.SpecialSituation_Description):
+ return provider.message()
+ try:
+ summary = provider.count()
+ except:
+ summary = None
+ logger >> "got summary " + str(summary)
+ # for some reason, one needs to clear some bits for the count returned
+ # to be correct when using directly CF*SetRef as compared to NS*Set
+ # this only happens on 64bit, and the bit mask was derived through
+ # experimentation (if counts start looking weird, then most probably
+ # the mask needs to be changed)
+ if summary is None:
+ summary = '<variable is not CFSet>'
+ if isinstance(summary, basestring):
+ return summary
+ else:
+ if provider.sys_params.is_64_bit:
+ summary = summary & ~0x1fff000000000000
+ summary = '@"' + str(summary) + \
+ (' values"' if summary != 1 else ' value"')
+ return summary
+ return 'Summary Unavailable'
+
+
+def __lldb_init_module(debugger, dict):
+ debugger.HandleCommand(
+ "type summary add -F NSSet.NSSet_SummaryProvider NSSet")
+ debugger.HandleCommand(
+ "type summary add -F NSSet.NSSet_SummaryProvider2 CFSetRef CFMutableSetRef")
diff --git a/examples/summaries/cocoa/NSURL.py b/examples/summaries/cocoa/NSURL.py
index ac47be365e5a..ad28849a44d6 100644
--- a/examples/summaries/cocoa/NSURL.py
+++ b/examples/summaries/cocoa/NSURL.py
@@ -22,116 +22,132 @@ statistics.add_metric('code_notrun')
# despite the similary to synthetic children providers, these classes are not
# trying to provide anything but a summary for an NSURL, so they need not
# obey the interface specification for synthetic children providers
+
+
class NSURLKnown_SummaryProvider:
- def adjust_for_architecture(self):
- pass
-
- def __init__(self, valobj, params):
- logger = lldb.formatters.Logger.Logger()
- self.valobj = valobj;
- self.sys_params = params
- if not(self.sys_params.types_cache.NSString):
- self.sys_params.types_cache.NSString = self.valobj.GetTarget().FindFirstType('NSString').GetPointerType()
- if not(self.sys_params.types_cache.NSURL):
- self.sys_params.types_cache.NSURL = self.valobj.GetTarget().FindFirstType('NSURL').GetPointerType()
- self.update();
-
- def update(self):
- logger = lldb.formatters.Logger.Logger()
- self.adjust_for_architecture();
-
- # one pointer is the ISA
- # then there is one more pointer and 8 bytes of plain data
- # (which are also present on a 32-bit system)
- # then there is a pointer to an NSString which is the url text
- # optionally, the next pointer is another NSURL which is the "base"
- # of this one when doing NSURLs composition (incidentally, NSURLs can
- # recurse the base+text mechanism to any desired depth)
- def offset_text(self):
- logger = lldb.formatters.Logger.Logger()
- return 24 if self.sys_params.is_64_bit else 16
- def offset_base(self):
- logger = lldb.formatters.Logger.Logger()
- return self.offset_text()+self.sys_params.pointer_size
-
- def url_text(self):
- logger = lldb.formatters.Logger.Logger()
- text = self.valobj.CreateChildAtOffset("text",
- self.offset_text(),
- self.sys_params.types_cache.NSString)
- base = self.valobj.CreateChildAtOffset("base",
- self.offset_base(),
- self.sys_params.types_cache.NSURL)
- my_string = CFString.CFString_SummaryProvider(text,None)
- if len(my_string) > 0 and base.GetValueAsUnsigned(0) != 0:
- # remove final " from myself
- my_string = my_string[0:len(my_string)-1]
- my_string = my_string + ' -- '
- my_base_string = NSURL_SummaryProvider(base,None)
- if len(my_base_string) > 2:
- # remove @" marker from base URL string
- my_base_string = my_base_string[2:]
- my_string = my_string + my_base_string
- return my_string
+
+ def adjust_for_architecture(self):
+ pass
+
+ def __init__(self, valobj, params):
+ logger = lldb.formatters.Logger.Logger()
+ self.valobj = valobj
+ self.sys_params = params
+ if not(self.sys_params.types_cache.NSString):
+ self.sys_params.types_cache.NSString = self.valobj.GetTarget(
+ ).FindFirstType('NSString').GetPointerType()
+ if not(self.sys_params.types_cache.NSURL):
+ self.sys_params.types_cache.NSURL = self.valobj.GetTarget(
+ ).FindFirstType('NSURL').GetPointerType()
+ self.update()
+
+ def update(self):
+ logger = lldb.formatters.Logger.Logger()
+ self.adjust_for_architecture()
+
+ # one pointer is the ISA
+ # then there is one more pointer and 8 bytes of plain data
+ # (which are also present on a 32-bit system)
+ # then there is a pointer to an NSString which is the url text
+ # optionally, the next pointer is another NSURL which is the "base"
+ # of this one when doing NSURLs composition (incidentally, NSURLs can
+ # recurse the base+text mechanism to any desired depth)
+ def offset_text(self):
+ logger = lldb.formatters.Logger.Logger()
+ return 24 if self.sys_params.is_64_bit else 16
+
+ def offset_base(self):
+ logger = lldb.formatters.Logger.Logger()
+ return self.offset_text() + self.sys_params.pointer_size
+
+ def url_text(self):
+ logger = lldb.formatters.Logger.Logger()
+ text = self.valobj.CreateChildAtOffset(
+ "text", self.offset_text(), self.sys_params.types_cache.NSString)
+ base = self.valobj.CreateChildAtOffset(
+ "base", self.offset_base(), self.sys_params.types_cache.NSURL)
+ my_string = CFString.CFString_SummaryProvider(text, None)
+ if len(my_string) > 0 and base.GetValueAsUnsigned(0) != 0:
+ # remove final " from myself
+ my_string = my_string[0:len(my_string) - 1]
+ my_string = my_string + ' -- '
+ my_base_string = NSURL_SummaryProvider(base, None)
+ if len(my_base_string) > 2:
+ # remove @" marker from base URL string
+ my_base_string = my_base_string[2:]
+ my_string = my_string + my_base_string
+ return my_string
class NSURLUnknown_SummaryProvider:
- def adjust_for_architecture(self):
- pass
- def __init__(self, valobj, params):
- logger = lldb.formatters.Logger.Logger()
- self.valobj = valobj;
- self.sys_params = params
- self.update()
+ def adjust_for_architecture(self):
+ pass
+
+ def __init__(self, valobj, params):
+ logger = lldb.formatters.Logger.Logger()
+ self.valobj = valobj
+ self.sys_params = params
+ self.update()
- def update(self):
- logger = lldb.formatters.Logger.Logger()
- self.adjust_for_architecture();
+ def update(self):
+ logger = lldb.formatters.Logger.Logger()
+ self.adjust_for_architecture()
- def url_text(self):
- logger = lldb.formatters.Logger.Logger()
- stream = lldb.SBStream()
- self.valobj.GetExpressionPath(stream)
- url_text_vo = self.valobj.CreateValueFromExpression("url","(NSString*)[" + stream.GetData() + " description]")
- if url_text_vo.IsValid():
- return CFString.CFString_SummaryProvider(url_text_vo,None)
- return '<variable is not NSURL>'
+ def url_text(self):
+ logger = lldb.formatters.Logger.Logger()
+ stream = lldb.SBStream()
+ self.valobj.GetExpressionPath(stream)
+ url_text_vo = self.valobj.CreateValueFromExpression(
+ "url", "(NSString*)[" + stream.GetData() + " description]")
+ if url_text_vo.IsValid():
+ return CFString.CFString_SummaryProvider(url_text_vo, None)
+ return '<variable is not NSURL>'
def GetSummary_Impl(valobj):
- logger = lldb.formatters.Logger.Logger()
- global statistics
- class_data,wrapper =lldb.runtime.objc.objc_runtime.Utilities.prepare_class_detection(valobj,statistics)
- if wrapper:
- return wrapper
-
- name_string = class_data.class_name()
- logger >> "class name is: " + str(name_string)
-
- if name_string == 'NSURL':
- wrapper = NSURLKnown_SummaryProvider(valobj, class_data.sys_params)
- statistics.metric_hit('code_notrun',valobj)
- else:
- wrapper = NSURLUnknown_SummaryProvider(valobj, class_data.sys_params)
- statistics.metric_hit('unknown_class',valobj.GetName() + " seen as " + name_string)
- return wrapper;
-
-def NSURL_SummaryProvider (valobj,dict):
- logger = lldb.formatters.Logger.Logger()
- provider = GetSummary_Impl(valobj);
- if provider != None:
- if isinstance(provider,lldb.runtime.objc.objc_runtime.SpecialSituation_Description):
- return provider.message()
- try:
- summary = provider.url_text();
- except:
- summary = None
- logger >> "got summary " + str(summary)
- if summary == None or summary == '':
- summary = '<variable is not NSURL>'
- return summary
- return 'Summary Unavailable'
-
-def __lldb_init_module(debugger,dict):
- debugger.HandleCommand("type summary add -F NSURL.NSURL_SummaryProvider NSURL CFURLRef")
+ logger = lldb.formatters.Logger.Logger()
+ global statistics
+ class_data, wrapper = lldb.runtime.objc.objc_runtime.Utilities.prepare_class_detection(
+ valobj, statistics)
+ if wrapper:
+ return wrapper
+
+ name_string = class_data.class_name()
+ logger >> "class name is: " + str(name_string)
+
+ if name_string == 'NSURL':
+ wrapper = NSURLKnown_SummaryProvider(valobj, class_data.sys_params)
+ statistics.metric_hit('code_notrun', valobj)
+ else:
+ wrapper = NSURLUnknown_SummaryProvider(valobj, class_data.sys_params)
+ statistics.metric_hit(
+ 'unknown_class',
+ valobj.GetName() +
+ " seen as " +
+ name_string)
+ return wrapper
+
+
+def NSURL_SummaryProvider(valobj, dict):
+ logger = lldb.formatters.Logger.Logger()
+ provider = GetSummary_Impl(valobj)
+ if provider is not None:
+ if isinstance(
+ provider,
+ lldb.runtime.objc.objc_runtime.SpecialSituation_Description):
+ return provider.message()
+ try:
+ summary = provider.url_text()
+ except:
+ summary = None
+ logger >> "got summary " + str(summary)
+ if summary is None or summary == '':
+ summary = '<variable is not NSURL>'
+ return summary
+ return 'Summary Unavailable'
+
+
+def __lldb_init_module(debugger, dict):
+ debugger.HandleCommand(
+ "type summary add -F NSURL.NSURL_SummaryProvider NSURL CFURLRef")
diff --git a/examples/summaries/cocoa/Selector.py b/examples/summaries/cocoa/Selector.py
index d0505204bf22..05a19606505e 100644
--- a/examples/summaries/cocoa/Selector.py
+++ b/examples/summaries/cocoa/Selector.py
@@ -7,8 +7,13 @@ License. See LICENSE.TXT for details.
"""
import lldb
-def SEL_Summary(valobj,dict):
- return valobj.Cast(valobj.GetType().GetBasicType(lldb.eBasicTypeChar).GetPointerType()).GetSummary()
-def SELPointer_Summary(valobj,dict):
- return valobj.CreateValueFromAddress('text',valobj.GetValueAsUnsigned(0),valobj.GetType().GetBasicType(lldb.eBasicTypeChar)).AddressOf().GetSummary()
+def SEL_Summary(valobj, dict):
+ return valobj.Cast(valobj.GetType().GetBasicType(
+ lldb.eBasicTypeChar).GetPointerType()).GetSummary()
+
+
+def SELPointer_Summary(valobj, dict):
+ return valobj.CreateValueFromAddress(
+ 'text', valobj.GetValueAsUnsigned(0), valobj.GetType().GetBasicType(
+ lldb.eBasicTypeChar)).AddressOf().GetSummary()
diff --git a/examples/summaries/cocoa/attrib_fromdict.py b/examples/summaries/cocoa/attrib_fromdict.py
index 86964d602b5b..39abe6bda478 100644
--- a/examples/summaries/cocoa/attrib_fromdict.py
+++ b/examples/summaries/cocoa/attrib_fromdict.py
@@ -5,34 +5,38 @@ part of The LLVM Compiler Infrastructure
This file is distributed under the University of Illinois Open Source
License. See LICENSE.TXT for details.
"""
+
+
class AttributesDictionary:
- def __init__(self, allow_reset = True):
- self.__dict__['_dictionary'] = {} # need to do it this way to prevent endless recursion
- self.__dict__['_allow_reset'] = allow_reset
-
- def __getattr__(self,name):
- if not self._check_exists(name):
- return None
- value = self._dictionary[name]
- return value
-
- def _set_impl(self,name,value):
- self._dictionary[name] = value
-
- def _check_exists(self,name):
- return name in self._dictionary
-
- def __setattr__(self,name,value):
- if self._allow_reset:
- self._set_impl(name,value)
- else:
- self.set_if_necessary(name,value)
-
- def set_if_necessary(self,name,value):
- if not self._check_exists(name):
- self._set_impl(name,value)
- return True
- return False
-
- def __len__(self):
- return len(self._dictionary) \ No newline at end of file
+
+ def __init__(self, allow_reset=True):
+ # need to do it this way to prevent endless recursion
+ self.__dict__['_dictionary'] = {}
+ self.__dict__['_allow_reset'] = allow_reset
+
+ def __getattr__(self, name):
+ if not self._check_exists(name):
+ return None
+ value = self._dictionary[name]
+ return value
+
+ def _set_impl(self, name, value):
+ self._dictionary[name] = value
+
+ def _check_exists(self, name):
+ return name in self._dictionary
+
+ def __setattr__(self, name, value):
+ if self._allow_reset:
+ self._set_impl(name, value)
+ else:
+ self.set_if_necessary(name, value)
+
+ def set_if_necessary(self, name, value):
+ if not self._check_exists(name):
+ self._set_impl(name, value)
+ return True
+ return False
+
+ def __len__(self):
+ return len(self._dictionary)
diff --git a/examples/summaries/cocoa/cache.py b/examples/summaries/cocoa/cache.py
index 066829d80d4f..63915cc66338 100644
--- a/examples/summaries/cocoa/cache.py
+++ b/examples/summaries/cocoa/cache.py
@@ -7,29 +7,30 @@ License. See LICENSE.TXT for details.
"""
import lldb.formatters.metrics
+
class Cache:
- def __init__(self):
- self.data = {}
- self.statistics = lldb.formatters.metrics.Metrics()
- self.statistics.add_metric('hit')
- self.statistics.add_metric('miss')
- def look_for_key(self,key):
- if key in self.data:
- return True
- return False
+ def __init__(self):
+ self.data = {}
+ self.statistics = lldb.formatters.metrics.Metrics()
+ self.statistics.add_metric('hit')
+ self.statistics.add_metric('miss')
- def add_item(self,key,value,ok_to_replace=True):
- if not(ok_to_replace) and self.look_for_key(key):
- return False
- self.data[key] = value
- return True
+ def look_for_key(self, key):
+ if key in self.data:
+ return True
+ return False
- def get_value(self,key,default=None):
- if self.look_for_key(key):
- self.statistics.metric_hit('hit',key)
- return self.data[key]
- else:
- self.statistics.metric_hit('miss',key)
- return default
+ def add_item(self, key, value, ok_to_replace=True):
+ if not(ok_to_replace) and self.look_for_key(key):
+ return False
+ self.data[key] = value
+ return True
+ def get_value(self, key, default=None):
+ if self.look_for_key(key):
+ self.statistics.metric_hit('hit', key)
+ return self.data[key]
+ else:
+ self.statistics.metric_hit('miss', key)
+ return default
diff --git a/examples/summaries/cocoa/metrics.py b/examples/summaries/cocoa/metrics.py
index 6b82ff3b3015..6a73a7344b95 100644
--- a/examples/summaries/cocoa/metrics.py
+++ b/examples/summaries/cocoa/metrics.py
@@ -6,89 +6,107 @@ This file is distributed under the University of Illinois Open Source
License. See LICENSE.TXT for details.
"""
import lldb
-import time, datetime
+import time
+import datetime
import inspect
+
class TimeMetrics:
- @staticmethod
- def generate(label=None):
- return TimeMetrics(label)
-
- def __init__(self,lbl=None):
- self.label = "" if lbl is None else lbl
- pass
-
- def __enter__(self):
- caller = inspect.stack()[1]
- self.function = str(caller)
- self.enter_time = time.clock()
-
- def __exit__(self, a,b,c):
- self.exit_time = time.clock()
- print("It took " + str(self.exit_time - self.enter_time) + " time units to run through " + self.function + self.label)
- return False
+
+ @staticmethod
+ def generate(label=None):
+ return TimeMetrics(label)
+
+ def __init__(self, lbl=None):
+ self.label = "" if lbl is None else lbl
+ pass
+
+ def __enter__(self):
+ caller = inspect.stack()[1]
+ self.function = str(caller)
+ self.enter_time = time.clock()
+
+ def __exit__(self, a, b, c):
+ self.exit_time = time.clock()
+ print("It took " + str(self.exit_time - self.enter_time) +
+ " time units to run through " + self.function + self.label)
+ return False
+
class Counter:
- def __init__(self):
- self.count = 0
- self.list = []
- def update(self,name):
- self.count = self.count + 1
- # avoid getting the full dump of this ValueObject just to save its metrics
- if isinstance(name,lldb.SBValue):
- self.list.append(name.GetName())
- else:
- self.list.append(str(name))
- def __str__(self):
- return str(self.count) + " times, for items [" + str(self.list) + "]"
+
+ def __init__(self):
+ self.count = 0
+ self.list = []
+
+ def update(self, name):
+ self.count = self.count + 1
+ # avoid getting the full dump of this ValueObject just to save its
+ # metrics
+ if isinstance(name, lldb.SBValue):
+ self.list.append(name.GetName())
+ else:
+ self.list.append(str(name))
+
+ def __str__(self):
+ return str(self.count) + " times, for items [" + str(self.list) + "]"
+
class MetricsPrinter_Verbose:
- def __init__(self,metrics):
- self.metrics = metrics
- def __str__(self):
- string = ""
- for key,value in self.metrics.metrics.items():
- string = string + "metric " + str(key) + ": " + str(value) + "\n"
- return string
+
+ def __init__(self, metrics):
+ self.metrics = metrics
+
+ def __str__(self):
+ string = ""
+ for key, value in self.metrics.metrics.items():
+ string = string + "metric " + str(key) + ": " + str(value) + "\n"
+ return string
+
class MetricsPrinter_Compact:
- def __init__(self,metrics):
- self.metrics = metrics
- def __str__(self):
- string = ""
- for key,value in self.metrics.metrics.items():
- string = string + "metric " + str(key) + " was hit " + str(value.count) + " times\n"
- return string
+
+ def __init__(self, metrics):
+ self.metrics = metrics
+
+ def __str__(self):
+ string = ""
+ for key, value in self.metrics.metrics.items():
+ string = string + "metric " + \
+ str(key) + " was hit " + str(value.count) + " times\n"
+ return string
+
class Metrics:
- def __init__(self):
- self.metrics = {}
-
- def add_metric(self,name):
- self.metrics[name] = Counter()
-
- def metric_hit(self,metric,trigger):
- self.metrics[metric].update(trigger)
-
- def __getitem__(self,key):
- return self.metrics[key]
-
- def __getattr__(self,name):
- if name == 'compact':
- return MetricsPrinter_Compact(self)
- if name == 'verbose':
- return MetricsPrinter_Verbose(self)
- raise AttributeError("%r object has no attribute %r" %
- (type(self).__name__, name))
-
- def __str__(self):
- return str(self.verbose)
-
- def metric_success(self,metric):
- total_count = 0
- metric_count = self[metric].count
- for key,value in self.metrics.items():
- total_count = total_count + value.count
- if total_count > 0:
- return metric_count / float(total_count)
- return 0
+
+ def __init__(self):
+ self.metrics = {}
+
+ def add_metric(self, name):
+ self.metrics[name] = Counter()
+
+ def metric_hit(self, metric, trigger):
+ self.metrics[metric].update(trigger)
+
+ def __getitem__(self, key):
+ return self.metrics[key]
+
+ def __getattr__(self, name):
+ if name == 'compact':
+ return MetricsPrinter_Compact(self)
+ if name == 'verbose':
+ return MetricsPrinter_Verbose(self)
+ raise AttributeError("%r object has no attribute %r" %
+ (type(self).__name__, name))
+
+ def __str__(self):
+ return str(self.verbose)
+
+ def metric_success(self, metric):
+ total_count = 0
+ metric_count = self[metric].count
+ for key, value in self.metrics.items():
+ total_count = total_count + value.count
+ if total_count > 0:
+ return metric_count / float(total_count)
+ return 0
diff --git a/examples/summaries/cocoa/objc_runtime.py b/examples/summaries/cocoa/objc_runtime.py
index 8b5debccb824..14ef1b42bf13 100644
--- a/examples/summaries/cocoa/objc_runtime.py
+++ b/examples/summaries/cocoa/objc_runtime.py
@@ -11,556 +11,641 @@ import lldb.formatters.attrib_fromdict
import functools
import lldb.formatters.Logger
+
class Utilities:
- @staticmethod
- def read_ascii(process, pointer,max_len=128):
- logger = lldb.formatters.Logger.Logger()
- error = lldb.SBError()
- content = None
- try:
- content = process.ReadCStringFromMemory(pointer,max_len,error)
- except:
- pass
- if content is None or len(content) == 0 or error.fail:
- return None
- return content
-
- @staticmethod
- def is_valid_pointer(pointer, pointer_size, allow_tagged=0, allow_NULL=0):
- logger = lldb.formatters.Logger.Logger()
- if pointer is None:
- return 0
- if pointer == 0:
- return allow_NULL
- if allow_tagged and (pointer % 2) == 1:
- return 1
- return ((pointer % pointer_size) == 0)
-
- # Objective-C runtime has a rule that pointers in a class_t will only have bits 0 thru 46 set
- # so if any pointer has bits 47 thru 63 high we know that this is not a valid isa
- @staticmethod
- def is_allowed_pointer(pointer):
- logger = lldb.formatters.Logger.Logger()
- if pointer is None:
- return 0
- return ((pointer & 0xFFFF800000000000) == 0)
-
- @staticmethod
- def read_child_of(valobj,offset,type):
- logger = lldb.formatters.Logger.Logger()
- if offset == 0 and type.GetByteSize() == valobj.GetByteSize():
- return valobj.GetValueAsUnsigned()
- child = valobj.CreateChildAtOffset("childUNK",offset,type)
- if child is None or child.IsValid() == 0:
- return None;
- return child.GetValueAsUnsigned()
-
- @staticmethod
- def is_valid_identifier(name):
- logger = lldb.formatters.Logger.Logger()
- if name is None:
- return None
- if len(name) == 0:
- return None
- # technically, the ObjC runtime does not enforce any rules about what name a class can have
- # in practice, the commonly used byte values for a class name are the letters, digits and some
- # symbols: $, %, -, _, .
- # WARNING: this means that you cannot use this runtime implementation if you need to deal
- # with class names that use anything but what is allowed here
- ok_values = dict.fromkeys("$%_.-ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890")
- return all(c in ok_values for c in name)
-
- @staticmethod
- def check_is_osx_lion(target):
- logger = lldb.formatters.Logger.Logger()
- # assume the only thing that has a Foundation.framework is a Mac
- # assume anything < Lion does not even exist
- try:
- mod = target.module['Foundation']
- except:
- mod = None
- if mod is None or mod.IsValid() == 0:
- return None
- ver = mod.GetVersion()
- if ver is None or ver == []:
- return None
- return (ver[0] < 900)
-
- # a utility method that factors out code common to almost all the formatters
- # takes in an SBValue and a metrics object
- # returns a class_data and a wrapper (or None, if the runtime alone can't decide on a wrapper)
- @staticmethod
- def prepare_class_detection(valobj,statistics):
- logger = lldb.formatters.Logger.Logger()
- class_data = ObjCRuntime(valobj)
- if class_data.is_valid() == 0:
- statistics.metric_hit('invalid_pointer',valobj)
- wrapper = InvalidPointer_Description(valobj.GetValueAsUnsigned(0) == 0)
- return class_data,wrapper
- class_data = class_data.read_class_data()
- if class_data.is_valid() == 0:
- statistics.metric_hit('invalid_isa',valobj)
- wrapper = InvalidISA_Description()
- return class_data,wrapper
- if class_data.is_kvo():
- class_data = class_data.get_superclass()
- if class_data.class_name() == '_NSZombie_OriginalClass':
- wrapper = ThisIsZombie_Description()
- return class_data,wrapper
- return class_data,None
+
+ @staticmethod
+ def read_ascii(process, pointer, max_len=128):
+ logger = lldb.formatters.Logger.Logger()
+ error = lldb.SBError()
+ content = None
+ try:
+ content = process.ReadCStringFromMemory(pointer, max_len, error)
+ except:
+ pass
+ if content is None or len(content) == 0 or error.fail:
+ return None
+ return content
+
+ @staticmethod
+ def is_valid_pointer(pointer, pointer_size, allow_tagged=0, allow_NULL=0):
+ logger = lldb.formatters.Logger.Logger()
+ if pointer is None:
+ return 0
+ if pointer == 0:
+ return allow_NULL
+ if allow_tagged and (pointer % 2) == 1:
+ return 1
+ return ((pointer % pointer_size) == 0)
+
+ # Objective-C runtime has a rule that pointers in a class_t will only have bits 0 thru 46 set
+ # so if any pointer has bits 47 thru 63 high we know that this is not a
+ # valid isa
+ @staticmethod
+ def is_allowed_pointer(pointer):
+ logger = lldb.formatters.Logger.Logger()
+ if pointer is None:
+ return 0
+ return ((pointer & 0xFFFF800000000000) == 0)
+
+ @staticmethod
+ def read_child_of(valobj, offset, type):
+ logger = lldb.formatters.Logger.Logger()
+ if offset == 0 and type.GetByteSize() == valobj.GetByteSize():
+ return valobj.GetValueAsUnsigned()
+ child = valobj.CreateChildAtOffset("childUNK", offset, type)
+ if child is None or child.IsValid() == 0:
+ return None
+ return child.GetValueAsUnsigned()
+
+ @staticmethod
+ def is_valid_identifier(name):
+ logger = lldb.formatters.Logger.Logger()
+ if name is None:
+ return None
+ if len(name) == 0:
+ return None
+ # technically, the ObjC runtime does not enforce any rules about what name a class can have
+ # in practice, the commonly used byte values for a class name are the letters, digits and some
+ # symbols: $, %, -, _, .
+ # WARNING: this means that you cannot use this runtime implementation if you need to deal
+ # with class names that use anything but what is allowed here
+ ok_values = dict.fromkeys(
+ "$%_.-ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890")
+ return all(c in ok_values for c in name)
+
+ @staticmethod
+ def check_is_osx_lion(target):
+ logger = lldb.formatters.Logger.Logger()
+ # assume the only thing that has a Foundation.framework is a Mac
+ # assume anything < Lion does not even exist
+ try:
+ mod = target.module['Foundation']
+ except:
+ mod = None
+ if mod is None or mod.IsValid() == 0:
+ return None
+ ver = mod.GetVersion()
+ if ver is None or ver == []:
+ return None
+ return (ver[0] < 900)
+
+ # a utility method that factors out code common to almost all the formatters
+ # takes in an SBValue and a metrics object
+ # returns a class_data and a wrapper (or None, if the runtime alone can't
+ # decide on a wrapper)
+ @staticmethod
+ def prepare_class_detection(valobj, statistics):
+ logger = lldb.formatters.Logger.Logger()
+ class_data = ObjCRuntime(valobj)
+ if class_data.is_valid() == 0:
+ statistics.metric_hit('invalid_pointer', valobj)
+ wrapper = InvalidPointer_Description(
+ valobj.GetValueAsUnsigned(0) == 0)
+ return class_data, wrapper
+ class_data = class_data.read_class_data()
+ if class_data.is_valid() == 0:
+ statistics.metric_hit('invalid_isa', valobj)
+ wrapper = InvalidISA_Description()
+ return class_data, wrapper
+ if class_data.is_kvo():
+ class_data = class_data.get_superclass()
+ if class_data.class_name() == '_NSZombie_OriginalClass':
+ wrapper = ThisIsZombie_Description()
+ return class_data, wrapper
+ return class_data, None
class RoT_Data:
- def __init__(self,rot_pointer,params):
- logger = lldb.formatters.Logger.Logger()
- if (Utilities.is_valid_pointer(rot_pointer.GetValueAsUnsigned(),params.pointer_size, allow_tagged=0)):
- self.sys_params = params
- self.valobj = rot_pointer
- #self.flags = Utilities.read_child_of(self.valobj,0,self.sys_params.uint32_t)
- #self.instanceStart = Utilities.read_child_of(self.valobj,4,self.sys_params.uint32_t)
- self.instanceSize = None # lazy fetching
- offset = 24 if self.sys_params.is_64_bit else 16
- #self.ivarLayoutPtr = Utilities.read_child_of(self.valobj,offset,self.sys_params.addr_ptr_type)
- self.namePointer = Utilities.read_child_of(self.valobj,offset,self.sys_params.types_cache.addr_ptr_type)
- self.valid = 1 # self.check_valid()
- else:
- logger >> "Marking as invalid - rot is invalid"
- self.valid = 0
- if self.valid:
- self.name = Utilities.read_ascii(self.valobj.GetTarget().GetProcess(),self.namePointer)
- if not(Utilities.is_valid_identifier(self.name)):
- logger >> "Marking as invalid - name is invalid"
- self.valid = 0
-
- # perform sanity checks on the contents of this class_ro_t
- def check_valid(self):
- self.valid = 1
- # misaligned pointers seem to be possible for this field
- #if not(Utilities.is_valid_pointer(self.namePointer,self.sys_params.pointer_size,allow_tagged=0)):
- # self.valid = 0
- # pass
-
- def __str__(self):
- logger = lldb.formatters.Logger.Logger()
- return \
- "instanceSize = " + hex(self.instance_size()) + "\n" + \
- "namePointer = " + hex(self.namePointer) + " --> " + self.name
-
- def is_valid(self):
- return self.valid
-
- def instance_size(self,align=0):
- logger = lldb.formatters.Logger.Logger()
- if self.is_valid() == 0:
- return None
- if self.instanceSize is None:
- self.instanceSize = Utilities.read_child_of(self.valobj,8,self.sys_params.types_cache.uint32_t)
- if align:
- unalign = self.instance_size(0)
- if self.sys_params.is_64_bit:
- return ((unalign + 7) & ~7) % 0x100000000
- else:
- return ((unalign + 3) & ~3) % 0x100000000
- else:
- return self.instanceSize
+
+ def __init__(self, rot_pointer, params):
+ logger = lldb.formatters.Logger.Logger()
+ if (Utilities.is_valid_pointer(rot_pointer.GetValueAsUnsigned(),
+ params.pointer_size, allow_tagged=0)):
+ self.sys_params = params
+ self.valobj = rot_pointer
+ #self.flags = Utilities.read_child_of(self.valobj,0,self.sys_params.uint32_t)
+ #self.instanceStart = Utilities.read_child_of(self.valobj,4,self.sys_params.uint32_t)
+ self.instanceSize = None # lazy fetching
+ offset = 24 if self.sys_params.is_64_bit else 16
+ #self.ivarLayoutPtr = Utilities.read_child_of(self.valobj,offset,self.sys_params.addr_ptr_type)
+ self.namePointer = Utilities.read_child_of(
+ self.valobj, offset, self.sys_params.types_cache.addr_ptr_type)
+ self.valid = 1 # self.check_valid()
+ else:
+ logger >> "Marking as invalid - rot is invalid"
+ self.valid = 0
+ if self.valid:
+ self.name = Utilities.read_ascii(
+ self.valobj.GetTarget().GetProcess(), self.namePointer)
+ if not(Utilities.is_valid_identifier(self.name)):
+ logger >> "Marking as invalid - name is invalid"
+ self.valid = 0
+
+ # perform sanity checks on the contents of this class_ro_t
+ def check_valid(self):
+ self.valid = 1
+ # misaligned pointers seem to be possible for this field
+ # if not(Utilities.is_valid_pointer(self.namePointer,self.sys_params.pointer_size,allow_tagged=0)):
+ # self.valid = 0
+ # pass
+
+ def __str__(self):
+ logger = lldb.formatters.Logger.Logger()
+ return \
+ "instanceSize = " + hex(self.instance_size()) + "\n" + \
+ "namePointer = " + hex(self.namePointer) + " --> " + self.name
+
+ def is_valid(self):
+ return self.valid
+
+ def instance_size(self, align=0):
+ logger = lldb.formatters.Logger.Logger()
+ if self.is_valid() == 0:
+ return None
+ if self.instanceSize is None:
+ self.instanceSize = Utilities.read_child_of(
+ self.valobj, 8, self.sys_params.types_cache.uint32_t)
+ if align:
+ unalign = self.instance_size(0)
+ if self.sys_params.is_64_bit:
+ return ((unalign + 7) & ~7) % 0x100000000
+ else:
+ return ((unalign + 3) & ~3) % 0x100000000
+ else:
+ return self.instanceSize
+
class RwT_Data:
- def __init__(self,rwt_pointer,params):
- logger = lldb.formatters.Logger.Logger()
- if (Utilities.is_valid_pointer(rwt_pointer.GetValueAsUnsigned(),params.pointer_size, allow_tagged=0)):
- self.sys_params = params
- self.valobj = rwt_pointer
- #self.flags = Utilities.read_child_of(self.valobj,0,self.sys_params.uint32_t)
- #self.version = Utilities.read_child_of(self.valobj,4,self.sys_params.uint32_t)
- self.roPointer = Utilities.read_child_of(self.valobj,8,self.sys_params.types_cache.addr_ptr_type)
- self.check_valid()
- else:
- logger >> "Marking as invalid - rwt is invald"
- self.valid = 0
- if self.valid:
- self.rot = self.valobj.CreateValueFromData("rot",lldb.SBData.CreateDataFromUInt64Array(self.sys_params.endianness, self.sys_params.pointer_size, [self.roPointer]),self.sys_params.types_cache.addr_ptr_type)
+
+ def __init__(self, rwt_pointer, params):
+ logger = lldb.formatters.Logger.Logger()
+ if (Utilities.is_valid_pointer(rwt_pointer.GetValueAsUnsigned(),
+ params.pointer_size, allow_tagged=0)):
+ self.sys_params = params
+ self.valobj = rwt_pointer
+ #self.flags = Utilities.read_child_of(self.valobj,0,self.sys_params.uint32_t)
+ #self.version = Utilities.read_child_of(self.valobj,4,self.sys_params.uint32_t)
+ self.roPointer = Utilities.read_child_of(
+ self.valobj, 8, self.sys_params.types_cache.addr_ptr_type)
+ self.check_valid()
+ else:
+ logger >> "Marking as invalid - rwt is invald"
+ self.valid = 0
+ if self.valid:
+ self.rot = self.valobj.CreateValueFromData(
+ "rot", lldb.SBData.CreateDataFromUInt64Array(
+ self.sys_params.endianness, self.sys_params.pointer_size, [
+ self.roPointer]), self.sys_params.types_cache.addr_ptr_type)
# self.rot = self.valobj.CreateValueFromAddress("rot",self.roPointer,self.sys_params.types_cache.addr_ptr_type).AddressOf()
- self.data = RoT_Data(self.rot,self.sys_params)
-
- # perform sanity checks on the contents of this class_rw_t
- def check_valid(self):
- logger = lldb.formatters.Logger.Logger()
- self.valid = 1
- if not(Utilities.is_valid_pointer(self.roPointer,self.sys_params.pointer_size,allow_tagged=0)):
- logger >> "Marking as invalid - ropointer is invalid"
- self.valid = 0
-
- def __str__(self):
- logger = lldb.formatters.Logger.Logger()
- return \
- "roPointer = " + hex(self.roPointer)
-
- def is_valid(self):
- logger = lldb.formatters.Logger.Logger()
- if self.valid:
- return self.data.is_valid()
- return 0
+ self.data = RoT_Data(self.rot, self.sys_params)
+
+ # perform sanity checks on the contents of this class_rw_t
+ def check_valid(self):
+ logger = lldb.formatters.Logger.Logger()
+ self.valid = 1
+ if not(
+ Utilities.is_valid_pointer(
+ self.roPointer,
+ self.sys_params.pointer_size,
+ allow_tagged=0)):
+ logger >> "Marking as invalid - ropointer is invalid"
+ self.valid = 0
+
+ def __str__(self):
+ logger = lldb.formatters.Logger.Logger()
+ return \
+ "roPointer = " + hex(self.roPointer)
+
+ def is_valid(self):
+ logger = lldb.formatters.Logger.Logger()
+ if self.valid:
+ return self.data.is_valid()
+ return 0
+
class Class_Data_V2:
- def __init__(self,isa_pointer,params):
- logger = lldb.formatters.Logger.Logger()
- if (isa_pointer != None) and (Utilities.is_valid_pointer(isa_pointer.GetValueAsUnsigned(),params.pointer_size, allow_tagged=0)):
- self.sys_params = params
- self.valobj = isa_pointer
- self.check_valid()
- else:
- logger >> "Marking as invalid - isa is invalid or None"
- self.valid = 0
- if self.valid:
- self.rwt = self.valobj.CreateValueFromData("rwt",lldb.SBData.CreateDataFromUInt64Array(self.sys_params.endianness, self.sys_params.pointer_size, [self.dataPointer]),self.sys_params.types_cache.addr_ptr_type)
+
+ def __init__(self, isa_pointer, params):
+ logger = lldb.formatters.Logger.Logger()
+ if (isa_pointer is not None) and (Utilities.is_valid_pointer(
+ isa_pointer.GetValueAsUnsigned(), params.pointer_size, allow_tagged=0)):
+ self.sys_params = params
+ self.valobj = isa_pointer
+ self.check_valid()
+ else:
+ logger >> "Marking as invalid - isa is invalid or None"
+ self.valid = 0
+ if self.valid:
+ self.rwt = self.valobj.CreateValueFromData(
+ "rwt", lldb.SBData.CreateDataFromUInt64Array(
+ self.sys_params.endianness, self.sys_params.pointer_size, [
+ self.dataPointer]), self.sys_params.types_cache.addr_ptr_type)
# self.rwt = self.valobj.CreateValueFromAddress("rwt",self.dataPointer,self.sys_params.types_cache.addr_ptr_type).AddressOf()
- self.data = RwT_Data(self.rwt,self.sys_params)
-
- # perform sanity checks on the contents of this class_t
- # this call tries to minimize the amount of data fetched- as soon as we have "proven"
- # that we have an invalid object, we stop reading
- def check_valid(self):
- logger = lldb.formatters.Logger.Logger()
- self.valid = 1
-
- self.isaPointer = Utilities.read_child_of(self.valobj,0,self.sys_params.types_cache.addr_ptr_type)
- if not(Utilities.is_valid_pointer(self.isaPointer,self.sys_params.pointer_size,allow_tagged=0)):
- logger >> "Marking as invalid - isaPointer is invalid"
- self.valid = 0
- return
- if not(Utilities.is_allowed_pointer(self.isaPointer)):
- logger >> "Marking as invalid - isaPointer is not allowed"
- self.valid = 0
- return
-
- self.cachePointer = Utilities.read_child_of(self.valobj,2*self.sys_params.pointer_size,self.sys_params.types_cache.addr_ptr_type)
- if not(Utilities.is_valid_pointer(self.cachePointer,self.sys_params.pointer_size,allow_tagged=0)):
- logger >> "Marking as invalid - cachePointer is invalid"
- self.valid = 0
- return
- if not(Utilities.is_allowed_pointer(self.cachePointer)):
- logger >> "Marking as invalid - cachePointer is not allowed"
- self.valid = 0
- return
- self.dataPointer = Utilities.read_child_of(self.valobj,4*self.sys_params.pointer_size,self.sys_params.types_cache.addr_ptr_type)
- if not(Utilities.is_valid_pointer(self.dataPointer,self.sys_params.pointer_size,allow_tagged=0)):
- logger >> "Marking as invalid - dataPointer is invalid"
- self.valid = 0
- return
- if not(Utilities.is_allowed_pointer(self.dataPointer)):
- logger >> "Marking as invalid - dataPointer is not allowed"
- self.valid = 0
- return
-
- self.superclassIsaPointer = Utilities.read_child_of(self.valobj,1*self.sys_params.pointer_size,self.sys_params.types_cache.addr_ptr_type)
- if not(Utilities.is_valid_pointer(self.superclassIsaPointer,self.sys_params.pointer_size,allow_tagged=0, allow_NULL=1)):
- logger >> "Marking as invalid - superclassIsa is invalid"
- self.valid = 0
- return
- if not(Utilities.is_allowed_pointer(self.superclassIsaPointer)):
- logger >> "Marking as invalid - superclassIsa is not allowed"
- self.valid = 0
- return
-
- # in general, KVO is implemented by transparently subclassing
- # however, there could be exceptions where a class does something else
- # internally to implement the feature - this method will have no clue that a class
- # has been KVO'ed unless the standard implementation technique is used
- def is_kvo(self):
- logger = lldb.formatters.Logger.Logger()
- if self.is_valid():
- if self.class_name().startswith("NSKVONotifying_"):
- return 1
- return 0
-
- # some CF classes have a valid ObjC isa in their CFRuntimeBase
- # but instead of being class-specific this isa points to a match-'em-all class
- # which is __NSCFType (the versions without __ also exists and we are matching to it
- # just to be on the safe side)
- def is_cftype(self):
- logger = lldb.formatters.Logger.Logger()
- if self.is_valid():
- return self.class_name() == '__NSCFType' or self.class_name() == 'NSCFType'
-
- def get_superclass(self):
- logger = lldb.formatters.Logger.Logger()
- if self.is_valid():
- parent_isa_pointer = self.valobj.CreateChildAtOffset("parent_isa",
- self.sys_params.pointer_size,
- self.sys_params.addr_ptr_type)
- return Class_Data_V2(parent_isa_pointer,self.sys_params)
- else:
- return None
-
- def class_name(self):
- logger = lldb.formatters.Logger.Logger()
- if self.is_valid():
- return self.data.data.name
- else:
- return None
-
- def is_valid(self):
- logger = lldb.formatters.Logger.Logger()
- if self.valid:
- return self.data.is_valid()
- return 0
-
- def __str__(self):
- logger = lldb.formatters.Logger.Logger()
- return 'isaPointer = ' + hex(self.isaPointer) + "\n" + \
- "superclassIsaPointer = " + hex(self.superclassIsaPointer) + "\n" + \
- "cachePointer = " + hex(self.cachePointer) + "\n" + \
- "data = " + hex(self.dataPointer)
-
- def is_tagged(self):
- return 0
-
- def instance_size(self,align=0):
- logger = lldb.formatters.Logger.Logger()
- if self.is_valid() == 0:
- return None
- return self.rwt.rot.instance_size(align)
-
-# runtime v1 is much less intricate than v2 and stores relevant information directly in the class_t object
+ self.data = RwT_Data(self.rwt, self.sys_params)
+
+ # perform sanity checks on the contents of this class_t
+ # this call tries to minimize the amount of data fetched- as soon as we have "proven"
+ # that we have an invalid object, we stop reading
+ def check_valid(self):
+ logger = lldb.formatters.Logger.Logger()
+ self.valid = 1
+
+ self.isaPointer = Utilities.read_child_of(
+ self.valobj, 0, self.sys_params.types_cache.addr_ptr_type)
+ if not(
+ Utilities.is_valid_pointer(
+ self.isaPointer,
+ self.sys_params.pointer_size,
+ allow_tagged=0)):
+ logger >> "Marking as invalid - isaPointer is invalid"
+ self.valid = 0
+ return
+ if not(Utilities.is_allowed_pointer(self.isaPointer)):
+ logger >> "Marking as invalid - isaPointer is not allowed"
+ self.valid = 0
+ return
+
+ self.cachePointer = Utilities.read_child_of(
+ self.valobj,
+ 2 * self.sys_params.pointer_size,
+ self.sys_params.types_cache.addr_ptr_type)
+ if not(
+ Utilities.is_valid_pointer(
+ self.cachePointer,
+ self.sys_params.pointer_size,
+ allow_tagged=0)):
+ logger >> "Marking as invalid - cachePointer is invalid"
+ self.valid = 0
+ return
+ if not(Utilities.is_allowed_pointer(self.cachePointer)):
+ logger >> "Marking as invalid - cachePointer is not allowed"
+ self.valid = 0
+ return
+ self.dataPointer = Utilities.read_child_of(
+ self.valobj,
+ 4 * self.sys_params.pointer_size,
+ self.sys_params.types_cache.addr_ptr_type)
+ if not(
+ Utilities.is_valid_pointer(
+ self.dataPointer,
+ self.sys_params.pointer_size,
+ allow_tagged=0)):
+ logger >> "Marking as invalid - dataPointer is invalid"
+ self.valid = 0
+ return
+ if not(Utilities.is_allowed_pointer(self.dataPointer)):
+ logger >> "Marking as invalid - dataPointer is not allowed"
+ self.valid = 0
+ return
+
+ self.superclassIsaPointer = Utilities.read_child_of(
+ self.valobj,
+ 1 * self.sys_params.pointer_size,
+ self.sys_params.types_cache.addr_ptr_type)
+ if not(
+ Utilities.is_valid_pointer(
+ self.superclassIsaPointer,
+ self.sys_params.pointer_size,
+ allow_tagged=0,
+ allow_NULL=1)):
+ logger >> "Marking as invalid - superclassIsa is invalid"
+ self.valid = 0
+ return
+ if not(Utilities.is_allowed_pointer(self.superclassIsaPointer)):
+ logger >> "Marking as invalid - superclassIsa is not allowed"
+ self.valid = 0
+ return
+
+ # in general, KVO is implemented by transparently subclassing
+ # however, there could be exceptions where a class does something else
+ # internally to implement the feature - this method will have no clue that a class
+ # has been KVO'ed unless the standard implementation technique is used
+ def is_kvo(self):
+ logger = lldb.formatters.Logger.Logger()
+ if self.is_valid():
+ if self.class_name().startswith("NSKVONotifying_"):
+ return 1
+ return 0
+
+ # some CF classes have a valid ObjC isa in their CFRuntimeBase
+ # but instead of being class-specific this isa points to a match-'em-all class
+ # which is __NSCFType (the versions without __ also exists and we are matching to it
+ # just to be on the safe side)
+ def is_cftype(self):
+ logger = lldb.formatters.Logger.Logger()
+ if self.is_valid():
+ return self.class_name() == '__NSCFType' or self.class_name() == 'NSCFType'
+
+ def get_superclass(self):
+ logger = lldb.formatters.Logger.Logger()
+ if self.is_valid():
+ parent_isa_pointer = self.valobj.CreateChildAtOffset(
+ "parent_isa", self.sys_params.pointer_size, self.sys_params.addr_ptr_type)
+ return Class_Data_V2(parent_isa_pointer, self.sys_params)
+ else:
+ return None
+
+ def class_name(self):
+ logger = lldb.formatters.Logger.Logger()
+ if self.is_valid():
+ return self.data.data.name
+ else:
+ return None
+
+ def is_valid(self):
+ logger = lldb.formatters.Logger.Logger()
+ if self.valid:
+ return self.data.is_valid()
+ return 0
+
+ def __str__(self):
+ logger = lldb.formatters.Logger.Logger()
+ return 'isaPointer = ' + hex(self.isaPointer) + "\n" + \
+ "superclassIsaPointer = " + hex(self.superclassIsaPointer) + "\n" + \
+ "cachePointer = " + hex(self.cachePointer) + "\n" + \
+ "data = " + hex(self.dataPointer)
+
+ def is_tagged(self):
+ return 0
+
+ def instance_size(self, align=0):
+ logger = lldb.formatters.Logger.Logger()
+ if self.is_valid() == 0:
+ return None
+ return self.rwt.rot.instance_size(align)
+
+# runtime v1 is much less intricate than v2 and stores relevant
+# information directly in the class_t object
+
+
class Class_Data_V1:
- def __init__(self,isa_pointer,params):
- logger = lldb.formatters.Logger.Logger()
- if (isa_pointer != None) and (Utilities.is_valid_pointer(isa_pointer.GetValueAsUnsigned(),params.pointer_size, allow_tagged=0)):
- self.valid = 1
- self.sys_params = params
- self.valobj = isa_pointer
- self.check_valid()
- else:
- logger >> "Marking as invalid - isaPointer is invalid or None"
- self.valid = 0
- if self.valid:
- self.name = Utilities.read_ascii(self.valobj.GetTarget().GetProcess(),self.namePointer)
- if not(Utilities.is_valid_identifier(self.name)):
- logger >> "Marking as invalid - name is not valid"
- self.valid = 0
-
- # perform sanity checks on the contents of this class_t
- def check_valid(self):
- logger = lldb.formatters.Logger.Logger()
- self.valid = 1
-
- self.isaPointer = Utilities.read_child_of(self.valobj,0,self.sys_params.types_cache.addr_ptr_type)
- if not(Utilities.is_valid_pointer(self.isaPointer,self.sys_params.pointer_size,allow_tagged=0)):
- logger >> "Marking as invalid - isaPointer is invalid"
- self.valid = 0
- return
-
- self.superclassIsaPointer = Utilities.read_child_of(self.valobj,1*self.sys_params.pointer_size,self.sys_params.types_cache.addr_ptr_type)
- if not(Utilities.is_valid_pointer(self.superclassIsaPointer,self.sys_params.pointer_size,allow_tagged=0,allow_NULL=1)):
- logger >> "Marking as invalid - superclassIsa is invalid"
- self.valid = 0
- return
-
- self.namePointer = Utilities.read_child_of(self.valobj,2*self.sys_params.pointer_size,self.sys_params.types_cache.addr_ptr_type)
- #if not(Utilities.is_valid_pointer(self.namePointer,self.sys_params.pointer_size,allow_tagged=0,allow_NULL=0)):
- # self.valid = 0
- # return
-
- # in general, KVO is implemented by transparently subclassing
- # however, there could be exceptions where a class does something else
- # internally to implement the feature - this method will have no clue that a class
- # has been KVO'ed unless the standard implementation technique is used
- def is_kvo(self):
- logger = lldb.formatters.Logger.Logger()
- if self.is_valid():
- if self.class_name().startswith("NSKVONotifying_"):
- return 1
- return 0
-
- # some CF classes have a valid ObjC isa in their CFRuntimeBase
- # but instead of being class-specific this isa points to a match-'em-all class
- # which is __NSCFType (the versions without __ also exists and we are matching to it
- # just to be on the safe side)
- def is_cftype(self):
- logger = lldb.formatters.Logger.Logger()
- if self.is_valid():
- return self.class_name() == '__NSCFType' or self.class_name() == 'NSCFType'
-
- def get_superclass(self):
- logger = lldb.formatters.Logger.Logger()
- if self.is_valid():
- parent_isa_pointer = self.valobj.CreateChildAtOffset("parent_isa",
- self.sys_params.pointer_size,
- self.sys_params.addr_ptr_type)
- return Class_Data_V1(parent_isa_pointer,self.sys_params)
- else:
- return None
-
- def class_name(self):
- logger = lldb.formatters.Logger.Logger()
- if self.is_valid():
- return self.name
- else:
- return None
-
- def is_valid(self):
- return self.valid
-
- def __str__(self):
- logger = lldb.formatters.Logger.Logger()
- return 'isaPointer = ' + hex(self.isaPointer) + "\n" + \
- "superclassIsaPointer = " + hex(self.superclassIsaPointer) + "\n" + \
- "namePointer = " + hex(self.namePointer) + " --> " + self.name + \
- "instanceSize = " + hex(self.instanceSize()) + "\n"
-
- def is_tagged(self):
- return 0
-
- def instance_size(self,align=0):
- logger = lldb.formatters.Logger.Logger()
- if self.is_valid() == 0:
- return None
- if self.instanceSize is None:
- self.instanceSize = Utilities.read_child_of(self.valobj,5*self.sys_params.pointer_size,self.sys_params.types_cache.addr_ptr_type)
- if align:
- unalign = self.instance_size(0)
- if self.sys_params.is_64_bit:
- return ((unalign + 7) & ~7) % 0x100000000
- else:
- return ((unalign + 3) & ~3) % 0x100000000
- else:
- return self.instanceSize
+
+ def __init__(self, isa_pointer, params):
+ logger = lldb.formatters.Logger.Logger()
+ if (isa_pointer is not None) and (Utilities.is_valid_pointer(
+ isa_pointer.GetValueAsUnsigned(), params.pointer_size, allow_tagged=0)):
+ self.valid = 1
+ self.sys_params = params
+ self.valobj = isa_pointer
+ self.check_valid()
+ else:
+ logger >> "Marking as invalid - isaPointer is invalid or None"
+ self.valid = 0
+ if self.valid:
+ self.name = Utilities.read_ascii(
+ self.valobj.GetTarget().GetProcess(), self.namePointer)
+ if not(Utilities.is_valid_identifier(self.name)):
+ logger >> "Marking as invalid - name is not valid"
+ self.valid = 0
+
+ # perform sanity checks on the contents of this class_t
+ def check_valid(self):
+ logger = lldb.formatters.Logger.Logger()
+ self.valid = 1
+
+ self.isaPointer = Utilities.read_child_of(
+ self.valobj, 0, self.sys_params.types_cache.addr_ptr_type)
+ if not(
+ Utilities.is_valid_pointer(
+ self.isaPointer,
+ self.sys_params.pointer_size,
+ allow_tagged=0)):
+ logger >> "Marking as invalid - isaPointer is invalid"
+ self.valid = 0
+ return
+
+ self.superclassIsaPointer = Utilities.read_child_of(
+ self.valobj,
+ 1 * self.sys_params.pointer_size,
+ self.sys_params.types_cache.addr_ptr_type)
+ if not(
+ Utilities.is_valid_pointer(
+ self.superclassIsaPointer,
+ self.sys_params.pointer_size,
+ allow_tagged=0,
+ allow_NULL=1)):
+ logger >> "Marking as invalid - superclassIsa is invalid"
+ self.valid = 0
+ return
+
+ self.namePointer = Utilities.read_child_of(
+ self.valobj,
+ 2 * self.sys_params.pointer_size,
+ self.sys_params.types_cache.addr_ptr_type)
+ # if not(Utilities.is_valid_pointer(self.namePointer,self.sys_params.pointer_size,allow_tagged=0,allow_NULL=0)):
+ # self.valid = 0
+ # return
+
+ # in general, KVO is implemented by transparently subclassing
+ # however, there could be exceptions where a class does something else
+ # internally to implement the feature - this method will have no clue that a class
+ # has been KVO'ed unless the standard implementation technique is used
+ def is_kvo(self):
+ logger = lldb.formatters.Logger.Logger()
+ if self.is_valid():
+ if self.class_name().startswith("NSKVONotifying_"):
+ return 1
+ return 0
+
+ # some CF classes have a valid ObjC isa in their CFRuntimeBase
+ # but instead of being class-specific this isa points to a match-'em-all class
+ # which is __NSCFType (the versions without __ also exists and we are matching to it
+ # just to be on the safe side)
+ def is_cftype(self):
+ logger = lldb.formatters.Logger.Logger()
+ if self.is_valid():
+ return self.class_name() == '__NSCFType' or self.class_name() == 'NSCFType'
+
+ def get_superclass(self):
+ logger = lldb.formatters.Logger.Logger()
+ if self.is_valid():
+ parent_isa_pointer = self.valobj.CreateChildAtOffset(
+ "parent_isa", self.sys_params.pointer_size, self.sys_params.addr_ptr_type)
+ return Class_Data_V1(parent_isa_pointer, self.sys_params)
+ else:
+ return None
+
+ def class_name(self):
+ logger = lldb.formatters.Logger.Logger()
+ if self.is_valid():
+ return self.name
+ else:
+ return None
+
+ def is_valid(self):
+ return self.valid
+
+ def __str__(self):
+ logger = lldb.formatters.Logger.Logger()
+ return 'isaPointer = ' + hex(self.isaPointer) + "\n" + \
+ "superclassIsaPointer = " + hex(self.superclassIsaPointer) + "\n" + \
+ "namePointer = " + hex(self.namePointer) + " --> " + self.name + \
+ "instanceSize = " + hex(self.instanceSize()) + "\n"
+
+ def is_tagged(self):
+ return 0
+
+ def instance_size(self, align=0):
+ logger = lldb.formatters.Logger.Logger()
+ if self.is_valid() == 0:
+ return None
+ if self.instanceSize is None:
+ self.instanceSize = Utilities.read_child_of(
+ self.valobj,
+ 5 * self.sys_params.pointer_size,
+ self.sys_params.types_cache.addr_ptr_type)
+ if align:
+ unalign = self.instance_size(0)
+ if self.sys_params.is_64_bit:
+ return ((unalign + 7) & ~7) % 0x100000000
+ else:
+ return ((unalign + 3) & ~3) % 0x100000000
+ else:
+ return self.instanceSize
# these are the only tagged pointers values for current versions
# of OSX - they might change in future OS releases, and no-one is
# advised to rely on these values, or any of the bitmasking formulas
# in TaggedClass_Data. doing otherwise is at your own risk
-TaggedClass_Values_Lion = {1 : 'NSNumber', \
- 5: 'NSManagedObject', \
- 6: 'NSDate', \
- 7: 'NSDateTS' };
-TaggedClass_Values_NMOS = {0: 'NSAtom', \
- 3 : 'NSNumber', \
- 4: 'NSDateTS', \
- 5: 'NSManagedObject', \
- 6: 'NSDate' };
+TaggedClass_Values_Lion = {1: 'NSNumber',
+ 5: 'NSManagedObject',
+ 6: 'NSDate',
+ 7: 'NSDateTS'}
+TaggedClass_Values_NMOS = {0: 'NSAtom',
+ 3: 'NSNumber',
+ 4: 'NSDateTS',
+ 5: 'NSManagedObject',
+ 6: 'NSDate'}
+
class TaggedClass_Data:
- def __init__(self,pointer,params):
- logger = lldb.formatters.Logger.Logger()
- global TaggedClass_Values_Lion,TaggedClass_Values_NMOS
- self.valid = 1
- self.name = None
- self.sys_params = params
- self.valobj = pointer
- self.val = (pointer & ~0x0000000000000000FF) >> 8
- self.class_bits = (pointer & 0xE) >> 1
- self.i_bits = (pointer & 0xF0) >> 4
-
- if self.sys_params.is_lion:
- if self.class_bits in TaggedClass_Values_Lion:
- self.name = TaggedClass_Values_Lion[self.class_bits]
- else:
- logger >> "Marking as invalid - not a good tagged pointer for Lion"
- self.valid = 0
- else:
- if self.class_bits in TaggedClass_Values_NMOS:
- self.name = TaggedClass_Values_NMOS[self.class_bits]
- else:
- logger >> "Marking as invalid - not a good tagged pointer for NMOS"
- self.valid = 0
-
-
- def is_valid(self):
- return self.valid
-
- def class_name(self):
- logger = lldb.formatters.Logger.Logger()
- if self.is_valid():
- return self.name
- else:
- return 0
-
- def value(self):
- return self.val if self.is_valid() else None
-
- def info_bits(self):
- return self.i_bits if self.is_valid() else None
-
- def is_kvo(self):
- return 0
-
- def is_cftype(self):
- return 0
-
- # we would need to go around looking for the superclass or ask the runtime
- # for now, we seem not to require support for this operation so we will merrily
- # pretend to be at a root point in the hierarchy
- def get_superclass(self):
- return None
-
- # anything that is handled here is tagged
- def is_tagged(self):
- return 1
-
- # it seems reasonable to say that a tagged pointer is the size of a pointer
- def instance_size(self,align=0):
- logger = lldb.formatters.Logger.Logger()
- if self.is_valid() == 0:
- return None
- return self.sys_params.pointer_size
+
+ def __init__(self, pointer, params):
+ logger = lldb.formatters.Logger.Logger()
+ global TaggedClass_Values_Lion, TaggedClass_Values_NMOS
+ self.valid = 1
+ self.name = None
+ self.sys_params = params
+ self.valobj = pointer
+ self.val = (pointer & ~0x0000000000000000FF) >> 8
+ self.class_bits = (pointer & 0xE) >> 1
+ self.i_bits = (pointer & 0xF0) >> 4
+
+ if self.sys_params.is_lion:
+ if self.class_bits in TaggedClass_Values_Lion:
+ self.name = TaggedClass_Values_Lion[self.class_bits]
+ else:
+ logger >> "Marking as invalid - not a good tagged pointer for Lion"
+ self.valid = 0
+ else:
+ if self.class_bits in TaggedClass_Values_NMOS:
+ self.name = TaggedClass_Values_NMOS[self.class_bits]
+ else:
+ logger >> "Marking as invalid - not a good tagged pointer for NMOS"
+ self.valid = 0
+
+ def is_valid(self):
+ return self.valid
+
+ def class_name(self):
+ logger = lldb.formatters.Logger.Logger()
+ if self.is_valid():
+ return self.name
+ else:
+ return 0
+
+ def value(self):
+ return self.val if self.is_valid() else None
+
+ def info_bits(self):
+ return self.i_bits if self.is_valid() else None
+
+ def is_kvo(self):
+ return 0
+
+ def is_cftype(self):
+ return 0
+
+ # we would need to go around looking for the superclass or ask the runtime
+ # for now, we seem not to require support for this operation so we will merrily
+ # pretend to be at a root point in the hierarchy
+ def get_superclass(self):
+ return None
+
+ # anything that is handled here is tagged
+ def is_tagged(self):
+ return 1
+
+ # it seems reasonable to say that a tagged pointer is the size of a pointer
+ def instance_size(self, align=0):
+ logger = lldb.formatters.Logger.Logger()
+ if self.is_valid() == 0:
+ return None
+ return self.sys_params.pointer_size
class InvalidClass_Data:
- def __init__(self):
- pass
- def is_valid(self):
- return 0
+
+ def __init__(self):
+ pass
+
+ def is_valid(self):
+ return 0
class Version:
- def __init__(self, major, minor, release, build_string):
- self._major = major
- self._minor = minor
- self._release = release
- self._build_string = build_string
-
- def get_major(self):
- return self._major
- def get_minor(self):
- return self._minor
- def get_release(self):
- return self._release
- def get_build_string(self):
- return self._build_string
-
- major = property(get_major,None)
- minor = property(get_minor,None)
- release = property(get_release,None)
- build_string = property(get_build_string,None)
-
- def __lt__(self,other):
- if (self.major < other.major):
- return 1
- if (self.minor < other.minor):
- return 1
- if (self.release < other.release):
- return 1
- # build strings are not compared since they are heavily platform-dependent and might not always
- # be available
- return 0
-
- def __eq__(self,other):
- return (self.major == other.major) and \
- (self.minor == other.minor) and \
- (self.release == other.release) and \
- (self.build_string == other.build_string)
-
- # Python 2.6 doesn't have functools.total_ordering, so we have to implement
- # other comparators
- def __gt__(self, other):
- return other < self
-
- def __le__(self, other):
- return not other < self
-
- def __ge__(self, other):
- return not self < other
+
+ def __init__(self, major, minor, release, build_string):
+ self._major = major
+ self._minor = minor
+ self._release = release
+ self._build_string = build_string
+
+ def get_major(self):
+ return self._major
+
+ def get_minor(self):
+ return self._minor
+
+ def get_release(self):
+ return self._release
+
+ def get_build_string(self):
+ return self._build_string
+
+ major = property(get_major, None)
+ minor = property(get_minor, None)
+ release = property(get_release, None)
+ build_string = property(get_build_string, None)
+
+ def __lt__(self, other):
+ if (self.major < other.major):
+ return 1
+ if (self.minor < other.minor):
+ return 1
+ if (self.release < other.release):
+ return 1
+ # build strings are not compared since they are heavily platform-dependent and might not always
+ # be available
+ return 0
+
+ def __eq__(self, other):
+ return (self.major == other.major) and \
+ (self.minor == other.minor) and \
+ (self.release == other.release) and \
+ (self.build_string == other.build_string)
+
+ # Python 2.6 doesn't have functools.total_ordering, so we have to implement
+ # other comparators
+ def __gt__(self, other):
+ return other < self
+
+ def __le__(self, other):
+ return not other < self
+
+ def __ge__(self, other):
+ return not self < other
runtime_version = lldb.formatters.cache.Cache()
@@ -568,214 +653,249 @@ os_version = lldb.formatters.cache.Cache()
types_caches = lldb.formatters.cache.Cache()
isa_caches = lldb.formatters.cache.Cache()
+
class SystemParameters:
- def __init__(self,valobj):
- logger = lldb.formatters.Logger.Logger()
- self.adjust_for_architecture(valobj)
- self.adjust_for_process(valobj)
-
- def adjust_for_process(self, valobj):
- logger = lldb.formatters.Logger.Logger()
- global runtime_version
- global os_version
- global types_caches
- global isa_caches
-
- process = valobj.GetTarget().GetProcess()
- self.pid = process.GetUniqueID() # using the unique ID for added guarantees (see svn revision 172628 for further details)
-
- if runtime_version.look_for_key(self.pid):
- self.runtime_version = runtime_version.get_value(self.pid)
- else:
- self.runtime_version = ObjCRuntime.runtime_version(process)
- runtime_version.add_item(self.pid,self.runtime_version)
-
- if os_version.look_for_key(self.pid):
- self.is_lion = os_version.get_value(self.pid)
- else:
- self.is_lion = Utilities.check_is_osx_lion(valobj.GetTarget())
- os_version.add_item(self.pid,self.is_lion)
-
- if types_caches.look_for_key(self.pid):
- self.types_cache = types_caches.get_value(self.pid)
- else:
- self.types_cache = lldb.formatters.attrib_fromdict.AttributesDictionary(allow_reset=0)
- self.types_cache.addr_type = valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong)
- self.types_cache.addr_ptr_type = self.types_cache.addr_type.GetPointerType()
- self.types_cache.uint32_t = valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt)
- types_caches.add_item(self.pid,self.types_cache)
-
- if isa_caches.look_for_key(self.pid):
- self.isa_cache = isa_caches.get_value(self.pid)
- else:
- self.isa_cache = lldb.formatters.cache.Cache()
- isa_caches.add_item(self.pid,self.isa_cache)
-
- def adjust_for_architecture(self,valobj):
- process = valobj.GetTarget().GetProcess()
- self.pointer_size = process.GetAddressByteSize()
- self.is_64_bit = (self.pointer_size == 8)
- self.endianness = process.GetByteOrder()
- self.is_little = (self.endianness == lldb.eByteOrderLittle)
- self.cfruntime_size = 16 if self.is_64_bit else 8
-
- # a simple helper function that makes it more explicit that one is calculating
- # an offset that is made up of X pointers and Y bytes of additional data
- # taking into account pointer size - if you know there is going to be some padding
- # you can pass that in and it will be taken into account (since padding may be different between
- # 32 and 64 bit versions, you can pass padding value for both, the right one will be used)
- def calculate_offset(self, num_pointers = 0, bytes_count = 0, padding32 = 0, padding64 = 0):
- value = bytes_count + num_pointers*self.pointer_size
- return value + padding64 if self.is_64_bit else value + padding32
+
+ def __init__(self, valobj):
+ logger = lldb.formatters.Logger.Logger()
+ self.adjust_for_architecture(valobj)
+ self.adjust_for_process(valobj)
+
+ def adjust_for_process(self, valobj):
+ logger = lldb.formatters.Logger.Logger()
+ global runtime_version
+ global os_version
+ global types_caches
+ global isa_caches
+
+ process = valobj.GetTarget().GetProcess()
+ # using the unique ID for added guarantees (see svn revision 172628 for
+ # further details)
+ self.pid = process.GetUniqueID()
+
+ if runtime_version.look_for_key(self.pid):
+ self.runtime_version = runtime_version.get_value(self.pid)
+ else:
+ self.runtime_version = ObjCRuntime.runtime_version(process)
+ runtime_version.add_item(self.pid, self.runtime_version)
+
+ if os_version.look_for_key(self.pid):
+ self.is_lion = os_version.get_value(self.pid)
+ else:
+ self.is_lion = Utilities.check_is_osx_lion(valobj.GetTarget())
+ os_version.add_item(self.pid, self.is_lion)
+
+ if types_caches.look_for_key(self.pid):
+ self.types_cache = types_caches.get_value(self.pid)
+ else:
+ self.types_cache = lldb.formatters.attrib_fromdict.AttributesDictionary(
+ allow_reset=0)
+ self.types_cache.addr_type = valobj.GetType(
+ ).GetBasicType(lldb.eBasicTypeUnsignedLong)
+ self.types_cache.addr_ptr_type = self.types_cache.addr_type.GetPointerType()
+ self.types_cache.uint32_t = valobj.GetType(
+ ).GetBasicType(lldb.eBasicTypeUnsignedInt)
+ types_caches.add_item(self.pid, self.types_cache)
+
+ if isa_caches.look_for_key(self.pid):
+ self.isa_cache = isa_caches.get_value(self.pid)
+ else:
+ self.isa_cache = lldb.formatters.cache.Cache()
+ isa_caches.add_item(self.pid, self.isa_cache)
+
+ def adjust_for_architecture(self, valobj):
+ process = valobj.GetTarget().GetProcess()
+ self.pointer_size = process.GetAddressByteSize()
+ self.is_64_bit = (self.pointer_size == 8)
+ self.endianness = process.GetByteOrder()
+ self.is_little = (self.endianness == lldb.eByteOrderLittle)
+ self.cfruntime_size = 16 if self.is_64_bit else 8
+
+ # a simple helper function that makes it more explicit that one is calculating
+ # an offset that is made up of X pointers and Y bytes of additional data
+ # taking into account pointer size - if you know there is going to be some padding
+ # you can pass that in and it will be taken into account (since padding may be different between
+ # 32 and 64 bit versions, you can pass padding value for both, the right
+ # one will be used)
+ def calculate_offset(
+ self,
+ num_pointers=0,
+ bytes_count=0,
+ padding32=0,
+ padding64=0):
+ value = bytes_count + num_pointers * self.pointer_size
+ return value + padding64 if self.is_64_bit else value + padding32
+
class ObjCRuntime:
- # the ObjC runtime has no explicit "version" field that we can use
- # instead, we discriminate v1 from v2 by looking for the presence
- # of a well-known section only present in v1
- @staticmethod
- def runtime_version(process):
- logger = lldb.formatters.Logger.Logger()
- if process.IsValid() == 0:
- logger >> "No process - bailing out"
- return None
- target = process.GetTarget()
- num_modules = target.GetNumModules()
- module_objc = None
- for idx in range(num_modules):
- module = target.GetModuleAtIndex(idx)
- if module.GetFileSpec().GetFilename() == 'libobjc.A.dylib':
- module_objc = module
- break
- if module_objc is None or module_objc.IsValid() == 0:
- logger >> "no libobjc - bailing out"
- return None
- num_sections = module.GetNumSections()
- section_objc = None
- for idx in range(num_sections):
- section = module.GetSectionAtIndex(idx)
- if section.GetName() == '__OBJC':
- section_objc = section
- break
- if section_objc != None and section_objc.IsValid():
- logger >> "found __OBJC: v1"
- return 1
- logger >> "no __OBJC: v2"
- return 2
-
- @staticmethod
- def runtime_from_isa(isa):
- logger = lldb.formatters.Logger.Logger()
- runtime = ObjCRuntime(isa)
- runtime.isa = isa
- return runtime
-
- def __init__(self,valobj):
- logger = lldb.formatters.Logger.Logger()
- self.valobj = valobj
- self.adjust_for_architecture()
- self.sys_params = SystemParameters(self.valobj)
- self.unsigned_value = self.valobj.GetValueAsUnsigned()
- self.isa_value = None
-
- def adjust_for_architecture(self):
- pass
+ # the ObjC runtime has no explicit "version" field that we can use
+ # instead, we discriminate v1 from v2 by looking for the presence
+ # of a well-known section only present in v1
+ @staticmethod
+ def runtime_version(process):
+ logger = lldb.formatters.Logger.Logger()
+ if process.IsValid() == 0:
+ logger >> "No process - bailing out"
+ return None
+ target = process.GetTarget()
+ num_modules = target.GetNumModules()
+ module_objc = None
+ for idx in range(num_modules):
+ module = target.GetModuleAtIndex(idx)
+ if module.GetFileSpec().GetFilename() == 'libobjc.A.dylib':
+ module_objc = module
+ break
+ if module_objc is None or module_objc.IsValid() == 0:
+ logger >> "no libobjc - bailing out"
+ return None
+ num_sections = module.GetNumSections()
+ section_objc = None
+ for idx in range(num_sections):
+ section = module.GetSectionAtIndex(idx)
+ if section.GetName() == '__OBJC':
+ section_objc = section
+ break
+ if section_objc is not None and section_objc.IsValid():
+ logger >> "found __OBJC: v1"
+ return 1
+ logger >> "no __OBJC: v2"
+ return 2
+
+ @staticmethod
+ def runtime_from_isa(isa):
+ logger = lldb.formatters.Logger.Logger()
+ runtime = ObjCRuntime(isa)
+ runtime.isa = isa
+ return runtime
+
+ def __init__(self, valobj):
+ logger = lldb.formatters.Logger.Logger()
+ self.valobj = valobj
+ self.adjust_for_architecture()
+ self.sys_params = SystemParameters(self.valobj)
+ self.unsigned_value = self.valobj.GetValueAsUnsigned()
+ self.isa_value = None
+
+ def adjust_for_architecture(self):
+ pass
# an ObjC pointer can either be tagged or must be aligned
- def is_tagged(self):
- logger = lldb.formatters.Logger.Logger()
- if self.valobj is None:
- return 0
- return (Utilities.is_valid_pointer(self.unsigned_value,self.sys_params.pointer_size, allow_tagged=1) and \
- not(Utilities.is_valid_pointer(self.unsigned_value,self.sys_params.pointer_size, allow_tagged=0)))
-
- def is_valid(self):
- logger = lldb.formatters.Logger.Logger()
- if self.valobj is None:
- return 0
- if self.valobj.IsInScope() == 0:
- return 0
- return Utilities.is_valid_pointer(self.unsigned_value,self.sys_params.pointer_size, allow_tagged=1)
-
- def is_nil(self):
- return self.unsigned_value == 0
-
- def read_isa(self):
- logger = lldb.formatters.Logger.Logger()
- if self.isa_value != None:
- logger >> "using cached isa"
- return self.isa_value
- self.isa_pointer = self.valobj.CreateChildAtOffset("cfisa",
- 0,
- self.sys_params.types_cache.addr_ptr_type)
- if self.isa_pointer is None or self.isa_pointer.IsValid() == 0:
- logger >> "invalid isa - bailing out"
- return None;
- self.isa_value = self.isa_pointer.GetValueAsUnsigned(1)
- if self.isa_value == 1:
- logger >> "invalid isa value - bailing out"
- return None;
- return Ellipsis
-
- def read_class_data(self):
- logger = lldb.formatters.Logger.Logger()
- global isa_cache
- if self.is_tagged():
- # tagged pointers only exist in ObjC v2
- if self.sys_params.runtime_version == 2:
- logger >> "on v2 and tagged - maybe"
- # not every odd-valued pointer is actually tagged. most are just plain wrong
- # we could try and predetect this before even creating a TaggedClass_Data object
- # but unless performance requires it, this seems a cleaner way to tackle the task
- tentative_tagged = TaggedClass_Data(self.unsigned_value,self.sys_params)
- if tentative_tagged.is_valid():
- logger >> "truly tagged"
- return tentative_tagged
- else:
- logger >> "not tagged - error"
- return InvalidClass_Data()
- else:
- logger >> "on v1 and tagged - error"
- return InvalidClass_Data()
- if self.is_valid() == 0 or self.read_isa() is None:
- return InvalidClass_Data()
- data = self.sys_params.isa_cache.get_value(self.isa_value,default=None)
- if data != None:
- return data
- if self.sys_params.runtime_version == 2:
- data = Class_Data_V2(self.isa_pointer,self.sys_params)
- else:
- data = Class_Data_V1(self.isa_pointer,self.sys_params)
- if data is None:
- return InvalidClass_Data()
- if data.is_valid():
- self.sys_params.isa_cache.add_item(self.isa_value,data,ok_to_replace=1)
- return data
-
-# these classes below can be used by the data formatters to provide a consistent message that describes a given runtime-generated situation
+ def is_tagged(self):
+ logger = lldb.formatters.Logger.Logger()
+ if self.valobj is None:
+ return 0
+ return (
+ Utilities.is_valid_pointer(
+ self.unsigned_value,
+ self.sys_params.pointer_size,
+ allow_tagged=1) and not(
+ Utilities.is_valid_pointer(
+ self.unsigned_value,
+ self.sys_params.pointer_size,
+ allow_tagged=0)))
+
+ def is_valid(self):
+ logger = lldb.formatters.Logger.Logger()
+ if self.valobj is None:
+ return 0
+ if self.valobj.IsInScope() == 0:
+ return 0
+ return Utilities.is_valid_pointer(
+ self.unsigned_value,
+ self.sys_params.pointer_size,
+ allow_tagged=1)
+
+ def is_nil(self):
+ return self.unsigned_value == 0
+
+ def read_isa(self):
+ logger = lldb.formatters.Logger.Logger()
+ if self.isa_value is not None:
+ logger >> "using cached isa"
+ return self.isa_value
+ self.isa_pointer = self.valobj.CreateChildAtOffset(
+ "cfisa", 0, self.sys_params.types_cache.addr_ptr_type)
+ if self.isa_pointer is None or self.isa_pointer.IsValid() == 0:
+ logger >> "invalid isa - bailing out"
+ return None
+ self.isa_value = self.isa_pointer.GetValueAsUnsigned(1)
+ if self.isa_value == 1:
+ logger >> "invalid isa value - bailing out"
+ return None
+ return Ellipsis
+
+ def read_class_data(self):
+ logger = lldb.formatters.Logger.Logger()
+ global isa_cache
+ if self.is_tagged():
+ # tagged pointers only exist in ObjC v2
+ if self.sys_params.runtime_version == 2:
+ logger >> "on v2 and tagged - maybe"
+ # not every odd-valued pointer is actually tagged. most are just plain wrong
+ # we could try and predetect this before even creating a TaggedClass_Data object
+ # but unless performance requires it, this seems a cleaner way
+ # to tackle the task
+ tentative_tagged = TaggedClass_Data(
+ self.unsigned_value, self.sys_params)
+ if tentative_tagged.is_valid():
+ logger >> "truly tagged"
+ return tentative_tagged
+ else:
+ logger >> "not tagged - error"
+ return InvalidClass_Data()
+ else:
+ logger >> "on v1 and tagged - error"
+ return InvalidClass_Data()
+ if self.is_valid() == 0 or self.read_isa() is None:
+ return InvalidClass_Data()
+ data = self.sys_params.isa_cache.get_value(
+ self.isa_value, default=None)
+ if data is not None:
+ return data
+ if self.sys_params.runtime_version == 2:
+ data = Class_Data_V2(self.isa_pointer, self.sys_params)
+ else:
+ data = Class_Data_V1(self.isa_pointer, self.sys_params)
+ if data is None:
+ return InvalidClass_Data()
+ if data.is_valid():
+ self.sys_params.isa_cache.add_item(
+ self.isa_value, data, ok_to_replace=1)
+ return data
+
+# these classes below can be used by the data formatters to provide a
+# consistent message that describes a given runtime-generated situation
+
+
class SpecialSituation_Description:
- def message(self):
- return ''
+
+ def message(self):
+ return ''
+
class InvalidPointer_Description(SpecialSituation_Description):
- def __init__(self,nil):
- self.is_nil = nil
+ def __init__(self, nil):
+ self.is_nil = nil
+
+ def message(self):
+ if self.is_nil:
+ return '@"<nil>"'
+ else:
+ return '<invalid pointer>'
- def message(self):
- if self.is_nil:
- return '@"<nil>"'
- else:
- return '<invalid pointer>'
class InvalidISA_Description(SpecialSituation_Description):
- def __init__(self):
- pass
+ def __init__(self):
+ pass
+
+ def message(self):
+ return '<not an Objective-C object>'
- def message(self):
- return '<not an Objective-C object>'
class ThisIsZombie_Description(SpecialSituation_Description):
- def message(self):
- return '<freed object>' \ No newline at end of file
+
+ def message(self):
+ return '<freed object>'
diff --git a/examples/summaries/objc.py b/examples/summaries/objc.py
index 75a4572add7a..486a9c821342 100644
--- a/examples/summaries/objc.py
+++ b/examples/summaries/objc.py
@@ -1,16 +1,19 @@
# Summaries for common ObjC types that require Python scripting
# to be generated fit into this file
-def BOOL_SummaryProvider (valobj,dict):
- if not (valobj.IsValid()):
- return "<invalid>"
- if valobj.GetValueAsUnsigned() == 0:
- return "NO"
- else:
- return "YES"
-def BOOLRef_SummaryProvider (valobj, dict):
- return BOOL_SummaryProvider (valobj.GetChildAtIndex(0),dict)
+def BOOL_SummaryProvider(valobj, dict):
+ if not (valobj.IsValid()):
+ return "<invalid>"
+ if valobj.GetValueAsUnsigned() == 0:
+ return "NO"
+ else:
+ return "YES"
-def BOOLPtr_SummaryProvider (valobj,dict):
- return BOOL_SummaryProvider (valobj.Dereference(),dict)
+
+def BOOLRef_SummaryProvider(valobj, dict):
+ return BOOL_SummaryProvider(valobj.GetChildAtIndex(0), dict)
+
+
+def BOOLPtr_SummaryProvider(valobj, dict):
+ return BOOL_SummaryProvider(valobj.Dereference(), dict)
diff --git a/examples/summaries/pysummary.py b/examples/summaries/pysummary.py
index 71414fdaeb78..22dffd6cae07 100644
--- a/examples/summaries/pysummary.py
+++ b/examples/summaries/pysummary.py
@@ -1,18 +1,24 @@
import lldb
-def pyobj_summary (value,unused):
- if value == None or value.IsValid() == False or value.GetValueAsUnsigned(0) == 0:
- return "<invalid>"
- refcnt = value.GetChildMemberWithName("ob_refcnt")
- expr = "(char*)PyString_AsString( (PyObject*)PyObject_Str( (PyObject*)0x%x) )" % (value.GetValueAsUnsigned(0))
- expr_summary = value.target.EvaluateExpression(expr,lldb.SBExpressionOptions()).GetSummary()
- refcnt_value = "rc = %d" % (refcnt.GetValueAsUnsigned(0))
- return "%s (%s)" % (expr_summary,refcnt_value)
-def __lldb_init_module(debugger, unused):
- debugger.HandleCommand("type summary add PyObject --python-function pysummary.pyobj_summary")
- debugger.HandleCommand("type summary add lldb_private::PythonObject -s ${var.m_py_obj%S}")
- debugger.HandleCommand("type summary add lldb_private::PythonDictionary -s ${var.m_py_obj%S}")
- debugger.HandleCommand("type summary add lldb_private::PythonString -s ${var.m_py_obj%S}")
+def pyobj_summary(value, unused):
+ if value is None or value.IsValid() == False or value.GetValueAsUnsigned(0) == 0:
+ return "<invalid>"
+ refcnt = value.GetChildMemberWithName("ob_refcnt")
+ expr = "(char*)PyString_AsString( (PyObject*)PyObject_Str( (PyObject*)0x%x) )" % (
+ value.GetValueAsUnsigned(0))
+ expr_summary = value.target.EvaluateExpression(
+ expr, lldb.SBExpressionOptions()).GetSummary()
+ refcnt_value = "rc = %d" % (refcnt.GetValueAsUnsigned(0))
+ return "%s (%s)" % (expr_summary, refcnt_value)
+def __lldb_init_module(debugger, unused):
+ debugger.HandleCommand(
+ "type summary add PyObject --python-function pysummary.pyobj_summary")
+ debugger.HandleCommand(
+ "type summary add lldb_private::PythonObject -s ${var.m_py_obj%S}")
+ debugger.HandleCommand(
+ "type summary add lldb_private::PythonDictionary -s ${var.m_py_obj%S}")
+ debugger.HandleCommand(
+ "type summary add lldb_private::PythonString -s ${var.m_py_obj%S}")
diff --git a/examples/summaries/sp_cp.py b/examples/summaries/sp_cp.py
index 9aa0a2f4fb93..e2ef18bfea44 100644
--- a/examples/summaries/sp_cp.py
+++ b/examples/summaries/sp_cp.py
@@ -6,56 +6,79 @@ This file is distributed under the University of Illinois Open Source
License. See LICENSE.TXT for details.
"""
+
class SharedPtr_SyntheticChildrenProvider:
- def __init__(self,valobj,dict):
- self.valobj = valobj
- self.update()
- def update(self):
- pass
- def num_children(self):
- return 1
- def get_child_index(self,name):
- if name == "ptr":
- return 0
- if name == "count":
- return 1
- return None
- def get_child_at_index(self,index):
- if index == 0:
- return self.valobj.GetChildMemberWithName('_M_ptr')
- if index == 1:
- return self.valobj.GetChildMemberWithName('_M_refcount').GetChildMemberWithName('_M_pi').GetChildMemberWithName('_M_use_count')
- return None
-
-def SharedPtr_SummaryProvider (valobj,dict):
- return 'use = ' + str(valobj.GetChildMemberWithName("count").GetValueAsUnsigned())
+
+ def __init__(self, valobj, dict):
+ self.valobj = valobj
+ self.update()
+
+ def update(self):
+ pass
+
+ def num_children(self):
+ return 1
+
+ def get_child_index(self, name):
+ if name == "ptr":
+ return 0
+ if name == "count":
+ return 1
+ return None
+
+ def get_child_at_index(self, index):
+ if index == 0:
+ return self.valobj.GetChildMemberWithName('_M_ptr')
+ if index == 1:
+ return self.valobj.GetChildMemberWithName('_M_refcount').GetChildMemberWithName(
+ '_M_pi').GetChildMemberWithName('_M_use_count')
+ return None
+
+
+def SharedPtr_SummaryProvider(valobj, dict):
+ return 'use = ' + \
+ str(valobj.GetChildMemberWithName("count").GetValueAsUnsigned())
+
class ValueObjectSP_SyntheticChildrenProvider:
- def __init__(self,valobj,dict):
- self.valobj = valobj
- self.update()
- def update(self):
- pass
- def num_children(self):
- return 1
- def get_child_index(self,name):
- if name == "ptr":
- return 0
- if name == "count":
- return 1
- return None
- def get_child_at_index(self,index):
- if index == 0:
- return self.valobj.GetChildMemberWithName('ptr_')
- if index == 1:
- return self.valobj.GetChildMemberWithName('cntrl_').GetChildMemberWithName('shared_owners_')
- return None
-
-def ValueObjectSP_SummaryProvider (valobj,dict):
- return 'use = ' + str(1 + valobj.GetChildMemberWithName("count").GetValueAsUnsigned())
+
+ def __init__(self, valobj, dict):
+ self.valobj = valobj
+ self.update()
+
+ def update(self):
+ pass
+
+ def num_children(self):
+ return 1
+
+ def get_child_index(self, name):
+ if name == "ptr":
+ return 0
+ if name == "count":
+ return 1
+ return None
+
+ def get_child_at_index(self, index):
+ if index == 0:
+ return self.valobj.GetChildMemberWithName('ptr_')
+ if index == 1:
+ return self.valobj.GetChildMemberWithName(
+ 'cntrl_').GetChildMemberWithName('shared_owners_')
+ return None
+
+
+def ValueObjectSP_SummaryProvider(valobj, dict):
+ return 'use = ' + \
+ str(1 + valobj.GetChildMemberWithName("count").GetValueAsUnsigned())
+
def __lldb_init_module(debugger, dict):
- debugger.HandleCommand('type summary add -x ".*ValueObjectSP" --expand -F sp_cp.ValueObjectSP_SummaryProvider')
- debugger.HandleCommand('type synthetic add -x ".*ValueObjectSP" -l sp_cp.ValueObjectSP_SyntheticChildrenProvider')
- debugger.HandleCommand('type summary add -x ".*SP" --expand -F sp_cp.SharedPtr_SummaryProvider')
- debugger.HandleCommand('type synthetic add -x ".*SP" -l sp_cp.SharedPtr_SyntheticChildrenProvider')
+ debugger.HandleCommand(
+ 'type summary add -x ".*ValueObjectSP" --expand -F sp_cp.ValueObjectSP_SummaryProvider')
+ debugger.HandleCommand(
+ 'type synthetic add -x ".*ValueObjectSP" -l sp_cp.ValueObjectSP_SyntheticChildrenProvider')
+ debugger.HandleCommand(
+ 'type summary add -x ".*SP" --expand -F sp_cp.SharedPtr_SummaryProvider')
+ debugger.HandleCommand(
+ 'type synthetic add -x ".*SP" -l sp_cp.SharedPtr_SyntheticChildrenProvider')
diff --git a/examples/summaries/synth.py b/examples/summaries/synth.py
new file mode 100644
index 000000000000..23f02d9b50f3
--- /dev/null
+++ b/examples/summaries/synth.py
@@ -0,0 +1,66 @@
+import lldb
+
+
+class PythonObjectSyntheticChildProvider(object):
+
+ def __init__(self, value, internal_dict):
+ self.value = value
+ self.values = self.make_children()
+ self.built_values = {}
+ self.bo = self.value.target.byte_order
+ self.ps = self.value.target.addr_size
+
+ def make_children(self):
+ pass
+
+ def num_children(self):
+ return len(self.values)
+
+ def get_child_index(self, name):
+ i = 0
+ for N, value in self.values:
+ if N == name:
+ return i
+ i += 1
+ return None
+
+ def update(self):
+ pass
+
+ def has_children(self):
+ return len(self.values) > 0
+
+ def gen_child(self, name, value):
+ data = None
+ type = None
+ if isinstance(value, int):
+ data = lldb.SBData.CreateDataFromUInt32Array(
+ self.bo, self.ps, [value])
+ type = self.value.target.GetBasicType(lldb.eBasicTypeInt)
+ elif isinstance(value, long):
+ data = lldb.SBData.CreateDataFromUInt64Array(
+ self.bo, self.ps, [value])
+ type = self.value.target.GetBasicType(lldb.eBasicTypeLong)
+ elif isinstance(value, float):
+ data = lldb.SBData.CreateDataFromDoubleArray(
+ self.bo, self.ps, [value])
+ type = self.value.target.GetBasicType(lldb.eBasicTypeDouble)
+ elif isinstance(value, str):
+ data = lldb.SBData.CreateDataFromCString(self.bo, self.ps, value)
+ type = self.value.target.GetBasicType(
+ lldb.eBasicTypeChar).GetArrayType(
+ len(value))
+ if (data is not None) and (type is not None):
+ return self.value.CreateValueFromData(name, data, type)
+ return None
+
+ def get_child_at_index(self, index):
+ if index in self.built_values:
+ return self.built_values[index]
+
+ bv = None
+
+ name, value = self.values[index]
+ bv = self.gen_child(name, value)
+ self.built_values[index] = bv
+ return bv
diff --git a/examples/summaries/unicode_strings.py b/examples/summaries/unicode_strings.py
index 319433ff3c15..a9ba15a10256 100644
--- a/examples/summaries/unicode_strings.py
+++ b/examples/summaries/unicode_strings.py
@@ -11,38 +11,43 @@ License. See LICENSE.TXT for details.
"""
import lldb
-def utf8_summary(value,unused):
- pointer = value.GetChildMemberWithName("first").GetValueAsUnsigned(0)
- length = value.GetChildMemberWithName("second").GetValueAsUnsigned(0)
- if pointer == 0:
- return False
- if length == 0:
- return '""'
- error = lldb.SBError()
- string_data = value.process.ReadMemory(pointer, length, error)
- return '"%s"' % (string_data) # utf8 is safe to emit as-is on OSX
-
-def utf16_summary(value,unused):
- pointer = value.GetChildMemberWithName("first").GetValueAsUnsigned(0)
- length = value.GetChildMemberWithName("second").GetValueAsUnsigned(0)
- # assume length is in bytes - if in UTF16 chars, just multiply by 2
- if pointer == 0:
- return False
- if length == 0:
- return '""'
- error = lldb.SBError()
- string_data = value.process.ReadMemory(pointer, length, error)
- return '"%s"' % (string_data.decode('utf-16').encode('utf-8')) # utf8 is safe to emit as-is on OSX
-
-def utf32_summary(value,unused):
- pointer = value.GetChildMemberWithName("first").GetValueAsUnsigned(0)
- length = value.GetChildMemberWithName("second").GetValueAsUnsigned(0)
- # assume length is in bytes - if in UTF32 chars, just multiply by 4
- if pointer == 0:
- return False
- if length == 0:
- return '""'
- error = lldb.SBError()
- string_data = value.process.ReadMemory(pointer, length, error)
- return '"%s"' % (string_data.decode('utf-32').encode('utf-8')) # utf8 is safe to emit as-is on OSX
+
+def utf8_summary(value, unused):
+ pointer = value.GetChildMemberWithName("first").GetValueAsUnsigned(0)
+ length = value.GetChildMemberWithName("second").GetValueAsUnsigned(0)
+ if pointer == 0:
+ return False
+ if length == 0:
+ return '""'
+ error = lldb.SBError()
+ string_data = value.process.ReadMemory(pointer, length, error)
+ return '"%s"' % (string_data) # utf8 is safe to emit as-is on OSX
+
+
+def utf16_summary(value, unused):
+ pointer = value.GetChildMemberWithName("first").GetValueAsUnsigned(0)
+ length = value.GetChildMemberWithName("second").GetValueAsUnsigned(0)
+ # assume length is in bytes - if in UTF16 chars, just multiply by 2
+ if pointer == 0:
+ return False
+ if length == 0:
+ return '""'
+ error = lldb.SBError()
+ string_data = value.process.ReadMemory(pointer, length, error)
+ # utf8 is safe to emit as-is on OSX
+ return '"%s"' % (string_data.decode('utf-16').encode('utf-8'))
+
+
+def utf32_summary(value, unused):
+ pointer = value.GetChildMemberWithName("first").GetValueAsUnsigned(0)
+ length = value.GetChildMemberWithName("second").GetValueAsUnsigned(0)
+ # assume length is in bytes - if in UTF32 chars, just multiply by 4
+ if pointer == 0:
+ return False
+ if length == 0:
+ return '""'
+ error = lldb.SBError()
+ string_data = value.process.ReadMemory(pointer, length, error)
+ # utf8 is safe to emit as-is on OSX
+ return '"%s"' % (string_data.decode('utf-32').encode('utf-8'))