Author: jingham
Date: Tue Apr  8 16:33:21 2014
New Revision: 205803

URL: http://llvm.org/viewvc/llvm-project?rev=205803&view=rev
Log:
Fix the behavior when hand-calling a function times out on one thread,
but by the time we go to halt, it has already stopped by hitting the 
function end breakpoint.  That wasn't being shown to the threads so the
Function call thread plan didn't know its job was done.

<rdar://problem/16515785>

Modified:
    lldb/trunk/source/Target/Process.cpp
    lldb/trunk/source/Target/ThreadList.cpp
    lldb/trunk/source/Target/ThreadPlanCallFunction.cpp

Modified: lldb/trunk/source/Target/Process.cpp
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Process.cpp?rev=205803&r1=205802&r2=205803&view=diff
==============================================================================
--- lldb/trunk/source/Target/Process.cpp (original)
+++ lldb/trunk/source/Target/Process.cpp Tue Apr  8 16:33:21 2014
@@ -3901,6 +3901,9 @@ Process::ShouldBroadcastEvent (Event *ev
                     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 (
         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
 
         // 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
                     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)

Modified: lldb/trunk/source/Target/ThreadList.cpp
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadList.cpp?rev=205803&r1=205802&r2=205803&view=diff
==============================================================================
--- lldb/trunk/source/Target/ThreadList.cpp (original)
+++ lldb/trunk/source/Target/ThreadList.cpp Tue Apr  8 16:33:21 2014
@@ -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

Modified: lldb/trunk/source/Target/ThreadPlanCallFunction.cpp
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadPlanCallFunction.cpp?rev=205803&r1=205802&r2=205803&view=diff
==============================================================================
--- lldb/trunk/source/Target/ThreadPlanCallFunction.cpp (original)
+++ lldb/trunk/source/Target/ThreadPlanCallFunction.cpp Tue Apr  8 16:33:21 2014
@@ -333,6 +333,14 @@ ThreadPlanCallFunction::DoPlanExplainsSt
     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.


_______________________________________________
lldb-commits mailing list
lldb-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits

Reply via email to