In GDB I have a Python script which uses gdb.prompt_hook
to send a command to an open vim session whenever the current file/line number changes. Effectively giving me a "live updating" source view. The script I use is publicly visible here.
I would like to port this script to LLDB, but I can't figure out an equivalent to gdb.prompt_hook
. I.e. some way to execute a Python script whenever control is returned to LLDB when execution stops, OR the current frame is changed (e.g. executing f N
).
Can someone suggest which APIs I might be able to use to implement this?
(NB: I am already aware of LLDB's gui
view.)
Jim's answer is probably the "correct" way of doing this so all cases are covered. However, after spending quite some time struggling with LLDB's Python APIs for event handling I stumbled across LLDB's target stop-hook ...
command. This can run a Python callback whenever execution pauses, and so covers most of what I want.
Unfortunately, target stop-hook
doesn't cover the need for updates as the user manually navigates the stack e.g. using commands like up
, down
, etc. To deal with this I re-implemented the commands I regularly use: up
, down
, and f
.
My implementation looks roughly like this:
class LLDBStopHandler:
def __init__(self, _target, _extra_args, _dict):
pass
def handle_stop(self, _exe_ctx, _stream):
MY_STOP_HOOK()
return True
def lldb_f_command(debugger, command, result, dict):
debugger.HandleCommand(f'frame select {args}')
MY_STOP_HOOK()
def lldb_down_command(debugger, command, result, dict):
frame_id = lldb.debugger.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame().GetFrameID()
debugger.HandleCommand(f'frame select {frame_id - 1}')
MY_STOP_HOOK()
def lldb_up_command(debugger, command, result, dict):
frame_id = lldb.debugger.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame().GetFrameID()
debugger.HandleCommand(f'frame select {frame_id + 1}')
MY_STOP_HOOK()
def __lldb_init_module(debugger, _dict):
debugger.HandleCommand(f'target stop-hook add -P {__name__}.LLDBStopHandler')
debugger.HandleCommand(f'command script add -f {__name__}.lldb_f_command f')
debugger.HandleCommand(f'command script add -f {__name__}.lldb_down_command down')
debugger.HandleCommand(f'command script add -f {__name__}.lldb_up_command up')
Note the frame
command cannot be overridden directly as it's a built-in. I don't tend to use it though. Also the above is missing anything to cover switching threads, and probably some other things I haven't had to worry about yet.