Hi,
I have a question about listeners and async mode. I'm building a debugger UI on
top of LLDB in Python, and basically what I want to do is instantiate an
SBDebugger, get its SBCommandInterpreter, loop on readline and feed the
commands to the command interpreter pretty much the same way that the regular
LLDB driver does. I’ve had a look at the driver code, but there’s quite a bit I
don’t understand about how the back end works. There is other stuff going on in
my tool that I won't go into that necessitates running it this way, rather than
as a script loaded into the regular LLDB driver (which is actually how the
existing version works).
>From what I understand, the way to do this is to use async mode. I've had a
>look at the process_events.py example, which makes sense, but I'm not sure how
>to proceed with regard to listeners when letting SBCommandInterpreter do the
>heavy lifting rather than calling Launch* with the API.
I was hoping to be able to do something like this:
import lldb
import time
debugger = lldb.SBDebugger.Create()
debugger.SetAsync(True)
ci = debugger.GetCommandInterpreter()
res = lldb.SBCommandReturnObject()
# "inferior" is a test program that when called with "loop" as the first
param just does `while(1);`
print("starting inferior")
ci.HandleCommand("file tests/inferior", res)
ci.HandleCommand("run loop", res)
# let the target run a bit and then get its status
print("sleeping 1 second")
time.sleep(1)
state =
debugger.StateAsCString(debugger.GetTargetAtIndex(0).process.GetState())
print("state (should be running): {}".format(state))
The state is always "stopped". After looking at `process_events.py` I figured I
need to set up a listener and consume the events, so I tried something like
this, with a listener running in a background thread (and a more realistic
example with accepting user commands rather than the contrived example above):
import lldb
import os
import threading
debugger = lldb.SBDebugger.Create()
debugger.SetAsync(True)
ci = debugger.GetCommandInterpreter()
done = threading.Event()
def run_listener():
event = lldb.SBEvent()
listener = debugger.GetListener()
while not done.is_set():
if listener.WaitForEvent(1, event):
print("Got a new LLDB event: {}".format(event))
else:
# print("Timed out waiting for LLDB event, trying again")
pass
t = threading.Thread(target=run_listener)
t.start()
try:
while True:
line = raw_input("> ")
res = lldb.SBCommandReturnObject()
ci.HandleCommand(line, res)
if res.Succeeded():
print(res.GetOutput().strip())
else:
print(res.GetError().strip())
except:
done.set()
t.join()
But running the listener like that causes HandleCommand() to block. I'm
assuming my listener consuming the events means that the debugger never
receives them. I do not really require handling the events from my code, I'm
happy for the debugger to handle that if it can do so and allow me to still
perform other operations asynchronously like inspecting the state/read
memory/etc.
Can anybody give me a clue as to how to proceed with this?
Thanks,
Loukas
_______________________________________________
lldb-dev mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev