[Lldb-commits] [lldb] r205803 - Fix the behavior when hand-calling a function times out on one thread,

Jim Ingham jingham at apple.com
Tue Apr 8 14:33:21 PDT 2014


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.





More information about the lldb-commits mailing list