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(self.debugger, 35 lldb.SBTarget.GetBroadcasterClassName(), 36 lldb.SBTarget.eBroadcastBitBreakpointChanged 37 #| lldb.SBTarget.eBroadcastBitModuleLoaded 38 #| lldb.SBTarget.eBroadcastBitModuleUnloaded 39 | lldb.SBTarget.eBroadcastBitWatchpointChanged 40 #| lldb.SBTarget.eBroadcastBitSymbolLoaded 41 ) 42 43 self.listener.StartListeningForEventClass(self.debugger, 44 lldb.SBThread.GetBroadcasterClassName(), 45 lldb.SBThread.eBroadcastBitStackChanged 46 # lldb.SBThread.eBroadcastBitBreakpointChanged 47 | lldb.SBThread.eBroadcastBitThreadSuspended 48 | lldb.SBThread.eBroadcastBitThreadResumed 49 | lldb.SBThread.eBroadcastBitSelectedFrameChanged 50 | lldb.SBThread.eBroadcastBitThreadSelected 51 ) 52 53 self.listener.StartListeningForEventClass(self.debugger, 54 lldb.SBProcess.GetBroadcasterClassName(), 55 lldb.SBProcess.eBroadcastBitStateChanged 56 | lldb.SBProcess.eBroadcastBitInterrupt 57 | lldb.SBProcess.eBroadcastBitSTDOUT 58 | lldb.SBProcess.eBroadcastBitSTDERR 59 | lldb.SBProcess.eBroadcastBitProfileData 60 ) 61 self.listener.StartListeningForEventClass(self.debugger, 62 lldb.SBCommandInterpreter.GetBroadcasterClass(), 63 lldb.SBCommandInterpreter.eBroadcastBitThreadShouldExit 64 | lldb.SBCommandInterpreter.eBroadcastBitResetPrompt 65 | lldb.SBCommandInterpreter.eBroadcastBitQuitCommandReceived 66 | lldb.SBCommandInterpreter.eBroadcastBitAsynchronousOutputData 67 | lldb.SBCommandInterpreter.eBroadcastBitAsynchronousErrorData 68 ) 69 70 def createTarget(self, target_image, args=None): 71 self.handleCommand("target create %s" % target_image) 72 if args is not None: 73 self.handleCommand("settings set target.run-args %s" % args) 74 75 def attachProcess(self, pid): 76 self.handleCommand("process attach -p %d" % pid) 77 pass 78 79 def loadCore(self, corefile): 80 self.handleCommand("target create -c %s" % corefile) 81 pass 82 83 def setDone(self): 84 self.done = True 85 86 def isDone(self): 87 return self.done 88 89 def getPrompt(self): 90 return self.debugger.GetPrompt() 91 92 def getCommandInterpreter(self): 93 return self.debugger.GetCommandInterpreter() 94 95 def getSourceManager(self): 96 return self.debugger.GetSourceManager() 97 98 def setSize(self, width, height): 99 # FIXME: respect height 100 self.debugger.SetTerminalWidth(width) 101 102 def getTarget(self): 103 return self.debugger.GetTargetAtIndex(0) 104 105 def handleCommand(self, cmd): 106 ret = lldb.SBCommandReturnObject() 107 self.getCommandInterpreter().HandleCommand(cmd, ret) 108 return ret 109 110 def eventLoop(self): 111 while not self.isDone(): 112 event = lldb.SBEvent() 113 got_event = self.listener.WaitForEvent(lldb.UINT32_MAX, event) 114 if got_event and not event.IsValid(): 115 self.winAddStr("Warning: Invalid or no event...") 116 continue 117 elif not event.GetBroadcaster().IsValid(): 118 continue 119 120 self.event_queue.put(event) 121 122 def run(self): 123 self.eventLoop() 124 125 def terminate(self): 126 lldb.SBDebugger.Terminate() 127 sys.exit(0) 128 129 130def createDriver(debugger, event_queue): 131 driver = DebuggerDriver(debugger, event_queue) 132 # driver.start() 133 # if pid specified: 134 # - attach to pid 135 # else if core file specified 136 # - create target from corefile 137 # else 138 # - create target from file 139 # - settings append target.run-args <args-from-cmdline> 140 # source .lldbinit file 141 142 return driver 143