mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-25 16:24:23 +00:00
Add possibility to set memory limit for binaries run via libSystem. This
is especially needed for bugpoint. This partly implements PR688 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@34349 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@ -709,7 +709,8 @@ dnl===
|
|||||||
dnl===-----------------------------------------------------------------------===
|
dnl===-----------------------------------------------------------------------===
|
||||||
|
|
||||||
AC_CHECK_FUNCS([backtrace ceilf floorf roundf rintf nearbyintf getcwd ])
|
AC_CHECK_FUNCS([backtrace ceilf floorf roundf rintf nearbyintf getcwd ])
|
||||||
AC_CHECK_FUNCS([getpagesize getrusage gettimeofday isatty mkdtemp mkstemp ])
|
AC_CHECK_FUNCS([getpagesize getrusage getrlimit setrlimit gettimeofday])
|
||||||
|
AC_CHECK_FUNCS([isatty mkdtemp mkstemp ])
|
||||||
AC_CHECK_FUNCS([mktemp realpath sbrk setrlimit strdup strerror strerror_r ])
|
AC_CHECK_FUNCS([mktemp realpath sbrk setrlimit strdup strerror strerror_r ])
|
||||||
AC_CHECK_FUNCS([strtoll strtoq sysconf malloc_zone_statistics ])
|
AC_CHECK_FUNCS([strtoll strtoq sysconf malloc_zone_statistics ])
|
||||||
AC_CHECK_FUNCS([setjmp longjmp sigsetjmp siglongjmp])
|
AC_CHECK_FUNCS([setjmp longjmp sigsetjmp siglongjmp])
|
||||||
|
@ -124,6 +124,9 @@
|
|||||||
/* Define to 1 if you have the `getpagesize' function. */
|
/* Define to 1 if you have the `getpagesize' function. */
|
||||||
#undef HAVE_GETPAGESIZE
|
#undef HAVE_GETPAGESIZE
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `getrlimit' function. */
|
||||||
|
#undef HAVE_GETRLIMIT
|
||||||
|
|
||||||
/* Define to 1 if you have the `getrusage' function. */
|
/* Define to 1 if you have the `getrusage' function. */
|
||||||
#undef HAVE_GETRUSAGE
|
#undef HAVE_GETRUSAGE
|
||||||
|
|
||||||
|
@ -72,6 +72,10 @@ namespace sys {
|
|||||||
///< expires, the child is killed and this call returns. If zero,
|
///< expires, the child is killed and this call returns. If zero,
|
||||||
///< this function will wait until the child finishes or forever if
|
///< this function will wait until the child finishes or forever if
|
||||||
///< it doesn't.
|
///< it doesn't.
|
||||||
|
unsigned memoryLimit = 0, ///< If non-zero, this specifies max. amount
|
||||||
|
///< of memory can be allocated by process. If memory usage will be
|
||||||
|
///< higher limit, the child is killed and this call returns. If zero -
|
||||||
|
///< no memory limit.
|
||||||
std::string* ErrMsg = 0 ///< If non-zero, provides a pointer to a string
|
std::string* ErrMsg = 0 ///< If non-zero, provides a pointer to a string
|
||||||
///< instance in which error messages will be returned. If the string
|
///< instance in which error messages will be returned. If the string
|
||||||
///< is non-empty upon return an error occurred while invoking the
|
///< is non-empty upon return an error occurred while invoking the
|
||||||
|
@ -29,7 +29,7 @@ void llvm::DisplayGraph(const sys::Path &Filename) {
|
|||||||
args.push_back(0);
|
args.push_back(0);
|
||||||
|
|
||||||
cerr << "Running 'Graphviz' program... " << std::flush;
|
cerr << "Running 'Graphviz' program... " << std::flush;
|
||||||
if (sys::Program::ExecuteAndWait(Graphviz, &args[0],0,0,0,&ErrMsg)) {
|
if (sys::Program::ExecuteAndWait(Graphviz, &args[0],0,0,0,0,&ErrMsg)) {
|
||||||
cerr << "Error viewing graph: " << ErrMsg << "\n";
|
cerr << "Error viewing graph: " << ErrMsg << "\n";
|
||||||
}
|
}
|
||||||
#elif (HAVE_GV && HAVE_DOT)
|
#elif (HAVE_GV && HAVE_DOT)
|
||||||
@ -49,7 +49,7 @@ void llvm::DisplayGraph(const sys::Path &Filename) {
|
|||||||
args.push_back(0);
|
args.push_back(0);
|
||||||
|
|
||||||
cerr << "Running 'dot' program... " << std::flush;
|
cerr << "Running 'dot' program... " << std::flush;
|
||||||
if (sys::Program::ExecuteAndWait(dot, &args[0],0,0,0,&ErrMsg)) {
|
if (sys::Program::ExecuteAndWait(dot, &args[0],0,0,0,0,&ErrMsg)) {
|
||||||
cerr << "Error viewing graph: '" << ErrMsg << "\n";
|
cerr << "Error viewing graph: '" << ErrMsg << "\n";
|
||||||
} else {
|
} else {
|
||||||
cerr << " done. \n";
|
cerr << " done. \n";
|
||||||
@ -61,7 +61,7 @@ void llvm::DisplayGraph(const sys::Path &Filename) {
|
|||||||
args.push_back(0);
|
args.push_back(0);
|
||||||
|
|
||||||
ErrMsg.clear();
|
ErrMsg.clear();
|
||||||
if (sys::Program::ExecuteAndWait(gv, &args[0],0,0,0,&ErrMsg)) {
|
if (sys::Program::ExecuteAndWait(gv, &args[0],0,0,0,0,&ErrMsg)) {
|
||||||
cerr << "Error viewing graph: " << ErrMsg << "\n";
|
cerr << "Error viewing graph: " << ErrMsg << "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -74,7 +74,7 @@ void llvm::DisplayGraph(const sys::Path &Filename) {
|
|||||||
args.push_back(0);
|
args.push_back(0);
|
||||||
|
|
||||||
cerr << "Running 'dotty' program... " << std::flush;
|
cerr << "Running 'dotty' program... " << std::flush;
|
||||||
if (sys::Program::ExecuteAndWait(dotty, &args[0],0,0,0,&ErrMsg)) {
|
if (sys::Program::ExecuteAndWait(dotty, &args[0],0,0,0,0,&ErrMsg)) {
|
||||||
cerr << "Error viewing graph: " << ErrMsg << "\n";
|
cerr << "Error viewing graph: " << ErrMsg << "\n";
|
||||||
} else {
|
} else {
|
||||||
#ifdef __MINGW32__ // Dotty spawns another app and doesn't wait until it returns
|
#ifdef __MINGW32__ // Dotty spawns another app and doesn't wait until it returns
|
||||||
|
@ -22,6 +22,9 @@
|
|||||||
#if HAVE_SYS_STAT_H
|
#if HAVE_SYS_STAT_H
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#endif
|
#endif
|
||||||
|
#if HAVE_SYS_RESOURCE_H
|
||||||
|
#include <sys/resource.h>
|
||||||
|
#endif
|
||||||
#if HAVE_SIGNAL_H
|
#if HAVE_SIGNAL_H
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#endif
|
#endif
|
||||||
@ -106,12 +109,34 @@ static void TimeOutHandler(int Sig) {
|
|||||||
Timeout = true;
|
Timeout = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void SetMemoryLimits (unsigned size)
|
||||||
|
{
|
||||||
|
#if HAVE_SYS_RESOURCE_H
|
||||||
|
struct rlimit r;
|
||||||
|
__typeof__ (r.rlim_cur) limit = (__typeof__ (r.rlim_cur)) (size) * 1048576;
|
||||||
|
|
||||||
|
// Heap size
|
||||||
|
getrlimit (RLIMIT_DATA, &r);
|
||||||
|
r.rlim_cur = limit;
|
||||||
|
setrlimit (RLIMIT_DATA, &r);
|
||||||
|
// Resident set size.
|
||||||
|
getrlimit (RLIMIT_RSS, &r);
|
||||||
|
r.rlim_cur = limit;
|
||||||
|
setrlimit (RLIMIT_RSS, &r);
|
||||||
|
// Virtual memory.
|
||||||
|
getrlimit (RLIMIT_AS, &r);
|
||||||
|
r.rlim_cur = limit;
|
||||||
|
setrlimit (RLIMIT_AS, &r);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
Program::ExecuteAndWait(const Path& path,
|
Program::ExecuteAndWait(const Path& path,
|
||||||
const char** args,
|
const char** args,
|
||||||
const char** envp,
|
const char** envp,
|
||||||
const Path** redirects,
|
const Path** redirects,
|
||||||
unsigned secondsToWait,
|
unsigned secondsToWait,
|
||||||
|
unsigned memoryLimit,
|
||||||
std::string* ErrMsg)
|
std::string* ErrMsg)
|
||||||
{
|
{
|
||||||
if (!path.canExecute()) {
|
if (!path.canExecute()) {
|
||||||
@ -160,6 +185,11 @@ Program::ExecuteAndWait(const Path& path,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set memory limits
|
||||||
|
if (memoryLimit!=0) {
|
||||||
|
SetMemoryLimits(memoryLimit);
|
||||||
|
}
|
||||||
|
|
||||||
// Execute!
|
// Execute!
|
||||||
if (envp != 0)
|
if (envp != 0)
|
||||||
execve (path.c_str(), (char** const)args, (char**)envp);
|
execve (path.c_str(), (char** const)args, (char**)envp);
|
||||||
|
@ -104,6 +104,7 @@ Program::ExecuteAndWait(const Path& path,
|
|||||||
const char** envp,
|
const char** envp,
|
||||||
const Path** redirects,
|
const Path** redirects,
|
||||||
unsigned secondsToWait,
|
unsigned secondsToWait,
|
||||||
|
unsigned memoryLimit,
|
||||||
std::string* ErrMsg) {
|
std::string* ErrMsg) {
|
||||||
if (!path.canExecute()) {
|
if (!path.canExecute()) {
|
||||||
if (ErrMsg)
|
if (ErrMsg)
|
||||||
|
@ -64,10 +64,10 @@ std::string llvm::getPassesString(const std::vector<const PassInfo*> &Passes) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
BugDriver::BugDriver(const char *toolname, bool as_child, bool find_bugs,
|
BugDriver::BugDriver(const char *toolname, bool as_child, bool find_bugs,
|
||||||
unsigned timeout)
|
unsigned timeout, unsigned memlimit)
|
||||||
: ToolName(toolname), ReferenceOutputFile(OutputFile),
|
: ToolName(toolname), ReferenceOutputFile(OutputFile),
|
||||||
Program(0), Interpreter(0), cbe(0), gcc(0), run_as_child(as_child),
|
Program(0), Interpreter(0), cbe(0), gcc(0), run_as_child(as_child),
|
||||||
run_find_bugs(find_bugs), Timeout(timeout) {}
|
run_find_bugs(find_bugs), Timeout(timeout), MemoryLimit(memlimit) {}
|
||||||
|
|
||||||
|
|
||||||
/// ParseInputFile - Given a bytecode or assembly input filename, parse and
|
/// ParseInputFile - Given a bytecode or assembly input filename, parse and
|
||||||
|
@ -50,6 +50,7 @@ class BugDriver {
|
|||||||
bool run_as_child;
|
bool run_as_child;
|
||||||
bool run_find_bugs;
|
bool run_find_bugs;
|
||||||
unsigned Timeout;
|
unsigned Timeout;
|
||||||
|
unsigned MemoryLimit;
|
||||||
|
|
||||||
// FIXME: sort out public/private distinctions...
|
// FIXME: sort out public/private distinctions...
|
||||||
friend class ReducePassList;
|
friend class ReducePassList;
|
||||||
@ -57,7 +58,7 @@ class BugDriver {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
BugDriver(const char *toolname, bool as_child, bool find_bugs,
|
BugDriver(const char *toolname, bool as_child, bool find_bugs,
|
||||||
unsigned timeout);
|
unsigned timeout, unsigned memlimit);
|
||||||
|
|
||||||
const std::string &getToolName() const { return ToolName; }
|
const std::string &getToolName() const { return ToolName; }
|
||||||
|
|
||||||
|
@ -263,11 +263,11 @@ std::string BugDriver::executeProgram(std::string OutputFile,
|
|||||||
InterpreterSel == CBE_bug)
|
InterpreterSel == CBE_bug)
|
||||||
RetVal = AI->ExecuteProgram(BytecodeFile, InputArgv, InputFile,
|
RetVal = AI->ExecuteProgram(BytecodeFile, InputArgv, InputFile,
|
||||||
OutputFile, AdditionalLinkerArgs, SharedObjs,
|
OutputFile, AdditionalLinkerArgs, SharedObjs,
|
||||||
Timeout);
|
Timeout, MemoryLimit);
|
||||||
else
|
else
|
||||||
RetVal = AI->ExecuteProgram(BytecodeFile, InputArgv, InputFile,
|
RetVal = AI->ExecuteProgram(BytecodeFile, InputArgv, InputFile,
|
||||||
OutputFile, std::vector<std::string>(),
|
OutputFile, std::vector<std::string>(),
|
||||||
SharedObjs, Timeout);
|
SharedObjs, Timeout, MemoryLimit);
|
||||||
|
|
||||||
if (RetVal == -1) {
|
if (RetVal == -1) {
|
||||||
std::cerr << "<timeout>";
|
std::cerr << "<timeout>";
|
||||||
|
@ -194,7 +194,8 @@ bool BugDriver::runPasses(const std::vector<const PassInfo*> &Passes,
|
|||||||
prog = sys::Program::FindProgramByName("valgrind");
|
prog = sys::Program::FindProgramByName("valgrind");
|
||||||
else
|
else
|
||||||
prog = tool;
|
prog = tool;
|
||||||
int result = sys::Program::ExecuteAndWait(prog,args,0,0,Timeout,&ErrMsg);
|
int result = sys::Program::ExecuteAndWait(prog, args, 0, 0,
|
||||||
|
Timeout, MemoryLimit, &ErrMsg);
|
||||||
|
|
||||||
// If we are supposed to delete the bytecode file or if the passes crashed,
|
// If we are supposed to delete the bytecode file or if the passes crashed,
|
||||||
// remove it now. This may fail if the file was never created, but that's ok.
|
// remove it now. This may fail if the file was never created, but that's ok.
|
||||||
|
@ -32,7 +32,8 @@ static int RunProgramWithTimeout(const sys::Path &ProgramPath,
|
|||||||
const sys::Path &StdInFile,
|
const sys::Path &StdInFile,
|
||||||
const sys::Path &StdOutFile,
|
const sys::Path &StdOutFile,
|
||||||
const sys::Path &StdErrFile,
|
const sys::Path &StdErrFile,
|
||||||
unsigned NumSeconds = 0) {
|
unsigned NumSeconds = 0,
|
||||||
|
unsigned MemoryLimit = 0) {
|
||||||
const sys::Path* redirects[3];
|
const sys::Path* redirects[3];
|
||||||
redirects[0] = &StdInFile;
|
redirects[0] = &StdInFile;
|
||||||
redirects[1] = &StdOutFile;
|
redirects[1] = &StdOutFile;
|
||||||
@ -46,7 +47,8 @@ static int RunProgramWithTimeout(const sys::Path &ProgramPath,
|
|||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
sys::Program::ExecuteAndWait(ProgramPath, Args, 0, redirects, NumSeconds);
|
sys::Program::ExecuteAndWait(ProgramPath, Args, 0, redirects,
|
||||||
|
NumSeconds, MemoryLimit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -102,7 +104,8 @@ namespace {
|
|||||||
const std::vector<std::string> &GCCArgs,
|
const std::vector<std::string> &GCCArgs,
|
||||||
const std::vector<std::string> &SharedLibs =
|
const std::vector<std::string> &SharedLibs =
|
||||||
std::vector<std::string>(),
|
std::vector<std::string>(),
|
||||||
unsigned Timeout = 0);
|
unsigned Timeout = 0,
|
||||||
|
unsigned MemoryLimit = 0);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,7 +115,8 @@ int LLI::ExecuteProgram(const std::string &Bytecode,
|
|||||||
const std::string &OutputFile,
|
const std::string &OutputFile,
|
||||||
const std::vector<std::string> &GCCArgs,
|
const std::vector<std::string> &GCCArgs,
|
||||||
const std::vector<std::string> &SharedLibs,
|
const std::vector<std::string> &SharedLibs,
|
||||||
unsigned Timeout) {
|
unsigned Timeout,
|
||||||
|
unsigned MemoryLimit) {
|
||||||
if (!SharedLibs.empty())
|
if (!SharedLibs.empty())
|
||||||
throw ToolExecutionError("LLI currently does not support "
|
throw ToolExecutionError("LLI currently does not support "
|
||||||
"loading shared libraries.");
|
"loading shared libraries.");
|
||||||
@ -142,7 +146,7 @@ int LLI::ExecuteProgram(const std::string &Bytecode,
|
|||||||
);
|
);
|
||||||
return RunProgramWithTimeout(sys::Path(LLIPath), &LLIArgs[0],
|
return RunProgramWithTimeout(sys::Path(LLIPath), &LLIArgs[0],
|
||||||
sys::Path(InputFile), sys::Path(OutputFile), sys::Path(OutputFile),
|
sys::Path(InputFile), sys::Path(OutputFile), sys::Path(OutputFile),
|
||||||
Timeout);
|
Timeout, MemoryLimit);
|
||||||
}
|
}
|
||||||
|
|
||||||
// LLI create method - Try to find the LLI executable
|
// LLI create method - Try to find the LLI executable
|
||||||
@ -209,7 +213,8 @@ int LLC::ExecuteProgram(const std::string &Bytecode,
|
|||||||
const std::string &OutputFile,
|
const std::string &OutputFile,
|
||||||
const std::vector<std::string> &ArgsForGCC,
|
const std::vector<std::string> &ArgsForGCC,
|
||||||
const std::vector<std::string> &SharedLibs,
|
const std::vector<std::string> &SharedLibs,
|
||||||
unsigned Timeout) {
|
unsigned Timeout,
|
||||||
|
unsigned MemoryLimit) {
|
||||||
|
|
||||||
sys::Path OutputAsmFile;
|
sys::Path OutputAsmFile;
|
||||||
OutputCode(Bytecode, OutputAsmFile);
|
OutputCode(Bytecode, OutputAsmFile);
|
||||||
@ -220,7 +225,8 @@ int LLC::ExecuteProgram(const std::string &Bytecode,
|
|||||||
|
|
||||||
// Assuming LLC worked, compile the result with GCC and run it.
|
// Assuming LLC worked, compile the result with GCC and run it.
|
||||||
return gcc->ExecuteProgram(OutputAsmFile.toString(), Args, GCC::AsmFile,
|
return gcc->ExecuteProgram(OutputAsmFile.toString(), Args, GCC::AsmFile,
|
||||||
InputFile, OutputFile, GCCArgs, Timeout);
|
InputFile, OutputFile, GCCArgs,
|
||||||
|
Timeout, MemoryLimit);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// createLLC - Try to find the LLC executable
|
/// createLLC - Try to find the LLC executable
|
||||||
@ -265,7 +271,8 @@ namespace {
|
|||||||
std::vector<std::string>(),
|
std::vector<std::string>(),
|
||||||
const std::vector<std::string> &SharedLibs =
|
const std::vector<std::string> &SharedLibs =
|
||||||
std::vector<std::string>(),
|
std::vector<std::string>(),
|
||||||
unsigned Timeout =0 );
|
unsigned Timeout =0,
|
||||||
|
unsigned MemoryLimit =0);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -275,7 +282,8 @@ int JIT::ExecuteProgram(const std::string &Bytecode,
|
|||||||
const std::string &OutputFile,
|
const std::string &OutputFile,
|
||||||
const std::vector<std::string> &GCCArgs,
|
const std::vector<std::string> &GCCArgs,
|
||||||
const std::vector<std::string> &SharedLibs,
|
const std::vector<std::string> &SharedLibs,
|
||||||
unsigned Timeout) {
|
unsigned Timeout,
|
||||||
|
unsigned MemoryLimit) {
|
||||||
if (!GCCArgs.empty())
|
if (!GCCArgs.empty())
|
||||||
throw ToolExecutionError("JIT does not support GCC Arguments.");
|
throw ToolExecutionError("JIT does not support GCC Arguments.");
|
||||||
// Construct a vector of parameters, incorporating those from the command-line
|
// Construct a vector of parameters, incorporating those from the command-line
|
||||||
@ -306,7 +314,7 @@ int JIT::ExecuteProgram(const std::string &Bytecode,
|
|||||||
DEBUG(std::cerr << "\nSending output to " << OutputFile << "\n");
|
DEBUG(std::cerr << "\nSending output to " << OutputFile << "\n");
|
||||||
return RunProgramWithTimeout(sys::Path(LLIPath), &JITArgs[0],
|
return RunProgramWithTimeout(sys::Path(LLIPath), &JITArgs[0],
|
||||||
sys::Path(InputFile), sys::Path(OutputFile), sys::Path(OutputFile),
|
sys::Path(InputFile), sys::Path(OutputFile), sys::Path(OutputFile),
|
||||||
Timeout);
|
Timeout, MemoryLimit);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// createJIT - Try to find the LLI executable
|
/// createJIT - Try to find the LLI executable
|
||||||
@ -370,7 +378,8 @@ int CBE::ExecuteProgram(const std::string &Bytecode,
|
|||||||
const std::string &OutputFile,
|
const std::string &OutputFile,
|
||||||
const std::vector<std::string> &ArgsForGCC,
|
const std::vector<std::string> &ArgsForGCC,
|
||||||
const std::vector<std::string> &SharedLibs,
|
const std::vector<std::string> &SharedLibs,
|
||||||
unsigned Timeout) {
|
unsigned Timeout,
|
||||||
|
unsigned MemoryLimit) {
|
||||||
sys::Path OutputCFile;
|
sys::Path OutputCFile;
|
||||||
OutputCode(Bytecode, OutputCFile);
|
OutputCode(Bytecode, OutputCFile);
|
||||||
|
|
||||||
@ -379,7 +388,8 @@ int CBE::ExecuteProgram(const std::string &Bytecode,
|
|||||||
std::vector<std::string> GCCArgs(ArgsForGCC);
|
std::vector<std::string> GCCArgs(ArgsForGCC);
|
||||||
GCCArgs.insert(GCCArgs.end(),SharedLibs.begin(),SharedLibs.end());
|
GCCArgs.insert(GCCArgs.end(),SharedLibs.begin(),SharedLibs.end());
|
||||||
return gcc->ExecuteProgram(OutputCFile.toString(), Args, GCC::CFile,
|
return gcc->ExecuteProgram(OutputCFile.toString(), Args, GCC::CFile,
|
||||||
InputFile, OutputFile, GCCArgs, Timeout);
|
InputFile, OutputFile, GCCArgs,
|
||||||
|
Timeout, MemoryLimit);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// createCBE - Try to find the 'llc' executable
|
/// createCBE - Try to find the 'llc' executable
|
||||||
@ -412,7 +422,8 @@ int GCC::ExecuteProgram(const std::string &ProgramFile,
|
|||||||
const std::string &InputFile,
|
const std::string &InputFile,
|
||||||
const std::string &OutputFile,
|
const std::string &OutputFile,
|
||||||
const std::vector<std::string> &ArgsForGCC,
|
const std::vector<std::string> &ArgsForGCC,
|
||||||
unsigned Timeout ) {
|
unsigned Timeout,
|
||||||
|
unsigned MemoryLimit) {
|
||||||
std::vector<const char*> GCCArgs;
|
std::vector<const char*> GCCArgs;
|
||||||
|
|
||||||
GCCArgs.push_back(GCCPath.c_str());
|
GCCArgs.push_back(GCCPath.c_str());
|
||||||
@ -488,7 +499,7 @@ int GCC::ExecuteProgram(const std::string &ProgramFile,
|
|||||||
FileRemover OutputBinaryRemover(OutputBinary);
|
FileRemover OutputBinaryRemover(OutputBinary);
|
||||||
return RunProgramWithTimeout(OutputBinary, &ProgramArgs[0],
|
return RunProgramWithTimeout(OutputBinary, &ProgramArgs[0],
|
||||||
sys::Path(InputFile), sys::Path(OutputFile), sys::Path(OutputFile),
|
sys::Path(InputFile), sys::Path(OutputFile), sys::Path(OutputFile),
|
||||||
Timeout);
|
Timeout, MemoryLimit);
|
||||||
}
|
}
|
||||||
|
|
||||||
int GCC::MakeSharedObject(const std::string &InputFile, FileType fileType,
|
int GCC::MakeSharedObject(const std::string &InputFile, FileType fileType,
|
||||||
|
@ -64,7 +64,8 @@ public:
|
|||||||
const std::string &OutputFile,
|
const std::string &OutputFile,
|
||||||
const std::vector<std::string> &GCCArgs =
|
const std::vector<std::string> &GCCArgs =
|
||||||
std::vector<std::string>(),
|
std::vector<std::string>(),
|
||||||
unsigned Timeout = 0);
|
unsigned Timeout = 0,
|
||||||
|
unsigned MemoryLimit = 0);
|
||||||
|
|
||||||
/// MakeSharedObject - This compiles the specified file (which is either a .c
|
/// MakeSharedObject - This compiles the specified file (which is either a .c
|
||||||
/// file or a .s file) into a shared object.
|
/// file or a .s file) into a shared object.
|
||||||
@ -124,7 +125,8 @@ public:
|
|||||||
std::vector<std::string>(),
|
std::vector<std::string>(),
|
||||||
const std::vector<std::string> &SharedLibs =
|
const std::vector<std::string> &SharedLibs =
|
||||||
std::vector<std::string>(),
|
std::vector<std::string>(),
|
||||||
unsigned Timeout = 0) = 0;
|
unsigned Timeout = 0,
|
||||||
|
unsigned MemoryLimit = 0) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
//===---------------------------------------------------------------------===//
|
//===---------------------------------------------------------------------===//
|
||||||
@ -156,7 +158,8 @@ public:
|
|||||||
std::vector<std::string>(),
|
std::vector<std::string>(),
|
||||||
const std::vector<std::string> &SharedLibs =
|
const std::vector<std::string> &SharedLibs =
|
||||||
std::vector<std::string>(),
|
std::vector<std::string>(),
|
||||||
unsigned Timeout = 0);
|
unsigned Timeout = 0,
|
||||||
|
unsigned MemoryLimit = 0);
|
||||||
|
|
||||||
/// OutputCode - Compile the specified program from bytecode to code
|
/// OutputCode - Compile the specified program from bytecode to code
|
||||||
/// understood by the GCC driver (either C or asm). If the code generator
|
/// understood by the GCC driver (either C or asm). If the code generator
|
||||||
@ -196,7 +199,8 @@ public:
|
|||||||
std::vector<std::string>(),
|
std::vector<std::string>(),
|
||||||
const std::vector<std::string> &SharedLibs =
|
const std::vector<std::string> &SharedLibs =
|
||||||
std::vector<std::string>(),
|
std::vector<std::string>(),
|
||||||
unsigned Timeout = 0);
|
unsigned Timeout = 0,
|
||||||
|
unsigned MemoryLimit = 0);
|
||||||
|
|
||||||
virtual GCC::FileType OutputCode(const std::string &Bytecode,
|
virtual GCC::FileType OutputCode(const std::string &Bytecode,
|
||||||
sys::Path &OutFile);
|
sys::Path &OutFile);
|
||||||
|
@ -46,6 +46,10 @@ TimeoutValue("timeout", cl::init(300), cl::value_desc("seconds"),
|
|||||||
cl::desc("Number of seconds program is allowed to run before it "
|
cl::desc("Number of seconds program is allowed to run before it "
|
||||||
"is killed (default is 300s), 0 disables timeout"));
|
"is killed (default is 300s), 0 disables timeout"));
|
||||||
|
|
||||||
|
static cl::opt<unsigned>
|
||||||
|
MemoryLimit("mlimit", cl::init(100), cl::value_desc("MBytes"),
|
||||||
|
cl::desc("Maximum amount of memory to use. 0 disables check."));
|
||||||
|
|
||||||
// The AnalysesList is automatically populated with registered Passes by the
|
// The AnalysesList is automatically populated with registered Passes by the
|
||||||
// PassNameParser.
|
// PassNameParser.
|
||||||
//
|
//
|
||||||
@ -68,7 +72,7 @@ int main(int argc, char **argv) {
|
|||||||
sys::PrintStackTraceOnErrorSignal();
|
sys::PrintStackTraceOnErrorSignal();
|
||||||
sys::SetInterruptFunction(BugpointInterruptFunction);
|
sys::SetInterruptFunction(BugpointInterruptFunction);
|
||||||
|
|
||||||
BugDriver D(argv[0],AsChild,FindBugs,TimeoutValue);
|
BugDriver D(argv[0], AsChild, FindBugs, TimeoutValue, MemoryLimit);
|
||||||
if (D.addSources(InputFilenames)) return 1;
|
if (D.addSources(InputFilenames)) return 1;
|
||||||
D.addPasses(PassList.begin(), PassList.end());
|
D.addPasses(PassList.begin(), PassList.end());
|
||||||
|
|
||||||
|
@ -244,7 +244,7 @@ static int GenerateAssembly(const std::string &OutputFilename,
|
|||||||
args.push_back(InputFilename.c_str());
|
args.push_back(InputFilename.c_str());
|
||||||
args.push_back(0);
|
args.push_back(0);
|
||||||
|
|
||||||
return sys::Program::ExecuteAndWait(llc,&args[0],0,0,0,&ErrMsg);
|
return sys::Program::ExecuteAndWait(llc, &args[0], 0, 0, 0, 0, &ErrMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// GenerateCFile - generates a C source file from the specified bytecode file.
|
/// GenerateCFile - generates a C source file from the specified bytecode file.
|
||||||
@ -261,7 +261,7 @@ static int GenerateCFile(const std::string &OutputFile,
|
|||||||
args.push_back(OutputFile.c_str());
|
args.push_back(OutputFile.c_str());
|
||||||
args.push_back(InputFile.c_str());
|
args.push_back(InputFile.c_str());
|
||||||
args.push_back(0);
|
args.push_back(0);
|
||||||
return sys::Program::ExecuteAndWait(llc, &args[0],0,0,0,&ErrMsg);
|
return sys::Program::ExecuteAndWait(llc, &args[0], 0, 0, 0, 0, &ErrMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// GenerateNative - generates a native object file from the
|
/// GenerateNative - generates a native object file from the
|
||||||
@ -342,7 +342,7 @@ static int GenerateNative(const std::string &OutputFilename,
|
|||||||
|
|
||||||
// Run the compiler to assembly and link together the program.
|
// Run the compiler to assembly and link together the program.
|
||||||
int R = sys::Program::ExecuteAndWait(
|
int R = sys::Program::ExecuteAndWait(
|
||||||
gcc, &args[0], (const char**)clean_env,0,0,&ErrMsg);
|
gcc, &args[0], (const char**)clean_env, 0, 0, 0, &ErrMsg);
|
||||||
delete [] clean_env;
|
delete [] clean_env;
|
||||||
return R;
|
return R;
|
||||||
}
|
}
|
||||||
@ -516,7 +516,7 @@ int main(int argc, char **argv, char **envp) {
|
|||||||
args[1] = RealBytecodeOutput.c_str();
|
args[1] = RealBytecodeOutput.c_str();
|
||||||
args[2] = tmp_output.c_str();
|
args[2] = tmp_output.c_str();
|
||||||
args[3] = 0;
|
args[3] = 0;
|
||||||
if (0 == sys::Program::ExecuteAndWait(prog, args, 0,0,0, &ErrMsg)) {
|
if (0 == sys::Program::ExecuteAndWait(prog, args, 0,0,0,0, &ErrMsg)) {
|
||||||
if (tmp_output.isBytecodeFile()) {
|
if (tmp_output.isBytecodeFile()) {
|
||||||
sys::Path target(RealBytecodeOutput);
|
sys::Path target(RealBytecodeOutput);
|
||||||
target.eraseFromDisk();
|
target.eraseFromDisk();
|
||||||
|
@ -499,14 +499,14 @@ private:
|
|||||||
Timer timer(action->program.toString());
|
Timer timer(action->program.toString());
|
||||||
timer.startTimer();
|
timer.startTimer();
|
||||||
int resultCode =
|
int resultCode =
|
||||||
sys::Program::ExecuteAndWait(action->program, Args,0,0,0,&ErrMsg);
|
sys::Program::ExecuteAndWait(action->program, Args,0,0,0,0, &ErrMsg);
|
||||||
timer.stopTimer();
|
timer.stopTimer();
|
||||||
timer.print(timer,std::cerr);
|
timer.print(timer,std::cerr);
|
||||||
return resultCode;
|
return resultCode;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return
|
return
|
||||||
sys::Program::ExecuteAndWait(action->program, Args, 0,0,0, &ErrMsg);
|
sys::Program::ExecuteAndWait(action->program, Args, 0,0,0,0, &ErrMsg);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -458,7 +458,7 @@ LTO::optimizeModules(const std::string &OutputFilename,
|
|||||||
args.push_back(tmpAsmFilePath.c_str());
|
args.push_back(tmpAsmFilePath.c_str());
|
||||||
args.push_back(0);
|
args.push_back(0);
|
||||||
|
|
||||||
if (sys::Program::ExecuteAndWait(gcc, &args[0], 0, 0, 1, &ErrMsg)) {
|
if (sys::Program::ExecuteAndWait(gcc, &args[0], 0, 0, 1, 0, &ErrMsg)) {
|
||||||
cerr << "lto: " << ErrMsg << "\n";
|
cerr << "lto: " << ErrMsg << "\n";
|
||||||
return LTO_ASM_FAILURE;
|
return LTO_ASM_FAILURE;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user