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

Reply via email to