This is an archive of the discontinued LLVM Phabricator instance.

Fix race during process interruption
ClosedPublic

Authored by labath on Nov 25 2015, 8:01 AM.

Details

Summary

The following situation was occuring in TestAttachResume:

  • we did a "continue" from a breakpoint (which involves a private start-stop to step over the breakpoint)
  • after receiving the stop-reply from the step-over, we issue a "detach" (which requires a process interrupt)
  • at this moment, the public state is "running", private state is "about-to-be-stopped" (the stopped event was broadcast, but it was not received yet)
  • StopForDestroyOrDetach (public thread) notes the public state is running, sends an interrupt request to the private thread
  • private thread gets the eBroadcastBitInterrupt (before the eStateStopped message), and asks the process plugin to stop (via Halt())
  • process plugin says it has nothing to do as the process is already stopped
  • private thread shrugs and carries on. receives the stop event, restores the breakpoint and resumes the process.
  • after a while, the public thread times out and says it failed to stop the process

This patch does the following:

  • splits Halt() into two functions, private and public, their usage depends on the context
    • public Halt(): sends eBroadcastBitInterrupt to the private thread and waits for the Stop event
    • HaltPrivate(): asks the plugin to stop and makes a note that the halt was requested. When the next stop event comes it sets the interrupt flag on it.
  • removes HijackPrivateProcessEvents(), as the only user (old Halt()) has gone away
  • removes the m_currently_handling_event hack, as the new Halt() does not need it
  • adds a use_run_lock parameter to public Halt() and WaitForProcessToStop(). This was needed because RunThreadPlan uses Halt() while holding the run lock and we don't want Halt() to take it away from him.

Diff Detail

Repository
rL LLVM

Event Timeline

labath updated this revision to Diff 41147.Nov 25 2015, 8:01 AM
labath retitled this revision from to Fix race during process interruption.
labath updated this object.
labath added reviewers: clayborg, jingham.
labath added a subscriber: lldb-commits.

Nice detective work.

include/lldb/Target/Process.h
1372 ↗(On Diff #41147)

Did you mean "Whether to release ..."?

labath updated this revision to Diff 41215.Nov 26 2015, 1:34 AM

Fix typo

clayborg accepted this revision.Nov 30 2015, 8:49 AM
clayborg edited edge metadata.

One minor nit, but looks good.

source/Target/Process.cpp
4622 ↗(On Diff #41215)

Put "{" on next line

This revision is now accepted and ready to land.Nov 30 2015, 8:49 AM
jingham edited edge metadata.Nov 30 2015, 12:36 PM

This looks correct, I just had a few more nits...

source/Target/Process.cpp
3827–3828 ↗(On Diff #41215)

Is this comment correct anymore?

5719–5720 ↗(On Diff #41215)

The convention in lldb for reminding ourselves which parameters we are passing is to do:

const bool clear_thread_plans = false;
const bool use_run_lock = false;
Halt (clear_thread_plans, use_run_lock);

This revision was automatically updated to reflect the committed changes.
labath marked 3 inline comments as done.