diff --git a/include/llvm/Support/Program.h b/include/llvm/Support/Program.h index 986c53e908d..a5026573aa9 100644 --- a/include/llvm/Support/Program.h +++ b/include/llvm/Support/Program.h @@ -85,8 +85,9 @@ namespace sys { /// This function waits for the program to exit. This function will block /// the current program until the invoked program exits. /// @returns an integer result code indicating the status of the program. - /// A zero or positive value indicates the result code of the program. A - /// negative value is the signal number on which it terminated. + /// A zero or positive value indicates the result code of the program. + /// -1 indicates failure to execute + /// -2 indicates a crash during execution or timeout /// @see Execute /// @brief Waits for the program to exit. int Wait @@ -96,11 +97,9 @@ namespace sys { ///< expires, the child is killed and this call returns. If zero, ///< this function will wait until the child finishes or forever if ///< it doesn't. - std::string* ErrMsg, ///< If non-zero, provides a pointer to a string + std::string* ErrMsg ///< If non-zero, provides a pointer to a string ///< instance in which error messages will be returned. If the string ///< is non-empty upon return an error occurred while waiting. - const char *SignalPrefix ///< If non-zero, provides a prefix to be - ///< prepended to ErrMsg if the process is terminated abnormally. ); /// This function terminates the program. @@ -139,8 +138,7 @@ namespace sys { const sys::Path** redirects = 0, unsigned secondsToWait = 0, unsigned memoryLimit = 0, - std::string* ErrMsg = 0, - const char *SignalPrefix = 0); + std::string* ErrMsg = 0); /// A convenience function equivalent to Program prg; prg.Execute(..); /// @see Execute diff --git a/lib/Support/Program.cpp b/lib/Support/Program.cpp index fa816f68c8a..01860b082d6 100644 --- a/lib/Support/Program.cpp +++ b/lib/Support/Program.cpp @@ -28,11 +28,10 @@ Program::ExecuteAndWait(const Path& path, const Path** redirects, unsigned secondsToWait, unsigned memoryLimit, - std::string* ErrMsg, - const char* SignalPrefix) { + std::string* ErrMsg) { Program prg; if (prg.Execute(path, args, envp, redirects, memoryLimit, ErrMsg)) - return prg.Wait(path, secondsToWait, ErrMsg, SignalPrefix); + return prg.Wait(path, secondsToWait, ErrMsg); else return -1; } diff --git a/lib/Support/Unix/Program.inc b/lib/Support/Unix/Program.inc index 86f3aa9eaca..346baf1744d 100644 --- a/lib/Support/Unix/Program.inc +++ b/lib/Support/Unix/Program.inc @@ -298,8 +298,7 @@ Program::Execute(const Path &path, const char **args, const char **envp, int Program::Wait(const sys::Path &path, unsigned secondsToWait, - std::string* ErrMsg, - const char* SignalPrefix) + std::string* ErrMsg) { #ifdef HAVE_SYS_WAIT_H struct sigaction Act, Old; @@ -339,7 +338,7 @@ Program::Wait(const sys::Path &path, else MakeErrMsg(ErrMsg, "Child timed out", 0); - return -1; // Timeout detected + return -2; // Timeout detected } else if (errno != EINTR) { MakeErrMsg(ErrMsg, "Error waiting for child process"); return -1; @@ -377,15 +376,15 @@ Program::Wait(const sys::Path &path, } } else if (WIFSIGNALED(status)) { if (ErrMsg) { - if (SignalPrefix) - *ErrMsg = SignalPrefix; - *ErrMsg += strsignal(WTERMSIG(status)); + *ErrMsg = strsignal(WTERMSIG(status)); #ifdef WCOREDUMP if (WCOREDUMP(status)) *ErrMsg += " (core dumped)"; #endif } - return -1; + // Return a special value to indicate that the process received an unhandled + // signal during execution as opposed to failing to execute. + return -2; } return result; #else diff --git a/lib/Support/Windows/Program.inc b/lib/Support/Windows/Program.inc index b685bb8b851..e486e6ec238 100644 --- a/lib/Support/Windows/Program.inc +++ b/lib/Support/Windows/Program.inc @@ -332,8 +332,7 @@ Program::Execute(const Path& path, int Program::Wait(const Path &path, unsigned secondsToWait, - std::string* ErrMsg, - const char* /*SignalPrefix*/) { + std::string* ErrMsg) { if (Data_ == 0) { MakeErrMsg(ErrMsg, "Process not started!"); return -1; @@ -350,7 +349,8 @@ Program::Wait(const Path &path, if (WaitForSingleObject(hProcess, millisecondsToWait) == WAIT_TIMEOUT) { if (!TerminateProcess(hProcess, 1)) { MakeErrMsg(ErrMsg, "Failed to terminate timed-out program."); - return -1; + // -2 indicates a crash or timeout as opposed to failure to execute. + return -2; } WaitForSingleObject(hProcess, INFINITE); } @@ -363,7 +363,8 @@ Program::Wait(const Path &path, if (!rc) { SetLastError(err); MakeErrMsg(ErrMsg, "Failed getting status for program."); - return -1; + // -2 indicates a crash or timeout as opposed to failure to execute. + return -2; } return status; diff --git a/tools/bugpoint/OptimizerDriver.cpp b/tools/bugpoint/OptimizerDriver.cpp index c6be271ae2b..336c83d7b1f 100644 --- a/tools/bugpoint/OptimizerDriver.cpp +++ b/tools/bugpoint/OptimizerDriver.cpp @@ -223,7 +223,7 @@ bool BugDriver::runPasses(Module *Program, if (result == -1) outs() << "Execute failed: " << ErrMsg << "\n"; else - outs() << "Crashed with signal #" << abs(result) << "\n"; + outs() << "Crashed: " << ErrMsg << "\n"; } if (result & 0x01000000) outs() << "Dumped core\n"; diff --git a/tools/bugpoint/ToolRunner.cpp b/tools/bugpoint/ToolRunner.cpp index f9d8603b5a6..0d98262b431 100644 --- a/tools/bugpoint/ToolRunner.cpp +++ b/tools/bugpoint/ToolRunner.cpp @@ -50,11 +50,6 @@ namespace { cl::desc("Remote execution (rsh/ssh) extra options")); } -// Add a prefix to ErrMsg if the program is terminated by a signal to -// distinguish compiled program crashes from other execution -// failures. Miscompilation likely results in SIGSEGV. -static const char *SignalPrefix = "Signal - "; - /// RunProgramWithTimeout - This function provides an alternate interface /// to the sys::Program::ExecuteAndWait interface. /// @see sys::Program::ExecuteAndWait @@ -82,7 +77,7 @@ static int RunProgramWithTimeout(const sys::Path &ProgramPath, return sys::Program::ExecuteAndWait(ProgramPath, Args, 0, redirects, - NumSeconds, MemoryLimit, ErrMsg, SignalPrefix); + NumSeconds, MemoryLimit, ErrMsg); } /// RunProgramRemotelyWithTimeout - This function runs the given program @@ -862,9 +857,9 @@ int GCC::ExecuteProgram(const std::string &ProgramFile, int ExitCode = RunProgramWithTimeout(OutputBinary, &ProgramArgs[0], sys::Path(InputFile), sys::Path(OutputFile), sys::Path(OutputFile), Timeout, MemoryLimit, Error); - // Treat a signal (usually SIGSEGV) as part of the program output so that - // crash-causing miscompilation is handled seamlessly. - if (Error->find(SignalPrefix) == 0) { + // Treat a signal (usually SIGSEGV) or timeout as part of the program output + // so that crash-causing miscompilation is handled seamlessly. + if (ExitCode < -1) { std::ofstream outFile(OutputFile.c_str(), std::ios_base::app); outFile << *Error << '\n'; outFile.close();