summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/source/Target/Process.cpp37
-rw-r--r--lldb/source/Target/ThreadList.cpp11
-rw-r--r--lldb/source/Target/ThreadPlanCallFunction.cpp8
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.
OpenPOWER on IntegriCloud