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