llvm-project
627 строк · 20.3 Кб
1#!/usr/bin/env python
2
3import lldb4import shlex5import sys6
7try:8from tkinter import *9import tkinter.ttk as ttk10except ImportError:11from Tkinter import *12import ttk13
14
15class ValueTreeItemDelegate(object):16def __init__(self, value):17self.value = value18
19def get_item_dictionary(self):20name = self.value.name21if name is None:22name = ""23typename = self.value.type24if typename is None:25typename = ""26value = self.value.value27if value is None:28value = ""29summary = self.value.summary30if summary is None:31summary = ""32has_children = self.value.MightHaveChildren()33return {34"#0": name,35"typename": typename,36"value": value,37"summary": summary,38"children": has_children,39"tree-item-delegate": self,40}41
42def get_child_item_dictionaries(self):43item_dicts = list()44for i in range(self.value.num_children):45item_delegate = ValueTreeItemDelegate(self.value.GetChildAtIndex(i))46item_dicts.append(item_delegate.get_item_dictionary())47return item_dicts48
49
50class FrameTreeItemDelegate(object):51def __init__(self, frame):52self.frame = frame53
54def get_item_dictionary(self):55id = self.frame.GetFrameID()56name = "frame #%u" % (id)57value = "0x%16.16x" % (self.frame.GetPC())58stream = lldb.SBStream()59self.frame.GetDescription(stream)60summary = stream.GetData().split("`")[1]61return {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,67}68
69def get_child_item_dictionaries(self):70item_dicts = list()71variables = self.frame.GetVariables(True, True, True, True)72n = variables.GetSize()73for i in range(n):74item_delegate = ValueTreeItemDelegate(variables[i])75item_dicts.append(item_delegate.get_item_dictionary())76return item_dicts77
78
79class ThreadTreeItemDelegate(object):80def __init__(self, thread):81self.thread = thread82
83def get_item_dictionary(self):84num_frames = self.thread.GetNumFrames()85name = "thread #%u" % (self.thread.GetIndexID())86value = "0x%x" % (self.thread.GetThreadID())87summary = "%u frames" % (num_frames)88return {89"#0": name,90"value": value,91"summary": summary,92"children": num_frames > 0,93"tree-item-delegate": self,94}95
96def get_child_item_dictionaries(self):97item_dicts = list()98for frame in self.thread:99item_delegate = FrameTreeItemDelegate(frame)100item_dicts.append(item_delegate.get_item_dictionary())101return item_dicts102
103
104class ProcessTreeItemDelegate(object):105def __init__(self, process):106self.process = process107
108def get_item_dictionary(self):109id = self.process.GetProcessID()110num_threads = self.process.GetNumThreads()111value = str(self.process.GetProcessID())112summary = self.process.target.executable.fullpath113return {114"#0": "process",115"value": value,116"summary": summary,117"children": num_threads > 0,118"tree-item-delegate": self,119}120
121def get_child_item_dictionaries(self):122item_dicts = list()123for thread in self.process:124item_delegate = ThreadTreeItemDelegate(thread)125item_dicts.append(item_delegate.get_item_dictionary())126return item_dicts127
128
129class TargetTreeItemDelegate(object):130def __init__(self, target):131self.target = target132
133def get_item_dictionary(self):134value = str(self.target.triple)135summary = self.target.executable.fullpath136return {137"#0": "target",138"value": value,139"summary": summary,140"children": True,141"tree-item-delegate": self,142}143
144def get_child_item_dictionaries(self):145item_dicts = list()146image_item_delegate = TargetImagesTreeItemDelegate(self.target)147item_dicts.append(image_item_delegate.get_item_dictionary())148return item_dicts149
150
151class TargetImagesTreeItemDelegate(object):152def __init__(self, target):153self.target = target154
155def get_item_dictionary(self):156value = str(self.target.triple)157summary = self.target.executable.fullpath158num_modules = self.target.GetNumModules()159return {160"#0": "images",161"value": "",162"summary": "%u images" % num_modules,163"children": num_modules > 0,164"tree-item-delegate": self,165}166
167def get_child_item_dictionaries(self):168item_dicts = list()169for i in range(self.target.GetNumModules()):170module = self.target.GetModuleAtIndex(i)171image_item_delegate = ModuleTreeItemDelegate(self.target, module, i)172item_dicts.append(image_item_delegate.get_item_dictionary())173return item_dicts174
175
176class ModuleTreeItemDelegate(object):177def __init__(self, target, module, index):178self.target = target179self.module = module180self.index = index181
182def get_item_dictionary(self):183name = "module %u" % (self.index)184value = self.module.file.basename185summary = self.module.file.dirname186return {187"#0": name,188"value": value,189"summary": summary,190"children": True,191"tree-item-delegate": self,192}193
194def get_child_item_dictionaries(self):195item_dicts = list()196sections_item_delegate = ModuleSectionsTreeItemDelegate(197self.target, self.module198)199item_dicts.append(sections_item_delegate.get_item_dictionary())200
201symbols_item_delegate = ModuleSymbolsTreeItemDelegate(self.target, self.module)202item_dicts.append(symbols_item_delegate.get_item_dictionary())203
204comp_units_item_delegate = ModuleCompileUnitsTreeItemDelegate(205self.target, self.module206)207item_dicts.append(comp_units_item_delegate.get_item_dictionary())208return item_dicts209
210
211class ModuleSectionsTreeItemDelegate(object):212def __init__(self, target, module):213self.target = target214self.module = module215
216def get_item_dictionary(self):217name = "sections"218value = ""219summary = "%u sections" % (self.module.GetNumSections())220return {221"#0": name,222"value": value,223"summary": summary,224"children": True,225"tree-item-delegate": self,226}227
228def get_child_item_dictionaries(self):229item_dicts = list()230num_sections = self.module.GetNumSections()231for i in range(num_sections):232section = self.module.GetSectionAtIndex(i)233image_item_delegate = SectionTreeItemDelegate(self.target, section)234item_dicts.append(image_item_delegate.get_item_dictionary())235return item_dicts236
237
238class SectionTreeItemDelegate(object):239def __init__(self, target, section):240self.target = target241self.section = section242
243def get_item_dictionary(self):244name = self.section.name245section_load_addr = self.section.GetLoadAddress(self.target)246if section_load_addr != lldb.LLDB_INVALID_ADDRESS:247value = "0x%16.16x" % (section_load_addr)248else:249value = "0x%16.16x *" % (self.section.file_addr)250summary = ""251return {252"#0": name,253"value": value,254"summary": summary,255"children": self.section.GetNumSubSections() > 0,256"tree-item-delegate": self,257}258
259def get_child_item_dictionaries(self):260item_dicts = list()261num_sections = self.section.GetNumSubSections()262for i in range(num_sections):263section = self.section.GetSubSectionAtIndex(i)264image_item_delegate = SectionTreeItemDelegate(self.target, section)265item_dicts.append(image_item_delegate.get_item_dictionary())266return item_dicts267
268
269class ModuleCompileUnitsTreeItemDelegate(object):270def __init__(self, target, module):271self.target = target272self.module = module273
274def get_item_dictionary(self):275name = "compile units"276value = ""277summary = "%u compile units" % (self.module.GetNumSections())278return {279"#0": name,280"value": value,281"summary": summary,282"children": self.module.GetNumCompileUnits() > 0,283"tree-item-delegate": self,284}285
286def get_child_item_dictionaries(self):287item_dicts = list()288num_cus = self.module.GetNumCompileUnits()289for i in range(num_cus):290cu = self.module.GetCompileUnitAtIndex(i)291image_item_delegate = CompileUnitTreeItemDelegate(self.target, cu)292item_dicts.append(image_item_delegate.get_item_dictionary())293return item_dicts294
295
296class CompileUnitTreeItemDelegate(object):297def __init__(self, target, cu):298self.target = target299self.cu = cu300
301def get_item_dictionary(self):302name = self.cu.GetFileSpec().basename303value = ""304num_lines = self.cu.GetNumLineEntries()305summary = ""306return {307"#0": name,308"value": value,309"summary": summary,310"children": num_lines > 0,311"tree-item-delegate": self,312}313
314def get_child_item_dictionaries(self):315item_dicts = list()316item_delegate = LineTableTreeItemDelegate(self.target, self.cu)317item_dicts.append(item_delegate.get_item_dictionary())318return item_dicts319
320
321class LineTableTreeItemDelegate(object):322def __init__(self, target, cu):323self.target = target324self.cu = cu325
326def get_item_dictionary(self):327name = "line table"328value = ""329num_lines = self.cu.GetNumLineEntries()330summary = "%u line entries" % (num_lines)331return {332"#0": name,333"value": value,334"summary": summary,335"children": num_lines > 0,336"tree-item-delegate": self,337}338
339def get_child_item_dictionaries(self):340item_dicts = list()341num_lines = self.cu.GetNumLineEntries()342for i in range(num_lines):343line_entry = self.cu.GetLineEntryAtIndex(i)344item_delegate = LineEntryTreeItemDelegate(self.target, line_entry, i)345item_dicts.append(item_delegate.get_item_dictionary())346return item_dicts347
348
349class LineEntryTreeItemDelegate(object):350def __init__(self, target, line_entry, index):351self.target = target352self.line_entry = line_entry353self.index = index354
355def get_item_dictionary(self):356name = str(self.index)357address = self.line_entry.GetStartAddress()358load_addr = address.GetLoadAddress(self.target)359if load_addr != lldb.LLDB_INVALID_ADDRESS:360value = "0x%16.16x" % (load_addr)361else:362value = "0x%16.16x *" % (address.file_addr)363summary = (364self.line_entry.GetFileSpec().fullpath + ":" + str(self.line_entry.line)365)366return {367"#0": name,368"value": value,369"summary": summary,370"children": False,371"tree-item-delegate": self,372}373
374def get_child_item_dictionaries(self):375item_dicts = list()376return item_dicts377
378
379class InstructionTreeItemDelegate(object):380def __init__(self, target, instr):381self.target = target382self.instr = instr383
384def get_item_dictionary(self):385address = self.instr.GetAddress()386load_addr = address.GetLoadAddress(self.target)387if load_addr != lldb.LLDB_INVALID_ADDRESS:388name = "0x%16.16x" % (load_addr)389else:390name = "0x%16.16x *" % (address.file_addr)391value = (392self.instr.GetMnemonic(self.target)393+ " "394+ self.instr.GetOperands(self.target)395)396summary = self.instr.GetComment(self.target)397return {398"#0": name,399"value": value,400"summary": summary,401"children": False,402"tree-item-delegate": self,403}404
405
406class ModuleSymbolsTreeItemDelegate(object):407def __init__(self, target, module):408self.target = target409self.module = module410
411def get_item_dictionary(self):412name = "symbols"413value = ""414summary = "%u symbols" % (self.module.GetNumSymbols())415return {416"#0": name,417"value": value,418"summary": summary,419"children": True,420"tree-item-delegate": self,421}422
423def get_child_item_dictionaries(self):424item_dicts = list()425num_symbols = self.module.GetNumSymbols()426for i in range(num_symbols):427symbol = self.module.GetSymbolAtIndex(i)428image_item_delegate = SymbolTreeItemDelegate(self.target, symbol, i)429item_dicts.append(image_item_delegate.get_item_dictionary())430return item_dicts431
432
433class SymbolTreeItemDelegate(object):434def __init__(self, target, symbol, index):435self.target = target436self.symbol = symbol437self.index = index438
439def get_item_dictionary(self):440address = self.symbol.GetStartAddress()441name = "[%u]" % self.index442symbol_load_addr = address.GetLoadAddress(self.target)443if symbol_load_addr != lldb.LLDB_INVALID_ADDRESS:444value = "0x%16.16x" % (symbol_load_addr)445else:446value = "0x%16.16x *" % (address.file_addr)447summary = self.symbol.name448return {449"#0": name,450"value": value,451"summary": summary,452"children": False,453"tree-item-delegate": self,454}455
456def get_child_item_dictionaries(self):457item_dicts = list()458return item_dicts459
460
461class DelegateTree(ttk.Frame):462def __init__(self, column_dicts, delegate, title, name):463ttk.Frame.__init__(self, name=name)464self.pack(expand=Y, fill=BOTH)465self.master.title(title)466self.delegate = delegate467self.columns_dicts = column_dicts468self.item_id_to_item_dict = dict()469frame = Frame(self)470frame.pack(side=TOP, fill=BOTH, expand=Y)471self._create_treeview(frame)472self._populate_root()473
474def _create_treeview(self, parent):475frame = ttk.Frame(parent)476frame.pack(side=TOP, fill=BOTH, expand=Y)477
478column_ids = list()479for i in range(1, len(self.columns_dicts)):480column_ids.append(self.columns_dicts[i]["id"])481# create the tree and scrollbars482self.tree = ttk.Treeview(columns=column_ids)483
484scroll_bar_v = ttk.Scrollbar(orient=VERTICAL, command=self.tree.yview)485scroll_bar_h = ttk.Scrollbar(orient=HORIZONTAL, command=self.tree.xview)486self.tree["yscroll"] = scroll_bar_v.set487self.tree["xscroll"] = scroll_bar_h.set488
489# setup column headings and columns properties490for columns_dict in self.columns_dicts:491self.tree.heading(492columns_dict["id"],493text=columns_dict["text"],494anchor=columns_dict["anchor"],495)496self.tree.column(columns_dict["id"], stretch=columns_dict["stretch"])497
498# add tree and scrollbars to frame499self.tree.grid(in_=frame, row=0, column=0, sticky=NSEW)500scroll_bar_v.grid(in_=frame, row=0, column=1, sticky=NS)501scroll_bar_h.grid(in_=frame, row=1, column=0, sticky=EW)502
503# set frame resizing priorities504frame.rowconfigure(0, weight=1)505frame.columnconfigure(0, weight=1)506
507# action to perform when a node is expanded508self.tree.bind("<<TreeviewOpen>>", self._update_tree)509
510def insert_items(self, parent_id, item_dicts):511for item_dict in item_dicts:512name = None513values = list()514first = True515for columns_dict in self.columns_dicts:516if first:517name = item_dict[columns_dict["id"]]518first = False519else:520values.append(item_dict[columns_dict["id"]])521item_id = self.tree.insert(522parent_id, END, text=name, values=values # root item has an empty name523)524self.item_id_to_item_dict[item_id] = item_dict525if item_dict["children"]:526self.tree.insert(item_id, END, text="dummy")527
528def _populate_root(self):529# use current directory as root node530self.insert_items("", self.delegate.get_child_item_dictionaries())531
532def _update_tree(self, event):533# user expanded a node - build the related directory534item_id = self.tree.focus() # the id of the expanded node535children = self.tree.get_children(item_id)536if len(children):537first_child = children[0]538# if the node only has a 'dummy' child, remove it and539# build new directory; skip if the node is already540# populated541if self.tree.item(first_child, option="text") == "dummy":542self.tree.delete(first_child)543item_dict = self.item_id_to_item_dict[item_id]544item_dicts = item_dict[545"tree-item-delegate"546].get_child_item_dictionaries()547self.insert_items(item_id, item_dicts)548
549
550@lldb.command("tk-variables")551def tk_variable_display(debugger, command, result, dict):552# needed for tree creation in TK library as it uses sys.argv...553sys.argv = ["tk-variables"]554target = debugger.GetSelectedTarget()555if not target:556print("invalid target", file=result)557return558process = target.GetProcess()559if not process:560print("invalid process", file=result)561return562thread = process.GetSelectedThread()563if not thread:564print("invalid thread", file=result)565return566frame = thread.GetSelectedFrame()567if not frame:568print("invalid frame", file=result)569return570# Parse command line args571command_args = shlex.split(command)572column_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},577]578tree = DelegateTree(579column_dicts, FrameTreeItemDelegate(frame), "Variables", "lldb-tk-variables"580)581tree.mainloop()582
583
584@lldb.command("tk-process")585def tk_process_display(debugger, command, result, dict):586# needed for tree creation in TK library as it uses sys.argv...587sys.argv = ["tk-process"]588target = debugger.GetSelectedTarget()589if not target:590print("invalid target", file=result)591return592process = target.GetProcess()593if not process:594print("invalid process", file=result)595return596# Parse command line args597columnd_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},601]602command_args = shlex.split(command)603tree = DelegateTree(604columnd_dicts, ProcessTreeItemDelegate(process), "Process", "lldb-tk-process"605)606tree.mainloop()607
608
609@lldb.command("tk-target")610def tk_target_display(debugger, command, result, dict):611# needed for tree creation in TK library as it uses sys.argv...612sys.argv = ["tk-target"]613target = debugger.GetSelectedTarget()614if not target:615print("invalid target", file=result)616return617# Parse command line args618columnd_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},622]623command_args = shlex.split(command)624tree = DelegateTree(625columnd_dicts, TargetTreeItemDelegate(target), "Target", "lldb-tk-target"626)627tree.mainloop()628