summaryrefslogtreecommitdiff
path: root/lib/Debugger
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2004-01-14 21:18:03 +0000
committerChris Lattner <sabre@nondot.org>2004-01-14 21:18:03 +0000
commit411a9a6f0751810a1e8eadc7848d141507a2ed0f (patch)
tree2d69d43eabaf3290368e180730439d6aa4692fa6 /lib/Debugger
parentde31b76784c8c8e673afd2e14480df7644266da3 (diff)
downloadllvm-411a9a6f0751810a1e8eadc7848d141507a2ed0f.tar.gz
llvm-411a9a6f0751810a1e8eadc7848d141507a2ed0f.tar.bz2
llvm-411a9a6f0751810a1e8eadc7848d141507a2ed0f.tar.xz
"fix" a nasty race condition
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@10860 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Debugger')
-rw-r--r--lib/Debugger/UnixLocalInferiorProcess.cpp21
1 files changed, 20 insertions, 1 deletions
diff --git a/lib/Debugger/UnixLocalInferiorProcess.cpp b/lib/Debugger/UnixLocalInferiorProcess.cpp
index 8202036265..20d0480397 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