[lldb-dev] Running other threads while stepping

Ed Maste emaste at freebsd.org
Thu Sep 5 17:20:34 PDT 2013


On 5 September 2013 19:37, Kaylor, Andrew <andrew.kaylor at intel.com> wrote:
> When you say that you end up stopping on a breakpoint in another thread, do you mean that you stop at the user breakpoint that you set on the sleep call or that the other thread stops on the internal breakpoint associated with the step command?

It's the former - when I step I arrive at the sleep(1) in the main thread.

> If the other thread is hitting the user breakpoint, that sounds reasonable and it's probably just a matter of test timing whether or not it happens.  That is, you might hit the breakpoint in both threads at once and have it behave like a single stop (except that both thread stops should be reported), or you might hit just one and then hit the other during stepping.  In the log (assuming that Linux process logging is enabled), the case of both breakpoints being hit at once would show up as a breakpoint event being processed while we were trying to stop all threads.

In the FreeBSD case this race doesn't exist -- when the first thread
hits the breakpoint the entire process is stopped, and there's no way
to return another stop event until after the process is restarted.
Looking at the log confirms - both threads (the 3rd hadn't been
started yet) are set to running for the step.

> Incidentally, one of the changes in r166732 looks wrong.  The first change in ThreadPlanStepInRange.cpp was this:
>
> +        if (m_stop_others == lldb::eOnlyThisThread)
>              stop_others = false;
> +        else
> +            stop_others = true;

Yes, this looks backwards.  I did some further digging into one case
of my issue and it comes from the equivalent test in
ThreadPlanStepOverRange.cpp:

    if (m_stop_others == lldb::eOnlyThisThread)
        stop_others = true;
    else
        stop_others = false;

which at least has the expected sense.

In my case m_stop_others is eOnlyDuringStepping.  With the above test
stop_others is false and so ThreadPlanStepOverRange::ShouldStop calls
m_thread.QueueThreadPlanForStepOut and queues a thread plan that runs
the other threads.

Presumably I can explicitly suspend all threads but one before
stepping.  From a user's perspective though it currently seems
arbitrary whether or not other threads will run during a step.

Incidentally I found what appears to be another bug here (in
ThreadPlanStepOverRange::ShouldStop).  older_ctx_is_equivalent is
initialized to true, then set to true if certain conditions are met.
I presume this change is suitable:

--- a/source/Target/ThreadPlanStepOverRange.cpp
+++ b/source/Target/ThreadPlanStepOverRange.cpp
@@ -121,7 +121,7 @@ ThreadPlanStepOverRange::ShouldStop (Event *event_ptr)
             // in so I left out the target check.  And sometimes the
module comes in as the .o file from the
             // inlined range, so I left that out too...

-            bool older_ctx_is_equivalent = true;
+            bool older_ctx_is_equivalent = false;
             if (m_addr_context.comp_unit)
             {
                 if (m_addr_context.comp_unit == older_context.comp_unit)




More information about the lldb-dev mailing list