summaryrefslogtreecommitdiffstats
path: root/lldb/source/Expression/ClangFunction.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Expression/ClangFunction.cpp')
-rw-r--r--lldb/source/Expression/ClangFunction.cpp97
1 files changed, 50 insertions, 47 deletions
diff --git a/lldb/source/Expression/ClangFunction.cpp b/lldb/source/Expression/ClangFunction.cpp
index 40cddf3699d..84b8bff9a26 100644
--- a/lldb/source/Expression/ClangFunction.cpp
+++ b/lldb/source/Expression/ClangFunction.cpp
@@ -26,6 +26,7 @@
#include "lldb/Expression/ClangFunction.h"
#include "lldb/Symbol/Type.h"
#include "lldb/Core/DataExtractor.h"
+#include "lldb/Core/State.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Core/ValueObjectList.h"
#include "lldb/Interpreter/CommandReturnObject.h"
@@ -509,18 +510,25 @@ ClangFunction::ExecuteFunction (
if (call_plan_sp == NULL)
return eExecutionSetupError;
-//#define SINGLE_STEP_EXPRESSIONS
-
-#ifdef SINGLE_STEP_EXPRESSIONS
- return eExecutionInterrupted;
-#else
call_plan_sp->SetPrivate(true);
exe_ctx.thread->QueueThreadPlan(call_plan_sp, true);
-#endif
+
+ Listener listener("ClangFunction temporary listener");
+ exe_ctx.process->HijackProcessEvents(&listener);
+
+ Error resume_error = exe_ctx.process->Resume ();
+ if (!resume_error.Success())
+ {
+ errors.Printf("Error resuming inferior: \"%s\".\n", resume_error.AsCString());
+ exe_ctx.process->RestoreProcessEvents();
+ return eExecutionSetupError;
+ }
// We need to call the function synchronously, so spin waiting for it to return.
// If we get interrupted while executing, we're going to lose our context, and
// won't be able to gather the result at this point.
+ // We set the timeout AFTER the resume, since the resume takes some time and we
+ // don't want to charge that to the timeout.
TimeValue* timeout_ptr = NULL;
TimeValue real_timeout;
@@ -532,18 +540,7 @@ ClangFunction::ExecuteFunction (
timeout_ptr = &real_timeout;
}
- Listener listener("ClangFunction temporary listener");
- exe_ctx.process->HijackProcessEvents(&listener);
-
- Error resume_error = exe_ctx.process->Resume ();
- if (!resume_error.Success())
- {
- errors.Printf("Error resuming inferior: \"%s\".\n", resume_error.AsCString());
- return eExecutionSetupError;
- }
-
lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
-
while (1)
{
lldb::EventSP event_sp;
@@ -551,12 +548,11 @@ ClangFunction::ExecuteFunction (
// Now wait for the process to stop again:
bool got_event = listener.WaitForEvent (timeout_ptr, event_sp);
- if (!got_event && !call_plan_sp->IsPlanComplete())
+ if (!got_event)
{
// Right now this is the only way to tell we've timed out...
// We should interrupt the process here...
// Not really sure what to do if Halt fails here...
- log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
if (log)
if (try_all_threads)
log->Printf ("Running function with timeout: %d timed out, trying with all threads enabled.",
@@ -568,45 +564,54 @@ ClangFunction::ExecuteFunction (
if (exe_ctx.process->Halt().Success())
{
timeout_ptr = NULL;
-
- got_event = listener.WaitForEvent (timeout_ptr, event_sp);
- stop_state = Process::ProcessEventData::GetStateFromEvent(event_sp.get());
-
- if (stop_state == lldb::eStateInvalid)
- {
- errors.Printf ("Got an invalid stop state after halt.");
- }
- else if (stop_state != lldb::eStateStopped)
- {
- StreamString s;
- event_sp->Dump (&s);
+ if (log)
+ log->Printf ("Halt succeeded.");
- errors.Printf("Didn't get a stopped event after Halting the target, got: \"%s\"", s.GetData());
- }
+ // Between the time that we got the timeout and the time we halted, but target
+ // might have actually completed the plan. If so, we're done. Note, I call WFE here with a short
+ // timeout to
+ got_event = listener.WaitForEvent(NULL, event_sp);
- if (try_all_threads)
+ if (got_event)
{
- // Between the time that we got the timeout and the time we halted, but target
- // might have actually completed the plan. If so, we're done.
+ stop_state = Process::ProcessEventData::GetStateFromEvent(event_sp.get());
+ if (log)
+ {
+ log->Printf ("Stopped with event: %s", StateAsCString(stop_state));
+ if (stop_state == lldb::eStateStopped && Process::ProcessEventData::GetInterruptedFromEvent(event_sp.get()))
+ log->Printf (" Event was the Halt interruption event.");
+ }
+
if (exe_ctx.thread->IsThreadPlanDone (call_plan_sp.get()))
{
+ if (log)
+ log->Printf ("Even though we timed out, the call plan was done. Exiting wait loop.");
return_value = eExecutionCompleted;
break;
}
-
- call_plan_ptr->SetStopOthers (false);
- exe_ctx.process->Resume();
- continue;
- }
- else
- {
- exe_ctx.process->RestoreProcessEvents ();
- return eExecutionInterrupted;
+
+ if (try_all_threads)
+ {
+
+ call_plan_ptr->SetStopOthers (false);
+ if (log)
+ log->Printf ("About to resume.");
+
+ exe_ctx.process->Resume();
+ continue;
+ }
+ else
+ {
+ exe_ctx.process->RestoreProcessEvents ();
+ return eExecutionInterrupted;
+ }
}
}
}
stop_state = Process::ProcessEventData::GetStateFromEvent(event_sp.get());
+ if (log)
+ log->Printf("Got event: %s.", StateAsCString(stop_state));
if (stop_state == lldb::eStateRunning || stop_state == lldb::eStateStepping)
continue;
@@ -623,7 +628,6 @@ ClangFunction::ExecuteFunction (
}
else
{
- log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
if (log)
{
StreamString s;
@@ -690,7 +694,6 @@ ClangFunction::ExecuteFunction (
event_explanation = ts.GetData();
} while (0);
- log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
if (log)
log->Printf("Execution interrupted: %s %s", s.GetData(), event_explanation);
}
OpenPOWER on IntegriCloud