Author: gclayton
Date: Wed Jul 16 16:05:41 2014
New Revision: 213196

URL: http://llvm.org/viewvc/llvm-project?rev=213196&view=rev
Log:
^C wasn't interrupting an expression during a long evaluation or deadlock.

The problem was that we have an IOHandler thread that services the IOHandler 
stack. The command interepter is on the top of the stack and it receives a 
"expression ..." command, and it calls the IOHandlerIsComplete() callback in 
the command interpereter delegate which runs an expression. This causes the 
IOHandlerProcessSTDIO to be pushed, but since we are running the code from the 
IOHandler thread, it won't get run. When CTRL+C is pressed, we do deliver the 
interrupt to the IOHandlerProcessSTDIO::Interrupt() function, but it was always 
writing 'i' to the interrupt pipe, even if we weren't actively reading from the 
debugger input and the pipes. This fix works around the issue by directly 
issuing the async interrupt to the process if the process is running.

A longer term more correct fix would to be run the IOHandler thread and have it 
just do the determination of the input and when complete input is received, run 
the code that handles that input on another thread and syncronize with that 
other thread to detect when more input is desired. That change is too big to 
make right now, so this fix will tide us over until we can get there.

<rdar://problem/16556228>



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

Modified: lldb/trunk/source/Target/Process.cpp
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Process.cpp?rev=213196&r1=213195&r2=213196&view=diff
==============================================================================
--- lldb/trunk/source/Target/Process.cpp (original)
+++ lldb/trunk/source/Target/Process.cpp Wed Jul 16 16:05:41 2014
@@ -4595,8 +4595,28 @@ public:
         // interrupt the IOHandlerProcessSTDIO::Run() and we can look at the 
byte
         // that was written to the pipe and then call m_process->Halt() from a
         // much safer location in code.
-        char ch = 'i'; // Send 'i' for interrupt
-        return m_pipe.Write (&ch, 1) == 1;
+        if (m_active)
+        {
+            char ch = 'i'; // Send 'i' for interrupt
+            return m_pipe.Write (&ch, 1) == 1;
+        }
+        else
+        {
+            // This IOHandler might be pushed on the stack, but not being run 
currently
+            // so do the right thing if we aren't actively watching for STDIN 
by sending
+            // the interrupt to the process. Otherwise the write to the pipe 
above would
+            // do nothing. This can happen when the command interpreter is 
running and
+            // gets a "expression ...". It will be on the IOHandler thread and 
sending
+            // the input is complete to the delegate which will cause the 
expression to
+            // run, which will push the process IO handler, but not run it.
+            
+            if (StateIsRunningState(m_process->GetState()))
+            {
+                m_process->SendAsyncInterrupt();
+                return true;
+            }
+        }
+        return false;
     }
     
     virtual void


_______________________________________________
lldb-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits

Reply via email to