[lldb-dev] Stepping in a breakpoint callback with Python

Jim Ingham via lldb-dev lldb-dev at lists.llvm.org
Wed Sep 25 18:25:46 PDT 2019


Nikita,

There was a lot of other stuff in that scripted_step.py beyond the plan class itself.  I didn't follow what that did altogether.  But if I removed all that stuff, and changed your plan slightly to not rely on the global TARGET and START_ADDRESS (I attached my simplified version below), then I can do either:

 > lldb main -o "command script import /tmp/scripted_step.py" -o "break set -n main" -o run
(lldb) target create "main"
Current executable set to 'main' (x86_64).
(lldb) command script import /tmp/scripted_step.py
(lldb) break set -n main
Breakpoint 1: where = main`main + 15 at main.c:5:5, address = 0x0000000100000f5f
(lldb) run
Process 93318 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
    frame #0: 0x0000000100000f5f main`main at main.c:5
   2   	
   3   	int main()
   4   	{
-> 5   	    printf("Hello, world!\n");
    	    ^
   6   	    return 0;
   7   	}
   8   	
Target 0: (main) stopped.

Process 93318 launched: '/tmp/main' (x86_64)
(lldb) thread step-scripted -C scripted_step.SimpleStep
init

init done

should step

should stop

0x100000f66: mov al, 0x0  ; main:5

should stop done: False

should step

explains stop

explains stop done: True

should stop

0x100000f68: call 0x100000f7a  ; main:5

should stop done: False

should step

explains stop

explains stop done: True

should stop

should stop done: True

Process 93318 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = Python thread plan implemented by class scripted_step.SimpleStep.
    frame #0: 0x0000000100000f7a main`printf
main`printf:
    0x100000f7a <+0>: jmpq   *0x1080(%rip)             ; (void *)0x0000000100000f90
    0x100000f80:      leaq   0x1081(%rip), %r11        ; _dyld_private
    0x100000f87:      pushq  %r11
    0x100000f89:      jmpq   *0x71(%rip)               ; (void *)0x00007fff69523184: dyld_stub_binder
Target 0: (main) stopped.

or using the Python API:

(lldb) script lldb.thread.StepUsingScriptedThreadPlan("scripted_step.SimpleStep")
init

init done

should step
...

with the same results.  Does that simple use of the scripted plan also work for you?

Jim

-------------- next part --------------
A non-text attachment was scrubbed...
Name: scripted_step.py
Type: text/x-python-script
Size: 2068 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/lldb-dev/attachments/20190925/520aa152/attachment.bin>
-------------- next part --------------


> On Sep 23, 2019, at 11:51 PM, Nikita Karetnikov <nikita at karetnikov.org> wrote:
> 
> Jim,
> 
> >> Not sure if my current version of 'SimpleStep' is correct (I've made a few
> >> changes since testing via 'thread step-scripted'), but nothing happens (no
> >> prints on '__init__') when I add the class via 'StepUsingScriptedThreadPlan' in
> >> the callback.
> >>
> >> What's the proper way to do this?
> >>
> >
> > What happens?  Did you look at the "step" log to see what lldb thought it was
> > doing - i.e. "log enable -f /tmp/lldb-step-log.txt lldb step".  Also, what is
> > lldb doing then nothing happens?
> 
> Apologies, by "nothing" I meant that the class code doesn't seem to be invoked.
> Here's the output:
> 
> (lldb) log enable -f /tmp/lldb-step-log.txt lldb step
> (lldb) breakpoint delete
> About to delete all breakpoints, do you want to do that?: [Y/n] y
> All breakpoints removed. (1 breakpoint)
> (lldb) command script import scripted_step.py
> Process 37849 stopped
> * thread #1, stop reason = signal SIGSTOP
>     frame #0: 0x000000010255e000 dyld`_dyld_start
> dyld`_dyld_start:
> ->  0x10255e000 <+0>: pop    rdi
>     0x10255e001 <+1>: push   0x0
>     0x10255e003 <+3>: mov    rbp, rsp
>     0x10255e006 <+6>: and    rsp, -0x10
> (lldb) trace
> trace done
> Hello, world!
> Process 37849 exited with status = 0 (0x00000000)
> 
> Note that the "trace" messages are printed, but nothing from the class in
> between.
> 
> I'm also attaching the lldb step log for this run.  The SimpleStep class is
> referenced in the log, but it's hard for me to understand what's going on since
> I'm not familiar with the internals of lldb.  Do you see the problem?
> 
> Have you tried reproducing this?  debugserver just runs a "Hello, world!" program:
> 
> debugserver localhost:8000 main
> 
> > One thing I've recently found (in some other work I've been doing) is that if
> > you run the step asynchronously, then the call that ran the thread plan still
> > holds the API lock, and any calls the scripted thread plan makes block against
> > the other plan holding the lock.
> >
> > We already have a workaround for getting the "run lock" in Python code run for
> > internal purposes.  That is a bit of a hack, using the notion that the internal
> > state thread is always running code on behalf of the agent that had the API
> > lock - even though it is running on a separate thread.  So we make a separate
> > run lock for the internal state thread, and use that for code running on that
> > thread.  We probably need to do the same thing for the Target API lock.
> 
> If it turns out to be relevant, will you be able to share this patch?  If you
> don't want to add it to the tree, can you at least share it on the list?
> 
> Thanks,
> Nikita
> 
> <lldb-step-log.txt>



More information about the lldb-dev mailing list