[libc++] Granularize <mutex> includes (#117068)
[llvm-project.git] / lldb / examples / python / lldbtk.py
blobf1685c04313a00d502dd8403325ad67801fa86df
1 #!/usr/bin/env python
3 import lldb
4 import shlex
5 import sys
7 try:
8 from tkinter import *
9 import tkinter.ttk as ttk
10 except ImportError:
11 from Tkinter import *
12 import ttk
15 class ValueTreeItemDelegate(object):
16 def __init__(self, value):
17 self.value = value
19 def get_item_dictionary(self):
20 name = self.value.name
21 if name is None:
22 name = ""
23 typename = self.value.type
24 if typename is None:
25 typename = ""
26 value = self.value.value
27 if value is None:
28 value = ""
29 summary = self.value.summary
30 if summary is None:
31 summary = ""
32 has_children = self.value.MightHaveChildren()
33 return {
34 "#0": name,
35 "typename": typename,
36 "value": value,
37 "summary": summary,
38 "children": has_children,
39 "tree-item-delegate": self,
42 def get_child_item_dictionaries(self):
43 item_dicts = list()
44 for i in range(self.value.num_children):
45 item_delegate = ValueTreeItemDelegate(self.value.GetChildAtIndex(i))
46 item_dicts.append(item_delegate.get_item_dictionary())
47 return item_dicts
50 class FrameTreeItemDelegate(object):
51 def __init__(self, frame):
52 self.frame = frame
54 def get_item_dictionary(self):
55 id = self.frame.GetFrameID()
56 name = "frame #%u" % (id)
57 value = "0x%16.16x" % (self.frame.GetPC())
58 stream = lldb.SBStream()
59 self.frame.GetDescription(stream)
60 summary = stream.GetData().split("`")[1]
61 return {
62 "#0": name,
63 "value": value,
64 "summary": summary,
65 "children": self.frame.GetVariables(True, True, True, True).GetSize() > 0,
66 "tree-item-delegate": self,
69 def get_child_item_dictionaries(self):
70 item_dicts = list()
71 variables = self.frame.GetVariables(True, True, True, True)
72 n = variables.GetSize()
73 for i in range(n):
74 item_delegate = ValueTreeItemDelegate(variables[i])
75 item_dicts.append(item_delegate.get_item_dictionary())
76 return item_dicts
79 class ThreadTreeItemDelegate(object):
80 def __init__(self, thread):
81 self.thread = thread
83 def get_item_dictionary(self):
84 num_frames = self.thread.GetNumFrames()
85 name = "thread #%u" % (self.thread.GetIndexID())
86 value = "0x%x" % (self.thread.GetThreadID())
87 summary = "%u frames" % (num_frames)
88 return {
89 "#0": name,
90 "value": value,
91 "summary": summary,
92 "children": num_frames > 0,
93 "tree-item-delegate": self,
96 def get_child_item_dictionaries(self):
97 item_dicts = list()
98 for frame in self.thread:
99 item_delegate = FrameTreeItemDelegate(frame)
100 item_dicts.append(item_delegate.get_item_dictionary())
101 return item_dicts
104 class ProcessTreeItemDelegate(object):
105 def __init__(self, process):
106 self.process = process
108 def get_item_dictionary(self):
109 id = self.process.GetProcessID()
110 num_threads = self.process.GetNumThreads()
111 value = str(self.process.GetProcessID())
112 summary = self.process.target.executable.fullpath
113 return {
114 "#0": "process",
115 "value": value,
116 "summary": summary,
117 "children": num_threads > 0,
118 "tree-item-delegate": self,
121 def get_child_item_dictionaries(self):
122 item_dicts = list()
123 for thread in self.process:
124 item_delegate = ThreadTreeItemDelegate(thread)
125 item_dicts.append(item_delegate.get_item_dictionary())
126 return item_dicts
129 class TargetTreeItemDelegate(object):
130 def __init__(self, target):
131 self.target = target
133 def get_item_dictionary(self):
134 value = str(self.target.triple)
135 summary = self.target.executable.fullpath
136 return {
137 "#0": "target",
138 "value": value,
139 "summary": summary,
140 "children": True,
141 "tree-item-delegate": self,
144 def get_child_item_dictionaries(self):
145 item_dicts = list()
146 image_item_delegate = TargetImagesTreeItemDelegate(self.target)
147 item_dicts.append(image_item_delegate.get_item_dictionary())
148 return item_dicts
151 class TargetImagesTreeItemDelegate(object):
152 def __init__(self, target):
153 self.target = target
155 def get_item_dictionary(self):
156 value = str(self.target.triple)
157 summary = self.target.executable.fullpath
158 num_modules = self.target.GetNumModules()
159 return {
160 "#0": "images",
161 "value": "",
162 "summary": "%u images" % num_modules,
163 "children": num_modules > 0,
164 "tree-item-delegate": self,
167 def get_child_item_dictionaries(self):
168 item_dicts = list()
169 for i in range(self.target.GetNumModules()):
170 module = self.target.GetModuleAtIndex(i)
171 image_item_delegate = ModuleTreeItemDelegate(self.target, module, i)
172 item_dicts.append(image_item_delegate.get_item_dictionary())
173 return item_dicts
176 class ModuleTreeItemDelegate(object):
177 def __init__(self, target, module, index):
178 self.target = target
179 self.module = module
180 self.index = index
182 def get_item_dictionary(self):
183 name = "module %u" % (self.index)
184 value = self.module.file.basename
185 summary = self.module.file.dirname
186 return {
187 "#0": name,
188 "value": value,
189 "summary": summary,
190 "children": True,
191 "tree-item-delegate": self,
194 def get_child_item_dictionaries(self):
195 item_dicts = list()
196 sections_item_delegate = ModuleSectionsTreeItemDelegate(
197 self.target, self.module
199 item_dicts.append(sections_item_delegate.get_item_dictionary())
201 symbols_item_delegate = ModuleSymbolsTreeItemDelegate(self.target, self.module)
202 item_dicts.append(symbols_item_delegate.get_item_dictionary())
204 comp_units_item_delegate = ModuleCompileUnitsTreeItemDelegate(
205 self.target, self.module
207 item_dicts.append(comp_units_item_delegate.get_item_dictionary())
208 return item_dicts
211 class ModuleSectionsTreeItemDelegate(object):
212 def __init__(self, target, module):
213 self.target = target
214 self.module = module
216 def get_item_dictionary(self):
217 name = "sections"
218 value = ""
219 summary = "%u sections" % (self.module.GetNumSections())
220 return {
221 "#0": name,
222 "value": value,
223 "summary": summary,
224 "children": True,
225 "tree-item-delegate": self,
228 def get_child_item_dictionaries(self):
229 item_dicts = list()
230 num_sections = self.module.GetNumSections()
231 for i in range(num_sections):
232 section = self.module.GetSectionAtIndex(i)
233 image_item_delegate = SectionTreeItemDelegate(self.target, section)
234 item_dicts.append(image_item_delegate.get_item_dictionary())
235 return item_dicts
238 class SectionTreeItemDelegate(object):
239 def __init__(self, target, section):
240 self.target = target
241 self.section = section
243 def get_item_dictionary(self):
244 name = self.section.name
245 section_load_addr = self.section.GetLoadAddress(self.target)
246 if section_load_addr != lldb.LLDB_INVALID_ADDRESS:
247 value = "0x%16.16x" % (section_load_addr)
248 else:
249 value = "0x%16.16x *" % (self.section.file_addr)
250 summary = ""
251 return {
252 "#0": name,
253 "value": value,
254 "summary": summary,
255 "children": self.section.GetNumSubSections() > 0,
256 "tree-item-delegate": self,
259 def get_child_item_dictionaries(self):
260 item_dicts = list()
261 num_sections = self.section.GetNumSubSections()
262 for i in range(num_sections):
263 section = self.section.GetSubSectionAtIndex(i)
264 image_item_delegate = SectionTreeItemDelegate(self.target, section)
265 item_dicts.append(image_item_delegate.get_item_dictionary())
266 return item_dicts
269 class ModuleCompileUnitsTreeItemDelegate(object):
270 def __init__(self, target, module):
271 self.target = target
272 self.module = module
274 def get_item_dictionary(self):
275 name = "compile units"
276 value = ""
277 summary = "%u compile units" % (self.module.GetNumSections())
278 return {
279 "#0": name,
280 "value": value,
281 "summary": summary,
282 "children": self.module.GetNumCompileUnits() > 0,
283 "tree-item-delegate": self,
286 def get_child_item_dictionaries(self):
287 item_dicts = list()
288 num_cus = self.module.GetNumCompileUnits()
289 for i in range(num_cus):
290 cu = self.module.GetCompileUnitAtIndex(i)
291 image_item_delegate = CompileUnitTreeItemDelegate(self.target, cu)
292 item_dicts.append(image_item_delegate.get_item_dictionary())
293 return item_dicts
296 class CompileUnitTreeItemDelegate(object):
297 def __init__(self, target, cu):
298 self.target = target
299 self.cu = cu
301 def get_item_dictionary(self):
302 name = self.cu.GetFileSpec().basename
303 value = ""
304 num_lines = self.cu.GetNumLineEntries()
305 summary = ""
306 return {
307 "#0": name,
308 "value": value,
309 "summary": summary,
310 "children": num_lines > 0,
311 "tree-item-delegate": self,
314 def get_child_item_dictionaries(self):
315 item_dicts = list()
316 item_delegate = LineTableTreeItemDelegate(self.target, self.cu)
317 item_dicts.append(item_delegate.get_item_dictionary())
318 return item_dicts
321 class LineTableTreeItemDelegate(object):
322 def __init__(self, target, cu):
323 self.target = target
324 self.cu = cu
326 def get_item_dictionary(self):
327 name = "line table"
328 value = ""
329 num_lines = self.cu.GetNumLineEntries()
330 summary = "%u line entries" % (num_lines)
331 return {
332 "#0": name,
333 "value": value,
334 "summary": summary,
335 "children": num_lines > 0,
336 "tree-item-delegate": self,
339 def get_child_item_dictionaries(self):
340 item_dicts = list()
341 num_lines = self.cu.GetNumLineEntries()
342 for i in range(num_lines):
343 line_entry = self.cu.GetLineEntryAtIndex(i)
344 item_delegate = LineEntryTreeItemDelegate(self.target, line_entry, i)
345 item_dicts.append(item_delegate.get_item_dictionary())
346 return item_dicts
349 class LineEntryTreeItemDelegate(object):
350 def __init__(self, target, line_entry, index):
351 self.target = target
352 self.line_entry = line_entry
353 self.index = index
355 def get_item_dictionary(self):
356 name = str(self.index)
357 address = self.line_entry.GetStartAddress()
358 load_addr = address.GetLoadAddress(self.target)
359 if load_addr != lldb.LLDB_INVALID_ADDRESS:
360 value = "0x%16.16x" % (load_addr)
361 else:
362 value = "0x%16.16x *" % (address.file_addr)
363 summary = (
364 self.line_entry.GetFileSpec().fullpath + ":" + str(self.line_entry.line)
366 return {
367 "#0": name,
368 "value": value,
369 "summary": summary,
370 "children": False,
371 "tree-item-delegate": self,
374 def get_child_item_dictionaries(self):
375 item_dicts = list()
376 return item_dicts
379 class InstructionTreeItemDelegate(object):
380 def __init__(self, target, instr):
381 self.target = target
382 self.instr = instr
384 def get_item_dictionary(self):
385 address = self.instr.GetAddress()
386 load_addr = address.GetLoadAddress(self.target)
387 if load_addr != lldb.LLDB_INVALID_ADDRESS:
388 name = "0x%16.16x" % (load_addr)
389 else:
390 name = "0x%16.16x *" % (address.file_addr)
391 value = (
392 self.instr.GetMnemonic(self.target)
393 + " "
394 + self.instr.GetOperands(self.target)
396 summary = self.instr.GetComment(self.target)
397 return {
398 "#0": name,
399 "value": value,
400 "summary": summary,
401 "children": False,
402 "tree-item-delegate": self,
406 class ModuleSymbolsTreeItemDelegate(object):
407 def __init__(self, target, module):
408 self.target = target
409 self.module = module
411 def get_item_dictionary(self):
412 name = "symbols"
413 value = ""
414 summary = "%u symbols" % (self.module.GetNumSymbols())
415 return {
416 "#0": name,
417 "value": value,
418 "summary": summary,
419 "children": True,
420 "tree-item-delegate": self,
423 def get_child_item_dictionaries(self):
424 item_dicts = list()
425 num_symbols = self.module.GetNumSymbols()
426 for i in range(num_symbols):
427 symbol = self.module.GetSymbolAtIndex(i)
428 image_item_delegate = SymbolTreeItemDelegate(self.target, symbol, i)
429 item_dicts.append(image_item_delegate.get_item_dictionary())
430 return item_dicts
433 class SymbolTreeItemDelegate(object):
434 def __init__(self, target, symbol, index):
435 self.target = target
436 self.symbol = symbol
437 self.index = index
439 def get_item_dictionary(self):
440 address = self.symbol.GetStartAddress()
441 name = "[%u]" % self.index
442 symbol_load_addr = address.GetLoadAddress(self.target)
443 if symbol_load_addr != lldb.LLDB_INVALID_ADDRESS:
444 value = "0x%16.16x" % (symbol_load_addr)
445 else:
446 value = "0x%16.16x *" % (address.file_addr)
447 summary = self.symbol.name
448 return {
449 "#0": name,
450 "value": value,
451 "summary": summary,
452 "children": False,
453 "tree-item-delegate": self,
456 def get_child_item_dictionaries(self):
457 item_dicts = list()
458 return item_dicts
461 class DelegateTree(ttk.Frame):
462 def __init__(self, column_dicts, delegate, title, name):
463 ttk.Frame.__init__(self, name=name)
464 self.pack(expand=Y, fill=BOTH)
465 self.master.title(title)
466 self.delegate = delegate
467 self.columns_dicts = column_dicts
468 self.item_id_to_item_dict = dict()
469 frame = Frame(self)
470 frame.pack(side=TOP, fill=BOTH, expand=Y)
471 self._create_treeview(frame)
472 self._populate_root()
474 def _create_treeview(self, parent):
475 frame = ttk.Frame(parent)
476 frame.pack(side=TOP, fill=BOTH, expand=Y)
478 column_ids = list()
479 for i in range(1, len(self.columns_dicts)):
480 column_ids.append(self.columns_dicts[i]["id"])
481 # create the tree and scrollbars
482 self.tree = ttk.Treeview(columns=column_ids)
484 scroll_bar_v = ttk.Scrollbar(orient=VERTICAL, command=self.tree.yview)
485 scroll_bar_h = ttk.Scrollbar(orient=HORIZONTAL, command=self.tree.xview)
486 self.tree["yscroll"] = scroll_bar_v.set
487 self.tree["xscroll"] = scroll_bar_h.set
489 # setup column headings and columns properties
490 for columns_dict in self.columns_dicts:
491 self.tree.heading(
492 columns_dict["id"],
493 text=columns_dict["text"],
494 anchor=columns_dict["anchor"],
496 self.tree.column(columns_dict["id"], stretch=columns_dict["stretch"])
498 # add tree and scrollbars to frame
499 self.tree.grid(in_=frame, row=0, column=0, sticky=NSEW)
500 scroll_bar_v.grid(in_=frame, row=0, column=1, sticky=NS)
501 scroll_bar_h.grid(in_=frame, row=1, column=0, sticky=EW)
503 # set frame resizing priorities
504 frame.rowconfigure(0, weight=1)
505 frame.columnconfigure(0, weight=1)
507 # action to perform when a node is expanded
508 self.tree.bind("<<TreeviewOpen>>", self._update_tree)
510 def insert_items(self, parent_id, item_dicts):
511 for item_dict in item_dicts:
512 name = None
513 values = list()
514 first = True
515 for columns_dict in self.columns_dicts:
516 if first:
517 name = item_dict[columns_dict["id"]]
518 first = False
519 else:
520 values.append(item_dict[columns_dict["id"]])
521 item_id = self.tree.insert(
522 parent_id, END, text=name, values=values # root item has an empty name
524 self.item_id_to_item_dict[item_id] = item_dict
525 if item_dict["children"]:
526 self.tree.insert(item_id, END, text="dummy")
528 def _populate_root(self):
529 # use current directory as root node
530 self.insert_items("", self.delegate.get_child_item_dictionaries())
532 def _update_tree(self, event):
533 # user expanded a node - build the related directory
534 item_id = self.tree.focus() # the id of the expanded node
535 children = self.tree.get_children(item_id)
536 if len(children):
537 first_child = children[0]
538 # if the node only has a 'dummy' child, remove it and
539 # build new directory; skip if the node is already
540 # populated
541 if self.tree.item(first_child, option="text") == "dummy":
542 self.tree.delete(first_child)
543 item_dict = self.item_id_to_item_dict[item_id]
544 item_dicts = item_dict[
545 "tree-item-delegate"
546 ].get_child_item_dictionaries()
547 self.insert_items(item_id, item_dicts)
550 @lldb.command("tk-variables")
551 def tk_variable_display(debugger, command, result, dict):
552 # needed for tree creation in TK library as it uses sys.argv...
553 sys.argv = ["tk-variables"]
554 target = debugger.GetSelectedTarget()
555 if not target:
556 print("invalid target", file=result)
557 return
558 process = target.GetProcess()
559 if not process:
560 print("invalid process", file=result)
561 return
562 thread = process.GetSelectedThread()
563 if not thread:
564 print("invalid thread", file=result)
565 return
566 frame = thread.GetSelectedFrame()
567 if not frame:
568 print("invalid frame", file=result)
569 return
570 # Parse command line args
571 command_args = shlex.split(command)
572 column_dicts = [
573 {"id": "#0", "text": "Name", "anchor": W, "stretch": 0},
574 {"id": "typename", "text": "Type", "anchor": W, "stretch": 0},
575 {"id": "value", "text": "Value", "anchor": W, "stretch": 0},
576 {"id": "summary", "text": "Summary", "anchor": W, "stretch": 1},
578 tree = DelegateTree(
579 column_dicts, FrameTreeItemDelegate(frame), "Variables", "lldb-tk-variables"
581 tree.mainloop()
584 @lldb.command("tk-process")
585 def tk_process_display(debugger, command, result, dict):
586 # needed for tree creation in TK library as it uses sys.argv...
587 sys.argv = ["tk-process"]
588 target = debugger.GetSelectedTarget()
589 if not target:
590 print("invalid target", file=result)
591 return
592 process = target.GetProcess()
593 if not process:
594 print("invalid process", file=result)
595 return
596 # Parse command line args
597 columnd_dicts = [
598 {"id": "#0", "text": "Name", "anchor": W, "stretch": 0},
599 {"id": "value", "text": "Value", "anchor": W, "stretch": 0},
600 {"id": "summary", "text": "Summary", "anchor": W, "stretch": 1},
602 command_args = shlex.split(command)
603 tree = DelegateTree(
604 columnd_dicts, ProcessTreeItemDelegate(process), "Process", "lldb-tk-process"
606 tree.mainloop()
609 @lldb.command("tk-target")
610 def tk_target_display(debugger, command, result, dict):
611 # needed for tree creation in TK library as it uses sys.argv...
612 sys.argv = ["tk-target"]
613 target = debugger.GetSelectedTarget()
614 if not target:
615 print("invalid target", file=result)
616 return
617 # Parse command line args
618 columnd_dicts = [
619 {"id": "#0", "text": "Name", "anchor": W, "stretch": 0},
620 {"id": "value", "text": "Value", "anchor": W, "stretch": 0},
621 {"id": "summary", "text": "Summary", "anchor": W, "stretch": 1},
623 command_args = shlex.split(command)
624 tree = DelegateTree(
625 columnd_dicts, TargetTreeItemDelegate(target), "Target", "lldb-tk-target"
627 tree.mainloop()