From 411a9a6f0751810a1e8eadc7848d141507a2ed0f Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Wed, 14 Jan 2004 21:18:03 +0000 Subject: [PATCH] "fix" a nasty race condition git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@10860 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Debugger/UnixLocalInferiorProcess.cpp | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/lib/Debugger/UnixLocalInferiorProcess.cpp b/lib/Debugger/UnixLocalInferiorProcess.cpp index 82020362653..20d04803979 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