mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-28 09:31:03 +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:
parent
060913cce4
commit
de0213b9f5
@ -38,14 +38,15 @@ std::string FindExecutable(const std::string &ExeName,
|
||||
|
||||
/// RunProgramWithTimeout - This function executes the specified program, with
|
||||
/// 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.
|
||||
/// It returns the return value of the program, or -1 if a timeout is detected.
|
||||
///
|
||||
int RunProgramWithTimeout(const std::string &ProgramPath, const char **Args,
|
||||
const std::string &StdInFile = "",
|
||||
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
|
||||
/// wait for it to terminate.
|
||||
|
@ -38,14 +38,15 @@ std::string FindExecutable(const std::string &ExeName,
|
||||
|
||||
/// RunProgramWithTimeout - This function executes the specified program, with
|
||||
/// 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.
|
||||
/// It returns the return value of the program, or -1 if a timeout is detected.
|
||||
///
|
||||
int RunProgramWithTimeout(const std::string &ProgramPath, const char **Args,
|
||||
const std::string &StdInFile = "",
|
||||
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
|
||||
/// wait for it to terminate.
|
||||
|
@ -125,9 +125,14 @@ static void RedirectFD(const std::string &File, int 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
|
||||
/// 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.
|
||||
/// 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 std::string &StdInFile,
|
||||
const std::string &StdOutFile,
|
||||
const std::string &StdErrFile) {
|
||||
// FIXME: install sigalarm handler here for timeout...
|
||||
|
||||
const std::string &StdErrFile,
|
||||
unsigned NumSeconds) {
|
||||
#ifdef HAVE_SYS_WAIT_H
|
||||
int Child = fork();
|
||||
switch (Child) {
|
||||
@ -165,24 +169,50 @@ int llvm::RunProgramWithTimeout(const std::string &ProgramPath,
|
||||
// Make sure all output has been written while waiting
|
||||
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;
|
||||
if (wait(&Status) != Child) {
|
||||
while (wait(&Status) != Child) {
|
||||
if (errno == EINTR) {
|
||||
static bool FirstTimeout = true;
|
||||
if (FirstTimeout) {
|
||||
std::cout <<
|
||||
if (Timeout) {
|
||||
static bool FirstTimeout = true;
|
||||
if (FirstTimeout) {
|
||||
std::cout <<
|
||||
"*** Program execution timed out! This mechanism is designed to handle\n"
|
||||
" programs stuck in infinite loops gracefully. The -timeout option\n"
|
||||
" can be used to change the timeout threshold or disable it completely\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";
|
||||
exit(1);
|
||||
// Kill the child.
|
||||
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;
|
||||
|
||||
#else
|
||||
|
Loading…
x
Reference in New Issue
Block a user