[llvm] r183906 - [Support] Fix handle and memory leak for processes that are not waited for
Rafael EspĂndola
rafael.espindola at gmail.com
Thu Jun 13 09:02:17 PDT 2013
Thanks!
On 13 June 2013 11:27, Reid Kleckner <reid at kleckner.net> wrote:
> Author: rnk
> Date: Thu Jun 13 10:27:17 2013
> New Revision: 183906
>
> URL: http://llvm.org/viewvc/llvm-project?rev=183906&view=rev
> Log:
> [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.
>
> Modified:
> llvm/trunk/lib/Support/Program.cpp
> llvm/trunk/lib/Support/Unix/Program.inc
> llvm/trunk/lib/Support/Windows/Program.inc
>
> Modified: llvm/trunk/lib/Support/Program.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Program.cpp?rev=183906&r1=183905&r2=183906&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Support/Program.cpp (original)
> +++ llvm/trunk/lib/Support/Program.cpp Thu Jun 13 10:27:17 2013
> @@ -22,7 +22,7 @@ using namespace sys;
> //=== independent code.
> //===----------------------------------------------------------------------===//
>
> -static bool Execute(void *&Data, const Path &path, const char **args,
> +static bool Execute(void **Data, const Path &path, const char **args,
> const char **env, const sys::Path **redirects,
> unsigned memoryLimit, std::string *ErrMsg);
>
> @@ -34,7 +34,7 @@ int sys::ExecuteAndWait(const Path &path
> unsigned memoryLimit, std::string *ErrMsg,
> bool *ExecutionFailed) {
> void *Data = 0;
> - if (Execute(Data, path, args, envp, redirects, memoryLimit, ErrMsg)) {
> + if (Execute(&Data, path, args, envp, redirects, memoryLimit, ErrMsg)) {
> if (ExecutionFailed) *ExecutionFailed = false;
> return Wait(Data, path, secondsToWait, ErrMsg);
> }
> @@ -45,8 +45,7 @@ int sys::ExecuteAndWait(const Path &path
> void sys::ExecuteNoWait(const Path &path, const char **args, const char **envp,
> const Path **redirects, unsigned memoryLimit,
> std::string *ErrMsg) {
> - void *Data = 0;
> - Execute(Data, path, args, envp, redirects, memoryLimit, ErrMsg);
> + Execute(/*Data*/ 0, path, args, envp, redirects, memoryLimit, ErrMsg);
> }
>
> // Include the platform-specific parts of this class.
>
> Modified: llvm/trunk/lib/Support/Unix/Program.inc
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Unix/Program.inc?rev=183906&r1=183905&r2=183906&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Support/Unix/Program.inc (original)
> +++ llvm/trunk/lib/Support/Unix/Program.inc Thu Jun 13 10:27:17 2013
> @@ -178,7 +178,7 @@ static void SetMemoryLimits (unsigned si
>
> }
>
> -static bool Execute(void *&Data, const Path &path, const char **args,
> +static bool Execute(void **Data, const Path &path, const char **args,
> const char **envp, const Path **redirects,
> unsigned memoryLimit, std::string *ErrMsg) {
> // If this OS has posix_spawn and there is no memory limit being implied, use
> @@ -228,7 +228,8 @@ static bool Execute(void *&Data, const P
> if (Err)
> return !MakeErrMsg(ErrMsg, "posix_spawn failed", Err);
>
> - Data = reinterpret_cast<void*>(PID);
> + if (Data)
> + *Data = reinterpret_cast<void*>(PID);
> return true;
> }
> #endif
> @@ -290,7 +291,8 @@ static bool Execute(void *&Data, const P
> break;
> }
>
> - Data = reinterpret_cast<void*>(child);
> + if (Data)
> + *Data = reinterpret_cast<void*>(child);
>
> return true;
> }
> @@ -299,11 +301,7 @@ static int Wait(void *&Data, const sys::
> std::string *ErrMsg) {
> #ifdef HAVE_SYS_WAIT_H
> struct sigaction Act, Old;
> -
> - if (Data == 0) {
> - MakeErrMsg(ErrMsg, "Process not started!");
> - return -1;
> - }
> + assert(Data && "invalid pid to wait on, process not started?");
>
> // Install a timeout handler. The handler itself does nothing, but the simple
> // fact of having a handler at all causes the wait below to return with EINTR,
>
> Modified: llvm/trunk/lib/Support/Windows/Program.inc
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Windows/Program.inc?rev=183906&r1=183905&r2=183906&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Support/Windows/Program.inc (original)
> +++ llvm/trunk/lib/Support/Windows/Program.inc Thu Jun 13 10:27:17 2013
> @@ -170,20 +170,13 @@ static unsigned int ArgLenWithQuotes(con
>
> }
>
> -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 Pa
> 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;
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list