1##===-- debuggerdriver.py ------------------------------------*- Python -*-===## 2## 3# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4# See https://llvm.org/LICENSE.txt for license information. 5# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6## 7##===----------------------------------------------------------------------===## 8 9 10import lldb 11import lldbutil 12import sys 13from threading import Thread 14 15 16class DebuggerDriver(Thread): 17 """Drives the debugger and responds to events.""" 18 19 def __init__(self, debugger, event_queue): 20 Thread.__init__(self) 21 self.event_queue = event_queue 22 # This is probably not great because it does not give liblldb a chance 23 # to clean up 24 self.daemon = True 25 self.initialize(debugger) 26 27 def initialize(self, debugger): 28 self.done = False 29 self.debugger = debugger 30 self.listener = debugger.GetListener() 31 if not self.listener.IsValid(): 32 raise "Invalid listener" 33 34 self.listener.StartListeningForEventClass( 35 self.debugger, 36 lldb.SBTarget.GetBroadcasterClassName(), 37 lldb.SBTarget.eBroadcastBitBreakpointChanged 38 # | lldb.SBTarget.eBroadcastBitModuleLoaded 39 # | lldb.SBTarget.eBroadcastBitModuleUnloaded 40 | lldb.SBTarget.eBroadcastBitWatchpointChanged 41 # | lldb.SBTarget.eBroadcastBitSymbolLoaded 42 ) 43 44 self.listener.StartListeningForEventClass( 45 self.debugger, 46 lldb.SBThread.GetBroadcasterClassName(), 47 lldb.SBThread.eBroadcastBitStackChanged 48 # lldb.SBThread.eBroadcastBitBreakpointChanged 49 | lldb.SBThread.eBroadcastBitThreadSuspended 50 | lldb.SBThread.eBroadcastBitThreadResumed 51 | lldb.SBThread.eBroadcastBitSelectedFrameChanged 52 | lldb.SBThread.eBroadcastBitThreadSelected, 53 ) 54 55 self.listener.StartListeningForEventClass( 56 self.debugger, 57 lldb.SBProcess.GetBroadcasterClassName(), 58 lldb.SBProcess.eBroadcastBitStateChanged 59 | lldb.SBProcess.eBroadcastBitInterrupt 60 | lldb.SBProcess.eBroadcastBitSTDOUT 61 | lldb.SBProcess.eBroadcastBitSTDERR 62 | lldb.SBProcess.eBroadcastBitProfileData, 63 ) 64 self.listener.StartListeningForEventClass( 65 self.debugger, 66 lldb.SBCommandInterpreter.GetBroadcasterClass(), 67 lldb.SBCommandInterpreter.eBroadcastBitThreadShouldExit 68 | lldb.SBCommandInterpreter.eBroadcastBitResetPrompt 69 | lldb.SBCommandInterpreter.eBroadcastBitQuitCommandReceived 70 | lldb.SBCommandInterpreter.eBroadcastBitAsynchronousOutputData 71 | lldb.SBCommandInterpreter.eBroadcastBitAsynchronousErrorData, 72 ) 73 74 def createTarget(self, target_image, args=None): 75 self.handleCommand("target create %s" % target_image) 76 if args is not None: 77 self.handleCommand("settings set target.run-args %s" % args) 78 79 def attachProcess(self, pid): 80 self.handleCommand("process attach -p %d" % pid) 81 pass 82 83 def loadCore(self, corefile): 84 self.handleCommand("target create -c %s" % corefile) 85 pass 86 87 def setDone(self): 88 self.done = True 89 90 def isDone(self): 91 return self.done 92 93 def getPrompt(self): 94 return self.debugger.GetPrompt() 95 96 def getCommandInterpreter(self): 97 return self.debugger.GetCommandInterpreter() 98 99 def getSourceManager(self): 100 return self.debugger.GetSourceManager() 101 102 def setSize(self, width, height): 103 # FIXME: respect height 104 self.debugger.SetTerminalWidth(width) 105 106 def getTarget(self): 107 return self.debugger.GetTargetAtIndex(0) 108 109 def handleCommand(self, cmd): 110 ret = lldb.SBCommandReturnObject() 111 self.getCommandInterpreter().HandleCommand(cmd, ret) 112 return ret 113 114 def eventLoop(self): 115 while not self.isDone(): 116 event = lldb.SBEvent() 117 got_event = self.listener.WaitForEvent(lldb.UINT32_MAX, event) 118 if got_event and not event.IsValid(): 119 self.winAddStr("Warning: Invalid or no event...") 120 continue 121 elif not event.GetBroadcaster().IsValid(): 122 continue 123 124 self.event_queue.put(event) 125 126 def run(self): 127 self.eventLoop() 128 129 def terminate(self): 130 lldb.SBDebugger.Terminate() 131 sys.exit(0) 132 133 134def createDriver(debugger, event_queue): 135 driver = DebuggerDriver(debugger, event_queue) 136 # driver.start() 137 # if pid specified: 138 # - attach to pid 139 # else if core file specified 140 # - create target from corefile 141 # else 142 # - create target from file 143 # - settings append target.run-args <args-from-cmdline> 144 # source .lldbinit file 145 146 return driver 147