diff options
| -rw-r--r-- | lldb/source/Target/Process.cpp | 37 | ||||
| -rw-r--r-- | lldb/source/Target/ThreadList.cpp | 11 | ||||
| -rw-r--r-- | lldb/source/Target/ThreadPlanCallFunction.cpp | 8 |
3 files changed, 51 insertions, 5 deletions
diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp index db992dde4de..1259b72993c 100644 --- a/lldb/source/Target/Process.cpp +++ b/lldb/source/Target/Process.cpp @@ -3901,6 +3901,9 @@ Process::ShouldBroadcastEvent (Event *event_ptr) log->Printf ("Process::ShouldBroadcastEvent (%p) stopped due to an interrupt, state: %s", static_cast<void*>(event_ptr), StateAsCString(state)); + // Even though we know we are going to stop, we should let the threads have a look at the stop, + // so they can properly set their state. + m_thread_list.ShouldStop (event_ptr); return_value = true; } else @@ -4381,8 +4384,14 @@ Process::ProcessEventData::DoOnRemoval (Event *event_ptr) return; m_process_sp->SetPublicState (m_state, Process::ProcessEventData::GetRestartedFromEvent(event_ptr)); - - // If we're stopped and haven't restarted, then do the breakpoint commands here: + + // If this is a halt event, even if the halt stopped with some reason other than a plain interrupt (e.g. we had + // already stopped for a breakpoint when the halt request came through) don't do the StopInfo actions, as they may + // end up restarting the process. + if (m_interrupted) + return; + + // If we're stopped and haven't restarted, then do the StopInfo actions here: if (m_state == eStateStopped && ! m_restarted) { ThreadList &curr_thread_list = m_process_sp->GetThreadList(); @@ -5253,7 +5262,17 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx, // This while loop must exit out the bottom, there's cleanup that we need to do when we are done. // So don't call return anywhere within it. - + +#ifdef LLDB_RUN_THREAD_HALT_WITH_EVENT + // It's pretty much impossible to write test cases for things like: + // One thread timeout expires, I go to halt, but the process already stopped + // on the function call stop breakpoint. Turning on this define will make us not + // fetch the first event till after the halt. So if you run a quick function, it will have + // completed, and the completion event will be waiting, when you interrupt for halt. + // The expression evaluation should still succeed. + bool miss_first_event = true; +#endif + while (1) { // We usually want to resume the process if we get to the top of the loop. @@ -5383,7 +5402,17 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx, log->Printf ("Process::RunThreadPlan(): about to wait forever."); } } - + +#ifdef LLDB_RUN_THREAD_HALT_WITH_EVENT + // See comment above... + if (miss_first_event) + { + usleep(1000); + miss_first_event = false; + got_event = false; + } + else +#endif got_event = listener.WaitForEvent (timeout_ptr, event_sp); if (got_event) diff --git a/lldb/source/Target/ThreadList.cpp b/lldb/source/Target/ThreadList.cpp index 4fffdac9a34..7fb16fdac5c 100644 --- a/lldb/source/Target/ThreadList.cpp +++ b/lldb/source/Target/ThreadList.cpp @@ -262,7 +262,7 @@ ThreadList::ShouldStop (Event *event_ptr) Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); // The ShouldStop method of the threads can do a whole lot of work, - // running breakpoint commands & conditions, etc. So we don't want + // figuring out whether the thread plan conditions are met. So we don't want // to keep the ThreadList locked the whole time we are doing this. // FIXME: It is possible that running code could cause new threads // to be created. If that happens we will miss asking them whether @@ -287,7 +287,16 @@ ThreadList::ShouldStop (Event *event_ptr) } bool did_anybody_stop_for_a_reason = false; + + // If the event is an Interrupt event, then we're going to stop no matter what. Otherwise, presume we won't stop. bool should_stop = false; + if (Process::ProcessEventData::GetInterruptedFromEvent(event_ptr)) + { + if (log) + log->Printf("ThreadList::%s handling interrupt event, should stop set to true", __FUNCTION__); + + should_stop = true; + } // Now we run through all the threads and get their stop info's. We want to make sure to do this first before // we start running the ShouldStop, because one thread's ShouldStop could destroy information (like deleting a diff --git a/lldb/source/Target/ThreadPlanCallFunction.cpp b/lldb/source/Target/ThreadPlanCallFunction.cpp index 0f2a0d32045..5a3ebd7b128 100644 --- a/lldb/source/Target/ThreadPlanCallFunction.cpp +++ b/lldb/source/Target/ThreadPlanCallFunction.cpp @@ -333,6 +333,14 @@ ThreadPlanCallFunction::DoPlanExplainsStop (Event *event_ptr) if (stop_reason == eStopReasonBreakpoint && BreakpointsExplainStop()) return true; + // One more quirk here. If this event was from Halt interrupting the target, then we should not consider + // ourselves complete. Return true to acknowledge the stop. + if (Process::ProcessEventData::GetInterruptedFromEvent(event_ptr)) + { + if (log) + log->Printf ("ThreadPlanCallFunction::PlanExplainsStop: The event is an Interrupt, returning true."); + return true; + } // We control breakpoints separately from other "stop reasons." So first, // check the case where we stopped for an internal breakpoint, in that case, continue on. // If it is not an internal breakpoint, consult m_ignore_breakpoints. |

