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