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 | 411a9a6f0751810a1e8eadc7848d141507a2ed0f (patch) | |
tree | 2d69d43eabaf3290368e180730439d6aa4692fa6 | |
parent | de31b76784c8c8e673afd2e14480df7644266da3 (diff) | |
download | external_llvm-411a9a6f0751810a1e8eadc7848d141507a2ed0f.zip external_llvm-411a9a6f0751810a1e8eadc7848d141507a2ed0f.tar.gz external_llvm-411a9a6f0751810a1e8eadc7848d141507a2ed0f.tar.bz2 |
"fix" a nasty race condition
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@10860 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Debugger/UnixLocalInferiorProcess.cpp | 21 |
1 files changed, 20 insertions, 1 deletions
diff --git a/lib/Debugger/UnixLocalInferiorProcess.cpp b/lib/Debugger/UnixLocalInferiorProcess.cpp index 8202036..20d0480 100644 --- a/lib/Debugger/UnixLocalInferiorProcess.cpp +++ b/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 |