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

Nikita Karetnikov via lldb-dev lldb-dev at lists.llvm.org
Mon Sep 23 23:51:50 PDT 2019


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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/lldb-dev/attachments/20190924/d8aa4236/attachment-0001.html>
-------------- next part --------------
 Discarding thread plans for thread (tid = 0x30ed7ae, force 1)
 Thread::PushPlan(0x0x7fa32c69ee78): "Base thread plan.", tid = 0x30ed7ae.
 
 ThreadList::ShouldStop: 1 threads, 1 unsuspended threads
 Thread::ShouldStop(0x7fa32c69ee78) for tid = 0x30ed7ae 0x30ed7ae, pc = 0x000000010255e000
 ^^^^^^^^ Thread::ShouldStop Begin ^^^^^^^^
 Plan stack initial state:
  thread #1: tid = 0x30ed7ae:
    Active plan stack:
      Element 0: Base thread plan.

 Plan base plan explains stop, auto-continue 0.
 Base plan discarding thread plans for thread tid = 0x30ed7ae (signal: signal SIGSTOP)
 Discarding thread plans for thread (tid = 0x30ed7ae, force 0)
 Base plan says should stop: 1.
 Plan stack final state:
  thread #1: tid = 0x30ed7ae:
    Active plan stack:
      Element 0: Base thread plan.

 vvvvvvvv Thread::ShouldStop End (returning 1) vvvvvvvv
 ThreadList::ShouldStop overall should_stop = 1
 Process::PrivateResume() m_stop_id = 1, public state: stopped private state: stopped
 WillResume Thread #1 (0x0x7fa32c69ee78): tid = 0x30ed7ae, pc = 0x10255e000, sp = 0x7ffeee646800, fp = 0x00000000, plan = 'base plan', state = running, stop others = 0
 Current Plan for thread 1(0x7fa32c69ee78) (0x30ed7ae, running): base plan being asked whether we should report run.
 Process thinks the process has resumed.
 
 ThreadList::ShouldStop: 1 threads, 1 unsuspended threads
 Thread::ShouldStop(0x7fa32c69ee78) for tid = 0x30ed7ae 0x30ed7ae, pc = 0x000000010256e64f
 ^^^^^^^^ Thread::ShouldStop Begin ^^^^^^^^
 Plan stack initial state:
  thread #1: tid = 0x30ed7ae:
    Active plan stack:
      Element 0: Base thread plan.

 StopInfo::ShouldStop async callback says we should not stop, returning ShouldStop of false.
 ThreadList::ShouldStop overall should_stop = 0
 ThreadList::ShouldReportStop 1 threads
 Thread::ShouldReportStop() tid = 0x30ed7ae: returning vote 0 for current plan
 Returning no opinion
 Process::PrivateResume() m_stop_id = 2, public state: running private state: stopped
 Thread::PushPlan(0x0x7fa32c69ee78): "Single stepping past breakpoint site 46 at 0x10256e64f", tid = 0x30ed7ae.
 WillResume Thread #1 (0x0x7fa32c69ee78): tid = 0x30ed7ae, pc = 0x10256e64f, sp = 0x7ffeee645428, fp = 0x7ffeee645600, plan = 'Step over breakpoint trap', state = stepping, stop others = 1
 Process thinks the process has resumed.
 
 ThreadList::ShouldStop: 1 threads, 1 unsuspended threads
 Thread::ShouldStop(0x7fa32c69ee78) for tid = 0x30ed7ae 0x30ed7ae, pc = 0x000000010256e650
 ^^^^^^^^ Thread::ShouldStop Begin ^^^^^^^^
 Plan stack initial state:
  thread #1: tid = 0x30ed7ae:
    Active plan stack:
      Element 0: Base thread plan.
      Element 1: Single stepping past breakpoint site 46 at 0x10256e64f

 Step over breakpoint stopped for reason: trace.
 Plan Step over breakpoint trap explains stop, auto-continue 1.
 Plan Step over breakpoint trap should stop: 0.
 Completed step over breakpoint plan.
 Popping plan: "Step over breakpoint trap", tid = 0x30ed7ae.
 Plan stack final state:
  thread #1: tid = 0x30ed7ae:
    Active plan stack:
      Element 0: Base thread plan.
    Completed Plan Stack:
      Element 0: Single stepping past breakpoint site 46 at 0x10256e64f

 vvvvvvvv Thread::ShouldStop End (returning 0) vvvvvvvv
 ThreadList::ShouldStop overall should_stop = 0
 ThreadList::ShouldReportStop 1 threads
 Thread::ShouldReportStop() tid = 0x30ed7ae: returning vote  for complete stack's back plan
 Returning vote: no
 Returning no
 Process::PrivateResume() m_stop_id = 3, public state: running private state: stopped
 WillResume Thread #1 (0x0x7fa32c69ee78): tid = 0x30ed7ae, pc = 0x10256e650, sp = 0x7ffeee645420, fp = 0x7ffeee645600, plan = 'base plan', state = running, stop others = 0
 Process thinks the process has resumed.
 
 ThreadList::ShouldStop: 1 threads, 1 unsuspended threads
 Thread::ShouldStop(0x7fa32c69ee78) for tid = 0x30ed7ae 0x30ed7ae, pc = 0x00000001015b9f50
 ^^^^^^^^ Thread::ShouldStop Begin ^^^^^^^^
 Plan stack initial state:
  thread #1: tid = 0x30ed7ae:
    Active plan stack:
      Element 0: Base thread plan.

 Plan base plan explains stop, auto-continue 0.
 Base plan discarding thread plans for thread tid = 0x30ed7ae (breakpoint hit.)
 Discarding thread plans for thread (tid = 0x30ed7ae, force 0)
 Base plan says should stop: 1.
 Plan stack final state:
  thread #1: tid = 0x30ed7ae:
    Active plan stack:
      Element 0: Base thread plan.

 vvvvvvvv Thread::ShouldStop End (returning 1) vvvvvvvv
 ThreadList::ShouldStop overall should_stop = 1
 Thread::PushPlan(0x0x7fa32c69ee78): "Python thread plan implemented by class SimpleStep.", tid = 0x30ed7ae.
 Process::PrivateResume() m_stop_id = 4, public state: stopped private state: stopped
 Thread::PushPlan(0x0x7fa32c69ee78): "Single stepping past breakpoint site 47 at 0x1015b9f50", tid = 0x30ed7ae.
 WillResume Thread #1 (0x0x7fa32c69ee78): tid = 0x30ed7ae, pc = 0x1015b9f50, sp = 0x7ffeee6467f8, fp = 0x7ffeee646800, plan = 'Step over breakpoint trap', state = stepping, stop others = 1
 Current Plan for thread 1(0x7fa32c69ee78) (0x30ed7ae, stepping): Step over breakpoint trap being asked whether we should report run.
 Process thinks the process has resumed.
 Process::PerformAction returning from action with m_should_stop: 0.
 
 ThreadList::ShouldStop: 1 threads, 1 unsuspended threads
 Thread::ShouldStop(0x7fa32c69ee78) for tid = 0x30ed7ae 0x30ed7ae, pc = 0x00000001015b9f51
 ^^^^^^^^ Thread::ShouldStop Begin ^^^^^^^^
 Plan stack initial state:
  thread #1: tid = 0x30ed7ae:
    Active plan stack:
      Element 0: Base thread plan.
      Element 1: Python thread plan implemented by class SimpleStep.
      Element 2: Single stepping past breakpoint site 47 at 0x1015b9f50

 Step over breakpoint stopped for reason: trace.
 Plan Step over breakpoint trap explains stop, auto-continue 1.
 Plan Step over breakpoint trap should stop: 0.
 Completed step over breakpoint plan.
 Popping plan: "Step over breakpoint trap", tid = 0x30ed7ae.
 Plan Python based Thread Plan should stop: 0.
 Plan stack final state:
  thread #1: tid = 0x30ed7ae:
    Active plan stack:
      Element 0: Base thread plan.
      Element 1: Python thread plan implemented by class SimpleStep.
    Completed Plan Stack:
      Element 0: Single stepping past breakpoint site 47 at 0x1015b9f50

 vvvvvvvv Thread::ShouldStop End (returning 0) vvvvvvvv
 ThreadList::ShouldStop overall should_stop = 0
 ThreadList::ShouldReportStop 1 threads
 Thread::ShouldReportStop() tid = 0x30ed7ae: returning vote  for complete stack's back plan
 Returning vote: no
 Returning no
 Process::PrivateResume() m_stop_id = 5, public state: running private state: stopped
 WillResume Thread #1 (0x0x7fa32c69ee78): tid = 0x30ed7ae, pc = 0x1015b9f51, sp = 0x7ffeee6467f0, fp = 0x7ffeee646800, plan = 'Python based Thread Plan', state = running, stop others = 0
 Process thinks the process has resumed.


More information about the lldb-dev mailing list