blob: 4adc4388350a6eb99aa4673a925519c020fc3831 [file] [log] [blame]
Torne (Richard Coles)5c87bf82012-11-14 11:46:17 +00001# Copyright (C) 2012 Apple. All rights reserved.
2#
3# Redistribution and use in source and binary forms, with or without
4# modification, are permitted provided that the following conditions
5# are met:
6# 1. Redistributions of source code must retain the above copyright
7# notice, this list of conditions and the following disclaimer.
8# 2. Redistributions in binary form must reproduce the above copyright
9# notice, this list of conditions and the following disclaimer in the
10# documentation and/or other materials provided with the distribution.
11#
12# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
13# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
14# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
15# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
16# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
17# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
18# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
19# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
20# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
21# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22
23"""
24 LLDB Support for WebKit Types
25
26 Add the following to your .lldbinit file to add WebKit Type summaries in LLDB and Xcode:
27
28 command script import {Path to WebKit Root}/Tools/lldb/lldb_webkit.py
29
30"""
31
32import lldb
33
34
35def __lldb_init_module(debugger, dict):
36 debugger.HandleCommand('type summary add --expand -F lldb_webkit.WTFString_SummaryProvider WTF::String')
37 debugger.HandleCommand('type summary add --expand -F lldb_webkit.WTFStringImpl_SummaryProvider WTF::StringImpl')
38 debugger.HandleCommand('type summary add --expand -F lldb_webkit.WTFAtomicString_SummaryProvider WTF::AtomicString')
39 debugger.HandleCommand('type summary add --expand -F lldb_webkit.WTFVector_SummaryProvider -x "WTF::Vector<.+>$"')
Torne (Richard Coles)926b0012013-03-28 15:32:48 +000040 debugger.HandleCommand('type summary add --expand -F lldb_webkit.WTFHashTable_SummaryProvider -x "WTF::HashTable<.+>$"')
Torne (Richard Coles)5c87bf82012-11-14 11:46:17 +000041 debugger.HandleCommand('type synthetic add -x "WTF::Vector<.+>$" --python-class lldb_webkit.WTFVectorProvider')
Torne (Richard Coles)926b0012013-03-28 15:32:48 +000042 debugger.HandleCommand('type synthetic add -x "WTF::HashTable<.+>$" --python-class lldb_webkit.WTFHashTableProvider')
Torne (Richard Coles)5c87bf82012-11-14 11:46:17 +000043
44
45def WTFString_SummaryProvider(valobj, dict):
46 provider = WTFStringProvider(valobj, dict)
47 return "{ length = %d, contents = '%s' }" % (provider.get_length(), provider.to_string())
48
49
50def WTFStringImpl_SummaryProvider(valobj, dict):
51 provider = WTFStringImplProvider(valobj, dict)
52 return "{ length = %d, is8bit = %d, contents = '%s' }" % (provider.get_length(), provider.is_8bit(), provider.to_string())
53
54
55def WTFAtomicString_SummaryProvider(valobj, dict):
56 return WTFString_SummaryProvider(valobj.GetChildMemberWithName('m_string'), dict)
57
58
59def WTFVector_SummaryProvider(valobj, dict):
60 provider = WTFVectorProvider(valobj, dict)
61 return "{ size = %d, capacity = %d }" % (provider.size, provider.capacity)
62
Torne (Richard Coles)926b0012013-03-28 15:32:48 +000063
64def WTFHashTable_SummaryProvider(valobj, dict):
65 provider = WTFHashTableProvider(valobj, dict)
66 return "{ tableSize = %d, keyCount = %d }" % (provider.tableSize(), provider.keyCount())
67
Torne (Richard Coles)5c87bf82012-11-14 11:46:17 +000068# FIXME: Provide support for the following types:
69# def WTFVector_SummaryProvider(valobj, dict):
70# def WTFCString_SummaryProvider(valobj, dict):
71# def WebCoreKURLGooglePrivate_SummaryProvider(valobj, dict):
72# def WebCoreQualifiedName_SummaryProvider(valobj, dict):
73# def JSCIdentifier_SummaryProvider(valobj, dict):
74# def JSCJSString_SummaryProvider(valobj, dict):
75
76
77def guess_string_length(valobj, error):
78 if not valobj.GetValue():
79 return 0
80
81 for i in xrange(0, 2048):
82 if valobj.GetPointeeData(i, 1).GetUnsignedInt16(error, 0) == 0:
83 return i
84
85 return 256
86
87
88def ustring_to_string(valobj, error, length=None):
89 if length is None:
90 length = guess_string_length(valobj, error)
91 else:
92 length = int(length)
93
94 out_string = u""
95 for i in xrange(0, length):
96 char_value = valobj.GetPointeeData(i, 1).GetUnsignedInt16(error, 0)
97 out_string = out_string + unichr(char_value)
98
99 return out_string.encode('utf-8')
100
101
102def lstring_to_string(valobj, error, length=None):
103 if length is None:
104 length = guess_string_length(valobj, error)
105 else:
106 length = int(length)
107
108 out_string = u""
109 for i in xrange(0, length):
110 char_value = valobj.GetPointeeData(i, 1).GetUnsignedInt8(error, 0)
111 out_string = out_string + unichr(char_value)
112
113 return out_string.encode('utf-8')
114
115
116class WTFStringImplProvider:
117 def __init__(self, valobj, dict):
118 self.valobj = valobj
119
120 def get_length(self):
121 return self.valobj.GetChildMemberWithName('m_length').GetValueAsUnsigned(0)
122
123 def get_data8(self):
124 return self.valobj.GetChildAtIndex(2).GetChildMemberWithName('m_data8')
125
126 def get_data16(self):
127 return self.valobj.GetChildAtIndex(2).GetChildMemberWithName('m_data16')
128
129 def to_string(self):
130 error = lldb.SBError()
131 if self.is_8bit():
132 return lstring_to_string(self.get_data8(), error, self.get_length())
133 return ustring_to_string(self.get_data16(), error, self.get_length())
134
135 def is_8bit(self):
136 # FIXME: find a way to access WTF::StringImpl::s_hashFlag8BitBuffer
137 return bool(self.valobj.GetChildMemberWithName('m_hashAndFlags').GetValueAsUnsigned(0) \
138 & 1 << 6)
139
140
141class WTFStringProvider:
142 def __init__(self, valobj, dict):
143 self.valobj = valobj
144
145 def stringimpl(self):
146 impl_ptr = self.valobj.GetChildMemberWithName('m_impl').GetChildMemberWithName('m_ptr')
147 return WTFStringImplProvider(impl_ptr, dict)
148
149 def get_length(self):
150 impl = self.stringimpl()
151 if not impl:
152 return 0
153 return impl.get_length()
154
155 def to_string(self):
156 impl = self.stringimpl()
157 if not impl:
158 return u""
159 return impl.to_string()
160
161
162class WTFVectorProvider:
163 def __init__(self, valobj, internal_dict):
164 self.valobj = valobj
165 self.update()
166
167 def num_children(self):
168 return self.size + 2
169
170 def get_child_index(self, name):
171 if name == "m_size":
172 return self.size
173 elif name == "m_buffer":
174 return self.size + 1
175 else:
176 return int(name.lstrip('[').rstrip(']'))
177
178 def get_child_at_index(self, index):
179 if index == self.size:
180 return self.valobj.GetChildMemberWithName("m_size")
181 elif index == self.size + 1:
182 return self.vector_buffer
183 elif index < self.size:
184 offset = index * self.data_size
185 child = self.buffer.CreateChildAtOffset('[' + str(index) + ']', offset, self.data_type)
186 return child
187 else:
188 return None
189
190 def update(self):
191 self.vector_buffer = self.valobj.GetChildMemberWithName('m_buffer')
192 self.buffer = self.vector_buffer.GetChildMemberWithName('m_buffer')
193 self.size = self.valobj.GetChildMemberWithName('m_size').GetValueAsUnsigned(0)
194 self.capacity = self.vector_buffer.GetChildMemberWithName('m_capacity').GetValueAsUnsigned(0)
195 self.data_type = self.buffer.GetType().GetPointeeType()
196 self.data_size = self.data_type.GetByteSize()
197
198 def has_children(self):
199 return True
Torne (Richard Coles)926b0012013-03-28 15:32:48 +0000200
201
202class WTFHashTableProvider:
203 def __init__(self, valobj, internal_dict):
204 self.valobj = valobj
205 self.update()
206
207 def num_children(self):
208 return self.tableSize() + 5
209
210 def get_child_index(self, name):
211 if name == "m_table":
212 return self.tableSize()
213 elif name == "m_tableSize":
214 return self.tableSize() + 1
215 elif name == "m_tableSizeMask":
216 return self.tableSize() + 2
217 elif name == "m_keyCount":
218 return self.tableSize() + 3
219 elif name == "m_deletedCount":
220 return self.tableSize() + 4
221 else:
222 return int(name.lstrip('[').rstrip(']'))
223
224 def get_child_at_index(self, index):
225 if index == self.tableSize():
226 return self.valobj.GetChildMemberWithName('m_table')
227 elif index == self.tableSize() + 1:
228 return self.valobj.GetChildMemberWithName('m_tableSize')
229 elif index == self.tableSize() + 2:
230 return self.valobj.GetChildMemberWithName('m_tableSizeMask')
231 elif index == self.tableSize() + 3:
232 return self.valobj.GetChildMemberWithName('m_keyCount')
233 elif index == self.tableSize() + 4:
234 return self.valobj.GetChildMemberWithName('m_deletedCount')
235 elif index < self.tableSize():
236 table = self.valobj.GetChildMemberWithName('m_table')
237 return table.CreateChildAtOffset('[' + str(index) + ']', index * self.data_size, self.data_type)
238 else:
239 return None
240
241 def tableSize(self):
242 return self.valobj.GetChildMemberWithName('m_tableSize').GetValueAsUnsigned(0)
243
244 def keyCount(self):
245 return self.valobj.GetChildMemberWithName('m_keyCount').GetValueAsUnsigned(0)
246
247 def update(self):
248 self.data_type = self.valobj.GetType().GetTemplateArgumentType(0)
249 self.data_size = self.data_type.GetByteSize()
250
251 def has_children(self):
252 return True