yum-mirror/slang

Making it easier to work with shaders

git clone https://git.yummers.dev/yum-mirror/slang

Sam EstepDocument how to use LLDB in the Slang codebase (#7809)9666fbcab

master
8.9 KiB267 linesraw
1"""
2This python script provides LLDB formatters for Slang core types.
3To use it, see the `docs/debugging.md` file in this repo.
4"""
5
6import lldb
7
8# Set to True to enable the logger
9ENABLE_LOGGING = True
10
11
12# log to the LLDB formatter stream
13def log(msg):
14    if ENABLE_LOGGING:
15        lldb.formatters.Logger.Logger() >> msg
16
17
18def make_string(F: lldb.SBData, L: int) -> str:
19    strval = ""
20    G = F.uint8
21    for X in range(L):
22        V = G[X]
23        if V == 0:
24            break
25        strval = strval + chr(V % 256)
26    return '"' + strval + '"'
27
28
29# Return the pointer to the data in a Slang::RefPtr
30def get_ref_pointer(valobj: lldb.SBValue) -> lldb.SBValue:
31    return valobj.GetNonSyntheticValue().GetChildMemberWithName("pointer")
32
33
34# Check if a pointer is nullptr
35def is_nullptr(valobj: lldb.SBValue) -> bool:
36    return valobj.GetValueAsUnsigned(0) == 0
37
38
39# Slang::String summary
40def String_summary(valobj: lldb.SBValue, dict) -> str:
41    buffer_ptr = get_ref_pointer(valobj.GetChildMemberWithName("m_buffer"))
42    if is_nullptr(buffer_ptr):
43        return '""'
44    buffer = buffer_ptr.Dereference()
45    length = buffer.GetChildMemberWithName("length").GetValueAsUnsigned(0)
46    data = buffer_ptr.GetPointeeData(1, length)
47    return make_string(data, length)
48
49
50# Slang::UnownedStringSlice summary
51def UnownedStringSlice_summary(valobj: lldb.SBValue, dict) -> str:
52    begin = valobj.GetChildMemberWithName("m_begin")
53    end = valobj.GetChildMemberWithName("m_end")
54    length = end.GetValueAsUnsigned(0) - begin.GetValueAsUnsigned(0)
55    if length <= 0:
56        return '""'
57    data = begin.GetPointeeData(0, length)
58    return make_string(data, length)
59
60
61# Slang::RefPtr synthetic provider
62class RefPtr_synthetic(lldb.SBSyntheticValueProvider):
63    def __init__(self, valobj: lldb.SBValue, dict):
64        self.valobj = valobj
65
66    def has_children(self):
67        return True
68
69    def num_children(self):
70        return len(self.children)
71
72    def get_child_index(self, name):
73        for idx in range(self.num_children()):
74            if self.children[idx].GetName() == name:
75                return idx
76        return -1
77
78    def get_child_at_index(self, idx):
79        if idx >= 0 and idx < self.num_children():
80            return self.children[idx]
81        else:
82            return None
83
84    def update(self):
85        self.pointer = self.valobj.GetNonSyntheticValue().GetChildMemberWithName(
86            "pointer"
87        )
88        self.children = []
89        if not is_nullptr(self.pointer):
90            self.children = self.pointer.Dereference().children
91
92
93# Slang::RefPtr summary
94def RefPtr_summary(valobj: lldb.SBValue, dict) -> str:
95    pointer = valobj.GetNonSyntheticValue().GetChildMemberWithName("pointer")
96    if is_nullptr(pointer):
97        return "nullptr"
98    pointee = pointer.Dereference()
99    refcount = pointee.GetChildMemberWithName("referenceCount").GetValueAsUnsigned()
100    return str(pointer.GetValue()) + " refcount=" + str(refcount)
101
102
103# Slang::ComPtr synthetic provider
104class ComPtr_synthetic(lldb.SBSyntheticValueProvider):
105    def __init__(self, valobj: lldb.SBValue, dict):
106        self.valobj = valobj
107
108    def has_children(self):
109        return len(self.children) > 0
110
111    def num_children(self):
112        return len(self.children)
113
114    def get_child_index(self, name):
115        for idx in range(self.num_children()):
116            if self.children[idx].GetName() == name:
117                return idx
118        return -1
119
120    def get_child_at_index(self, idx):
121        if idx >= 0 and idx < self.num_children():
122            return self.children[idx]
123        else:
124            return None
125
126    def update(self):
127        self.pointer = self.valobj.GetChildMemberWithName("m_ptr")
128        self.children = []
129        if not is_nullptr(self.pointer):
130            self.children = self.pointer.Dereference().children
131
132
133# Slang::ComPtr summary
134def ComPtr_summary(valobj: lldb.SBValue, dict) -> str:
135    pointer = valobj.GetNonSyntheticValue().GetChildMemberWithName("m_ptr")
136    if is_nullptr(pointer):
137        return "nullptr"
138    return str(pointer.GetValue())
139
140
141# Slang::Array synthetic provider
142class Array_synthetic(lldb.SBSyntheticValueProvider):
143    def __init__(self, valobj: lldb.SBValue, dict):
144        self.valobj = valobj
145
146    def has_children(self):
147        return True
148
149    def num_children(self):
150        return self.count.GetValueAsUnsigned(0)
151
152    def get_child_index(self, name):
153        return int(name.lstrip("[").rstrip("]"))
154
155    def get_child_at_index(self, idx):
156        if idx >= 0 and idx < self.num_children():
157            offset = idx * self.data_size
158            return self.buffer.CreateChildAtOffset(
159                "[" + str(idx) + "]", offset, self.data_type
160            )
161        else:
162            return None
163
164    def update(self):
165        self.count = self.valobj.GetChildMemberWithName("m_count")
166        self.buffer = self.valobj.GetChildMemberWithName("m_buffer")
167        self.data_type = self.buffer.GetType().GetArrayElementType()
168        self.data_size = self.data_type.GetByteSize()
169
170
171# Slang::List synthetic provider
172class List_synthetic(lldb.SBSyntheticValueProvider):
173    def __init__(self, valobj: lldb.SBValue, dict):
174        self.valobj = valobj
175
176    def has_children(self):
177        return True
178
179    def num_children(self):
180        return self.count.GetValueAsUnsigned(0)
181
182    def get_child_index(self, name):
183        return int(name.lstrip("[").rstrip("]"))
184
185    def get_child_at_index(self, idx):
186        if idx >= 0 and idx < self.num_children():
187            offset = idx * self.data_size
188            return self.buffer.CreateChildAtOffset(
189                "[" + str(idx) + "]", offset, self.data_type
190            )
191        else:
192            return None
193
194    def update(self):
195        self.count = self.valobj.GetChildMemberWithName("m_count")
196        self.buffer = self.valobj.GetChildMemberWithName("m_buffer")
197        self.data_type = self.buffer.GetType().GetPointeeType()
198        self.data_size = self.data_type.GetByteSize()
199
200
201# Slang::ShortList synthetic provider
202class ShortList_synthetic(lldb.SBSyntheticValueProvider):
203    def __init__(self, valobj: lldb.SBValue, dict):
204        self.valobj = valobj
205
206    def has_children(self):
207        return True
208
209    def num_children(self):
210        return self.count.GetValueAsUnsigned(0)
211
212    def get_child_index(self, name):
213        return int(name.lstrip("[").rstrip("]"))
214
215    def get_child_at_index(self, idx):
216        if idx >= 0 and idx < self.short_count:
217            offset = idx * self.data_size
218            return self.short_buffer.CreateChildAtOffset(
219                "[" + str(idx) + "]", offset, self.data_type
220            )
221        elif idx >= self.short_count and idx < self.num_children():
222            offset = (idx - self.short_count) * self.data_size
223            return self.buffer.CreateChildAtOffset(
224                "[" + str(idx) + "]", offset, self.data_type
225            )
226        else:
227            return None
228
229    def update(self):
230        self.count = self.valobj.GetChildMemberWithName("m_count")
231        self.buffer = self.valobj.GetChildMemberWithName("m_buffer")
232        self.short_buffer = self.valobj.GetChildMemberWithName("m_shortBuffer")
233        self.short_count = self.short_buffer.GetNumChildren()
234        self.data_type = self.buffer.GetType().GetPointeeType()
235        self.data_size = self.data_type.GetByteSize()
236
237
238def __lldb_init_module(debugger: lldb.SBDebugger, internal_dict):
239    if ENABLE_LOGGING:
240        lldb.formatters.Logger._lldb_formatters_debug_level = 2
241
242    commands = [
243        # Slang::String
244        "type summary add Slang::String -F core_lldb.String_summary -w slang",
245        # Slang::UnownedStringSlice
246        "type summary add Slang::UnownedStringSlice -F core_lldb.UnownedStringSlice_summary -w slang",
247        # Slang::RefPtr
248        'type synthetic add -x "^Slang::RefPtr<.+>$" -l core_lldb.RefPtr_synthetic -w slang',
249        'type summary add -x "^Slang::RefPtr<.+>$" -F core_lldb.RefPtr_summary -w slang',
250        # Slang::ComPtr
251        'type synthetic add -x "^Slang::ComPtr<.+>$" -l core_lldb.ComPtr_synthetic -w slang',
252        'type summary add -x "^Slang::ComPtr<.+>$" -F core_lldb.ComPtr_summary -w slang',
253        # Slang::Array
254        'type synthetic add -x "^Slang::Array<.+>$" -l core_lldb.Array_synthetic -w slang',
255        'type summary add --x "^Slang::Array<.+>$" --summary-string "size=${svar%#}" -w slang',
256        # Slang::List
257        'type synthetic add -x "^Slang::List<.+>$" -l core_lldb.List_synthetic -w slang',
258        'type summary add --expand -x "^Slang::List<.+>$" --summary-string "size=${var.m_count} capacity=${var.m_capacity}" -w slang',
259        # Slang::ShortList
260        'type synthetic add -x "^Slang::ShortList<.+>$" -l core_lldb.ShortList_synthetic -w slang',
261        'type summary add --expand -x "^Slang::ShortList<.+>$" --summary-string "size=${var.m_count} capacity=${var.m_capacity}" -w slang',
262        # Enable slang category
263        "type category enable slang",
264    ]
265
266    for c in commands:
267        debugger.HandleCommand(c)