aboutsummaryrefslogtreecommitdiffhomepage
path: root/lib/Core/Executor.cpp
diff options
context:
space:
mode:
authorMartinNowack <martin.nowack@gmail.com>2016-05-18 13:18:56 +0200
committerMartinNowack <martin.nowack@gmail.com>2016-05-18 13:18:56 +0200
commitf8a757c17454d7e5f4297cef5fad5591e40a6a87 (patch)
treee03582fee517db083a42b3057b1f4bad187de059 /lib/Core/Executor.cpp
parente481f415042b9bcb5af6d057648852a9d8ef7d4e (diff)
parenteba0093c4887473be2562a7ab4e16b3d09793f4e (diff)
downloadklee-f8a757c17454d7e5f4297cef5fad5591e40a6a87.tar.gz
Merge pull request #387 from andreamattavelli/feat_instruction_logging
Modified -debug-print-instructions to write directly on log file.
Diffstat (limited to 'lib/Core/Executor.cpp')
-rw-r--r--lib/Core/Executor.cpp132
1 files changed, 98 insertions, 34 deletions
diff --git a/lib/Core/Executor.cpp b/lib/Core/Executor.cpp
index 3b2a860e..ff346487 100644
--- a/lib/Core/Executor.cpp
+++ b/lib/Core/Executor.cpp
@@ -126,9 +126,38 @@ namespace {
cl::init(false),
cl::desc("Allow calls with symbolic arguments to external functions. This concretizes the symbolic arguments. (default=off)"));
- cl::opt<bool>
- DebugPrintInstructions("debug-print-instructions",
- cl::desc("Print instructions during execution."));
+ /// The different query logging solvers that can switched on/off
+ enum PrintDebugInstructionsType {
+ STDERR_ALL, ///
+ STDERR_SRC,
+ STDERR_COMPACT,
+ FILE_ALL, ///
+ FILE_SRC, ///
+ FILE_COMPACT ///
+ };
+
+ llvm::cl::list<PrintDebugInstructionsType> DebugPrintInstructions(
+ "debug-print-instructions",
+ llvm::cl::desc("Log instructions during execution."),
+ llvm::cl::values(
+ clEnumValN(STDERR_ALL, "all:stderr", "Log all instructions to stderr "
+ "in format [src, inst_id, "
+ "llvm_inst]"),
+ clEnumValN(STDERR_SRC, "src:stderr",
+ "Log all instructions to stderr in format [src, inst_id]"),
+ clEnumValN(STDERR_COMPACT, "compact:stderr",
+ "Log all instructions to stderr in format [inst_id]"),
+ clEnumValN(FILE_ALL, "all:file", "Log all instructions to file "
+ "instructions.txt in format [src, "
+ "inst_id, llvm_inst]"),
+ clEnumValN(FILE_SRC, "src:file", "Log all instructions to file "
+ "instructions.txt in format [src, "
+ "inst_id]"),
+ clEnumValN(FILE_COMPACT, "compact:file",
+ "Log all instructions to file instructions.txt in format "
+ "[inst_id]"),
+ clEnumValEnd),
+ llvm::cl::CommaSeparated);
cl::opt<bool>
DebugCheckForImpliedValues("debug-check-for-implied-values");
@@ -269,30 +298,18 @@ namespace klee {
RNG theRNG;
}
+Executor::Executor(const InterpreterOptions &opts, InterpreterHandler *ih)
+ : Interpreter(opts), kmodule(0), interpreterHandler(ih), searcher(0),
+ externalDispatcher(new ExternalDispatcher()), statsTracker(0),
+ pathWriter(0), symPathWriter(0), specialFunctionHandler(0),
+ processTree(0), replayKTest(0), replayPath(0), usingSeeds(0),
+ atMemoryLimit(false), inhibitForking(false), haltExecution(false),
+ ivcEnabled(false),
+ coreSolverTimeout(MaxCoreSolverTime != 0 && MaxInstructionTime != 0
+ ? std::min(MaxCoreSolverTime, MaxInstructionTime)
+ : std::max(MaxCoreSolverTime, MaxInstructionTime)),
+ debugInstFile(0), debugLogBuffer(debugBufferString) {
-Executor::Executor(const InterpreterOptions &opts,
- InterpreterHandler *ih)
- : Interpreter(opts),
- kmodule(0),
- interpreterHandler(ih),
- searcher(0),
- externalDispatcher(new ExternalDispatcher()),
- statsTracker(0),
- pathWriter(0),
- symPathWriter(0),
- specialFunctionHandler(0),
- processTree(0),
- replayKTest(0),
- replayPath(0),
- usingSeeds(0),
- atMemoryLimit(false),
- inhibitForking(false),
- haltExecution(false),
- ivcEnabled(false),
- coreSolverTimeout(MaxCoreSolverTime != 0 && MaxInstructionTime != 0
- ? std::min(MaxCoreSolverTime,MaxInstructionTime)
- : std::max(MaxCoreSolverTime,MaxInstructionTime)) {
-
if (coreSolverTimeout) UseForkedCoreSolver = true;
Solver *coreSolver = klee::createCoreSolver(CoreSolverToUse);
if (!coreSolver) {
@@ -308,6 +325,21 @@ Executor::Executor(const InterpreterOptions &opts,
this->solver = new TimingSolver(solver, EqualitySubstitution);
memory = new MemoryManager(&arrayCache);
+
+ if (optionIsSet(DebugPrintInstructions, FILE_ALL) ||
+ optionIsSet(DebugPrintInstructions, FILE_COMPACT) ||
+ optionIsSet(DebugPrintInstructions, FILE_SRC)) {
+ std::string debug_file_name =
+ interpreterHandler->getOutputFilename("instructions.txt");
+ std::string ErrorInfo;
+#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 5)
+ debugInstFile = new llvm::raw_fd_ostream(debug_file_name.c_str(), ErrorInfo,
+ llvm::sys::fs::OpenFlags::F_Text),
+#else
+ debugInstFile =
+ new llvm::raw_fd_ostream(debug_file_name.c_str(), ErrorInfo);
+#endif
+ }
}
@@ -357,6 +389,9 @@ Executor::~Executor() {
delete timers.back();
timers.pop_back();
}
+ if (debugInstFile) {
+ delete debugInstFile;
+ }
}
/***/
@@ -1115,13 +1150,41 @@ void Executor::executeGetValue(ExecutionState &state,
}
}
-void Executor::stepInstruction(ExecutionState &state) {
- if (DebugPrintInstructions) {
- printFileLine(state, state.pc);
- llvm::errs().indent(10) << stats::instructions << " ";
- llvm::errs() << *(state.pc->inst) << '\n';
+void Executor::printDebugInstructions(ExecutionState &state) {
+ // check do not print
+ if (DebugPrintInstructions.size() == 0)
+ return;
+
+ llvm::raw_ostream *stream = 0;
+ if (optionIsSet(DebugPrintInstructions, STDERR_ALL) ||
+ optionIsSet(DebugPrintInstructions, STDERR_SRC) ||
+ optionIsSet(DebugPrintInstructions, STDERR_COMPACT))
+ stream = &llvm::errs();
+ else
+ stream = &debugLogBuffer;
+
+ if (!optionIsSet(DebugPrintInstructions, STDERR_COMPACT) &&
+ !optionIsSet(DebugPrintInstructions, FILE_COMPACT))
+ printFileLine(state, state.pc, *stream);
+
+ (*stream) << state.pc->info->id;
+
+ if (optionIsSet(DebugPrintInstructions, STDERR_ALL) ||
+ optionIsSet(DebugPrintInstructions, FILE_ALL))
+ (*stream) << ":" << *(state.pc->inst);
+ (*stream) << "\n";
+
+ if (optionIsSet(DebugPrintInstructions, FILE_ALL) ||
+ optionIsSet(DebugPrintInstructions, FILE_COMPACT) ||
+ optionIsSet(DebugPrintInstructions, FILE_SRC)) {
+ debugLogBuffer.flush();
+ (*debugInstFile) << debugLogBuffer.str();
+ debugBufferString = "";
}
+}
+void Executor::stepInstruction(ExecutionState &state) {
+ printDebugInstructions(state);
if (statsTracker)
statsTracker->stepInstruction(state);
@@ -1317,12 +1380,13 @@ void Executor::transferToBasicBlock(BasicBlock *dst, BasicBlock *src,
}
}
-void Executor::printFileLine(ExecutionState &state, KInstruction *ki) {
+void Executor::printFileLine(ExecutionState &state, KInstruction *ki,
+ llvm::raw_ostream &debugFile) {
const InstructionInfo &ii = *ki->info;
if (ii.file != "")
- llvm::errs() << " " << ii.file << ":" << ii.line << ":";
+ debugFile << " " << ii.file << ":" << ii.line << ":";
else
- llvm::errs() << " [no debug info]:";
+ debugFile << " [no debug info]:";
}
/// Compute the true target of a function call, resolving LLVM and KLEE aliases