summaryrefslogtreecommitdiffstats
path: root/lldb/source/Target/Process.cpp
diff options
context:
space:
mode:
authorGreg Clayton <gclayton@apple.com>2014-07-16 21:05:41 +0000
committerGreg Clayton <gclayton@apple.com>2014-07-16 21:05:41 +0000
commit0fdd3ae54d07ec8a84efa9ff676d64d7693f88dc (patch)
tree4b4fe88f2f3b3fea6430cd2dea6c1c26fc0796f9 /lldb/source/Target/Process.cpp
parent9185115abb9942d673236b4cb919bc3560530484 (diff)
downloadbcm5719-llvm-0fdd3ae54d07ec8a84efa9ff676d64d7693f88dc.tar.gz
bcm5719-llvm-0fdd3ae54d07ec8a84efa9ff676d64d7693f88dc.zip
^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> llvm-svn: 213196
Diffstat (limited to 'lldb/source/Target/Process.cpp')
-rw-r--r--lldb/source/Target/Process.cpp24
1 files changed, 22 insertions, 2 deletions
diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp
index 20947b9d9ba..2c9b1e560fd 100644
--- a/lldb/source/Target/Process.cpp
+++ b/lldb/source/Target/Process.cpp
@@ -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
OpenPOWER on IntegriCloud