issues with python scripting in LLDB

I have a script, something like:

Hi Michael,
I have tried to reproduce your issue (BTW, which version of LLDB are you using? - I have tried with a revision of the code from yesterday).
I have defined your script as a Python command using “command script add”.
In my case, there is no lockup, but the SBThread::StepOver() function appears to “over-step” and the test program terminates prematurely at the end of the stepping.
The issue, which effectively does not occur when sleeping between the several calls, seems to be related to the StepOver() method itself. I have also tried changing the lldb.thread.StepOver() call with debugger.HandleCommand(“thread step-over -m this-thread”), but doing so, the test program terminates and the thread gets deselected. If thread.StepOver() is replaced with some other operation that does not involve threading (I have used debugger.HandleCommand(“frame variable”) in my example), everything works as it should.
I would bet the issue lies in stepping over itself, but I have never worked on ThreadPlans, so I leave it to someone who knows more about them.

As per your second question, you may want to try the solution described here: http://stackoverflow.com/questions/230751/how-to-flush-output-of-python-print

I have attached the Python script and test program used.

script.py (502 Bytes)

programma.cpp (113 Bytes)

Michael,

The script interpreter runs in "asynchronous" mode by default. So if you want to step the program you are debugging, and the do something after that step returns, you have to wait on the process for state changed events. Otherwise you're queueing up a bunch of steps, executing your prints before the step returns, and then exiting your command with a bunch of stuff still queued up. It looks like doing that may get lldb confused, if what Enrico describes is true. We'll have to figure out why that it true, though that seems secondary.

Anyway, rather than figure out how the event system works, however, for your purposes it's easier to just put the debugger in synchronous mode.. So for instance with Enrico's version of your script, rewritten as:

gdbrulez:lldb-clean/build/Debug > cat ~/Desktop/script.py

Jim,

an easy way to have commands run synchronous would be to change ScriptInterpreterPython::RunScriptBasedCommand() to run “debugger.SetAsync(False)” before actually invoking the target function, and “debugger.SetAsync(True)” immediately after.

Of course, one could add a --asynchronous flag to “command script add” and have all commands added without this flag run synchronous through the above trick.
If you want, I can try to work on this in the coming days and let you have a patch for this.

Otherwise, if the preferred idea is to leave it to the individual scripted commands to pick their synchronicity, I guess it is safer to have the code in a try-finally block, as in:

def StepOver(debugger, args, result, dict):
arg_split = args.split(" ")
print type(arg_split)
count = int(arg_split[0])

try:

debugger.SetAsync(False)

for i in range(0,count):
lldb.thread.StepOver(lldb.eOnlyThisThread)
debugger.HandleCommand(“fr var”)
print “step<%d>”%i
finally:

debugger.SetAsync (True)

Sincerely,

  • Enrico Granata

I think the idea of having a flag to "command script add" is the best way to do it, with "synchronous" the default. That way people who want to get fancy could, but by default things would work as you naively expected them to... If you have some time to work on this, that would be excellent!

Jim