aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Support/Windows/Program.inc
diff options
context:
space:
mode:
authorReid Kleckner <reid@kleckner.net>2013-06-13 15:27:17 +0000
committerReid Kleckner <reid@kleckner.net>2013-06-13 15:27:17 +0000
commit6e6a0f50b3314b1d0e6e8706959bd29b57ecd5be (patch)
tree72b9b1d2347c870b42baf1f70f17eaf447c56834 /llvm/lib/Support/Windows/Program.inc
parent92509c1c0c8c9b3ad17aa265c2426a69ff0d0997 (diff)
downloadllvm-6e6a0f50b3314b1d0e6e8706959bd29b57ecd5be.zip
llvm-6e6a0f50b3314b1d0e6e8706959bd29b57ecd5be.tar.gz
llvm-6e6a0f50b3314b1d0e6e8706959bd29b57ecd5be.tar.bz2
[Support] Fix handle and memory leak for processes that are not waited for
Execute's Data parameter is now optional, so we won't allocate memory for it on Windows and we'll close the process handle. The Unix code should probably do something similar to avoid accumulation of zombie children that haven't been waited on. Tested on Linux and Windows. llvm-svn: 183906
Diffstat (limited to 'llvm/lib/Support/Windows/Program.inc')
-rw-r--r--llvm/lib/Support/Windows/Program.inc46
1 files changed, 18 insertions, 28 deletions
diff --git a/llvm/lib/Support/Windows/Program.inc b/llvm/lib/Support/Windows/Program.inc
index 0e8bbc80..90a5cdb 100644
--- a/llvm/lib/Support/Windows/Program.inc
+++ b/llvm/lib/Support/Windows/Program.inc
@@ -170,20 +170,13 @@ static unsigned int ArgLenWithQuotes(const char *Str) {
}
-static bool Execute(void *&Data,
+static bool Execute(void **Data,
const Path& path,
const char** args,
const char** envp,
const Path** redirects,
unsigned memoryLimit,
std::string* ErrMsg) {
- if (Data) {
- Win32ProcessInfo* wpi = reinterpret_cast<Win32ProcessInfo*>(Data);
- CloseHandle(wpi->hProcess);
- delete wpi;
- Data = 0;
- }
-
if (!path.canExecute()) {
if (ErrMsg)
*ErrMsg = "program not executable";
@@ -321,10 +314,12 @@ static bool Execute(void *&Data,
path.str() + "'");
return false;
}
- Win32ProcessInfo* wpi = new Win32ProcessInfo;
- wpi->hProcess = pi.hProcess;
- wpi->dwProcessId = pi.dwProcessId;
- Data = wpi;
+ if (Data) {
+ Win32ProcessInfo* wpi = new Win32ProcessInfo;
+ wpi->hProcess = pi.hProcess;
+ wpi->dwProcessId = pi.dwProcessId;
+ *Data = wpi;
+ }
// Make sure these get closed no matter what.
ScopedCommonHandle hThread(pi.hThread);
@@ -354,21 +349,17 @@ static bool Execute(void *&Data,
}
}
+ // Don't leak the handle if the caller doesn't want it.
+ if (!Data)
+ CloseHandle(pi.hProcess);
+
return true;
}
-static int WaitAux(void *&Data, const Path &path,
- unsigned secondsToWait,
- std::string* ErrMsg) {
- if (Data == 0) {
- MakeErrMsg(ErrMsg, "Process not started!");
- return -1;
- }
-
- Win32ProcessInfo* wpi = reinterpret_cast<Win32ProcessInfo*>(Data);
- HANDLE hProcess = wpi->hProcess;
-
+static int WaitAux(Win32ProcessInfo *wpi, const Path &path,
+ unsigned secondsToWait, std::string *ErrMsg) {
// Wait for the process to terminate.
+ HANDLE hProcess = wpi->hProcess;
DWORD millisecondsToWait = INFINITE;
if (secondsToWait > 0)
millisecondsToWait = secondsToWait * 1000;
@@ -407,12 +398,11 @@ static int WaitAux(void *&Data, const Path &path,
return 1;
}
-static int Wait(void *&Data, const Path &path,
- unsigned secondsToWait,
- std::string* ErrMsg) {
- int Ret = WaitAux(Data, path, secondsToWait, ErrMsg);
+static int Wait(void *&Data, const Path &path, unsigned secondsToWait,
+ std::string *ErrMsg) {
+ Win32ProcessInfo *wpi = reinterpret_cast<Win32ProcessInfo *>(Data);
+ int Ret = WaitAux(wpi, path, secondsToWait, ErrMsg);
- Win32ProcessInfo* wpi = reinterpret_cast<Win32ProcessInfo*>(Data);
CloseHandle(wpi->hProcess);
delete wpi;
Data = 0;