147 lines · python
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-exception6##7##===----------------------------------------------------------------------===##8 9 10import lldb11import lldbutil12import sys13from threading import Thread14 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_queue22 # This is probably not great because it does not give liblldb a chance23 # to clean up24 self.daemon = True25 self.initialize(debugger)26 27 def initialize(self, debugger):28 self.done = False29 self.debugger = debugger30 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.eBroadcastBitBreakpointChanged38 # | lldb.SBTarget.eBroadcastBitModuleLoaded39 # | lldb.SBTarget.eBroadcastBitModuleUnloaded40 | lldb.SBTarget.eBroadcastBitWatchpointChanged41 # | lldb.SBTarget.eBroadcastBitSymbolLoaded42 )43 44 self.listener.StartListeningForEventClass(45 self.debugger,46 lldb.SBThread.GetBroadcasterClassName(),47 lldb.SBThread.eBroadcastBitStackChanged48 # lldb.SBThread.eBroadcastBitBreakpointChanged49 | lldb.SBThread.eBroadcastBitThreadSuspended50 | lldb.SBThread.eBroadcastBitThreadResumed51 | lldb.SBThread.eBroadcastBitSelectedFrameChanged52 | lldb.SBThread.eBroadcastBitThreadSelected,53 )54 55 self.listener.StartListeningForEventClass(56 self.debugger,57 lldb.SBProcess.GetBroadcasterClassName(),58 lldb.SBProcess.eBroadcastBitStateChanged59 | lldb.SBProcess.eBroadcastBitInterrupt60 | lldb.SBProcess.eBroadcastBitSTDOUT61 | lldb.SBProcess.eBroadcastBitSTDERR62 | lldb.SBProcess.eBroadcastBitProfileData,63 )64 self.listener.StartListeningForEventClass(65 self.debugger,66 lldb.SBCommandInterpreter.GetBroadcasterClass(),67 lldb.SBCommandInterpreter.eBroadcastBitThreadShouldExit68 | lldb.SBCommandInterpreter.eBroadcastBitResetPrompt69 | lldb.SBCommandInterpreter.eBroadcastBitQuitCommandReceived70 | lldb.SBCommandInterpreter.eBroadcastBitAsynchronousOutputData71 | 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 pass82 83 def loadCore(self, corefile):84 self.handleCommand("target create -c %s" % corefile)85 pass86 87 def setDone(self):88 self.done = True89 90 def isDone(self):91 return self.done92 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 height104 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 ret113 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 continue121 elif not event.GetBroadcaster().IsValid():122 continue123 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 pid139 # else if core file specified140 # - create target from corefile141 # else142 # - create target from file143 # - settings append target.run-args <args-from-cmdline>144 # source .lldbinit file145 146 return driver147