summaryrefslogtreecommitdiff
path: root/source/Target/Process.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/Target/Process.cpp')
-rw-r--r--source/Target/Process.cpp137
1 files changed, 67 insertions, 70 deletions
diff --git a/source/Target/Process.cpp b/source/Target/Process.cpp
index ff86b0dbe051..c6ad536cee10 100644
--- a/source/Target/Process.cpp
+++ b/source/Target/Process.cpp
@@ -4823,6 +4823,48 @@ GetExpressionTimeout(const EvaluateExpressionOptions &options,
return *options.GetTimeout() - GetOneThreadExpressionTimeout(options);
}
+static llvm::Optional<ExpressionResults>
+HandleStoppedEvent(Thread &thread, const ThreadPlanSP &thread_plan_sp,
+ RestorePlanState &restorer, const EventSP &event_sp,
+ EventSP &event_to_broadcast_sp,
+ const EvaluateExpressionOptions &options, bool handle_interrupts) {
+ Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_STEP | LIBLLDB_LOG_PROCESS);
+
+ ThreadPlanSP plan = thread.GetCompletedPlan();
+ if (plan == thread_plan_sp && plan->PlanSucceeded()) {
+ LLDB_LOG(log, "execution completed successfully");
+
+ // Restore the plan state so it will get reported as intended when we are
+ // done.
+ restorer.Clean();
+ return eExpressionCompleted;
+ }
+
+ StopInfoSP stop_info_sp = thread.GetStopInfo();
+ if (stop_info_sp && stop_info_sp->GetStopReason() == eStopReasonBreakpoint &&
+ stop_info_sp->ShouldNotify(event_sp.get())) {
+ LLDB_LOG(log, "stopped for breakpoint: {0}.", stop_info_sp->GetDescription());
+ if (!options.DoesIgnoreBreakpoints()) {
+ // Restore the plan state and then force Private to false. We are going
+ // to stop because of this plan so we need it to become a public plan or
+ // it won't report correctly when we continue to its termination later on.
+ restorer.Clean();
+ thread_plan_sp->SetPrivate(false);
+ event_to_broadcast_sp = event_sp;
+ }
+ return eExpressionHitBreakpoint;
+ }
+
+ if (!handle_interrupts &&
+ Process::ProcessEventData::GetInterruptedFromEvent(event_sp.get()))
+ return llvm::None;
+
+ LLDB_LOG(log, "thread plan did not successfully complete");
+ if (!options.DoesUnwindOnError())
+ event_to_broadcast_sp = event_sp;
+ return eExpressionInterrupted;
+}
+
ExpressionResults
Process::RunThreadPlan(ExecutionContext &exe_ctx,
lldb::ThreadPlanSP &thread_plan_sp,
@@ -5228,65 +5270,22 @@ Process::RunThreadPlan(ExecutionContext &exe_ctx,
"but our thread (index-id=%u) has vanished.",
thread_idx_id);
return_value = eExpressionInterrupted;
- } else {
+ } else if (Process::ProcessEventData::GetRestartedFromEvent(
+ event_sp.get())) {
// If we were restarted, we just need to go back up to fetch
// another event.
- if (Process::ProcessEventData::GetRestartedFromEvent(
- event_sp.get())) {
- if (log) {
- log->Printf("Process::RunThreadPlan(): Got a stop and "
- "restart, so we'll continue waiting.");
- }
- keep_going = true;
- do_resume = false;
- handle_running_event = true;
- } else {
- ThreadPlanSP plan = thread->GetCompletedPlan();
- if (plan == thread_plan_sp && plan->PlanSucceeded()) {
-
- if (log)
- log->PutCString("Process::RunThreadPlan(): execution "
- "completed successfully.");
-
- // Restore the plan state so it will get reported as
- // intended when we are done.
- thread_plan_restorer.Clean();
-
- return_value = eExpressionCompleted;
- } else {
- StopInfoSP stop_info_sp = thread_sp->GetStopInfo();
- // Something restarted the target, so just wait for it to
- // stop for real.
- if (stop_info_sp &&
- stop_info_sp->GetStopReason() == eStopReasonBreakpoint) {
- if (log)
- log->Printf("Process::RunThreadPlan() stopped for "
- "breakpoint: %s.",
- stop_info_sp->GetDescription());
- return_value = eExpressionHitBreakpoint;
- if (!options.DoesIgnoreBreakpoints()) {
- // Restore the plan state and then force Private to
- // false. We are
- // going to stop because of this plan so we need it to
- // become a public
- // plan or it won't report correctly when we continue to
- // its termination
- // later on.
- thread_plan_restorer.Clean();
- if (thread_plan_sp)
- thread_plan_sp->SetPrivate(false);
- event_to_broadcast_sp = event_sp;
- }
- } else {
- if (log)
- log->PutCString("Process::RunThreadPlan(): thread plan "
- "didn't successfully complete.");
- if (!options.DoesUnwindOnError())
- event_to_broadcast_sp = event_sp;
- return_value = eExpressionInterrupted;
- }
- }
+ if (log) {
+ log->Printf("Process::RunThreadPlan(): Got a stop and "
+ "restart, so we'll continue waiting.");
}
+ keep_going = true;
+ do_resume = false;
+ handle_running_event = true;
+ } else {
+ const bool handle_interrupts = true;
+ return_value = *HandleStoppedEvent(
+ *thread, thread_plan_sp, thread_plan_restorer, event_sp,
+ event_to_broadcast_sp, options, handle_interrupts);
}
} break;
@@ -5392,20 +5391,6 @@ Process::RunThreadPlan(ExecutionContext &exe_ctx,
}
if (stop_state == lldb::eStateStopped) {
- // Between the time we initiated the Halt and the time we
- // delivered it, the process could have
- // already finished its job. Check that here:
-
- if (thread->IsThreadPlanDone(thread_plan_sp.get())) {
- if (log)
- log->PutCString("Process::RunThreadPlan(): Even though we "
- "timed out, the call plan was done. "
- "Exiting wait loop.");
- return_value = eExpressionCompleted;
- back_to_top = false;
- break;
- }
-
if (Process::ProcessEventData::GetRestartedFromEvent(
event_sp.get())) {
if (log)
@@ -5419,6 +5404,18 @@ Process::RunThreadPlan(ExecutionContext &exe_ctx,
continue;
}
+ // Between the time we initiated the Halt and the time we
+ // delivered it, the process could have
+ // already finished its job. Check that here:
+ const bool handle_interrupts = false;
+ if (auto result = HandleStoppedEvent(
+ *thread, thread_plan_sp, thread_plan_restorer, event_sp,
+ event_to_broadcast_sp, options, handle_interrupts)) {
+ return_value = *result;
+ back_to_top = false;
+ break;
+ }
+
if (!options.GetTryAllThreads()) {
if (log)
log->PutCString("Process::RunThreadPlan(): try_all_threads "