mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-09-23 01:25:32 +00:00
Add support for killing the program if it executes for too long.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@15158 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -38,14 +38,15 @@ std::string FindExecutable(const std::string &ExeName,
|
|||||||
|
|
||||||
/// RunProgramWithTimeout - This function executes the specified program, with
|
/// RunProgramWithTimeout - This function executes the specified program, with
|
||||||
/// the specified null-terminated argument array, with the stdin/out/err fd's
|
/// the specified null-terminated argument array, with the stdin/out/err fd's
|
||||||
/// redirected, with a timeout specified on the commandline. This terminates
|
/// redirected, with a timeout specified by the last argument. This terminates
|
||||||
/// the calling program if there is an error executing the specified program.
|
/// the calling program if there is an error executing the specified program.
|
||||||
/// It returns the return value of the program, or -1 if a timeout is detected.
|
/// It returns the return value of the program, or -1 if a timeout is detected.
|
||||||
///
|
///
|
||||||
int RunProgramWithTimeout(const std::string &ProgramPath, const char **Args,
|
int RunProgramWithTimeout(const std::string &ProgramPath, const char **Args,
|
||||||
const std::string &StdInFile = "",
|
const std::string &StdInFile = "",
|
||||||
const std::string &StdOutFile = "",
|
const std::string &StdOutFile = "",
|
||||||
const std::string &StdErrFile = "");
|
const std::string &StdErrFile = "",
|
||||||
|
unsigned NumSeconds = 0);
|
||||||
|
|
||||||
/// ExecWait - Execute a program with the given arguments and environment and
|
/// ExecWait - Execute a program with the given arguments and environment and
|
||||||
/// wait for it to terminate.
|
/// wait for it to terminate.
|
||||||
|
@@ -38,14 +38,15 @@ std::string FindExecutable(const std::string &ExeName,
|
|||||||
|
|
||||||
/// RunProgramWithTimeout - This function executes the specified program, with
|
/// RunProgramWithTimeout - This function executes the specified program, with
|
||||||
/// the specified null-terminated argument array, with the stdin/out/err fd's
|
/// the specified null-terminated argument array, with the stdin/out/err fd's
|
||||||
/// redirected, with a timeout specified on the commandline. This terminates
|
/// redirected, with a timeout specified by the last argument. This terminates
|
||||||
/// the calling program if there is an error executing the specified program.
|
/// the calling program if there is an error executing the specified program.
|
||||||
/// It returns the return value of the program, or -1 if a timeout is detected.
|
/// It returns the return value of the program, or -1 if a timeout is detected.
|
||||||
///
|
///
|
||||||
int RunProgramWithTimeout(const std::string &ProgramPath, const char **Args,
|
int RunProgramWithTimeout(const std::string &ProgramPath, const char **Args,
|
||||||
const std::string &StdInFile = "",
|
const std::string &StdInFile = "",
|
||||||
const std::string &StdOutFile = "",
|
const std::string &StdOutFile = "",
|
||||||
const std::string &StdErrFile = "");
|
const std::string &StdErrFile = "",
|
||||||
|
unsigned NumSeconds = 0);
|
||||||
|
|
||||||
/// ExecWait - Execute a program with the given arguments and environment and
|
/// ExecWait - Execute a program with the given arguments and environment and
|
||||||
/// wait for it to terminate.
|
/// wait for it to terminate.
|
||||||
|
@@ -125,9 +125,14 @@ static void RedirectFD(const std::string &File, int FD) {
|
|||||||
close(InFD); // Close the original FD
|
close(InFD); // Close the original FD
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool Timeout = false;
|
||||||
|
static void TimeOutHandler(int Sig) {
|
||||||
|
Timeout = true;
|
||||||
|
}
|
||||||
|
|
||||||
/// RunProgramWithTimeout - This function executes the specified program, with
|
/// RunProgramWithTimeout - This function executes the specified program, with
|
||||||
/// the specified null-terminated argument array, with the stdin/out/err fd's
|
/// the specified null-terminated argument array, with the stdin/out/err fd's
|
||||||
/// redirected, with a timeout specified on the command line. This terminates
|
/// redirected, with a timeout specified by the last argument. This terminates
|
||||||
/// the calling program if there is an error executing the specified program.
|
/// the calling program if there is an error executing the specified program.
|
||||||
/// It returns the return value of the program, or -1 if a timeout is detected.
|
/// It returns the return value of the program, or -1 if a timeout is detected.
|
||||||
///
|
///
|
||||||
@@ -135,9 +140,8 @@ int llvm::RunProgramWithTimeout(const std::string &ProgramPath,
|
|||||||
const char **Args,
|
const char **Args,
|
||||||
const std::string &StdInFile,
|
const std::string &StdInFile,
|
||||||
const std::string &StdOutFile,
|
const std::string &StdOutFile,
|
||||||
const std::string &StdErrFile) {
|
const std::string &StdErrFile,
|
||||||
// FIXME: install sigalarm handler here for timeout...
|
unsigned NumSeconds) {
|
||||||
|
|
||||||
#ifdef HAVE_SYS_WAIT_H
|
#ifdef HAVE_SYS_WAIT_H
|
||||||
int Child = fork();
|
int Child = fork();
|
||||||
switch (Child) {
|
switch (Child) {
|
||||||
@@ -165,24 +169,50 @@ int llvm::RunProgramWithTimeout(const std::string &ProgramPath,
|
|||||||
// Make sure all output has been written while waiting
|
// Make sure all output has been written while waiting
|
||||||
std::cout << std::flush;
|
std::cout << std::flush;
|
||||||
|
|
||||||
|
// Install a timeout handler.
|
||||||
|
Timeout = false;
|
||||||
|
struct sigaction Act, Old;
|
||||||
|
Act.sa_sigaction = 0;
|
||||||
|
Act.sa_handler = TimeOutHandler;
|
||||||
|
Act.sa_flags = SA_NOMASK;
|
||||||
|
sigaction(SIGALRM, &Act, &Old);
|
||||||
|
|
||||||
|
// Set the timeout if one is set.
|
||||||
|
if (NumSeconds)
|
||||||
|
alarm(NumSeconds);
|
||||||
|
|
||||||
int Status;
|
int Status;
|
||||||
if (wait(&Status) != Child) {
|
while (wait(&Status) != Child) {
|
||||||
if (errno == EINTR) {
|
if (errno == EINTR) {
|
||||||
static bool FirstTimeout = true;
|
if (Timeout) {
|
||||||
if (FirstTimeout) {
|
static bool FirstTimeout = true;
|
||||||
std::cout <<
|
if (FirstTimeout) {
|
||||||
|
std::cout <<
|
||||||
"*** Program execution timed out! This mechanism is designed to handle\n"
|
"*** Program execution timed out! This mechanism is designed to handle\n"
|
||||||
" programs stuck in infinite loops gracefully. The -timeout option\n"
|
" programs stuck in infinite loops gracefully. The -timeout option\n"
|
||||||
" can be used to change the timeout threshold or disable it completely\n"
|
" can be used to change the timeout threshold or disable it completely\n"
|
||||||
" (with -timeout=0). This message is only displayed once.\n";
|
" (with -timeout=0). This message is only displayed once.\n";
|
||||||
FirstTimeout = false;
|
FirstTimeout = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return -1; // Timeout detected
|
|
||||||
}
|
|
||||||
|
|
||||||
std::cerr << "Error waiting for child process!\n";
|
// Kill the child.
|
||||||
exit(1);
|
kill(Child, SIGKILL);
|
||||||
|
|
||||||
|
if (wait(&Status) != Child)
|
||||||
|
std::cerr << "Something funny happened waiting for the child!\n";
|
||||||
|
|
||||||
|
alarm(0);
|
||||||
|
sigaction(SIGALRM, &Old, 0);
|
||||||
|
return -1; // Timeout detected
|
||||||
|
} else {
|
||||||
|
std::cerr << "Error waiting for child process!\n";
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
alarm(0);
|
||||||
|
sigaction(SIGALRM, &Old, 0);
|
||||||
return Status;
|
return Status;
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
Reference in New Issue
Block a user