[Lldb-commits] [lldb] r213196 - ^C wasn't interrupting an expression during a long evaluation or deadlock.
gclayton at apple.com
Wed Jul 16 14:05:42 PDT 2014
Date: Wed Jul 16 16:05:41 2014
New Revision: 213196
^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.
--- 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;
+ // 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()))
+ return true;
+ return false;
More information about the lldb-commits