1# Copyright (c) 2020 Google LLC. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5# The following Skia types can be natively visualized in LLDB: 6# - AutoTArray, AutoSTArray 7# - SkString 8# - SkTArray, SkSTArray 9# - sk_sp 10# 11# To enable LLDB debugging support, run the following command at the (lldb) prompt: 12# 13# command script import (your-skia-local-path)/platform_tools/debugging/lldb/skia.py 14# 15# This can be automatically enabled at the start of every debugging session by creating a 16# ~/.lldbinit file which contains this command. 17 18import lldb 19 20def SkString_SummaryProvider(valobj, dict): 21 fRec = valobj.GetChildMemberWithName('fRec') 22 # The fPtr inside fRec is automatically consumed by sk_sp_SynthProvider. 23 fLength = fRec.GetChildMemberWithName('fLength') 24 if fLength.GetValueAsUnsigned(0) <= 0: 25 return '""' 26 fBeginningOfData = fRec.GetChildMemberWithName('fBeginningOfData') 27 28 # Fetch string contents into an SBData. 29 string = fBeginningOfData.AddressOf().GetPointeeData(0, fLength.GetValueAsUnsigned(0)) 30 # Zero terminate the SBData. (This actually adds four zero bytes, but that's harmless.) 31 string.Append(lldb.SBData.CreateDataFromInt(0)) 32 # Convert our SBData into a string. 33 error = lldb.SBError() 34 string = string.GetString(error, 0) 35 if error.Fail(): 36 return '<error: ' + error.GetCString() + '>' 37 else: 38 return '"' + string + '"' 39 40 41class SkTArray_SynthProvider: 42 43 def __init__(self, valobj, dict): 44 self.valobj = valobj 45 46 def num_children(self): 47 try: 48 size = self.fSize.GetValueAsSigned(0) 49 size = max(size, 0) 50 size = min(size, 10000) 51 return size 52 except: 53 return 0 54 55 def get_child_index(self, name): 56 try: 57 return int(name.lstrip('[').rstrip(']')) 58 except: 59 return -1 60 61 def get_child_at_index(self, index): 62 if index < 0: 63 return None 64 if index >= self.num_children(): 65 return None 66 67 try: 68 offset = index * self.dataSize 69 return self.fData.CreateChildAtOffset('[' + str(index) + ']', offset, self.dataType) 70 except: 71 return None 72 73 def update(self): 74 try: 75 self.fData = self.valobj.GetChildMemberWithName('fData') 76 self.fSize = self.valobj.GetChildMemberWithName('fSize') 77 self.dataType = self.fData.GetType().GetPointeeType() 78 self.dataSize = self.dataType.GetByteSize() 79 except: 80 pass 81 82 def has_children(self): 83 return True 84 85 86class AutoTArray_SynthProvider: 87 88 def __init__(self, valobj, dict): 89 self.valobj = valobj 90 91 def num_children(self): 92 try: 93 count = self.fCount.GetValueAsSigned(0) 94 count = max(count, 0) 95 count = min(count, 10000) 96 return count 97 except: 98 return 0 99 100 def get_child_index(self, name): 101 try: 102 return int(name.lstrip('[').rstrip(']')) 103 except: 104 return -1 105 106 def get_child_at_index(self, index): 107 if index < 0: 108 return None 109 if index >= self.num_children(): 110 return None 111 112 try: 113 offset = index * self.dataSize 114 return self.fValue.CreateChildAtOffset('[' + str(index) + ']', 115 offset, self.dataType) 116 except: 117 return None 118 119 def update(self): 120 try: 121 self.fCount = self.valobj.GetChildMemberWithName('fCount') 122 fArray = self.valobj.GetChildMemberWithName('fArray') 123 # These lookups rely on implementation details of unique_ptr and __compressed_pair. 124 ptr = fArray.GetChildMemberWithName('__ptr_') 125 self.fValue = ptr.GetChildMemberWithName('__value_') 126 self.dataType = self.fValue.GetType().GetPointeeType() 127 self.dataSize = self.dataType.GetByteSize() 128 except: 129 pass 130 131 def has_children(self): 132 return True 133 134 135class SkSpan_SynthProvider: 136 137 def __init__(self, valobj, dict): 138 self.valobj = valobj 139 140 def num_children(self): 141 try: 142 count = self.fSize.GetValueAsSigned(0) 143 count = max(count, 0) 144 count = min(count, 10000) 145 return count 146 except: 147 return 0 148 149 def get_child_index(self, name): 150 try: 151 return int(name.lstrip('[').rstrip(']')) 152 except: 153 return -1 154 155 def get_child_at_index(self, index): 156 if index < 0: 157 return None 158 if index >= self.num_children(): 159 return None 160 161 try: 162 offset = index * self.dataSize 163 return self.fPtr.CreateChildAtOffset('[' + str(index) + ']', 164 offset, self.dataType) 165 except: 166 return None 167 168 def update(self): 169 try: 170 self.fPtr = self.valobj.GetChildMemberWithName('fPtr') 171 self.fSize = self.valobj.GetChildMemberWithName('fSize') 172 self.dataType = self.fPtr.GetType().GetPointeeType() 173 self.dataSize = self.dataType.GetByteSize() 174 except: 175 pass 176 177 def has_children(self): 178 return True 179 180 181 182class sk_sp_SynthProvider: 183 184 def __init__(self, valobj, dict): 185 self.valobj = valobj 186 187 def num_children(self): 188 return self.fPtr.GetNumChildren() 189 190 def get_child_at_index(self, index): 191 try: 192 return self.fPtr.GetChildAtIndex(index) 193 except: 194 return None 195 196 def get_child_index(self, name): 197 return self.fPtr.GetIndexOfChildWithName(name) 198 199 def update(self): 200 try: 201 self.fPtr = self.valobj.GetChildMemberWithName('fPtr') 202 except: 203 pass 204 205 206def __lldb_init_module(debugger, dict): 207 debugger.HandleCommand( 208 'type summary add -F skia.SkString_SummaryProvider "SkString" -w skia') 209 debugger.HandleCommand( 210 'type synthetic add -l skia.sk_sp_SynthProvider -x "^sk_sp<.+>$" -w skia') 211 debugger.HandleCommand( 212 'type summary add --summary-string "fPtr = ${var.fPtr}" -x "^sk_sp<.+>$" -w skia') 213 debugger.HandleCommand( 214 'type synthetic add -l skia.SkTArray_SynthProvider -x "^SkS?TArray<.+>$" -w skia') 215 debugger.HandleCommand( 216 'type synthetic add -l skia.SkSpan_SynthProvider -x "^SkSpan<.+>$" -w skia') 217 debugger.HandleCommand( 218 'type summary add --summary-string "size=${svar%#}" -e -x "^SkS?TArray<.+>$" -w skia') 219 debugger.HandleCommand( 220 'type synthetic add -l skia.AutoTArray_SynthProvider -x "^AutoS?TArray<.+>$" -w skia') 221 debugger.HandleCommand( 222 'type summary add --summary-string "size=${svar%#}" -e -x "^AutoS?TArray<.+>$" -w skia') 223 debugger.HandleCommand("type category enable skia") 224