llvm-project

Форк
0
627 строк · 20.3 Кб
1
#!/usr/bin/env python
2

3
import lldb
4
import shlex
5
import sys
6

7
try:
8
    from tkinter import *
9
    import tkinter.ttk as ttk
10
except ImportError:
11
    from Tkinter import *
12
    import ttk
13

14

15
class ValueTreeItemDelegate(object):
16
    def __init__(self, value):
17
        self.value = value
18

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,
40
        }
41

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
48

49

50
class FrameTreeItemDelegate(object):
51
    def __init__(self, frame):
52
        self.frame = frame
53

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,
67
        }
68

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
77

78

79
class ThreadTreeItemDelegate(object):
80
    def __init__(self, thread):
81
        self.thread = thread
82

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,
94
        }
95

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
102

103

104
class ProcessTreeItemDelegate(object):
105
    def __init__(self, process):
106
        self.process = process
107

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,
119
        }
120

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
127

128

129
class TargetTreeItemDelegate(object):
130
    def __init__(self, target):
131
        self.target = target
132

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,
142
        }
143

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
149

150

151
class TargetImagesTreeItemDelegate(object):
152
    def __init__(self, target):
153
        self.target = target
154

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,
165
        }
166

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
174

175

176
class ModuleTreeItemDelegate(object):
177
    def __init__(self, target, module, index):
178
        self.target = target
179
        self.module = module
180
        self.index = index
181

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,
192
        }
193

194
    def get_child_item_dictionaries(self):
195
        item_dicts = list()
196
        sections_item_delegate = ModuleSectionsTreeItemDelegate(
197
            self.target, self.module
198
        )
199
        item_dicts.append(sections_item_delegate.get_item_dictionary())
200

201
        symbols_item_delegate = ModuleSymbolsTreeItemDelegate(self.target, self.module)
202
        item_dicts.append(symbols_item_delegate.get_item_dictionary())
203

204
        comp_units_item_delegate = ModuleCompileUnitsTreeItemDelegate(
205
            self.target, self.module
206
        )
207
        item_dicts.append(comp_units_item_delegate.get_item_dictionary())
208
        return item_dicts
209

210

211
class ModuleSectionsTreeItemDelegate(object):
212
    def __init__(self, target, module):
213
        self.target = target
214
        self.module = module
215

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,
226
        }
227

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
236

237

238
class SectionTreeItemDelegate(object):
239
    def __init__(self, target, section):
240
        self.target = target
241
        self.section = section
242

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,
257
        }
258

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
267

268

269
class ModuleCompileUnitsTreeItemDelegate(object):
270
    def __init__(self, target, module):
271
        self.target = target
272
        self.module = module
273

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,
284
        }
285

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
294

295

296
class CompileUnitTreeItemDelegate(object):
297
    def __init__(self, target, cu):
298
        self.target = target
299
        self.cu = cu
300

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,
312
        }
313

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
319

320

321
class LineTableTreeItemDelegate(object):
322
    def __init__(self, target, cu):
323
        self.target = target
324
        self.cu = cu
325

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,
337
        }
338

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
347

348

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
354

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)
365
        )
366
        return {
367
            "#0": name,
368
            "value": value,
369
            "summary": summary,
370
            "children": False,
371
            "tree-item-delegate": self,
372
        }
373

374
    def get_child_item_dictionaries(self):
375
        item_dicts = list()
376
        return item_dicts
377

378

379
class InstructionTreeItemDelegate(object):
380
    def __init__(self, target, instr):
381
        self.target = target
382
        self.instr = instr
383

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)
395
        )
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,
403
        }
404

405

406
class ModuleSymbolsTreeItemDelegate(object):
407
    def __init__(self, target, module):
408
        self.target = target
409
        self.module = module
410

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,
421
        }
422

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
431

432

433
class SymbolTreeItemDelegate(object):
434
    def __init__(self, target, symbol, index):
435
        self.target = target
436
        self.symbol = symbol
437
        self.index = index
438

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,
454
        }
455

456
    def get_child_item_dictionaries(self):
457
        item_dicts = list()
458
        return item_dicts
459

460

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()
473

474
    def _create_treeview(self, parent):
475
        frame = ttk.Frame(parent)
476
        frame.pack(side=TOP, fill=BOTH, expand=Y)
477

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)
483

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
488

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"],
495
            )
496
            self.tree.column(columns_dict["id"], stretch=columns_dict["stretch"])
497

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)
502

503
        # set frame resizing priorities
504
        frame.rowconfigure(0, weight=1)
505
        frame.columnconfigure(0, weight=1)
506

507
        # action to perform when a node is expanded
508
        self.tree.bind("<<TreeviewOpen>>", self._update_tree)
509

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
523
            )
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")
527

528
    def _populate_root(self):
529
        # use current directory as root node
530
        self.insert_items("", self.delegate.get_child_item_dictionaries())
531

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)
548

549

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},
577
    ]
578
    tree = DelegateTree(
579
        column_dicts, FrameTreeItemDelegate(frame), "Variables", "lldb-tk-variables"
580
    )
581
    tree.mainloop()
582

583

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},
601
    ]
602
    command_args = shlex.split(command)
603
    tree = DelegateTree(
604
        columnd_dicts, ProcessTreeItemDelegate(process), "Process", "lldb-tk-process"
605
    )
606
    tree.mainloop()
607

608

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},
622
    ]
623
    command_args = shlex.split(command)
624
    tree = DelegateTree(
625
        columnd_dicts, TargetTreeItemDelegate(target), "Target", "lldb-tk-target"
626
    )
627
    tree.mainloop()
628

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.