I think Zach's right. The only plugin that calls SetResumeState inside WillResume is POSIXThread, and that seems to be overridden by FreeBSDThread.
If I remove the call of SetResumeState from TargetThreadWindows::WillResume, everything starts to work. I'll look into adding some logging in ThreadList::WillResume. Thanks everyone. On Mon, Jun 1, 2015 at 12:58 PM, Zachary Turner <ztur...@google.com> wrote: > Currently ThreadWindows::WillResume() looks like this: > > > void > TargetThreadWindows::WillResume(lldb::StateType resume_state) > { > SetResumeState(resume_state); > } > > I originally put this code in because that's what one or two of the other > plugins did and I wasn't sure what the "correct" thing to do was. I'm not > sure if it's correct though, or if it could be a cause for the bug. But if > the resume state is eStateSuspended as you say, then that suggests that > something lower level already decided that this thread should continue to > be suspended after the user continues. So the bug might actually still be > earlier. > > There's not a lot of logging in ThreadList::WillResume, I wonder if it > would be worth adding some? > > On Mon, Jun 1, 2015 at 12:44 PM Adrian McCarthy <amcca...@google.com> > wrote: > >> >The way this works is that when we go to resume the process, all the >> thread's get asked whether they need to stop other threads to implement >> whatever strategy they are currently pursuing. That query ends up calling >> the currently active thread plan's "StopOthers" method. >> >> Right, and since the ThreadPlanStepOverBreakpoint responds true to >> StopOthers, all the other threads get suspended. Once the breakpoint is >> restored and stepped over and the ThreadPlanStepOverBreakpoint is popped, >> the rest of the threads are still suspended. >> >> > But ThreadPlanBase::ShouldStop returns false, so if all your threads >> are running just the ThreadPlanBase, then they should all resume. >> >> Except that ShouldStop is not called for threads that are already >> suspended (Thread::ShouldStop has an early out if the resume state is >> eStateSuspended). So I still don't see how those threads can ever get out >> of the suspended state. >> >> >> >> On Mon, Jun 1, 2015 at 11:51 AM, Jim Ingham <jing...@apple.com> wrote: >> >>> The way this works is that when we go to resume the process, all the >>> thread's get asked whether they need to stop other threads to implement >>> whatever strategy they are currently pursuing. That query ends up calling >>> the currently active thread plan's "StopOthers" method. If one thread >>> returns true to StopOthers, then that thread will get to run solo. If more >>> than one thread returns true I do a little round robin to pick which one >>> gets to go. But ThreadPlanBase::ShouldStop returns false, so if all your >>> threads are running just the ThreadPlanBase, then they should all resume. >>> >>> This all happens in ThreadList::WillResume. >>> >>> Note I started to add some commands to manipulate the thread plans - of >>> which "thread plan list" is the relevant one. The work isn't done yet (for >>> instance I should actually DO something with the --internal and --verbose >>> options, but for now I only print user visible plans, not implementation >>> only plans. Anyway, if you are poking around in this area that might be of >>> some use. >>> >>> Jim >>> >>> >>> > On Jun 1, 2015, at 8:04 AM, Adrian McCarthy <amcca...@google.com> >>> wrote: >>> > >>> > Thanks for the info. >>> > >>> > This is not theoretical. I'm trying to get TestBreakAfterJoin to pass >>> on Windows. Step 1 was to convert it use <thread> instead of >>> <pthreads.h>. Step 2 was to fix some minor issues in TargetThreadWindows. >>> > >>> > But now the inferior deadlocks because the one thread that's not >>> suspended is waiting on the ones that are. Once the >>> ThreadPlanStepOverBreakpoint plan is popped, the current plan is >>> ThreadPlanBase, which, as far as I can tell, does nothing to resume >>> suspended threads. >>> > >>> > I'll compare this to what happens on another platform to see if there >>> should be some other thread plan in use. >>> > >>> > Adrian. >>> > >>> > On Fri, May 29, 2015 at 4:50 PM, Jim Ingham <jing...@apple.com> wrote: >>> > When stepping over a breakpoint, the ThreadPlanStepOverBreakpoint gets >>> pushed, handles the single instruction step - during which it does suspend >>> the other threads - then it gets popped. When you next resume, whatever >>> plan was handling the stepping before the breakpoint was hit will resume >>> with whatever policy for running other threads it was using. >>> > >>> > So it's up to the plan that was on the stack before the >>> "StepOverBreakpoint" was pushed to decide this. Most of the more complex >>> plans (like step-over/step-into) try to keep the other threads from running >>> if possible (unless the user instructed otherwise) but they also will let >>> all the threads run if there's something going on that might deadlock. For >>> instance, if you are doing "next" and we step through straight-line >>> instructions in a function, we will only run the one thread you are >>> stepping in (by default, you can control this with options to the "thread >>> step-over" command. But if we step into a function, we set a breakpoint >>> on the return address and then run with all threads resumed because >>> stepping out of a function could run arbitrary code. >>> > >>> > Anyway, was this a theoretical question, or do you have some instance >>> where you are actually seeing a deadlock? >>> > >>> > Jim >>> > >>> > >>> > > On May 29, 2015, at 1:59 PM, Adrian McCarthy <amcca...@google.com> >>> wrote: >>> > > >>> > > [I'm trying to make TestBreakAfterJoin work on Windows.] >>> > > >>> > > I'm unclear how continuing from a breakpoint in a multi-threaded >>> inferior is supposed to work. >>> > > >>> > > A breakpoint is set, and the inferior runs until one of its threads >>> hits the breakpoint. The user then selects continue. >>> > > >>> > > The thread that had hit the breakpoint has a thread plan type of >>> ThreadPlanStepOverBreakpoint, which causes all of the other threads to be >>> set to state eStateSuspended. The thread that had hit the breakpoint then >>> steps beyond the breakpoint, and the breakpoint is restored. The thread is >>> then resumed again. >>> > > >>> > > But the other threads are all still suspended, causing the inferior >>> to deadlock. >>> > > >>> > > The question is: Where should the other threads have their resume >>> states set back to a running state? >>> > > >>> > > Adrian >>> > > _______________________________________________ >>> > > lldb-dev mailing list >>> > > lldb-dev@cs.uiuc.edu >>> > > http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev >>> > >>> > >>> >>> >> _______________________________________________ >> lldb-dev mailing list >> lldb-dev@cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev >> >
_______________________________________________ lldb-dev mailing list lldb-dev@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev