diff options
author | Chris Lattner <sabre@nondot.org> | 2004-01-14 21:18:03 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2004-01-14 21:18:03 +0000 |
commit | 369dbe2a090653385afee9c14ed74e91f92d47d7 (patch) | |
tree | 1bbe0f2c0146a69b83a69e81178b75233d97cb25 /llvm/lib/Debugger/UnixLocalInferiorProcess.cpp | |
parent | 55ca34ab8ad464b942d376ffe96805d03813afea (diff) | |
download | bcm5719-llvm-369dbe2a090653385afee9c14ed74e91f92d47d7.tar.gz bcm5719-llvm-369dbe2a090653385afee9c14ed74e91f92d47d7.zip |
"fix" a nasty race condition
llvm-svn: 10860
Diffstat (limited to 'llvm/lib/Debugger/UnixLocalInferiorProcess.cpp')
-rw-r--r-- | llvm/lib/Debugger/UnixLocalInferiorProcess.cpp | 21 |
1 files changed, 20 insertions, 1 deletions
diff --git a/llvm/lib/Debugger/UnixLocalInferiorProcess.cpp b/llvm/lib/Debugger/UnixLocalInferiorProcess.cpp index 82020362653..20d04803979 100644 --- a/llvm/lib/Debugger/UnixLocalInferiorProcess.cpp +++ b/llvm/lib/Debugger/UnixLocalInferiorProcess.cpp @@ -419,6 +419,9 @@ void IP::writeToChild(void *Buffer, unsigned Size) const { void IP::killChild() const { assert(ChildPID != 0 && "Child has already been reaped!"); + // If the process terminated on its own accord, closing the pipe file + // descriptors, we will get here. Check to see if the process has already + // died in this manner, gracefully. int Status = 0; int PID; do { @@ -426,7 +429,23 @@ void IP::killChild() const { } while (PID < 0 && errno == EINTR); if (PID < 0) throw "Error waiting for child to exit!"; - // If the child process was already dead, then it died unexpectedly. + // Ok, there is a slight race condition here. It's possible that we will find + // out that the file descriptor closed before waitpid will indicate that the + // process gracefully died. If we don't know that the process gracefully + // died, wait a bit and try again. This is pretty nasty. + if (PID == 0) { + usleep(10000); // Wait a bit. + + // Try again. + Status = 0; + do { + PID = waitpid(ChildPID, &Status, WNOHANG); + } while (PID < 0 && errno == EINTR); + if (PID < 0) throw "Error waiting for child to exit!"; + } + + // If the child process was already dead, then indicate that the process + // terminated on its own. if (PID) { assert(PID == ChildPID && "Didn't reap child?"); ChildPID = 0; // Child has been reaped |