9 import tkinter
.ttk
as ttk
15 class ValueTreeItemDelegate(object):
16 def __init__(self
, value
):
19 def get_item_dictionary(self
):
20 name
= self
.value
.name
23 typename
= self
.value
.type
26 value
= self
.value
.value
29 summary
= self
.value
.summary
32 has_children
= self
.value
.MightHaveChildren()
38 "children": has_children
,
39 "tree-item-delegate": self
,
42 def get_child_item_dictionaries(self
):
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())
50 class FrameTreeItemDelegate(object):
51 def __init__(self
, 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]
65 "children": self
.frame
.GetVariables(True, True, True, True).GetSize() > 0,
66 "tree-item-delegate": self
,
69 def get_child_item_dictionaries(self
):
71 variables
= self
.frame
.GetVariables(True, True, True, True)
72 n
= variables
.GetSize()
74 item_delegate
= ValueTreeItemDelegate(variables
[i
])
75 item_dicts
.append(item_delegate
.get_item_dictionary())
79 class ThreadTreeItemDelegate(object):
80 def __init__(self
, 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
)
92 "children": num_frames
> 0,
93 "tree-item-delegate": self
,
96 def get_child_item_dictionaries(self
):
98 for frame
in self
.thread
:
99 item_delegate
= FrameTreeItemDelegate(frame
)
100 item_dicts
.append(item_delegate
.get_item_dictionary())
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
117 "children": num_threads
> 0,
118 "tree-item-delegate": self
,
121 def get_child_item_dictionaries(self
):
123 for thread
in self
.process
:
124 item_delegate
= ThreadTreeItemDelegate(thread
)
125 item_dicts
.append(item_delegate
.get_item_dictionary())
129 class TargetTreeItemDelegate(object):
130 def __init__(self
, target
):
133 def get_item_dictionary(self
):
134 value
= str(self
.target
.triple
)
135 summary
= self
.target
.executable
.fullpath
141 "tree-item-delegate": self
,
144 def get_child_item_dictionaries(self
):
146 image_item_delegate
= TargetImagesTreeItemDelegate(self
.target
)
147 item_dicts
.append(image_item_delegate
.get_item_dictionary())
151 class TargetImagesTreeItemDelegate(object):
152 def __init__(self
, 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()
162 "summary": "%u images" % num_modules
,
163 "children": num_modules
> 0,
164 "tree-item-delegate": self
,
167 def get_child_item_dictionaries(self
):
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())
176 class ModuleTreeItemDelegate(object):
177 def __init__(self
, target
, module
, 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
191 "tree-item-delegate": self
,
194 def get_child_item_dictionaries(self
):
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())
211 class ModuleSectionsTreeItemDelegate(object):
212 def __init__(self
, target
, module
):
216 def get_item_dictionary(self
):
219 summary
= "%u sections" % (self
.module
.GetNumSections())
225 "tree-item-delegate": self
,
228 def get_child_item_dictionaries(self
):
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())
238 class SectionTreeItemDelegate(object):
239 def __init__(self
, target
, section
):
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
)
249 value
= "0x%16.16x *" % (self
.section
.file_addr
)
255 "children": self
.section
.GetNumSubSections() > 0,
256 "tree-item-delegate": self
,
259 def get_child_item_dictionaries(self
):
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())
269 class ModuleCompileUnitsTreeItemDelegate(object):
270 def __init__(self
, target
, module
):
274 def get_item_dictionary(self
):
275 name
= "compile units"
277 summary
= "%u compile units" % (self
.module
.GetNumSections())
282 "children": self
.module
.GetNumCompileUnits() > 0,
283 "tree-item-delegate": self
,
286 def get_child_item_dictionaries(self
):
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())
296 class CompileUnitTreeItemDelegate(object):
297 def __init__(self
, target
, cu
):
301 def get_item_dictionary(self
):
302 name
= self
.cu
.GetFileSpec().basename
304 num_lines
= self
.cu
.GetNumLineEntries()
310 "children": num_lines
> 0,
311 "tree-item-delegate": self
,
314 def get_child_item_dictionaries(self
):
316 item_delegate
= LineTableTreeItemDelegate(self
.target
, self
.cu
)
317 item_dicts
.append(item_delegate
.get_item_dictionary())
321 class LineTableTreeItemDelegate(object):
322 def __init__(self
, target
, cu
):
326 def get_item_dictionary(self
):
329 num_lines
= self
.cu
.GetNumLineEntries()
330 summary
= "%u line entries" % (num_lines
)
335 "children": num_lines
> 0,
336 "tree-item-delegate": self
,
339 def get_child_item_dictionaries(self
):
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())
349 class LineEntryTreeItemDelegate(object):
350 def __init__(self
, target
, line_entry
, index
):
352 self
.line_entry
= line_entry
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
)
362 value
= "0x%16.16x *" % (address
.file_addr
)
364 self
.line_entry
.GetFileSpec().fullpath
+ ":" + str(self
.line_entry
.line
)
371 "tree-item-delegate": self
,
374 def get_child_item_dictionaries(self
):
379 class InstructionTreeItemDelegate(object):
380 def __init__(self
, target
, 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
)
390 name
= "0x%16.16x *" % (address
.file_addr
)
392 self
.instr
.GetMnemonic(self
.target
)
394 + self
.instr
.GetOperands(self
.target
)
396 summary
= self
.instr
.GetComment(self
.target
)
402 "tree-item-delegate": self
,
406 class ModuleSymbolsTreeItemDelegate(object):
407 def __init__(self
, target
, module
):
411 def get_item_dictionary(self
):
414 summary
= "%u symbols" % (self
.module
.GetNumSymbols())
420 "tree-item-delegate": self
,
423 def get_child_item_dictionaries(self
):
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())
433 class SymbolTreeItemDelegate(object):
434 def __init__(self
, target
, symbol
, 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
)
446 value
= "0x%16.16x *" % (address
.file_addr
)
447 summary
= self
.symbol
.name
453 "tree-item-delegate": self
,
456 def get_child_item_dictionaries(self
):
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()
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
)
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
:
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
:
515 for columns_dict
in self
.columns_dicts
:
517 name
= item_dict
[columns_dict
["id"]]
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
)
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
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
[
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()
556 print("invalid target", file=result
)
558 process
= target
.GetProcess()
560 print("invalid process", file=result
)
562 thread
= process
.GetSelectedThread()
564 print("invalid thread", file=result
)
566 frame
= thread
.GetSelectedFrame()
568 print("invalid frame", file=result
)
570 # Parse command line args
571 command_args
= shlex
.split(command
)
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},
579 column_dicts
, FrameTreeItemDelegate(frame
), "Variables", "lldb-tk-variables"
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()
590 print("invalid target", file=result
)
592 process
= target
.GetProcess()
594 print("invalid process", file=result
)
596 # Parse command line args
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
)
604 columnd_dicts
, ProcessTreeItemDelegate(process
), "Process", "lldb-tk-process"
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()
615 print("invalid target", file=result
)
617 # Parse command line args
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
)
625 columnd_dicts
, TargetTreeItemDelegate(target
), "Target", "lldb-tk-target"