xref: /llvm-project/lldb/utils/lui/lui.py (revision 602e47c5f9fd2e14c7bfb6111e6558fa0d27c87f)
1#!/usr/bin/env python
2##===-- lui.py -----------------------------------------------*- Python -*-===##
3##
4# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5# See https://llvm.org/LICENSE.txt for license information.
6# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7##
8##===----------------------------------------------------------------------===##
9
10
11import curses
12
13import lldb
14import lldbutil
15
16from optparse import OptionParser
17import os
18import signal
19import sys
20
21try:
22    import queue
23except ImportError:
24    import Queue as queue
25
26import debuggerdriver
27import cui
28
29import breakwin
30import commandwin
31import eventwin
32import sourcewin
33import statuswin
34
35event_queue = None
36
37
38def handle_args(driver, argv):
39    parser = OptionParser()
40    parser.add_option(
41        "-p", "--attach", dest="pid", help="Attach to specified Process ID", type="int"
42    )
43    parser.add_option(
44        "-c", "--core", dest="core", help="Load specified core file", type="string"
45    )
46
47    (options, args) = parser.parse_args(argv)
48
49    if options.pid is not None:
50        try:
51            pid = int(options.pid)
52            driver.attachProcess(ui, pid)
53        except ValueError:
54            print("Error: expecting integer PID, got '%s'" % options.pid)
55    elif options.core is not None:
56        if not os.path.exists(options.core):
57            raise Exception("Specified core file '%s' does not exist." % options.core)
58        driver.loadCore(options.core)
59    elif len(args) == 2:
60        if not os.path.isfile(args[1]):
61            raise Exception("Specified target '%s' does not exist" % args[1])
62        driver.createTarget(args[1])
63    elif len(args) > 2:
64        if not os.path.isfile(args[1]):
65            raise Exception("Specified target '%s' does not exist" % args[1])
66        driver.createTarget(args[1], args[2:])
67
68
69def sigint_handler(signal, frame):
70    global debugger
71    debugger.terminate()
72
73
74class LLDBUI(cui.CursesUI):
75    def __init__(self, screen, event_queue, driver):
76        super(LLDBUI, self).__init__(screen, event_queue)
77
78        self.driver = driver
79
80        h, w = self.screen.getmaxyx()
81
82        command_win_height = 20
83        break_win_width = 60
84
85        self.status_win = statuswin.StatusWin(0, h - 1, w, 1)
86        h -= 1
87        self.command_win = commandwin.CommandWin(
88            driver, 0, h - command_win_height, w, command_win_height
89        )
90        h -= command_win_height
91        self.source_win = sourcewin.SourceWin(driver, 0, 0, w - break_win_width - 1, h)
92        self.break_win = breakwin.BreakWin(
93            driver, w - break_win_width, 0, break_win_width, h
94        )
95
96        self.wins = [
97            self.status_win,
98            # self.event_win,
99            self.source_win,
100            self.break_win,
101            self.command_win,
102        ]
103
104        self.focus = len(self.wins) - 1  # index of command window;
105
106    def handleEvent(self, event):
107        # hack
108        if isinstance(event, int):
109            if event == curses.KEY_F10:
110                self.driver.terminate()
111            if event == 20:  # ctrl-T
112
113                def foo(cmd):
114                    ret = lldb.SBCommandReturnObject()
115                    self.driver.getCommandInterpreter().HandleCommand(cmd, ret)
116
117                foo("target create a.out")
118                foo("b main")
119                foo("run")
120        super(LLDBUI, self).handleEvent(event)
121
122
123def main(screen):
124    signal.signal(signal.SIGINT, sigint_handler)
125
126    global event_queue
127    event_queue = queue.Queue()
128
129    global debugger
130    debugger = lldb.SBDebugger.Create()
131
132    driver = debuggerdriver.createDriver(debugger, event_queue)
133    view = LLDBUI(screen, event_queue, driver)
134
135    driver.start()
136
137    # hack to avoid hanging waiting for prompts!
138    driver.handleCommand("settings set auto-confirm true")
139
140    handle_args(driver, sys.argv)
141    view.eventLoop()
142
143
144if __name__ == "__main__":
145    try:
146        curses.wrapper(main)
147    except KeyboardInterrupt:
148        exit()
149