| import lldb |
| from lldbutils import utils |
| |
| def summarize_string(valobj, internal_dict): |
| data = valobj.GetChildMemberWithName("mData") |
| length = valobj.GetChildMemberWithName("mLength").GetValueAsUnsigned(0) |
| return utils.format_string(data, length) |
| |
| class TArraySyntheticChildrenProvider: |
| def __init__(self, valobj, internal_dict): |
| self.valobj = valobj |
| self.header = self.valobj.GetChildMemberWithName("mHdr") |
| self.element_type = self.valobj.GetType().GetTemplateArgumentType(0) |
| self.element_size = self.element_type.GetByteSize() |
| header_size = self.header.GetType().GetPointeeType().GetByteSize() |
| self.element_base_addr = self.header.GetValueAsUnsigned(0) + header_size |
| |
| def num_children(self): |
| return self.header.Dereference().GetChildMemberWithName("mLength").GetValueAsUnsigned(0) |
| |
| def get_child_index(self, name): |
| try: |
| index = int(name) |
| if index >= self.num_children(): |
| return None |
| except: |
| pass |
| return None |
| |
| def get_child_at_index(self, index): |
| if index >= self.num_children(): |
| return None |
| addr = self.element_base_addr + index * self.element_size |
| return self.valobj.CreateValueFromAddress("[%d]" % index, addr, self.element_type) |
| |
| def prefcnt(debugger, command, result, dict): |
| """Displays the refcount of an object.""" |
| # We handled regular nsISupports-like refcounted objects and cycle collected |
| # objects. |
| target = debugger.GetSelectedTarget() |
| process = target.GetProcess() |
| thread = process.GetSelectedThread() |
| frame = thread.GetSelectedFrame() |
| obj = frame.EvaluateExpression(command) |
| if obj.GetError().Fail(): |
| print "could not evaluate expression" |
| return |
| obj = utils.dereference(obj) |
| field = obj.GetChildMemberWithName("mRefCnt") |
| if field.GetError().Fail(): |
| field = obj.GetChildMemberWithName("refCnt") |
| if field.GetError().Fail(): |
| print "not a refcounted object" |
| return |
| refcnt_type = field.GetType().GetCanonicalType().GetName() |
| if refcnt_type == "nsAutoRefCnt": |
| print field.GetChildMemberWithName("mValue").GetValueAsUnsigned(0) |
| elif refcnt_type == "nsCycleCollectingAutoRefCnt": |
| print field.GetChildMemberWithName("mRefCntAndFlags").GetValueAsUnsigned(0) >> 2 |
| elif refcnt_type == "mozilla::ThreadSafeAutoRefCnt": |
| print field.GetChildMemberWithName("mValue").GetChildMemberWithName("mValue").GetValueAsUnsigned(0) |
| elif refcnt_type == "int": # non-atomic mozilla::RefCounted object |
| print field.GetValueAsUnsigned(0) |
| elif refcnt_type == "mozilla::Atomic<int>": # atomic mozilla::RefCounted object |
| print field.GetChildMemberWithName("mValue").GetValueAsUnsigned(0) |
| else: |
| print "unknown mRefCnt type " + refcnt_type |
| |
| # Used to work around http://llvm.org/bugs/show_bug.cgi?id=22211 |
| def callfunc(debugger, command, result, dict): |
| """Calls a function for which debugger information is unavailable by getting its address from the symbol table. |
| The function is assumed to return void.""" |
| |
| if '(' not in command: |
| print 'Usage: callfunc your_function(args)' |
| return |
| |
| command_parts = command.split('(') |
| funcname = command_parts[0].strip() |
| args = command_parts[1] |
| |
| target = debugger.GetSelectedTarget() |
| symbols = target.FindFunctions(funcname).symbols |
| if not symbols: |
| print 'Could not find a function symbol for a function called "%s"' % funcname |
| return |
| |
| sym = symbols[0] |
| arg_types = '()' |
| if sym.name and sym.name.startswith(funcname + '('): |
| arg_types = sym.name[len(funcname):] |
| debugger.HandleCommand('print ((void(*)%s)0x%0x)(%s' % (arg_types, sym.addr.GetLoadAddress(target), args)) |
| |
| def init(debugger): |
| debugger.HandleCommand("type summary add nsAString_internal -F lldbutils.general.summarize_string") |
| debugger.HandleCommand("type summary add nsACString_internal -F lldbutils.general.summarize_string") |
| debugger.HandleCommand("type summary add nsFixedString -F lldbutils.general.summarize_string") |
| debugger.HandleCommand("type summary add nsFixedCString -F lldbutils.general.summarize_string") |
| debugger.HandleCommand("type summary add nsAutoString -F lldbutils.general.summarize_string") |
| debugger.HandleCommand("type summary add nsAutoCString -F lldbutils.general.summarize_string") |
| debugger.HandleCommand("type synthetic add -x \"nsTArray<\" -l lldbutils.general.TArraySyntheticChildrenProvider") |
| debugger.HandleCommand("type synthetic add -x \"nsAutoTArray<\" -l lldbutils.general.TArraySyntheticChildrenProvider") |
| debugger.HandleCommand("type synthetic add -x \"FallibleTArray<\" -l lldbutils.general.TArraySyntheticChildrenProvider") |
| debugger.HandleCommand("type synthetic add -x \"AutoFallibleTArray<\" -l lldbutils.general.TArraySyntheticChildrenProvider") |
| debugger.HandleCommand("command script add -f lldbutils.general.prefcnt -f lldbutils.general.prefcnt prefcnt") |
| debugger.HandleCommand("command script add -f lldbutils.general.callfunc -f lldbutils.general.callfunc callfunc") |