1# Any copyright is dedicated to the Public Domain. 2# http://creativecommons.org/publicdomain/zero/1.0/ 3 4from __future__ import absolute_import, print_function 5import lldb 6from lldbutils import utils 7 8 9def summarize_string(valobj, internal_dict): 10 data = valobj.GetChildMemberWithName("mData") 11 length = valobj.GetChildMemberWithName("mLength").GetValueAsUnsigned(0) 12 return utils.format_string(data, length) 13 14 15def summarize_atom(valobj, internal_dict): 16 target = lldb.debugger.GetSelectedTarget() 17 length = valobj.GetChildMemberWithName("mLength").GetValueAsUnsigned() 18 string = target.EvaluateExpression( 19 "(char16_t*)%s.GetUTF16String()" % valobj.GetName() 20 ) 21 return utils.format_string(string, length) 22 23 24class TArraySyntheticChildrenProvider: 25 def __init__(self, valobj, internal_dict): 26 self.valobj = valobj 27 self.header = self.valobj.GetChildMemberWithName("mHdr") 28 self.element_type = self.valobj.GetType().GetTemplateArgumentType(0) 29 self.element_size = self.element_type.GetByteSize() 30 header_size = self.header.GetType().GetPointeeType().GetByteSize() 31 self.element_base_addr = self.header.GetValueAsUnsigned(0) + header_size 32 33 def num_children(self): 34 return ( 35 self.header.Dereference() 36 .GetChildMemberWithName("mLength") 37 .GetValueAsUnsigned(0) 38 ) 39 40 def get_child_index(self, name): 41 try: 42 index = int(name) 43 if index >= self.num_children(): 44 return None 45 # Ideally we'd use the exception type, but it's unclear what that is 46 # without knowing how to trigger the original exception. 47 except: # NOQA: E501, E722 48 pass 49 return None 50 51 def get_child_at_index(self, index): 52 if index >= self.num_children(): 53 return None 54 addr = self.element_base_addr + index * self.element_size 55 return self.valobj.CreateValueFromAddress( 56 "[%d]" % index, addr, self.element_type 57 ) 58 59 60def prefcnt(debugger, command, result, dict): 61 """Displays the refcount of an object.""" 62 # We handled regular nsISupports-like refcounted objects and cycle collected 63 # objects. 64 target = debugger.GetSelectedTarget() 65 process = target.GetProcess() 66 thread = process.GetSelectedThread() 67 frame = thread.GetSelectedFrame() 68 obj = frame.EvaluateExpression(command) 69 if obj.GetError().Fail(): 70 print("could not evaluate expression") 71 return 72 obj = utils.dereference(obj) 73 field = obj.GetChildMemberWithName("mRefCnt") 74 if field.GetError().Fail(): 75 field = obj.GetChildMemberWithName("refCnt") 76 if field.GetError().Fail(): 77 print("not a refcounted object") 78 return 79 refcnt_type = field.GetType().GetCanonicalType().GetName() 80 if refcnt_type == "nsAutoRefCnt": 81 print(field.GetChildMemberWithName("mValue").GetValueAsUnsigned(0)) 82 elif refcnt_type == "nsCycleCollectingAutoRefCnt": 83 print( 84 field.GetChildMemberWithName("mRefCntAndFlags").GetValueAsUnsigned(0) >> 2 85 ) 86 elif refcnt_type == "mozilla::ThreadSafeAutoRefCnt": 87 print( 88 field.GetChildMemberWithName("mValue") 89 .GetChildMemberWithName("mValue") 90 .GetValueAsUnsigned(0) 91 ) 92 elif refcnt_type == "int": # non-atomic mozilla::RefCounted object 93 print(field.GetValueAsUnsigned(0)) 94 elif refcnt_type == "mozilla::Atomic<int>": # atomic mozilla::RefCounted object 95 print(field.GetChildMemberWithName("mValue").GetValueAsUnsigned(0)) 96 else: 97 print("unknown mRefCnt type " + refcnt_type) 98 99 100# Used to work around http://llvm.org/bugs/show_bug.cgi?id=22211 101def callfunc(debugger, command, result, dict): 102 """Calls a function for which debugger information is unavailable by getting its address 103 from the symbol table. The function is assumed to return void.""" 104 105 if "(" not in command: 106 print("Usage: callfunc your_function(args)") 107 return 108 109 command_parts = command.split("(") 110 funcname = command_parts[0].strip() 111 args = command_parts[1] 112 113 target = debugger.GetSelectedTarget() 114 symbols = target.FindFunctions(funcname).symbols 115 if not symbols: 116 print('Could not find a function symbol for a function called "%s"' % funcname) 117 return 118 119 sym = symbols[0] 120 arg_types = "()" 121 if sym.name and sym.name.startswith(funcname + "("): 122 arg_types = sym.name[len(funcname) :] 123 debugger.HandleCommand( 124 "print ((void(*)%s)0x%0x)(%s" 125 % (arg_types, sym.addr.GetLoadAddress(target), args) 126 ) 127 128 129def init(debugger): 130 debugger.HandleCommand( 131 "type summary add nsAString -F lldbutils.general.summarize_string" 132 ) 133 debugger.HandleCommand( 134 "type summary add nsACString -F lldbutils.general.summarize_string" 135 ) 136 debugger.HandleCommand( 137 "type summary add nsFixedString -F lldbutils.general.summarize_string" 138 ) 139 debugger.HandleCommand( 140 "type summary add nsFixedCString -F lldbutils.general.summarize_string" 141 ) 142 debugger.HandleCommand( 143 "type summary add nsAutoString -F lldbutils.general.summarize_string" 144 ) 145 debugger.HandleCommand( 146 "type summary add nsAutoCString -F lldbutils.general.summarize_string" 147 ) 148 debugger.HandleCommand( 149 "type summary add nsAtom -F lldbutils.general.summarize_atom" 150 ) 151 debugger.HandleCommand( 152 'type synthetic add -x "nsTArray<" -l lldbutils.general.TArraySyntheticChildrenProvider' 153 ) 154 debugger.HandleCommand( 155 'type synthetic add -x "AutoTArray<" -l lldbutils.general.TArraySyntheticChildrenProvider' # NOQA: E501 156 ) 157 debugger.HandleCommand( 158 'type synthetic add -x "FallibleTArray<" -l lldbutils.general.TArraySyntheticChildrenProvider' # NOQA: E501 159 ) 160 debugger.HandleCommand( 161 "command script add -f lldbutils.general.prefcnt -f lldbutils.general.prefcnt prefcnt" 162 ) 163 debugger.HandleCommand( 164 "command script add -f lldbutils.general.callfunc -f lldbutils.general.callfunc callfunc" 165 ) 166