Moved the code in ClangUserExpression that set up & ran the thread plan with timeouts, and restarting with all threads into a utility function in Process.  This required a bunch of renaming. 

Added a ThreadPlanCallUserExpression that differs from ThreadPlanCallFunction in that it holds onto a shared pointer to its ClangUserExpression so that can't go away before the thread plan is done using it.

Fixed the stop message when you hit a breakpoint while running a user expression so it is more obvious what has happened.

git-svn-id: https://llvm.org/svn/llvm-project/llvdb/trunk@120386 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Expression/ClangFunction.cpp b/source/Expression/ClangFunction.cpp
index 1eeeb00..3dc31ec 100644
--- a/source/Expression/ClangFunction.cpp
+++ b/source/Expression/ClangFunction.cpp
@@ -275,7 +275,7 @@
         
     Error error;
     using namespace clang;
-    ExecutionResults return_value = eExecutionSetupError;
+    Process::ExecutionResults return_value = Process::eExecutionSetupError;
 
     Process *process = exe_ctx.process;
 
@@ -439,13 +439,13 @@
     exe_ctx.process->DeallocateMemory(args_addr);
 }
 
-ClangFunction::ExecutionResults
+Process::ExecutionResults
 ClangFunction::ExecuteFunction(ExecutionContext &exe_ctx, Stream &errors, Value &results)
 {
     return ExecuteFunction (exe_ctx, errors, 1000, true, results);
 }
 
-ClangFunction::ExecutionResults
+Process::ExecutionResults
 ClangFunction::ExecuteFunction(ExecutionContext &exe_ctx, Stream &errors, bool stop_others, Value &results)
 {
     const bool try_all_threads = false;
@@ -453,7 +453,7 @@
     return ExecuteFunction (exe_ctx, NULL, errors, stop_others, NULL, try_all_threads, discard_on_error, results);
 }
 
-ClangFunction::ExecutionResults
+Process::ExecutionResults
 ClangFunction::ExecuteFunction(
         ExecutionContext &exe_ctx, 
         Stream &errors, 
@@ -468,7 +468,7 @@
 }
 
 // This is the static function
-ClangFunction::ExecutionResults 
+Process::ExecutionResults 
 ClangFunction::ExecuteFunction (
         ExecutionContext &exe_ctx, 
         lldb::addr_t function_address, 
@@ -480,259 +480,19 @@
         Stream &errors,
         lldb::addr_t *this_arg)
 {
-    // Save this value for restoration of the execution context after we run
-    uint32_t tid = exe_ctx.thread->GetIndexID();
-    
-    // N.B. Running the target may unset the currently selected thread and frame.  We don't want to do that either, 
-    // so we should arrange to reset them as well.
-    
-    lldb::ThreadSP selected_thread_sp = exe_ctx.process->GetThreadList().GetSelectedThread();
-    lldb::StackFrameSP selected_frame_sp;
-    
-    uint32_t selected_tid; 
-    if (selected_thread_sp != NULL)
-    {
-        selected_tid = selected_thread_sp->GetIndexID();
-        selected_frame_sp = selected_thread_sp->GetSelectedFrame();
-    }
-    else
-    {
-        selected_tid = LLDB_INVALID_THREAD_ID;
-    }
-
-    ClangFunction::ExecutionResults return_value = eExecutionSetupError;
     lldb::ThreadPlanSP call_plan_sp(ClangFunction::GetThreadPlanToCallFunction(exe_ctx, function_address, void_arg, 
                                                                                errors, stop_others, discard_on_error, 
                                                                                this_arg));
-    
-    ThreadPlanCallFunction *call_plan_ptr = static_cast<ThreadPlanCallFunction *> (call_plan_sp.get());
-    
     if (call_plan_sp == NULL)
-        return eExecutionSetupError;
+        return Process::eExecutionSetupError;
     
     call_plan_sp->SetPrivate(true);
-    exe_ctx.thread->QueueThreadPlan(call_plan_sp, true);
     
-    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;
-    
-    if (single_thread_timeout_usec != 0)
-    {
-        real_timeout = TimeValue::Now();
-        real_timeout.OffsetWithMicroSeconds(single_thread_timeout_usec);
-        timeout_ptr = &real_timeout;
-    }
-    
-    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
-    while (1)
-    {
-        lldb::EventSP event_sp;
-        lldb::StateType stop_state = lldb::eStateInvalid;
-        // Now wait for the process to stop again:
-        bool got_event = listener.WaitForEvent (timeout_ptr, event_sp);
-        
-        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...
-            if (log)
-                if (try_all_threads)
-                    log->Printf ("Running function with timeout: %d timed out, trying with all threads enabled.",
-                                 single_thread_timeout_usec);
-                else
-                    log->Printf ("Running function with timeout: %d timed out, abandoning execution.", 
-                                 single_thread_timeout_usec);
-            
-            if (exe_ctx.process->Halt().Success())
-            {
-                timeout_ptr = NULL;
-                if (log)
-                    log->Printf ("Halt succeeded.");
-                    
-                // 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 (got_event)
-                {
-                    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;
-                    }
-
-                    if (try_all_threads 
-                        && (stop_state == lldb::eStateStopped && Process::ProcessEventData::GetInterruptedFromEvent (event_sp.get())))
-                    {
-                        
-                        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;
-        
-        if (exe_ctx.thread->IsThreadPlanDone (call_plan_sp.get()))
-        {
-            return_value = eExecutionCompleted;
-            break;
-        }
-        else if (exe_ctx.thread->WasThreadPlanDiscarded (call_plan_sp.get()))
-        {
-            return_value = eExecutionDiscarded;
-            break;
-        }
-        else
-        {
-            if (log)
-            {
-                StreamString s;
-                event_sp->Dump (&s);
-                StreamString ts;
-
-                const char *event_explanation;                
-                
-                do 
-                {
-                    const Process::ProcessEventData *event_data = Process::ProcessEventData::GetEventDataFromEvent (event_sp.get());
-
-                    if (!event_data)
-                    {
-                        event_explanation = "<no event data>";
-                        break;
-                    }
-                    
-                    Process *process = event_data->GetProcessSP().get();
-
-                    if (!process)
-                    {
-                        event_explanation = "<no process>";
-                        break;
-                    }
-                    
-                    ThreadList &thread_list = process->GetThreadList();
-                    
-                    uint32_t num_threads = thread_list.GetSize();
-                    uint32_t thread_index;
-                    
-                    ts.Printf("<%u threads> ", num_threads);
-                    
-                    for (thread_index = 0;
-                         thread_index < num_threads;
-                         ++thread_index)
-                    {
-                        Thread *thread = thread_list.GetThreadAtIndex(thread_index).get();
-                        
-                        if (!thread)
-                        {
-                            ts.Printf("<?> ");
-                            continue;
-                        }
-                        
-                        ts.Printf("<");
-                        RegisterContext *register_context = thread->GetRegisterContext();
-                        
-                        if (register_context)
-                            ts.Printf("[ip 0x%llx] ", register_context->GetPC());
-                        else
-                            ts.Printf("[ip unknown] ");
-                        
-                        lldb::StopInfoSP stop_info_sp = thread->GetStopInfo();
-                        if (stop_info_sp)
-                        {
-                            const char *stop_desc = stop_info_sp->GetDescription();
-                            if (stop_desc)
-                                ts.PutCString (stop_desc);
-                        }
-                        ts.Printf(">");
-                    }
-                    
-                    event_explanation = ts.GetData();
-                } while (0);
-                
-                if (log)
-                    log->Printf("Execution interrupted: %s %s", s.GetData(), event_explanation);
-            }
-            
-            if (discard_on_error && call_plan_sp)
-            {
-                exe_ctx.thread->DiscardThreadPlansUpToPlan (call_plan_sp);
-            }
-            return_value = eExecutionInterrupted;
-            break;
-        }
-    }
-    
-    if (exe_ctx.process)
-        exe_ctx.process->RestoreProcessEvents ();
-            
-    // Thread we ran the function in may have gone away because we ran the target
-    // Check that it's still there.
-    exe_ctx.thread = exe_ctx.process->GetThreadList().FindThreadByIndexID(tid, true).get();
-    if (exe_ctx.thread)
-        exe_ctx.frame = exe_ctx.thread->GetStackFrameAtIndex(0).get();
-    
-    // Also restore the current process'es selected frame & thread, since this function calling may
-    // be done behind the user's back.
-    
-    if (selected_tid != LLDB_INVALID_THREAD_ID)
-    {
-        if (exe_ctx.process->GetThreadList().SetSelectedThreadByIndexID (selected_tid))
-        {
-            // We were able to restore the selected thread, now restore the frame:
-            exe_ctx.process->GetThreadList().GetSelectedThread()->SetSelectedFrame(selected_frame_sp.get());
-        }
-    }
-    
-    return return_value;
+    return exe_ctx.process->RunThreadPlan (exe_ctx, call_plan_sp, stop_others, try_all_threads, discard_on_error,
+                                            single_thread_timeout_usec, errors);
 }  
 
-ClangFunction::ExecutionResults
+Process::ExecutionResults
 ClangFunction::ExecuteFunction(
         ExecutionContext &exe_ctx, 
         lldb::addr_t *args_addr_ptr, 
@@ -744,7 +504,7 @@
         Value &results)
 {
     using namespace clang;
-    ExecutionResults return_value = eExecutionSetupError;
+    Process::ExecutionResults return_value = Process::eExecutionSetupError;
     
     lldb::addr_t args_addr;
     
@@ -754,12 +514,12 @@
         args_addr = LLDB_INVALID_ADDRESS;
         
     if (CompileFunction(errors) != 0)
-        return eExecutionSetupError;
+        return Process::eExecutionSetupError;
     
     if (args_addr == LLDB_INVALID_ADDRESS)
     {
         if (!InsertFunction(exe_ctx, args_addr, errors))
-            return eExecutionSetupError;
+            return Process::eExecutionSetupError;
     }
     
     return_value = ClangFunction::ExecuteFunction(exe_ctx, m_wrapper_function_addr, args_addr, stop_others, 
@@ -768,7 +528,7 @@
     if (args_addr_ptr != NULL)
         *args_addr_ptr = args_addr;
     
-    if (return_value != eExecutionCompleted)
+    if (return_value != Process::eExecutionCompleted)
         return return_value;
 
     FetchFunctionResults(exe_ctx, args_addr, results);
@@ -776,7 +536,7 @@
     if (args_addr_ptr == NULL)
         DeallocateFunctionResults(exe_ctx, args_addr);
         
-    return eExecutionCompleted;
+    return Process::eExecutionCompleted;
 }
 
 clang::ASTConsumer *