Fix the error message when an expression evaluation is interrupted by a crash/breakpoint hit to
give the reason for the interrupt. Also make sure it we don't want to unwind from the evaluation
we print something if it is interrupted.
git-svn-id: https://llvm.org/svn/llvm-project/llvdb/trunk@131448 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Expression/ClangUserExpression.cpp b/source/Expression/ClangUserExpression.cpp
index 6eafd7b..563c28a 100644
--- a/source/Expression/ClangUserExpression.cpp
+++ b/source/Expression/ClangUserExpression.cpp
@@ -504,7 +504,7 @@
lldb::addr_t function_stack_pointer = static_cast<ThreadPlanCallFunction *>(call_plan_sp.get())->GetFunctionStackPointer();
- call_plan_sp->SetPrivate(true);
+ // call_plan_sp->SetPrivate(true);
uint32_t single_thread_timeout_usec = 500000;
@@ -524,10 +524,23 @@
if (execution_result == eExecutionInterrupted)
{
- if (discard_on_error)
- error_stream.Printf ("Expression execution was interrupted. The process has been returned to the state before execution.");
+ const char *error_desc = NULL;
+
+ if (call_plan_sp)
+ {
+ lldb::StopInfoSP real_stop_info_sp = call_plan_sp->GetRealStopInfo();
+ if (real_stop_info_sp)
+ error_desc = real_stop_info_sp->GetDescription();
+ }
+ if (error_desc)
+ error_stream.Printf ("Execution was interrupted, reason: %s.", error_desc);
else
- error_stream.Printf ("Expression execution was interrupted. The process has been left at the point where it was interrupted.");
+ error_stream.Printf ("Execution was interrupted.", error_desc);
+
+ if (discard_on_error)
+ error_stream.Printf ("\nThe process has been returned to the state before execution.");
+ else
+ error_stream.Printf ("\nThe process has been left at the point where it was interrupted.");
return execution_result;
}
diff --git a/source/Target/Process.cpp b/source/Target/Process.cpp
index f185d57..88b813c 100644
--- a/source/Target/Process.cpp
+++ b/source/Target/Process.cpp
@@ -3498,11 +3498,40 @@
switch (stop_state)
{
case lldb::eStateStopped:
- // Yay, we're done.
- if (log)
- log->Printf ("Execution completed successfully.");
- return_value = eExecutionCompleted;
- break;
+ {
+ // Yay, we're done. Now make sure that our thread plan actually completed.
+ ThreadSP thread_sp = exe_ctx.process->GetThreadList().FindThreadByIndexID (tid);
+ if (!thread_sp)
+ {
+ // Ooh, our thread has vanished. Unlikely that this was successful execution...
+ if (log)
+ log->Printf ("Execution completed but our thread has vanished.");
+ return_value = eExecutionInterrupted;
+ }
+ else
+ {
+ StopInfoSP stop_info_sp = thread_sp->GetStopInfo ();
+ StopReason stop_reason = stop_info_sp->GetStopReason();
+ if (stop_reason == eStopReasonPlanComplete)
+ {
+ if (log)
+ log->Printf ("Execution completed successfully.");
+ // Now mark this plan as private so it doesn't get reported as the stop reason
+ // after this point.
+ if (thread_plan_sp)
+ thread_plan_sp->SetPrivate (true);
+ return_value = eExecutionCompleted;
+ }
+ else
+ {
+ if (log)
+ log->Printf ("Thread plan didn't successfully complete.");
+
+ return_value = eExecutionInterrupted;
+ }
+ }
+ }
+ break;
case lldb::eStateCrashed:
if (log)
log->Printf ("Execution crashed.");
@@ -3515,6 +3544,8 @@
default:
if (log)
log->Printf("Execution stopped with unexpected state: %s.", StateAsCString(stop_state));
+
+ errors.Printf ("Execution stopped with unexpected state.");
return_value = eExecutionInterrupted;
break;
}
diff --git a/source/Target/ThreadPlanCallFunction.cpp b/source/Target/ThreadPlanCallFunction.cpp
index 371f3a4..7d798fc 100644
--- a/source/Target/ThreadPlanCallFunction.cpp
+++ b/source/Target/ThreadPlanCallFunction.cpp
@@ -282,6 +282,7 @@
if (log)
log->Printf ("DoTakedown called for thread 0x%4.4x, m_valid: %d complete: %d.\n", m_thread.GetID(), m_valid, IsPlanComplete());
m_takedown_done = true;
+ m_real_stop_info_sp = GetPrivateStopReason();
m_thread.RestoreThreadStateFromCheckpoint(m_stored_thread_state);
SetPlanComplete();
ClearBreakpoints();
@@ -327,6 +328,8 @@
bool
ThreadPlanCallFunction::PlanExplainsStop ()
{
+ m_real_stop_info_sp = GetPrivateStopReason();
+
// If our subplan knows why we stopped, even if it's done (which would forward the question to us)
// we answer yes.
if(m_subplan_sp.get() != NULL && m_subplan_sp->PlanExplainsStop())
@@ -343,11 +346,10 @@
// Otherwise, check the case where we stopped for an internal breakpoint, in that case, continue on.
// If it is not an internal breakpoint, consult OkayToDiscard.
- StopInfoSP stop_info_sp = GetPrivateStopReason();
- if (stop_info_sp && stop_info_sp->GetStopReason() == eStopReasonBreakpoint)
+ if (m_real_stop_info_sp && m_real_stop_info_sp->GetStopReason() == eStopReasonBreakpoint)
{
- uint64_t break_site_id = stop_info_sp->GetValue();
+ uint64_t break_site_id = m_real_stop_info_sp->GetValue();
BreakpointSiteSP bp_site_sp = m_thread.GetProcess().GetBreakpointSiteList().FindByID(break_site_id);
if (bp_site_sp)
{