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