From e0c94340d86334ab089192d3c8a9c59bc72c8a1a Mon Sep 17 00:00:00 2001 From: sanghu Date: Tue, 9 Oct 2018 16:38:08 +0800 Subject: [PATCH 01/13] works on local but not on amazon --- lib/Core/Executor.cpp | 91 +++- lib/Core/Executor.h | 5 +- lib/Module/LowerSwitch.cpp | 3 + tools/klee/main.cpp | 880 +++++++++++++++++++------------------ 4 files changed, 542 insertions(+), 437 deletions(-) diff --git a/lib/Core/Executor.cpp b/lib/Core/Executor.cpp index 779914848..62856b414 100644 --- a/lib/Core/Executor.cpp +++ b/lib/Core/Executor.cpp @@ -1479,9 +1479,22 @@ void Executor::transferToBasicBlock(BasicBlock *dst, BasicBlock *src, PHINode *first = static_cast(state.pc->inst); state.incomingBBIndex = first->getBasicBlockIndex(src); } - if (INTERPOLATION_ENABLED) +// if (INTERPOLATION_ENABLED) // blockCount increased to count all visited Basic Blocks - TxTree::blockCount++; + +// TxTree::blockCount++; + //llvm::outs() << "**************\n"; + //dst->back().dump(); + + //visitedBlocks.insert(dst); //count all destination basic blocks + visitedBlocks.insert(src); + visitedBlocks.insert(dst); + + //kf->function->dump(); + //llvm::errs() << "Abhi change start"; + //dst->dump(); + + //llvm::errs() << "Abhi change end"; } void Executor::printFileLine(ExecutionState &state, KInstruction *ki, @@ -1578,7 +1591,9 @@ void Executor::executeInstruction(ExecutionState &state, KInstruction *ki) { statsTracker->framePopped(state); if (InvokeInst *ii = dyn_cast(caller)) { - transferToBasicBlock(ii->getNormalDest(), caller->getParent(), state); +// llvm::outs() << "******Linh-Sanghu**********\n"; +// ii->dump(); + transferToBasicBlock(ii->getNormalDest(), caller->getParent(), state); } else { state.pc = kcaller; ++state.pc; @@ -3966,6 +3981,47 @@ void Executor::runFunctionAsMain(Function *f, unsigned NumPtrBytes = Context::get().getPointerWidth() / 8; KFunction *kf = kmodule->functionMap[f]; assert(kf); + //Logic to dump all Branch and ret instructions + int allblockcount = 0; + llvm::errs() << "************All Blocks Start****************" << "\n"; + + // llvm::errs() << kf << "\n"; + //kf->dump(); + + for (std::map::iterator it= kmodule->functionMap.begin(),ie=kmodule->functionMap.end(); + it!=ie;++it) { + + + Function *tmpF = it->first; + + + for (llvm::Function::iterator b = tmpF->begin(); b != tmpF->end(); ++b) { + + /*for (llvm::BasicBlock::iterator ins = b->begin(); ins != b->end(); + ++ins) { + if (llvm::isa(ins) || llvm::isa(ins)) { + allblockcount++; + llvm::errs() << "All Block count: " << allblockcount << "\n"; + llvm::errs() << *ins << "\n"; + } + }*/ + //tmpF->dump(); + llvm::errs() << "BlockScopeStarts: " << "\n"; + allblockcount++; + llvm::errs() << "Block Number: " << allblockcount << "\n"; + llvm::errs() <<"Function:"<< (*b->getParent()).getName(); //This logic is to print function name and block name together + (*b).dump(); + llvm::errs() << "BlockScopeEnds: " << "\n"; + } + + //it->first->dump(); //Uncomment it to dump all blocks + + } + + + + llvm::errs() << "************All Blocks End****************" << "\n"; + Function::arg_iterator ai = f->arg_begin(), ae = f->arg_end(); if (ai!=ae) { arguments.push_back(ConstantExpr::alloc(argc, Expr::Int32)); @@ -4053,8 +4109,37 @@ void Executor::runFunctionAsMain(Function *f, #ifdef ENABLE_Z3 // Print interpolation time statistics interpreterHandler->assignSubsumptionStats(TxTree::getInterpolationStat()); + #endif } + llvm::outs() << "Total number executed Basic Blocks at least once: " << visitedBlocks.size() << "\n"; + llvm::outs() << "**************\n"; + //dst->back().dump(); + + + + llvm::errs() << "************Visited Blocks Starts****************" << "\n"; + for (std::set::iterator it = visitedBlocks.begin(), ie=visitedBlocks.end(); it!=ie;++it + ) { + + llvm::errs() << "BlockScopeStarts: " << "\n"; + (*it)->getParent()->getName(); + //llvm::errs() <<";"<< (*BB.getParent()).getName(); + llvm::errs() <<"Function:"<< ((*it)->getParent())->getName(); //This logic is to print function name and block name together + (*it)->dump(); //print whole visited blocks + llvm::errs() << "BlockScopeEnds: " << "\n"; + + //kf->function->dump(); + //(*it)->back().dump(); //print only branch instructions + } + llvm::errs() << "************Visited Blocks Ends****************" << "\n"; + + + + + + //llvm::outs() << "******function********\n"; + //f->dump(); // hack to clear memory objects delete memory; diff --git a/lib/Core/Executor.h b/lib/Core/Executor.h index 64491ae13..bcc73eeab 100644 --- a/lib/Core/Executor.h +++ b/lib/Core/Executor.h @@ -22,7 +22,7 @@ #include "klee/Internal/Module/KModule.h" #include "klee/util/ArrayCache.h" #include "llvm/Support/raw_ostream.h" - +#include "llvm/IR/BasicBlock.h" #include "llvm/ADT/Twine.h" #include @@ -92,6 +92,9 @@ class Executor : public Interpreter { friend class StatsTracker; public: + std::set visitedBlocks; + std::set visitedBlocks1; + class Timer { public: Timer(); diff --git a/lib/Module/LowerSwitch.cpp b/lib/Module/LowerSwitch.cpp index a98b84add..3aa2c1b09 100644 --- a/lib/Module/LowerSwitch.cpp +++ b/lib/Module/LowerSwitch.cpp @@ -89,6 +89,9 @@ void LowerSwitchPass::switchConvert(CaseItr begin, CaseItr end, // Branch to our shiny new if-then stuff... BranchInst::Create(curHead, origBlock); + + + } // processSwitchInst - Replace the specified switch instruction with a sequence diff --git a/tools/klee/main.cpp b/tools/klee/main.cpp index 990363732..65371f8b2 100644 --- a/tools/klee/main.cpp +++ b/tools/klee/main.cpp @@ -8,44 +8,48 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// +#include "klee/Internal/Support/Timer.h" + +#include "klee/Internal/System/Time.h" +#include #include "klee/CommandLine.h" +#include "klee/Config/Version.h" #include "klee/ExecutionState.h" #include "klee/Expr.h" -#include "klee/Interpreter.h" -#include "klee/Statistics.h" -#include "klee/Config/Version.h" #include "klee/Internal/ADT/KTest.h" #include "klee/Internal/ADT/TreeStream.h" #include "klee/Internal/Support/Debug.h" +#include "klee/Internal/Support/ErrorHandling.h" #include "klee/Internal/Support/ModuleUtil.h" -#include "klee/Internal/System/Time.h" #include "klee/Internal/Support/PrintVersion.h" -#include "klee/Internal/Support/ErrorHandling.h" +#include "klee/Internal/System/Time.h" +#include "klee/Interpreter.h" +#include "klee/Statistics.h" #include "klee/util/TxTreeGraph.h" #if LLVM_VERSION_CODE > LLVM_VERSION(3, 2) #include "llvm/IR/Constants.h" -#include "llvm/IR/Module.h" -#include "llvm/IR/Type.h" #include "llvm/IR/InstrTypes.h" #include "llvm/IR/Instruction.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/LLVMContext.h" +#include "llvm/IR/Module.h" +#include "llvm/IR/Type.h" #else #include "llvm/Constants.h" -#include "llvm/Module.h" -#include "llvm/Type.h" #include "llvm/InstrTypes.h" #include "llvm/Instruction.h" #include "llvm/Instructions.h" #include "llvm/LLVMContext.h" +#include "llvm/Module.h" #include "llvm/Support/FileSystem.h" +#include "llvm/Type.h" #endif -#include "llvm/Support/Errno.h" -#include "llvm/Support/FileSystem.h" #include "llvm/Bitcode/ReaderWriter.h" #include "llvm/Support/CommandLine.h" +#include "llvm/Support/Errno.h" +#include "llvm/Support/FileSystem.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/raw_ostream.h" @@ -63,9 +67,9 @@ #include #include -#include #include #include +#include #include #include @@ -73,156 +77,142 @@ #include #include - using namespace llvm; using namespace klee; namespace { - cl::opt - InputFile(cl::desc(""), cl::Positional, cl::init("-")); +cl::opt InputFile(cl::desc(""), cl::Positional, + cl::init("-")); - cl::opt - EntryPoint("entry-point", - cl::desc("Consider the function with the given name as the entrypoint"), - cl::init("main")); - - cl::opt - RunInDir("run-in", cl::desc("Change to the given directory prior to executing")); - - cl::opt - Environ("environ", cl::desc("Parse environ from given file (in \"env\" format)")); - - cl::list - InputArgv(cl::ConsumeAfter, - cl::desc("...")); - - cl::opt - NoOutput("no-output", - cl::desc("Don't generate test files")); - - cl::opt - WarnAllExternals("warn-all-externals", - cl::desc("Give initial warning for all externals.")); - - cl::opt - WriteCVCs("write-cvcs", - cl::desc("Write .cvc files for each test case")); - - cl::opt - WritePCs("write-pcs", - cl::desc("Write .pc files for each test case")); - - cl::opt - WriteSMT2s("write-smt2s", - cl::desc("Write .smt2 (SMT-LIBv2) files for each test case")); - - cl::opt - WriteCov("write-cov", - cl::desc("Write coverage information for each test case")); - - cl::opt - WriteTestInfo("write-test-info", - cl::desc("Write additional test case information")); - - cl::opt - WritePaths("write-paths", - cl::desc("Write .path files for each test case")); - - cl::opt - WriteSymPaths("write-sym-paths", - cl::desc("Write .sym.path files for each test case")); - - cl::opt - ExitOnError("exit-on-error", - cl::desc("Exit if errors occur")); - - - enum LibcType { - NoLibc, KleeLibc, UcLibc - }; - - cl::opt - Libc("libc", - cl::desc("Choose libc version (none by default)."), - cl::values(clEnumValN(NoLibc, "none", "Don't link in a libc"), - clEnumValN(KleeLibc, "klee", "Link in klee libc"), - clEnumValN(UcLibc, "uclibc", "Link in uclibc (adapted for klee)"), - clEnumValEnd), - cl::init(NoLibc)); - - - cl::opt - WithPOSIXRuntime("posix-runtime", - cl::desc("Link with POSIX runtime. Options that can be passed as arguments to the programs are: --sym-arg --sym-args + file model options"), - cl::init(false)); - - cl::opt - OptimizeModule("optimize", - cl::desc("Optimize before execution"), - cl::init(false)); - - cl::opt - CheckDivZero("check-div-zero", - cl::desc("Inject checks for division-by-zero"), - cl::init(true)); - - cl::opt - CheckOvershift("check-overshift", - cl::desc("Inject checks for overshift"), - cl::init(true)); - - cl::opt - OutputDir("output-dir", - cl::desc("Directory to write results in (defaults to klee-out-N)"), - cl::init("")); - - cl::opt - ReplayKeepSymbolic("replay-keep-symbolic", - cl::desc("Replay the test cases only by asserting " - "the bytes, not necessarily making them concrete.")); - - cl::list - ReplayKTestFile("replay-ktest-file", - cl::desc("Specify a ktest file to use for replay"), - cl::value_desc("ktest file")); - - cl::list - ReplayKTestDir("replay-ktest-dir", - cl::desc("Specify a directory to replay ktest files from"), - cl::value_desc("output directory")); - - cl::opt - ReplayPathFile("replay-path", - cl::desc("Specify a path file to replay"), - cl::value_desc("path file")); - - cl::list - SeedOutFile("seed-out"); - - cl::list - SeedOutDir("seed-out-dir"); - - cl::list - LinkLibraries("link-llvm-lib", - cl::desc("Link the given libraries before execution"), - cl::value_desc("library file")); - - cl::opt - MakeConcreteSymbolic("make-concrete-symbolic", - cl::desc("Probabilistic rate at which to make concrete reads symbolic, " - "i.e. approximately 1 in n concrete reads will be made symbolic (0=off, 1=all). " - "Used for testing."), - cl::init(0)); - - cl::opt - StopAfterNTests("stop-after-n-tests", - cl::desc("Stop execution after generating the given number of tests. Extra tests corresponding to partially explored paths will also be dumped."), - cl::init(0)); - - cl::opt - Watchdog("watchdog", - cl::desc("Use a watchdog process to enforce --max-time."), - cl::init(0)); +cl::opt EntryPoint( + "entry-point", + cl::desc("Consider the function with the given name as the entrypoint"), + cl::init("main")); + +cl::opt + RunInDir("run-in", + cl::desc("Change to the given directory prior to executing")); + +cl::opt + Environ("environ", + cl::desc("Parse environ from given file (in \"env\" format)")); + +cl::list InputArgv(cl::ConsumeAfter, + cl::desc("...")); + +cl::opt NoOutput("no-output", cl::desc("Don't generate test files")); + +cl::opt + WarnAllExternals("warn-all-externals", + cl::desc("Give initial warning for all externals.")); + +cl::opt WriteCVCs("write-cvcs", + cl::desc("Write .cvc files for each test case")); + +cl::opt WritePCs("write-pcs", + cl::desc("Write .pc files for each test case")); + +cl::opt + WriteSMT2s("write-smt2s", + cl::desc("Write .smt2 (SMT-LIBv2) files for each test case")); + +cl::opt + WriteCov("write-cov", + cl::desc("Write coverage information for each test case")); + +cl::opt WriteTestInfo("write-test-info", + cl::desc("Write additional test case information")); + +cl::opt WritePaths("write-paths", + cl::desc("Write .path files for each test case")); + +cl::opt + WriteSymPaths("write-sym-paths", + cl::desc("Write .sym.path files for each test case")); + +cl::opt ExitOnError("exit-on-error", cl::desc("Exit if errors occur")); + +enum LibcType { NoLibc, KleeLibc, UcLibc }; + +cl::opt + Libc("libc", cl::desc("Choose libc version (none by default)."), + cl::values(clEnumValN(NoLibc, "none", "Don't link in a libc"), + clEnumValN(KleeLibc, "klee", "Link in klee libc"), + clEnumValN(UcLibc, "uclibc", + "Link in uclibc (adapted for klee)"), + clEnumValEnd), + cl::init(NoLibc)); + +cl::opt WithPOSIXRuntime( + "posix-runtime", + cl::desc("Link with POSIX runtime. Options that can be passed as " + "arguments to the programs are: --sym-arg --sym-args " + " + file model options"), + cl::init(false)); + +cl::opt OptimizeModule("optimize", cl::desc("Optimize before execution"), + cl::init(false)); + +cl::opt CheckDivZero("check-div-zero", + cl::desc("Inject checks for division-by-zero"), + cl::init(true)); + +cl::opt CheckOvershift("check-overshift", + cl::desc("Inject checks for overshift"), + cl::init(true)); + +cl::opt OutputDir( + "output-dir", + cl::desc("Directory to write results in (defaults to klee-out-N)"), + cl::init("")); + +cl::opt ReplayKeepSymbolic( + "replay-keep-symbolic", + cl::desc("Replay the test cases only by asserting " + "the bytes, not necessarily making them concrete.")); + +cl::list + ReplayKTestFile("replay-ktest-file", + cl::desc("Specify a ktest file to use for replay"), + cl::value_desc("ktest file")); + +cl::list + ReplayKTestDir("replay-ktest-dir", + cl::desc("Specify a directory to replay ktest files from"), + cl::value_desc("output directory")); + +cl::opt ReplayPathFile("replay-path", + cl::desc("Specify a path file to replay"), + cl::value_desc("path file")); + +cl::list SeedOutFile("seed-out"); + +cl::list SeedOutDir("seed-out-dir"); + +cl::list + LinkLibraries("link-llvm-lib", + cl::desc("Link the given libraries before execution"), + cl::value_desc("library file")); + +cl::opt MakeConcreteSymbolic( + "make-concrete-symbolic", + cl::desc("Probabilistic rate at which to make concrete reads symbolic, " + "i.e. approximately 1 in n concrete reads will be made symbolic " + "(0=off, 1=all). " + "Used for testing."), + cl::init(0)); + +cl::opt + StopAfterNTests("stop-after-n-tests", + cl::desc("Stop execution after generating the given number " + "of tests. Extra tests corresponding to " + "partially explored paths will also be dumped."), + cl::init(0)); + +cl::opt + Watchdog("watchdog", + cl::desc("Use a watchdog process to enforce --max-time."), + cl::init(0)); } extern cl::opt MaxTime; @@ -237,37 +227,48 @@ class KleeHandler : public InterpreterHandler { SmallString<128> m_outputDirectory; - unsigned m_testIndex; // number of tests written so far + unsigned m_testIndex; // number of tests written so far unsigned m_pathsExplored; // number of paths explored so far - unsigned m_totalBranchingDepthOnExitTermination; // total depth paths explored so far - // on exit - unsigned m_totalInstructionsDepthOnExitTermination; // total instructions explored so far on - // exit - unsigned m_totalBranchingDepthOnEarlyTermination; // total depth paths explored so - // far on early - unsigned m_totalInstructionsDepthOnEarlyTermination; // total instructions explored so far on - // early - unsigned m_totalBranchingDepthOnErrorTermination; // total depth paths explored so - // far on error - unsigned m_totalInstructionsDepthOnErrorTermination; // total instructions explored so far on - // error + unsigned m_totalBranchingDepthOnExitTermination; // total depth paths explored + // so far + // on exit + unsigned m_totalInstructionsDepthOnExitTermination; // total instructions + // explored so far on + // exit + unsigned + m_totalBranchingDepthOnEarlyTermination; // total depth paths explored so + // far on early + unsigned m_totalInstructionsDepthOnEarlyTermination; // total instructions + // explored so far on + // early + unsigned + m_totalBranchingDepthOnErrorTermination; // total depth paths explored so + // far on error + unsigned m_totalInstructionsDepthOnErrorTermination; // total instructions + // explored so far on + // error unsigned m_totalBranchingDepthOnSubsumption; // total depth explored so - // far on subsumption - unsigned m_totalInstructionsDepthOnSubsumption; // total instruction explored so + // far on subsumption + unsigned + m_totalInstructionsDepthOnSubsumption; // total instruction explored so // far on subsumption unsigned m_subsumptionTermination; // number of termination by subsumption unsigned m_subsumptionTerminationTest; // number of tests generated from // termination by subsumption - unsigned m_earlyTermination; // number of early termination - unsigned m_earlyTerminationTest; // number of tests generated from early termination - unsigned m_errorTermination; // number of error termination - unsigned m_errorTerminationTest; // number of tests generated from error termination - unsigned m_exitTermination; // number of exit termination - unsigned m_exitTerminationTest; // number of tests generated from exit termination - unsigned m_otherTermination; // number of other termination (strategy, state merging, - // not in seed, etc. + unsigned m_earlyTermination; // number of early termination + unsigned m_earlyTerminationTest; // number of tests generated from early + // termination + unsigned m_errorTermination; // number of error termination + unsigned m_errorTerminationTest; // number of tests generated from error + // termination + unsigned m_exitTermination; // number of exit termination + unsigned + m_exitTerminationTest; // number of tests generated from exit termination + unsigned m_otherTermination; // number of other termination (strategy, state + // merging, + // not in seed, etc. std::string m_subsumptionStats; // subsumption statistics result @@ -379,8 +380,7 @@ class KleeHandler : public InterpreterHandler { void setInterpreter(Interpreter *i); - void processTestCase(const ExecutionState &state, - const char *errorMessage, + void processTestCase(const ExecutionState &state, const char *errorMessage, const char *errorSuffix); std::string getOutputFilename(const std::string &filename); @@ -389,8 +389,7 @@ class KleeHandler : public InterpreterHandler { llvm::raw_fd_ostream *openTestFile(const std::string &suffix, unsigned id); // load a .path file - static void loadPathFile(std::string name, - std::vector &buffer); + static void loadPathFile(std::string name, std::vector &buffer); static void getKTestFilesInDir(std::string directoryPath, std::vector &results); @@ -418,7 +417,8 @@ KleeHandler::KleeHandler(int argc, char **argv) bool dir_given = OutputDir != ""; SmallString<128> directory(dir_given ? OutputDir : InputFile); - if (!dir_given) sys::path::remove_filename(directory); + if (!dir_given) + sys::path::remove_filename(directory); #if LLVM_VERSION_CODE < LLVM_VERSION(3, 5) error_code ec; if ((ec = sys::fs::make_absolute(directory)) != errc::success) { @@ -431,7 +431,8 @@ KleeHandler::KleeHandler(int argc, char **argv) if (dir_given) { // OutputDir if (mkdir(directory.c_str(), 0775) < 0) - klee_error("cannot create \"%s\": %s", directory.c_str(), strerror(errno)); + klee_error("cannot create \"%s\": %s", directory.c_str(), + strerror(errno)); m_outputDirectory = directory; } else { @@ -440,7 +441,9 @@ KleeHandler::KleeHandler(int argc, char **argv) for (; i <= INT_MAX; ++i) { SmallString<128> d(directory); llvm::sys::path::append(d, "klee-out-"); - raw_svector_ostream ds(d); ds << i; ds.flush(); + raw_svector_ostream ds(d); + ds << i; + ds.flush(); // create directory and try to link klee-last if (mkdir(d.c_str(), 0775) == 0) { @@ -460,10 +463,11 @@ KleeHandler::KleeHandler(int argc, char **argv) // otherwise try again or exit on error if (errno != EEXIST) - klee_error("cannot create \"%s\": %s", m_outputDirectory.c_str(), strerror(errno)); + klee_error("cannot create \"%s\": %s", m_outputDirectory.c_str(), + strerror(errno)); } if (i == INT_MAX && m_outputDirectory.str().equals("")) - klee_error("cannot create output directory: index out of range"); + klee_error("cannot create output directory: index out of range"); } klee_message("output directory is \"%s\"", m_outputDirectory.c_str()); @@ -471,20 +475,24 @@ KleeHandler::KleeHandler(int argc, char **argv) // open warnings.txt std::string file_path = getOutputFilename("warnings.txt"); if ((klee_warning_file = fopen(file_path.c_str(), "w")) == NULL) - klee_error("cannot open file \"%s\": %s", file_path.c_str(), strerror(errno)); + klee_error("cannot open file \"%s\": %s", file_path.c_str(), + strerror(errno)); // open messages.txt file_path = getOutputFilename("messages.txt"); if ((klee_message_file = fopen(file_path.c_str(), "w")) == NULL) - klee_error("cannot open file \"%s\": %s", file_path.c_str(), strerror(errno)); + klee_error("cannot open file \"%s\": %s", file_path.c_str(), + strerror(errno)); // open info m_infoFile = openOutputFile("info"); } KleeHandler::~KleeHandler() { - if (m_pathWriter) delete m_pathWriter; - if (m_symPathWriter) delete m_symPathWriter; + if (m_pathWriter) + delete m_pathWriter; + if (m_symPathWriter) + delete m_symPathWriter; fclose(klee_warning_file); fclose(klee_message_file); delete m_infoFile; @@ -508,7 +516,7 @@ void KleeHandler::setInterpreter(Interpreter *i) { std::string KleeHandler::getOutputFilename(const std::string &filename) { SmallString<128> path = m_outputDirectory; - sys::path::append(path,filename); + sys::path::append(path, filename); return path.str(); } @@ -516,12 +524,13 @@ llvm::raw_fd_ostream *KleeHandler::openOutputFile(const std::string &filename) { llvm::raw_fd_ostream *f; std::string Error; std::string path = getOutputFilename(filename); -#if LLVM_VERSION_CODE >= LLVM_VERSION(3,5) +#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 5) f = new llvm::raw_fd_ostream(path.c_str(), Error, llvm::sys::fs::F_None); -#elif LLVM_VERSION_CODE >= LLVM_VERSION(3,4) +#elif LLVM_VERSION_CODE >= LLVM_VERSION(3, 4) f = new llvm::raw_fd_ostream(path.c_str(), Error, llvm::sys::fs::F_Binary); #else - f = new llvm::raw_fd_ostream(path.c_str(), Error, llvm::raw_fd_ostream::F_Binary); + f = new llvm::raw_fd_ostream(path.c_str(), Error, + llvm::raw_fd_ostream::F_Binary); #endif if (!Error.empty()) { klee_warning("error opening file \"%s\". KLEE may have run out of file " @@ -535,9 +544,11 @@ llvm::raw_fd_ostream *KleeHandler::openOutputFile(const std::string &filename) { return f; } -std::string KleeHandler::getTestFilename(const std::string &suffix, unsigned id) { +std::string KleeHandler::getTestFilename(const std::string &suffix, + unsigned id) { std::stringstream filename; - filename << "test" << std::setfill('0') << std::setw(6) << id << '.' << suffix; + filename << "test" << std::setfill('0') << std::setw(6) << id << '.' + << suffix; return filename.str(); } @@ -546,7 +557,6 @@ llvm::raw_fd_ostream *KleeHandler::openTestFile(const std::string &suffix, return openOutputFile(getTestFilename(suffix, id)); } - /* Outputs all files (.ktest, .pc, .cov etc.) describing a test case */ void KleeHandler::processTestCase(const ExecutionState &state, const char *errorMessage, @@ -562,7 +572,7 @@ void KleeHandler::processTestCase(const ExecutionState &state, } if (!NoOutput) { - std::vector< std::pair > > out; + std::vector > > out; bool success = m_interpreter->getSymbolicSolution(state, out); if (!success) @@ -581,20 +591,21 @@ void KleeHandler::processTestCase(const ExecutionState &state, b.numObjects = out.size(); b.objects = new KTestObject[b.numObjects]; assert(b.objects); - for (unsigned i=0; iname = const_cast(out[i].first.c_str()); + o->name = const_cast(out[i].first.c_str()); o->numBytes = out[i].second.size(); o->bytes = new unsigned char[o->numBytes]; assert(o->bytes); std::copy(out[i].second.begin(), out[i].second.end(), o->bytes); } - if (!kTest_toFile(&b, getOutputFilename(getTestFilename("ktest", id)).c_str())) { + if (!kTest_toFile( + &b, getOutputFilename(getTestFilename("ktest", id)).c_str())) { klee_warning("unable to write output test case, losing it"); } - for (unsigned i=0; igetConstraintLog(state, constraints,Interpreter::KQUERY); + m_interpreter->getConstraintLog(state, constraints, Interpreter::KQUERY); llvm::raw_ostream *f = openTestFile("pc", id); *f << constraints; delete f; @@ -636,12 +647,12 @@ void KleeHandler::processTestCase(const ExecutionState &state, delete f; } - if(WriteSMT2s) { + if (WriteSMT2s) { std::string constraints; - m_interpreter->getConstraintLog(state, constraints, Interpreter::SMTLIB2); - llvm::raw_ostream *f = openTestFile("smt2", id); - *f << constraints; - delete f; + m_interpreter->getConstraintLog(state, constraints, Interpreter::SMTLIB2); + llvm::raw_ostream *f = openTestFile("smt2", id); + *f << constraints; + delete f; } if (m_symPathWriter) { @@ -649,21 +660,24 @@ void KleeHandler::processTestCase(const ExecutionState &state, m_symPathWriter->readStream(m_interpreter->getSymbolicPathStreamID(state), symbolicBranches); llvm::raw_fd_ostream *f = openTestFile("sym.path", id); - for (std::vector::iterator I = symbolicBranches.begin(), E = symbolicBranches.end(); I!=E; ++I) { + for (std::vector::iterator I = symbolicBranches.begin(), + E = symbolicBranches.end(); + I != E; ++I) { *f << *I << "\n"; } delete f; } if (WriteCov) { - std::map > cov; + std::map > cov; m_interpreter->getCoveredLines(state, cov); llvm::raw_ostream *f = openTestFile("cov", id); - for (std::map >::iterator - it = cov.begin(), ie = cov.end(); + for (std::map >::iterator + it = cov.begin(), + ie = cov.end(); it != ie; ++it) { - for (std::set::iterator - it2 = it->second.begin(), ie = it->second.end(); + for (std::set::iterator it2 = it->second.begin(), + ie = it->second.end(); it2 != ie; ++it2) *f << *it->first << ":" << *it2 << "\n"; } @@ -676,16 +690,16 @@ void KleeHandler::processTestCase(const ExecutionState &state, if (WriteTestInfo) { double elapsed_time = util::getWallTime() - start_time; llvm::raw_ostream *f = openTestFile("info", id); - *f << "Time to generate test case: " - << elapsed_time << "s\n"; + + *f << "Time to generate test case: " << elapsed_time << "\n"; + delete f; } } } - // load a .path file -void KleeHandler::loadPathFile(std::string name, - std::vector &buffer) { +// load a .path file +void KleeHandler::loadPathFile(std::string name, std::vector &buffer) { std::ifstream f(name.c_str(), std::ios::in | std::ios::binary); if (!f.good()) @@ -709,8 +723,8 @@ void KleeHandler::getKTestFilesInDir(std::string directoryPath, for (llvm::sys::fs::directory_iterator i(directoryPath, ec), e; i != e && !ec; i.increment(ec)) { std::string f = (*i).path(); - if (f.substr(f.size()-6,f.size()) == ".ktest") { - results.push_back(f); + if (f.substr(f.size() - 6, f.size()) == ".ktest") { + results.push_back(f); } } @@ -731,12 +745,12 @@ std::string KleeHandler::getRunTimeLibraryPath(const char *argv0) { // C++ standard) void *MainExecAddr = (void *)(intptr_t)getRunTimeLibraryPath; SmallString<128> toolRoot( - #if LLVM_VERSION_CODE >= LLVM_VERSION(3,4) +#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 4) llvm::sys::fs::getMainExecutable(argv0, MainExecAddr) - #else +#else llvm::sys::Path::GetMainExecutable(argv0, MainExecAddr).str() - #endif - ); +#endif + ); // Strip off executable so we have a directory path llvm::sys::path::remove_filename(toolRoot); @@ -746,23 +760,22 @@ std::string KleeHandler::getRunTimeLibraryPath(const char *argv0) { if (strlen(KLEE_INSTALL_BIN_DIR) != 0 && strlen(KLEE_INSTALL_RUNTIME_DIR) != 0 && toolRoot.str().endswith(KLEE_INSTALL_BIN_DIR)) { - KLEE_DEBUG_WITH_TYPE("klee_runtime", llvm::dbgs() << - "Using installed KLEE library runtime: "); + KLEE_DEBUG_WITH_TYPE("klee_runtime", + llvm::dbgs() + << "Using installed KLEE library runtime: "); libDir = toolRoot.str().substr(0, toolRoot.str().size() - strlen(KLEE_INSTALL_BIN_DIR)); llvm::sys::path::append(libDir, KLEE_INSTALL_RUNTIME_DIR); - } - else - { - KLEE_DEBUG_WITH_TYPE("klee_runtime", llvm::dbgs() << - "Using build directory KLEE library runtime :"); + } else { + KLEE_DEBUG_WITH_TYPE("klee_runtime", + llvm::dbgs() + << "Using build directory KLEE library runtime :"); libDir = KLEE_DIR; - llvm::sys::path::append(libDir,RUNTIME_CONFIGURATION); - llvm::sys::path::append(libDir,"lib"); + llvm::sys::path::append(libDir, RUNTIME_CONFIGURATION); + llvm::sys::path::append(libDir, "lib"); } - KLEE_DEBUG_WITH_TYPE("klee_runtime", llvm::dbgs() << - libDir.c_str() << "\n"); + KLEE_DEBUG_WITH_TYPE("klee_runtime", llvm::dbgs() << libDir.c_str() << "\n"); return libDir.str(); } @@ -772,11 +785,11 @@ std::string KleeHandler::getRunTimeLibraryPath(const char *argv0) { static std::string strip(std::string &in) { unsigned len = in.size(); unsigned lead = 0, trail = len; - while (leadlead && isspace(in[trail-1])) + while (trail > lead && isspace(in[trail - 1])) --trail; - return in.substr(lead, trail-lead); + return in.substr(lead, trail - lead); } static void parseArguments(int argc, char **argv) { @@ -785,7 +798,8 @@ static void parseArguments(int argc, char **argv) { // This version always reads response files cl::ParseCommandLineOptions(argc, argv, " klee\n"); #else - cl::ParseCommandLineOptions(argc, argv, " klee\n", /*ReadResponseFiles=*/ true); + cl::ParseCommandLineOptions(argc, argv, " klee\n", + /*ReadResponseFiles=*/true); #endif } @@ -809,39 +823,37 @@ static int initEnv(Module *mainModule) { } if (mainFn->arg_size() < 2) { - klee_error("Cannot handle ""--posix-runtime"" when main() has less than two arguments.\n"); + klee_error("Cannot handle " + "--posix-runtime" + " when main() has less than two arguments.\n"); } - Instruction* firstInst = mainFn->begin()->begin(); + Instruction *firstInst = mainFn->begin()->begin(); - Value* oldArgc = mainFn->arg_begin(); - Value* oldArgv = ++mainFn->arg_begin(); + Value *oldArgc = mainFn->arg_begin(); + Value *oldArgv = ++mainFn->arg_begin(); - AllocaInst* argcPtr = - new AllocaInst(oldArgc->getType(), "argcPtr", firstInst); - AllocaInst* argvPtr = - new AllocaInst(oldArgv->getType(), "argvPtr", firstInst); + AllocaInst *argcPtr = + new AllocaInst(oldArgc->getType(), "argcPtr", firstInst); + AllocaInst *argvPtr = + new AllocaInst(oldArgv->getType(), "argvPtr", firstInst); /* Insert void klee_init_env(int* argc, char*** argv) */ - std::vector params; + std::vector params; params.push_back(Type::getInt32Ty(getGlobalContext())); params.push_back(Type::getInt32Ty(getGlobalContext())); - Function* initEnvFn = - cast(mainModule->getOrInsertFunction("klee_init_env", - Type::getVoidTy(getGlobalContext()), - argcPtr->getType(), - argvPtr->getType(), - NULL)); + Function *initEnvFn = cast(mainModule->getOrInsertFunction( + "klee_init_env", Type::getVoidTy(getGlobalContext()), argcPtr->getType(), + argvPtr->getType(), NULL)); assert(initEnvFn); - std::vector args; + std::vector args; args.push_back(argcPtr); args.push_back(argvPtr); #if LLVM_VERSION_CODE >= LLVM_VERSION(3, 0) - Instruction* initEnvCall = CallInst::Create(initEnvFn, args, - "", firstInst); + Instruction *initEnvCall = CallInst::Create(initEnvFn, args, "", firstInst); #else - Instruction* initEnvCall = CallInst::Create(initEnvFn, args.begin(), args.end(), - "", firstInst); + Instruction *initEnvCall = + CallInst::Create(initEnvFn, args.begin(), args.end(), "", firstInst); #endif Value *argc = new LoadInst(argcPtr, "newArgc", firstInst); Value *argv = new LoadInst(argvPtr, "newArgv", firstInst); @@ -855,7 +867,6 @@ static int initEnv(Module *mainModule) { return 0; } - // This is a terrible hack until we get some real modeling of the // system. All we do is check the undefined symbols and warn about // any "unrecognized" externals and about any obviously unsafe ones. @@ -976,49 +987,42 @@ static const char *dontCareExternals[] = { }; // Extra symbols we aren't going to warn about with klee-libc static const char *dontCareKlee[] = { - "__ctype_b_loc", - "__ctype_get_mb_cur_max", - - // io system calls - "open", - "write", - "read", - "close", + "__ctype_b_loc", "__ctype_get_mb_cur_max", + + // io system calls + "open", "write", "read", "close", }; // Extra symbols we aren't going to warn about with uclibc static const char *dontCareUclibc[] = { - "__dso_handle", + "__dso_handle", - // Don't warn about these since we explicitly commented them out of - // uclibc. - "printf", - "vprintf" -}; + // Don't warn about these since we explicitly commented them out of + // uclibc. + "printf", "vprintf"}; // Symbols we consider unsafe static const char *unsafeExternals[] = { - "fork", // oh lord - "exec", // heaven help us - "error", // calls _exit - "raise", // yeah - "kill", // mmmhmmm + "fork", // oh lord + "exec", // heaven help us + "error", // calls _exit + "raise", // yeah + "kill", // mmmhmmm }; -#define NELEMS(array) (sizeof(array)/sizeof(array[0])) +#define NELEMS(array) (sizeof(array) / sizeof(array[0])) void externalsAndGlobalsCheck(const Module *m) { std::map externals; std::set modelled(modelledExternals, - modelledExternals+NELEMS(modelledExternals)); + modelledExternals + NELEMS(modelledExternals)); std::set dontCare(dontCareExternals, - dontCareExternals+NELEMS(dontCareExternals)); + dontCareExternals + NELEMS(dontCareExternals)); std::set unsafe(unsafeExternals, - unsafeExternals+NELEMS(unsafeExternals)); + unsafeExternals + NELEMS(unsafeExternals)); switch (Libc) { case KleeLibc: - dontCare.insert(dontCareKlee, dontCareKlee+NELEMS(dontCareKlee)); + dontCare.insert(dontCareKlee, dontCareKlee + NELEMS(dontCareKlee)); break; case UcLibc: - dontCare.insert(dontCareUclibc, - dontCareUclibc+NELEMS(dontCareUclibc)); + dontCare.insert(dontCareUclibc, dontCareUclibc + NELEMS(dontCareUclibc)); break; case NoLibc: /* silence compiler warning */ break; @@ -1037,54 +1041,48 @@ void externalsAndGlobalsCheck(const Module *m) { it != ie; ++it) { if (const CallInst *ci = dyn_cast(it)) { if (isa(ci->getCalledValue())) { - klee_warning_once(&*fnIt, - "function \"%s\" has inline asm", + klee_warning_once(&*fnIt, "function \"%s\" has inline asm", fnIt->getName().data()); } } } } } - for (Module::const_global_iterator - it = m->global_begin(), ie = m->global_end(); + for (Module::const_global_iterator it = m->global_begin(), + ie = m->global_end(); it != ie; ++it) if (it->isDeclaration() && !it->use_empty()) externals.insert(std::make_pair(it->getName(), true)); // and remove aliases (they define the symbol after global // initialization) - for (Module::const_alias_iterator - it = m->alias_begin(), ie = m->alias_end(); + for (Module::const_alias_iterator it = m->alias_begin(), ie = m->alias_end(); it != ie; ++it) { - std::map::iterator it2 = - externals.find(it->getName()); - if (it2!=externals.end()) + std::map::iterator it2 = externals.find(it->getName()); + if (it2 != externals.end()) externals.erase(it2); } std::map foundUnsafe; - for (std::map::iterator - it = externals.begin(), ie = externals.end(); + for (std::map::iterator it = externals.begin(), + ie = externals.end(); it != ie; ++it) { const std::string &ext = it->first; - if (!modelled.count(ext) && (WarnAllExternals || - !dontCare.count(ext))) { + if (!modelled.count(ext) && (WarnAllExternals || !dontCare.count(ext))) { if (unsafe.count(ext)) { foundUnsafe.insert(*it); } else { klee_warning("undefined reference to %s: %s", - it->second ? "variable" : "function", - ext.c_str()); + it->second ? "variable" : "function", ext.c_str()); } } } - for (std::map::iterator - it = foundUnsafe.begin(), ie = foundUnsafe.end(); + for (std::map::iterator it = foundUnsafe.begin(), + ie = foundUnsafe.end(); it != ie; ++it) { const std::string &ext = it->first; klee_warning("undefined reference to %s: %s (UNSAFE)!", - it->second ? "variable" : "function", - ext.c_str()); + it->second ? "variable" : "function", ext.c_str()); } } @@ -1093,15 +1091,9 @@ static Interpreter *theInterpreter = 0; static bool interrupted = false; // Pulled out so it can be easily called from a debugger. -extern "C" -void halt_execution() { - theInterpreter->setHaltExecution(true); -} +extern "C" void halt_execution() { theInterpreter->setHaltExecution(true); } -extern "C" -void stop_forking() { - theInterpreter->setInhibitForking(true); -} +extern "C" void stop_forking() { theInterpreter->setInhibitForking(true); } static void interrupt_handle() { if (!interrupted && theInterpreter) { @@ -1126,38 +1118,40 @@ static void interrupt_handle_watchdog() { // the state data before going ahead and killing it. static void halt_via_gdb(int pid) { char buffer[256]; - sprintf(buffer, - "gdb --batch --eval-command=\"p halt_execution()\" " - "--eval-command=detach --pid=%d &> /dev/null", + sprintf(buffer, "gdb --batch --eval-command=\"p halt_execution()\" " + "--eval-command=detach --pid=%d &> /dev/null", pid); // fprintf(stderr, "KLEE: WATCHDOG: running: %s\n", buffer); - if (system(buffer)==-1) + if (system(buffer) == -1) perror("system"); } // returns the end of the string put in buf -static char *format_tdiff(char *buf, long seconds) -{ +static char *format_tdiff(char *buf, long seconds) { assert(seconds >= 0); - long minutes = seconds / 60; seconds %= 60; - long hours = minutes / 60; minutes %= 60; - long days = hours / 24; hours %= 24; + long minutes = seconds / 60; + seconds %= 60; + long hours = minutes / 60; + minutes %= 60; + long days = hours / 24; + hours %= 24; buf = strrchr(buf, '\0'); - if (days > 0) buf += sprintf(buf, "%ld days, ", days); + if (days > 0) + buf += sprintf(buf, "%ld days, ", days); buf += sprintf(buf, "%02ld:%02ld:%02ld", hours, minutes, seconds); return buf; } #ifndef SUPPORT_KLEE_UCLIBC -static llvm::Module *linkWithUclibc(llvm::Module *mainModule, StringRef libDir) { +static llvm::Module *linkWithUclibc(llvm::Module *mainModule, + StringRef libDir) { klee_error("invalid libc, no uclibc support!\n"); } #else -static void replaceOrRenameFunction(llvm::Module *module, - const char *old_name, const char *new_name) -{ +static void replaceOrRenameFunction(llvm::Module *module, const char *old_name, + const char *new_name) { Function *f, *f2; f = module->getFunction(new_name); f2 = module->getFunction(old_name); @@ -1171,47 +1165,44 @@ static void replaceOrRenameFunction(llvm::Module *module, } } } -static llvm::Module *linkWithUclibc(llvm::Module *mainModule, StringRef libDir) { +static llvm::Module *linkWithUclibc(llvm::Module *mainModule, + StringRef libDir) { // Ensure that klee-uclibc exists SmallString<128> uclibcBCA(libDir); llvm::sys::path::append(uclibcBCA, KLEE_UCLIBC_BCA_NAME); - bool uclibcExists=false; + bool uclibcExists = false; llvm::sys::fs::exists(uclibcBCA.c_str(), uclibcExists); if (!uclibcExists) klee_error("Cannot find klee-uclibc : %s", uclibcBCA.c_str()); Function *f; // force import of __uClibc_main - mainModule->getOrInsertFunction("__uClibc_main", - FunctionType::get(Type::getVoidTy(getGlobalContext()), - std::vector(), - true)); + mainModule->getOrInsertFunction( + "__uClibc_main", + FunctionType::get(Type::getVoidTy(getGlobalContext()), + std::vector(), true)); // force various imports if (WithPOSIXRuntime) { LLVM_TYPE_Q llvm::Type *i8Ty = Type::getInt8Ty(getGlobalContext()); - mainModule->getOrInsertFunction("realpath", - PointerType::getUnqual(i8Ty), - PointerType::getUnqual(i8Ty), - PointerType::getUnqual(i8Ty), - NULL); - mainModule->getOrInsertFunction("getutent", + mainModule->getOrInsertFunction("realpath", PointerType::getUnqual(i8Ty), PointerType::getUnqual(i8Ty), + PointerType::getUnqual(i8Ty), NULL); + mainModule->getOrInsertFunction("getutent", PointerType::getUnqual(i8Ty), NULL); mainModule->getOrInsertFunction("__fgetc_unlocked", Type::getInt32Ty(getGlobalContext()), - PointerType::getUnqual(i8Ty), - NULL); + PointerType::getUnqual(i8Ty), NULL); mainModule->getOrInsertFunction("__fputc_unlocked", Type::getInt32Ty(getGlobalContext()), Type::getInt32Ty(getGlobalContext()), - PointerType::getUnqual(i8Ty), - NULL); + PointerType::getUnqual(i8Ty), NULL); } f = mainModule->getFunction("__ctype_get_mb_cur_max"); - if (f) f->setName("_stdlib_mb_cur_max"); + if (f) + f->setName("_stdlib_mb_cur_max"); // Strip of asm prefixes for 64 bit versions because they are not // present in uclibc and we want to make sure stuff will get @@ -1222,9 +1213,9 @@ static llvm::Module *linkWithUclibc(llvm::Module *mainModule, StringRef libDir) fi != fe; ++fi) { Function *f = fi; const std::string &name = f->getName(); - if (name[0]=='\01') { + if (name[0] == '\01') { unsigned size = name.size(); - if (name[size-2]=='6' && name[size-1]=='4') { + if (name[size - 2] == '6' && name[size - 1] == '4') { std::string unprefixed = name.substr(1); // See if the unprefixed version exists. @@ -1241,7 +1232,6 @@ static llvm::Module *linkWithUclibc(llvm::Module *mainModule, StringRef libDir) mainModule = klee::linkWithLibrary(mainModule, uclibcBCA.c_str()); assert(mainModule && "unable to link with uclibc"); - replaceOrRenameFunction(mainModule, "__libc_open", "open"); replaceOrRenameFunction(mainModule, "__libc_fcntl", "fcntl"); @@ -1267,20 +1257,19 @@ static llvm::Module *linkWithUclibc(llvm::Module *mainModule, StringRef libDir) const FunctionType *ft = uclibcMainFn->getFunctionType(); assert(ft->getNumParams() == 7); - std::vector fArgs; + std::vector fArgs; fArgs.push_back(ft->getParamType(1)); // argc fArgs.push_back(ft->getParamType(2)); // argv - Function *stub = Function::Create(FunctionType::get(Type::getInt32Ty(getGlobalContext()), fArgs, false), - GlobalVariable::ExternalLinkage, - EntryPoint, - mainModule); + Function *stub = Function::Create( + FunctionType::get(Type::getInt32Ty(getGlobalContext()), fArgs, false), + GlobalVariable::ExternalLinkage, EntryPoint, mainModule); BasicBlock *bb = BasicBlock::Create(getGlobalContext(), "entry", stub); - std::vector args; - args.push_back(llvm::ConstantExpr::getBitCast(userMainFn, - ft->getParamType(0))); - args.push_back(stub->arg_begin()); // argc - args.push_back(++stub->arg_begin()); // argv + std::vector args; + args.push_back( + llvm::ConstantExpr::getBitCast(userMainFn, ft->getParamType(0))); + args.push_back(stub->arg_begin()); // argc + args.push_back(++stub->arg_begin()); // argv args.push_back(Constant::getNullValue(ft->getParamType(3))); // app_init args.push_back(Constant::getNullValue(ft->getParamType(4))); // app_fini args.push_back(Constant::getNullValue(ft->getParamType(5))); // rtld_fini @@ -1298,8 +1287,14 @@ static llvm::Module *linkWithUclibc(llvm::Module *mainModule, StringRef libDir) } #endif +std::string convert(double counts) { + std::ostringstream ss; + ss << std::fixed << counts; + return ss.str(); +} + int main(int argc, char **argv, char **envp) { - atexit(llvm_shutdown); // Call llvm_shutdown() on exit. + atexit(llvm_shutdown); // Call llvm_shutdown() on exit. llvm::InitializeNativeTarget(); @@ -1307,19 +1302,19 @@ int main(int argc, char **argv, char **envp) { sys::PrintStackTraceOnErrorSignal(); if (Watchdog) { - if (MaxTime==0) { + if (MaxTime == 0) { klee_error("--watchdog used without --max-time"); } int pid = fork(); - if (pid<0) { + if (pid < 0) { klee_error("unable to fork watchdog"); } else if (pid) { klee_message("KLEE: WATCHDOG: watching %d\n", pid); fflush(stderr); sys::SetInterruptFunction(interrupt_handle_watchdog); - double nextStep = util::getWallTime() + MaxTime*1.1; + double nextStep = util::getWallTime() + MaxTime * 1.1; int level = 0; // Simple stupid code... @@ -1329,16 +1324,16 @@ int main(int argc, char **argv, char **envp) { int status, res = waitpid(pid, &status, WNOHANG); if (res < 0) { - if (errno==ECHILD) { // No child, no need to watch but - // return error since we didn't catch - // the exit. + if (errno == ECHILD) { // No child, no need to watch but + // return error since we didn't catch + // the exit. klee_warning("KLEE: watchdog exiting (no child)\n"); return 1; - } else if (errno!=EINTR) { + } else if (errno != EINTR) { perror("watchdog waitpid"); exit(1); } - } else if (res==pid && WIFEXITED(status)) { + } else if (res == pid && WIFEXITED(status)) { return WEXITSTATUS(status); } else { double time = util::getWallTime(); @@ -1346,11 +1341,11 @@ int main(int argc, char **argv, char **envp) { if (time > nextStep) { ++level; - if (level==1) { + if (level == 1) { klee_warning( "KLEE: WATCHDOG: time expired, attempting halt via INT\n"); kill(pid, SIGINT); - } else if (level==2) { + } else if (level == 2) { klee_warning( "KLEE: WATCHDOG: time expired, attempting halt via gdb\n"); halt_via_gdb(pid); @@ -1363,7 +1358,7 @@ int main(int argc, char **argv, char **envp) { // Ideally this triggers a dump, which may take a while, // so try and give the process extra time to clean up. - nextStep = util::getWallTime() + std::max(15., MaxTime*.1); + nextStep = util::getWallTime() + std::max(15., MaxTime * .1); } } } @@ -1379,13 +1374,14 @@ int main(int argc, char **argv, char **envp) { Module *mainModule = 0; #if LLVM_VERSION_CODE < LLVM_VERSION(3, 5) OwningPtr BufferPtr; - error_code ec=MemoryBuffer::getFileOrSTDIN(InputFile.c_str(), BufferPtr); + error_code ec = MemoryBuffer::getFileOrSTDIN(InputFile.c_str(), BufferPtr); if (ec) { klee_error("error loading program '%s': %s", InputFile.c_str(), ec.message().c_str()); } - mainModule = getLazyBitcodeModule(BufferPtr.get(), getGlobalContext(), &ErrorMsg); + mainModule = + getLazyBitcodeModule(BufferPtr.get(), getGlobalContext(), &ErrorMsg); if (mainModule) { if (mainModule->MaterializeAllPermanently(&ErrorMsg)) { @@ -1402,13 +1398,13 @@ int main(int argc, char **argv, char **envp) { klee_error("error loading program '%s': %s", InputFile.c_str(), Buffer.getError().message().c_str()); - auto mainModuleOrError = getLazyBitcodeModule(Buffer->get(), getGlobalContext()); + auto mainModuleOrError = + getLazyBitcodeModule(Buffer->get(), getGlobalContext()); if (!mainModuleOrError) { klee_error("error loading program '%s': %s", InputFile.c_str(), mainModuleOrError.getError().message().c_str()); - } - else { + } else { // The module has taken ownership of the MemoryBuffer so release it // from the std::unique_ptr Buffer->release(); @@ -1440,7 +1436,7 @@ int main(int argc, char **argv, char **envp) { case KleeLibc: { // FIXME: Find a reasonable solution for this. SmallString<128> Path(Opts.LibraryDir); -#if LLVM_VERSION_CODE >= LLVM_VERSION(3,3) +#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 3) llvm::sys::path::append(Path, "klee-libc.bc"); #else llvm::sys::path::append(Path, "libklee-libc.bca"); @@ -1495,8 +1491,8 @@ int main(int argc, char **argv, char **envp) { items.push_back(line); } f.close(); - pEnvp = new char *[items.size()+1]; - unsigned i=0; + pEnvp = new char *[items.size() + 1]; + unsigned i = 0; for (; i != items.size(); ++i) pEnvp[i] = strdup(items[i].c_str()); pEnvp[i] = 0; @@ -1506,8 +1502,8 @@ int main(int argc, char **argv, char **envp) { pArgc = InputArgv.size() + 1; pArgv = new char *[pArgc]; - for (unsigned i=0; isetInterpreter(interpreter); - for (int i=0; igetInfoStream() << argv[i] << (i + 1 < argc ? " " : "\n"); } handler->getInfoStream() << "PID: " << getpid() << "\n"; - const Module *finalModule = - interpreter->setModule(mainModule, Opts); + const Module *finalModule = interpreter->setModule(mainModule, Opts); externalsAndGlobalsCheck(finalModule); if (ReplayPathFile != "") { @@ -1547,6 +1542,9 @@ int main(int argc, char **argv, char **envp) { time_t t[2]; t[0] = time(NULL); strftime(buf, sizeof(buf), "Started: %Y-%m-%d %H:%M:%S\n", localtime(&t[0])); + + double t1 = util::getWallTime(); + handler->getInfoStream() << buf; handler->getInfoStream().flush(); @@ -1559,7 +1557,7 @@ int main(int argc, char **argv, char **envp) { ie = ReplayKTestDir.end(); it != ie; ++it) KleeHandler::getKTestFilesInDir(*it, kTestFiles); - std::vector kTests; + std::vector kTests; for (std::vector::iterator it = kTestFiles.begin(), ie = kTestFiles.end(); it != ie; ++it) { @@ -1579,9 +1577,8 @@ int main(int argc, char **argv, char **envp) { } } - unsigned i=0; - for (std::vector::iterator - it = kTests.begin(), ie = kTests.end(); + unsigned i = 0; + for (std::vector::iterator it = kTests.begin(), ie = kTests.end(); it != ie; ++it) { KTest *out = *it; interpreter->setReplayKTest(out); @@ -1590,7 +1587,8 @@ int main(int argc, char **argv, char **envp) { << " (" << ++i << "/" << kTestFiles.size() << ")\n"; // XXX should put envp in .ktest ? interpreter->runFunctionAsMain(mainFn, out->numArgs, out->args, pEnvp); - if (interrupted) break; + if (interrupted) + break; } interpreter->setReplayKTest(0); while (!kTests.empty()) { @@ -1599,8 +1597,8 @@ int main(int argc, char **argv, char **envp) { } } else { std::vector seeds; - for (std::vector::iterator - it = SeedOutFile.begin(), ie = SeedOutFile.end(); + for (std::vector::iterator it = SeedOutFile.begin(), + ie = SeedOutFile.end(); it != ie; ++it) { KTest *out = kTest_fromFile(it->c_str()); if (!out) { @@ -1608,8 +1606,8 @@ int main(int argc, char **argv, char **envp) { } seeds.push_back(out); } - for (std::vector::iterator - it = SeedOutDir.begin(), ie = SeedOutDir.end(); + for (std::vector::iterator it = SeedOutDir.begin(), + ie = SeedOutDir.end(); it != ie; ++it) { std::vector kTestFiles; KleeHandler::getKTestFilesInDir(*it, kTestFiles); @@ -1650,46 +1648,55 @@ int main(int argc, char **argv, char **envp) { strftime(buf, sizeof(buf), "Finished: %Y-%m-%d %H:%M:%S\n", localtime(&t[1])); handler->getInfoStream() << buf; + double t2 = util::getWallTime(); + +// llvm::outs() << "Actual_time: " << t2 - t1 << '\n'; + strcpy(buf, "Elapsed: "); strcpy(format_tdiff(buf, t[1] - t[0]), "\n"); handler->getInfoStream() << buf; + std::string s1 = convert(t2 - t1); + +// handler->getInfoStream().precision(5); +// handler->getInfoStream() << "Acutual time: " << std::fixed<< t2 - t1 << "\n"; + handler->getInfoStream() << "Acutual time: " << s1 <<"\n"; + // Free all the args. - for (unsigned i=0; igetStatisticByName("Queries"); + uint64_t queries = *theStatisticManager->getStatisticByName("Queries"); uint64_t queriesValid = - *theStatisticManager->getStatisticByName("QueriesValid"); + *theStatisticManager->getStatisticByName("QueriesValid"); uint64_t queriesInvalid = - *theStatisticManager->getStatisticByName("QueriesInvalid"); + *theStatisticManager->getStatisticByName("QueriesInvalid"); uint64_t queryCounterexamples = - *theStatisticManager->getStatisticByName("QueriesCEX"); + *theStatisticManager->getStatisticByName("QueriesCEX"); uint64_t queryConstructs = - *theStatisticManager->getStatisticByName("QueriesConstructs"); + *theStatisticManager->getStatisticByName("QueriesConstructs"); uint64_t instructions = - *theStatisticManager->getStatisticByName("Instructions"); - uint64_t forks = - *theStatisticManager->getStatisticByName("Forks"); + *theStatisticManager->getStatisticByName("Instructions"); + uint64_t forks = *theStatisticManager->getStatisticByName("Forks"); - handler->getInfoStream() - << "KLEE: done: explored paths = " << 1 + forks << "\n"; + handler->getInfoStream() << "KLEE: done: explored paths = " << 1 + forks + << "\n"; // Write some extra information in the info file which users won't // necessarily care about or understand. if (queries) - handler->getInfoStream() - << "KLEE: done: avg. constructs per query = " + handler->getInfoStream() << "KLEE: done: avg. constructs per query = " << queryConstructs / queries << "\n"; - handler->getInfoStream() - << "KLEE: done: total queries = " << queries << "\n" - << "KLEE: done: valid queries = " << queriesValid << "\n" - << "KLEE: done: invalid queries = " << queriesInvalid << "\n" - << "KLEE: done: query cex = " << queryCounterexamples << "\n"; + handler->getInfoStream() << "KLEE: done: total queries = " << queries << "\n" + << "KLEE: done: valid queries = " << queriesValid + << "\n" + << "KLEE: done: invalid queries = " << queriesInvalid + << "\n" + << "KLEE: done: query cex = " << queryCounterexamples + << "\n"; std::stringstream stats; if (INTERPOLATION_ENABLED) { @@ -1697,11 +1704,11 @@ int main(int argc, char **argv, char **envp) { } stats << "\n"; - stats << "KLEE: done: total instructions = " - << instructions << "\n"; - stats << "KLEE: done: completed paths = " - << handler->getNumPathsExplored() << ", among which\n"; - stats << "KLEE: done: early-terminating paths (instruction time limit, solver timeout, max-depth reached) = " + stats << "KLEE: done: total instructions = " << instructions << "\n"; + stats << "KLEE: done: completed paths = " << handler->getNumPathsExplored() + << ", among which\n"; + stats << "KLEE: done: early-terminating paths (instruction time limit, " + "solver timeout, max-depth reached) = " << handler->getEarlyTermination() << "\n"; if (INTERPOLATION_ENABLED) { @@ -1711,14 +1718,16 @@ int main(int argc, char **argv, char **envp) { handler->getTotalBranchingDepthOnErrorTermination()) / (double)(handler->getExitTermination() + handler->getEarlyTermination() + - handler->getErrorTermination()) << "\n"; + handler->getErrorTermination()) + << "\n"; if (handler->getSubsumptionTermination() == 0.0) { stats << "KLEE: done: average branching depth of subsumed paths = " << 0 << "\n"; } else { stats << "KLEE: done: average branching depth of subsumed paths = " << (double)handler->getTotalBranchingDepthOnSubsumption() / - (double)handler->getSubsumptionTermination() << "\n"; + (double)handler->getSubsumptionTermination() + << "\n"; } } @@ -1729,28 +1738,31 @@ int main(int argc, char **argv, char **envp) { handler->getTotalInstructionsDepthOnErrorTermination()) / (double)(handler->getExitTermination() + handler->getEarlyTermination() + - handler->getErrorTermination()) << "\n"; + handler->getErrorTermination()) + << "\n"; if (handler->getSubsumptionTermination() == 0.0) { stats << "KLEE: done: average instructions of subsumed paths = " << 0 << "\n"; } else { - stats << "KLEE: done: average instructions of subsumed paths = " - << (double) - handler->getTotalInstructionPathsExploredOnSubsumption() / - (double)handler->getSubsumptionTermination() << "\n"; + stats + << "KLEE: done: average instructions of subsumed paths = " + << (double)handler->getTotalInstructionPathsExploredOnSubsumption() / + (double)handler->getSubsumptionTermination() + << "\n"; } } if (INTERPOLATION_ENABLED) stats << "KLEE: done: subsumed paths = " << handler->getSubsumptionTermination() << "\n"; - stats << "KLEE: done: error paths = " - << handler->getErrorTermination() << "\n"; + stats << "KLEE: done: error paths = " << handler->getErrorTermination() + << "\n"; stats << "KLEE: done: program exit paths = " << handler->getExitTermination() << "\n"; - stats << "KLEE: done: generated tests = " - << handler->getNumTestCases() << ", among which\n"; - stats << "KLEE: done: early-terminating tests (instruction time limit, solver timeout, max-depth reached) = " + stats << "KLEE: done: generated tests = " << handler->getNumTestCases() + << ", among which\n"; + stats << "KLEE: done: early-terminating tests (instruction time limit, " + "solver timeout, max-depth reached) = " << handler->getEarlyTerminationTest() << "\n"; #ifdef ENABLE_Z3 if (SubsumedTest) @@ -1799,3 +1811,5 @@ int main(int argc, char **argv, char **envp) { return 0; } + + From 667bd3d1e22dc21bf9cc3a966af8ced7bf992964 Mon Sep 17 00:00:00 2001 From: sanghu Date: Mon, 15 Oct 2018 12:28:07 +0800 Subject: [PATCH 02/13] Adding the feature of live block coverage --- lib/Core/Executor.cpp | 152 ++++++++++++++++++++++++++++++++++++++--- lib/Core/Executor.h | 2 + lib/Module/KModule.cpp | 3 +- 3 files changed, 148 insertions(+), 9 deletions(-) diff --git a/lib/Core/Executor.cpp b/lib/Core/Executor.cpp index 62856b414..ee5196a27 100644 --- a/lib/Core/Executor.cpp +++ b/lib/Core/Executor.cpp @@ -106,6 +106,7 @@ #include #include + #include #include @@ -1487,9 +1488,106 @@ void Executor::transferToBasicBlock(BasicBlock *dst, BasicBlock *src, //dst->back().dump(); //visitedBlocks.insert(dst); //count all destination basic blocks + + + if((kf->function->getName() != "klee_div_zero_check") && (kf->function->getName()!= "klee_range") && (kf->function->getName() != "klee_int") && (kf->function->getName() != "klee_overshift_check") && (kf->function->getName() != "memcpy") && (kf->function->getName() != "memmove") && (kf->function->getName() != "mempcpy") && (kf->function->getName() != "memset")) + { + + + visitedBlocks.insert(src); visitedBlocks.insert(dst); + + } + //---TRY to implement Live Coverage-starts + + std::ofstream outfile; + outfile.open ("Livecoverage.txt", std::ofstream::app); + std::ofstream outfile1; + outfile1.open ("LogBlockCoverage.txt", std::ofstream::app); + + + //outfile << "Sanghu"; + //ios::out | ios::app | ios::binary + + + + + time_t now = time(0); + //time_t now3 = startingTime; + struct tm tstruct; + char buf[80]; + char buf1[80]; + tstruct = *localtime(&now); + // Visit http://en.cppreference.com/w/cpp/chrono/c/strftime + // for more information about date/time format + //strftime(buf, sizeof(buf), "%Y-%m-%d.%X", &tstruct); + //strftime(buf, sizeof(buf), "%T", &tstruct); + //strftime(buf1, sizeof(buf1), "%S", &tstruct); + //int diff; + //double difftime(time_t now, time_t now3) + + //diff = (now/60) - (startingTime/60); + //outfile << startingTime; + //outfile << now; + + //outfile << (time (0)) %60 << "\n"; + //outfile << (time(&now)/60) - (time(&now3)/60); + //outfile << (time(&now)) - (time(&now3)) << "\n"; + /*outfile << "time(0)" << time(0) << "\n"; + outfile << "time(&now)" << time(&now) << "\n"; + outfile << "now" << now << "\n"; + outfile << "time(&startingTime)" << time(&startingTime) << "\n"; + outfile << "startingTime" << startingTime << "\n";*/ + double diff; + double checkpointinitial = 0.00; + double checkpoint1 = 600.00; + double checkpoint2 = 1200.00; + double checkpoint3 = 1800.00; + double checkpoint4 = 2400.00; + double checkpoint5 = 3000.00; + double checkpoint6 = 3600.00; + + diff = now - startingTime; + float blockCoverage; + strftime(buf, sizeof(buf), "%T", &tstruct); + blockCoverage = ((float)visitedBlocks.size() / (float)allblockcount) * 100; + if((diff == checkpointinitial) || (diff == checkpoint1) || (diff == checkpoint2) || (diff == checkpoint3) || (diff == checkpoint4) || (diff == checkpoint5) || (diff == checkpoint6) ) + { + + outfile << "************Visited Blocks Starts Live****************" << "\n"; + + outfile << buf << "\n"; + outfile << "Total number executed Basic Blocks: " << visitedBlocks.size() << "\n"; + outfile << "Total number of Basic Blocks: " << allblockcount << "\n"; + + outfile << "Block Coverage : " << std::fixed << std::setprecision(2) << blockCoverage << " percentage" << "\n"; + + //outfile << "Block Coverage%f : " << blockCoverage << "%" << "\n"; + + + /*for (std::set::iterator it1 = visitedBlocks.begin(), ie1 = + visitedBlocks.end(); it1 != ie1; ++it1) { + outfile << "BlockScopeStarts: \n"; + // (*it)->getParent()->getName(); + //llvm::errs() <<";"<< (*BB.getParent()).getName(); + //std::string tmp = (*it1)->getParent()->getName(); + //outfile << "Function:" << tmp << "\n"; //This logic is to print function name and block name together + //(*it)->dump(); //print whole visited blocks + //std::string tmp1 = (*it); + // outfile << (*it)->dump() << "\n"; + outfile << "BlockScopeEnds: " << "\n"; + + //kf->function->dump(); + //(*it)->back().dump(); //print only branch instructions + }*/ + outfile << "************Visited Blocks Ends Live****************" << "\n"; + } + outfile1 << "[" << buf << "," << "(" << visitedBlocks.size() << "," << allblockcount << "," << std::fixed << std::setprecision(2) << blockCoverage << "%)]" << "\n"; + + //----TRY to implement Live Coverage Ends + //kf->function->dump(); //llvm::errs() << "Abhi change start"; //dst->dump(); @@ -3982,7 +4080,8 @@ void Executor::runFunctionAsMain(Function *f, KFunction *kf = kmodule->functionMap[f]; assert(kf); //Logic to dump all Branch and ret instructions - int allblockcount = 0; + //int allblockcount = 0; + allblockcount = 0; llvm::errs() << "************All Blocks Start****************" << "\n"; // llvm::errs() << kf << "\n"; @@ -3993,7 +4092,9 @@ void Executor::runFunctionAsMain(Function *f, Function *tmpF = it->first; - + //This logic is to eliminates klee's extra checks to dump in files + if((tmpF->getName() != "klee_div_zero_check") && (tmpF->getName() != "klee_range") && (tmpF->getName() != "klee_int") && (tmpF->getName() != "klee_overshift_check") && (tmpF->getName() != "memcpy") && (tmpF->getName() != "memmove") && (tmpF->getName() != "mempcpy") && (tmpF->getName() != "memset")) + { for (llvm::Function::iterator b = tmpF->begin(); b != tmpF->end(); ++b) { @@ -4006,6 +4107,8 @@ void Executor::runFunctionAsMain(Function *f, } }*/ //tmpF->dump(); + + llvm::errs() << "BlockScopeStarts: " << "\n"; allblockcount++; llvm::errs() << "Block Number: " << allblockcount << "\n"; @@ -4016,6 +4119,11 @@ void Executor::runFunctionAsMain(Function *f, //it->first->dump(); //Uncomment it to dump all blocks + } + + startingTime = time(0); + + } @@ -4116,12 +4224,12 @@ void Executor::runFunctionAsMain(Function *f, llvm::outs() << "**************\n"; //dst->back().dump(); - - llvm::errs() << "************Visited Blocks Starts****************" << "\n"; - for (std::set::iterator it = visitedBlocks.begin(), ie=visitedBlocks.end(); it!=ie;++it - ) { + for (std::set::iterator it = visitedBlocks.begin(), ie=visitedBlocks.end(); it!=ie;++it + ) { + if(( ((*it)->getParent())->getName()!= "klee_div_zero_check") && (((*it)->getParent())->getName() != "klee_range") && (((*it)->getParent())->getName() != "klee_int") && (((*it)->getParent())->getName() != "klee_overshift_check") && (((*it)->getParent())->getName() != "memcpy") && (((*it)->getParent())->getName() != "memmove") && (((*it)->getParent())->getName() != "mempcpy") && (((*it)->getParent())->getName() != "memset")) + { llvm::errs() << "BlockScopeStarts: " << "\n"; (*it)->getParent()->getName(); //llvm::errs() <<";"<< (*BB.getParent()).getName(); @@ -4131,9 +4239,37 @@ void Executor::runFunctionAsMain(Function *f, //kf->function->dump(); //(*it)->back().dump(); //print only branch instructions - } - llvm::errs() << "************Visited Blocks Ends****************" << "\n"; + } + } + llvm::errs() << "************Visited Blocks Ends****************" << "\n"; + + +// std::ofstream outfile; +// outfile.open("Livecoverage.txt"); +// outfile << "Sanghu"; +// std::error_code OutErrorInfo; +// llvm::raw_fd_ostream() outFile(llvm::StringRef("Livecoverage.txt"), OutErrorInfo, llvm::sys::fs::F_None); +// +// outfile << "************Visited Blocks Starts****************" << "\n"; +// +// for (std::set::iterator it1 = visitedBlocks.begin(), ie1 = +// visitedBlocks.end(); it1 != ie1; ++it1) { +// outfile << "BlockScopeStarts: \n"; +//// (*it)->getParent()->getName(); +// //llvm::errs() <<";"<< (*BB.getParent()).getName(); +// std::string tmp = (*it1)->getParent()->getName(); +// outfile << "Function:" << tmp << "\n"; //This logic is to print function name and block name together +// //(*it)->dump(); //print whole visited blocks +// //std::string tmp1 = (*it); +//// outfile << (*it)->dump() << "\n"; +// outfile << "BlockScopeEnds: " << "\n"; +// +// //kf->function->dump(); +// //(*it)->back().dump(); //print only branch instructions +// } +// outfile << "************Visited Blocks Ends****************" << "\n"; + //llvm::raw_ostream()* stream; diff --git a/lib/Core/Executor.h b/lib/Core/Executor.h index bcc73eeab..6420e1ad9 100644 --- a/lib/Core/Executor.h +++ b/lib/Core/Executor.h @@ -92,6 +92,8 @@ class Executor : public Interpreter { friend class StatsTracker; public: + time_t startingTime; + int allblockcount; std::set visitedBlocks; std::set visitedBlocks1; diff --git a/lib/Module/KModule.cpp b/lib/Module/KModule.cpp index f24202e11..609549178 100644 --- a/lib/Module/KModule.cpp +++ b/lib/Module/KModule.cpp @@ -466,7 +466,8 @@ void KModule::prepare(const Interpreter::ModuleOptions &opts, llvm::errs() << "KLEE: escaping functions: ["; for (std::set::iterator it = escapingFunctions.begin(), ie = escapingFunctions.end(); it != ie; ++it) { - llvm::errs() << (*it)->getName() << ", "; + std::string tmp2 = (*it)->getName(); + llvm::errs() << tmp2 << ", "; } llvm::errs() << "]\n"; } From 940e53c160760c07db17fc744029b61e9edc34c5 Mon Sep 17 00:00:00 2001 From: sanghu Date: Tue, 16 Oct 2018 12:06:32 +0800 Subject: [PATCH 03/13] Writing data (time,BC) into record.dat for graph plotting --- lib/Core/Executor.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/lib/Core/Executor.cpp b/lib/Core/Executor.cpp index ee5196a27..1df81fff7 100644 --- a/lib/Core/Executor.cpp +++ b/lib/Core/Executor.cpp @@ -1480,10 +1480,9 @@ void Executor::transferToBasicBlock(BasicBlock *dst, BasicBlock *src, PHINode *first = static_cast(state.pc->inst); state.incomingBBIndex = first->getBasicBlockIndex(src); } -// if (INTERPOLATION_ENABLED) + if (INTERPOLATION_ENABLED) // blockCount increased to count all visited Basic Blocks - -// TxTree::blockCount++; + TxTree::blockCount++; //llvm::outs() << "**************\n"; //dst->back().dump(); @@ -1506,7 +1505,8 @@ void Executor::transferToBasicBlock(BasicBlock *dst, BasicBlock *src, outfile.open ("Livecoverage.txt", std::ofstream::app); std::ofstream outfile1; outfile1.open ("LogBlockCoverage.txt", std::ofstream::app); - + std::ofstream outfile2; + outfile2.open ("record.dat", std::ofstream::app); //outfile << "Sanghu"; //ios::out | ios::app | ios::binary @@ -1552,6 +1552,7 @@ void Executor::transferToBasicBlock(BasicBlock *dst, BasicBlock *src, diff = now - startingTime; float blockCoverage; strftime(buf, sizeof(buf), "%T", &tstruct); + blockCoverage = ((float)visitedBlocks.size() / (float)allblockcount) * 100; if((diff == checkpointinitial) || (diff == checkpoint1) || (diff == checkpoint2) || (diff == checkpoint3) || (diff == checkpoint4) || (diff == checkpoint5) || (diff == checkpoint6) ) { @@ -1585,7 +1586,7 @@ void Executor::transferToBasicBlock(BasicBlock *dst, BasicBlock *src, outfile << "************Visited Blocks Ends Live****************" << "\n"; } outfile1 << "[" << buf << "," << "(" << visitedBlocks.size() << "," << allblockcount << "," << std::fixed << std::setprecision(2) << blockCoverage << "%)]" << "\n"; - + outfile2 << diff << " " << std::fixed << std::setprecision(2) << blockCoverage << "\n"; //----TRY to implement Live Coverage Ends //kf->function->dump(); From 9b2490ef3f13544737b551636a4ecce97aa3afb5 Mon Sep 17 00:00:00 2001 From: sanghu Date: Fri, 19 Oct 2018 10:52:43 +0800 Subject: [PATCH 04/13] Uncommenting "TxTree::blockCount++;" line at Executor.cpp to count basic block by TX --- lib/Core/Executor.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/Core/Executor.cpp b/lib/Core/Executor.cpp index 1df81fff7..4c40e6f17 100644 --- a/lib/Core/Executor.cpp +++ b/lib/Core/Executor.cpp @@ -1480,14 +1480,19 @@ void Executor::transferToBasicBlock(BasicBlock *dst, BasicBlock *src, PHINode *first = static_cast(state.pc->inst); state.incomingBBIndex = first->getBasicBlockIndex(src); } - if (INTERPOLATION_ENABLED) + if (INTERPOLATION_ENABLED){ // blockCount increased to count all visited Basic Blocks TxTree::blockCount++; + } //llvm::outs() << "**************\n"; //dst->back().dump(); //visitedBlocks.insert(dst); //count all destination basic blocks + //llvm::errs() << "************Dumping executed Blocks -- starts****************" << "\n"; + //src->dump(); + //dst->dump(); + //llvm::errs() << "************Dumping executed Blocks -- Ends****************" << "\n"; if((kf->function->getName() != "klee_div_zero_check") && (kf->function->getName()!= "klee_range") && (kf->function->getName() != "klee_int") && (kf->function->getName() != "klee_overshift_check") && (kf->function->getName() != "memcpy") && (kf->function->getName() != "memmove") && (kf->function->getName() != "mempcpy") && (kf->function->getName() != "memset")) { From 7b541b371d2f7d9636826cb2264f6beb7bdfd6bf Mon Sep 17 00:00:00 2001 From: sanghu Date: Wed, 31 Oct 2018 10:18:10 +0800 Subject: [PATCH 05/13] Updating into executedblocks.txt, and removed Livecoverage.txt file and its logic of checkpoints. Also, cleaned the code. --- lib/Core/Executor.cpp | 115 ++++++++---------------------------------- 1 file changed, 20 insertions(+), 95 deletions(-) diff --git a/lib/Core/Executor.cpp b/lib/Core/Executor.cpp index 4c40e6f17..00dac5ea7 100644 --- a/lib/Core/Executor.cpp +++ b/lib/Core/Executor.cpp @@ -1484,121 +1484,46 @@ void Executor::transferToBasicBlock(BasicBlock *dst, BasicBlock *src, // blockCount increased to count all visited Basic Blocks TxTree::blockCount++; } - //llvm::outs() << "**************\n"; - //dst->back().dump(); - - //visitedBlocks.insert(dst); //count all destination basic blocks - - //llvm::errs() << "************Dumping executed Blocks -- starts****************" << "\n"; - //src->dump(); - //dst->dump(); - //llvm::errs() << "************Dumping executed Blocks -- Ends****************" << "\n"; if((kf->function->getName() != "klee_div_zero_check") && (kf->function->getName()!= "klee_range") && (kf->function->getName() != "klee_int") && (kf->function->getName() != "klee_overshift_check") && (kf->function->getName() != "memcpy") && (kf->function->getName() != "memmove") && (kf->function->getName() != "mempcpy") && (kf->function->getName() != "memset")) { - - - visitedBlocks.insert(src); visitedBlocks.insert(dst); - - } - //---TRY to implement Live Coverage-starts - - std::ofstream outfile; - outfile.open ("Livecoverage.txt", std::ofstream::app); - std::ofstream outfile1; + std::ofstream outfile1; outfile1.open ("LogBlockCoverage.txt", std::ofstream::app); std::ofstream outfile2; outfile2.open ("record.dat", std::ofstream::app); + std::ofstream outfile3; + outfile3.open ("executedblocks.txt", std::ofstream::app); - //outfile << "Sanghu"; - //ios::out | ios::app | ios::binary - - - - - time_t now = time(0); - //time_t now3 = startingTime; - struct tm tstruct; - char buf[80]; - char buf1[80]; - tstruct = *localtime(&now); - // Visit http://en.cppreference.com/w/cpp/chrono/c/strftime - // for more information about date/time format - //strftime(buf, sizeof(buf), "%Y-%m-%d.%X", &tstruct); - //strftime(buf, sizeof(buf), "%T", &tstruct); - //strftime(buf1, sizeof(buf1), "%S", &tstruct); - //int diff; - //double difftime(time_t now, time_t now3) - - //diff = (now/60) - (startingTime/60); - //outfile << startingTime; - //outfile << now; - - //outfile << (time (0)) %60 << "\n"; - //outfile << (time(&now)/60) - (time(&now3)/60); - //outfile << (time(&now)) - (time(&now3)) << "\n"; - /*outfile << "time(0)" << time(0) << "\n"; - outfile << "time(&now)" << time(&now) << "\n"; - outfile << "now" << now << "\n"; - outfile << "time(&startingTime)" << time(&startingTime) << "\n"; - outfile << "startingTime" << startingTime << "\n";*/ - double diff; - double checkpointinitial = 0.00; - double checkpoint1 = 600.00; - double checkpoint2 = 1200.00; - double checkpoint3 = 1800.00; - double checkpoint4 = 2400.00; - double checkpoint5 = 3000.00; - double checkpoint6 = 3600.00; + time_t now = time(0); + //time_t now3 = startingTime; + struct tm tstruct; + char buf[80]; + char buf1[80]; + tstruct = *localtime(&now); + double diff; diff = now - startingTime; float blockCoverage; strftime(buf, sizeof(buf), "%T", &tstruct); blockCoverage = ((float)visitedBlocks.size() / (float)allblockcount) * 100; - if((diff == checkpointinitial) || (diff == checkpoint1) || (diff == checkpoint2) || (diff == checkpoint3) || (diff == checkpoint4) || (diff == checkpoint5) || (diff == checkpoint6) ) - { - - outfile << "************Visited Blocks Starts Live****************" << "\n"; - - outfile << buf << "\n"; - outfile << "Total number executed Basic Blocks: " << visitedBlocks.size() << "\n"; - outfile << "Total number of Basic Blocks: " << allblockcount << "\n"; - - outfile << "Block Coverage : " << std::fixed << std::setprecision(2) << blockCoverage << " percentage" << "\n"; - - //outfile << "Block Coverage%f : " << blockCoverage << "%" << "\n"; - - /*for (std::set::iterator it1 = visitedBlocks.begin(), ie1 = + for (std::set::iterator it1 = visitedBlocks.begin(), ie1 = visitedBlocks.end(); it1 != ie1; ++it1) { - outfile << "BlockScopeStarts: \n"; - // (*it)->getParent()->getName(); - //llvm::errs() <<";"<< (*BB.getParent()).getName(); - //std::string tmp = (*it1)->getParent()->getName(); - //outfile << "Function:" << tmp << "\n"; //This logic is to print function name and block name together - //(*it)->dump(); //print whole visited blocks - //std::string tmp1 = (*it); - // outfile << (*it)->dump() << "\n"; - outfile << "BlockScopeEnds: " << "\n"; - - //kf->function->dump(); - //(*it)->back().dump(); //print only branch instructions - }*/ - outfile << "************Visited Blocks Ends Live****************" << "\n"; - } + outfile3 << "BlockScopeStarts: \n"; + std::string tmp = (*it1)->getParent()->getName(); + BasicBlock *b = (*it1); + std::string Str; + raw_string_ostream OS(Str); + b->print(OS); + outfile3 << "Function:" << tmp << Str <<"\n"; //This logic is to print function name and block name together + outfile3 << "BlockScopeEnds: " << "\n"; + } outfile1 << "[" << buf << "," << "(" << visitedBlocks.size() << "," << allblockcount << "," << std::fixed << std::setprecision(2) << blockCoverage << "%)]" << "\n"; outfile2 << diff << " " << std::fixed << std::setprecision(2) << blockCoverage << "\n"; - //----TRY to implement Live Coverage Ends - - //kf->function->dump(); - //llvm::errs() << "Abhi change start"; - //dst->dump(); - - //llvm::errs() << "Abhi change end"; } void Executor::printFileLine(ExecutionState &state, KInstruction *ki, From 505c06142f422a939d938c68b2a3ff4eef9afbe9 Mon Sep 17 00:00:00 2001 From: sanghu Date: Wed, 31 Oct 2018 12:02:26 +0800 Subject: [PATCH 06/13] Adding the feature to halt execution on max i.e 100% Block Coverage --- lib/Core/Executor.cpp | 16 ++++++++++++++-- lib/Core/Executor.h | 1 + 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/lib/Core/Executor.cpp b/lib/Core/Executor.cpp index 00dac5ea7..fe114eaf1 100644 --- a/lib/Core/Executor.cpp +++ b/lib/Core/Executor.cpp @@ -1485,8 +1485,15 @@ void Executor::transferToBasicBlock(BasicBlock *dst, BasicBlock *src, TxTree::blockCount++; } - if((kf->function->getName() != "klee_div_zero_check") && (kf->function->getName()!= "klee_range") && (kf->function->getName() != "klee_int") && (kf->function->getName() != "klee_overshift_check") && (kf->function->getName() != "memcpy") && (kf->function->getName() != "memmove") && (kf->function->getName() != "mempcpy") && (kf->function->getName() != "memset")) + if(blockCoverage < 100.00) + { + + if((kf->function->getName() != "klee_div_zero_check") && (kf->function->getName()!= "klee_range") && (kf->function->getName() != "klee_int") && (kf->function->getName() != "klee_overshift_check") && (kf->function->getName() != "memcpy") && (kf->function->getName() != "memmove") && (kf->function->getName() != "mempcpy") && (kf->function->getName() != "memset")) { +// if(visitedBlocks.find(src) == visitedBlocks.end() && visitedBlocks.find(dst) == visitedBlocks.end()) count = 0; +// else count++; +// if(count == 100) {print_visitedBlocks; exit(0);} + visitedBlocks.insert(src); visitedBlocks.insert(dst); } @@ -1506,7 +1513,6 @@ void Executor::transferToBasicBlock(BasicBlock *dst, BasicBlock *src, double diff; diff = now - startingTime; - float blockCoverage; strftime(buf, sizeof(buf), "%T", &tstruct); blockCoverage = ((float)visitedBlocks.size() / (float)allblockcount) * 100; @@ -1524,6 +1530,12 @@ void Executor::transferToBasicBlock(BasicBlock *dst, BasicBlock *src, } outfile1 << "[" << buf << "," << "(" << visitedBlocks.size() << "," << allblockcount << "," << std::fixed << std::setprecision(2) << blockCoverage << "%)]" << "\n"; outfile2 << diff << " " << std::fixed << std::setprecision(2) << blockCoverage << "\n"; + + } + else + { + return; + } } void Executor::printFileLine(ExecutionState &state, KInstruction *ki, diff --git a/lib/Core/Executor.h b/lib/Core/Executor.h index 6420e1ad9..368abb2fd 100644 --- a/lib/Core/Executor.h +++ b/lib/Core/Executor.h @@ -96,6 +96,7 @@ class Executor : public Interpreter { int allblockcount; std::set visitedBlocks; std::set visitedBlocks1; + float blockCoverage = 0; class Timer { public: From e405a8823b3799e365324a0ad90ca46edb25683b Mon Sep 17 00:00:00 2001 From: sanghu Date: Wed, 31 Oct 2018 16:50:59 +0800 Subject: [PATCH 07/13] Adding the feature of halting the execution when BC% will be constant for 100 new states i.e. countFreq=100. --- lib/Core/Executor.cpp | 24 ++++++++++++++++-------- lib/Core/Executor.h | 1 + 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/lib/Core/Executor.cpp b/lib/Core/Executor.cpp index fe114eaf1..c7fa49dab 100644 --- a/lib/Core/Executor.cpp +++ b/lib/Core/Executor.cpp @@ -1490,14 +1490,18 @@ void Executor::transferToBasicBlock(BasicBlock *dst, BasicBlock *src, if((kf->function->getName() != "klee_div_zero_check") && (kf->function->getName()!= "klee_range") && (kf->function->getName() != "klee_int") && (kf->function->getName() != "klee_overshift_check") && (kf->function->getName() != "memcpy") && (kf->function->getName() != "memmove") && (kf->function->getName() != "mempcpy") && (kf->function->getName() != "memset")) { -// if(visitedBlocks.find(src) == visitedBlocks.end() && visitedBlocks.find(dst) == visitedBlocks.end()) count = 0; -// else count++; -// if(count == 100) {print_visitedBlocks; exit(0);} - + if(visitedBlocks.find(src) == visitedBlocks.end() && visitedBlocks.find(dst) == visitedBlocks.end()) + countFreq = 0; + else + countFreq++; visitedBlocks.insert(src); visitedBlocks.insert(dst); - } - std::ofstream outfile1; + + } + + if(countFreq <= 100) + { + std::ofstream outfile1; outfile1.open ("LogBlockCoverage.txt", std::ofstream::app); std::ofstream outfile2; outfile2.open ("record.dat", std::ofstream::app); @@ -1531,11 +1535,15 @@ void Executor::transferToBasicBlock(BasicBlock *dst, BasicBlock *src, outfile1 << "[" << buf << "," << "(" << visitedBlocks.size() << "," << allblockcount << "," << std::fixed << std::setprecision(2) << blockCoverage << "%)]" << "\n"; outfile2 << diff << " " << std::fixed << std::setprecision(2) << blockCoverage << "\n"; - } - else + return; + } + } + else { return; } + + } void Executor::printFileLine(ExecutionState &state, KInstruction *ki, diff --git a/lib/Core/Executor.h b/lib/Core/Executor.h index 368abb2fd..2c596fe78 100644 --- a/lib/Core/Executor.h +++ b/lib/Core/Executor.h @@ -97,6 +97,7 @@ class Executor : public Interpreter { std::set visitedBlocks; std::set visitedBlocks1; float blockCoverage = 0; + int countFreq = 0; class Timer { public: From 88bfedf3a03ca06a1e66316f51ceec053608e798 Mon Sep 17 00:00:00 2001 From: sanghu Date: Wed, 7 Nov 2018 13:25:31 +0800 Subject: [PATCH 08/13] Adding a predicate which executes distinct basic blocks to optimize the running time of TX. --- lib/Core/Executor.cpp | 99 ++++++++++++++++++++----------------------- 1 file changed, 47 insertions(+), 52 deletions(-) diff --git a/lib/Core/Executor.cpp b/lib/Core/Executor.cpp index c7fa49dab..017707ba4 100644 --- a/lib/Core/Executor.cpp +++ b/lib/Core/Executor.cpp @@ -1485,63 +1485,58 @@ void Executor::transferToBasicBlock(BasicBlock *dst, BasicBlock *src, TxTree::blockCount++; } - if(blockCoverage < 100.00) - { - - if((kf->function->getName() != "klee_div_zero_check") && (kf->function->getName()!= "klee_range") && (kf->function->getName() != "klee_int") && (kf->function->getName() != "klee_overshift_check") && (kf->function->getName() != "memcpy") && (kf->function->getName() != "memmove") && (kf->function->getName() != "mempcpy") && (kf->function->getName() != "memset")) +if(blockCoverage < 100.00) { - if(visitedBlocks.find(src) == visitedBlocks.end() && visitedBlocks.find(dst) == visitedBlocks.end()) - countFreq = 0; - else - countFreq++; - visitedBlocks.insert(src); - visitedBlocks.insert(dst); - - } - if(countFreq <= 100) - { - std::ofstream outfile1; - outfile1.open ("LogBlockCoverage.txt", std::ofstream::app); - std::ofstream outfile2; - outfile2.open ("record.dat", std::ofstream::app); - std::ofstream outfile3; - outfile3.open ("executedblocks.txt", std::ofstream::app); - - time_t now = time(0); - //time_t now3 = startingTime; - struct tm tstruct; - char buf[80]; - char buf1[80]; - tstruct = *localtime(&now); - - double diff; - diff = now - startingTime; - strftime(buf, sizeof(buf), "%T", &tstruct); - - blockCoverage = ((float)visitedBlocks.size() / (float)allblockcount) * 100; - - for (std::set::iterator it1 = visitedBlocks.begin(), ie1 = - visitedBlocks.end(); it1 != ie1; ++it1) { - outfile3 << "BlockScopeStarts: \n"; - std::string tmp = (*it1)->getParent()->getName(); - BasicBlock *b = (*it1); - std::string Str; - raw_string_ostream OS(Str); - b->print(OS); - outfile3 << "Function:" << tmp << Str <<"\n"; //This logic is to print function name and block name together - outfile3 << "BlockScopeEnds: " << "\n"; - } + if((kf->function->getName() != "klee_div_zero_check") && (kf->function->getName()!= "klee_range") && (kf->function->getName() != "klee_int") && (kf->function->getName() != "klee_overshift_check") && (kf->function->getName() != "memcpy") && (kf->function->getName() != "memmove") && (kf->function->getName() != "mempcpy") && (kf->function->getName() != "memset")) + { + if(visitedBlocks.find(src) == visitedBlocks.end() || visitedBlocks.find(dst) == visitedBlocks.end()) + { + visitedBlocks.insert(src); + visitedBlocks.insert(dst); + std::ofstream outfile1; + outfile1.open ("LogBlockCoverage.txt", std::ofstream::app); + std::ofstream outfile2; + outfile2.open ("record.dat", std::ofstream::app); + std::ofstream outfile3; + outfile3.open ("executedblocks.txt", std::ofstream::app); + + time_t now = time(0); + //time_t now3 = startingTime; + struct tm tstruct; + char buf[80]; + char buf1[80]; + tstruct = *localtime(&now); + + double diff; + diff = now - startingTime; + strftime(buf, sizeof(buf), "%T", &tstruct); + + blockCoverage = ((float)visitedBlocks.size() / (float)allblockcount) * 100; + + for (std::set::iterator it1 = visitedBlocks.begin(), ie1 = + visitedBlocks.end(); it1 != ie1; ++it1) { + outfile3 << "BlockScopeStarts: \n"; + std::string tmp = (*it1)->getParent()->getName(); + BasicBlock *b = (*it1); + std::string Str; + raw_string_ostream OS(Str); + b->print(OS); + outfile3 << "Function:" << tmp << Str <<"\n"; //This logic is to print function name and block name together + outfile3 << "BlockScopeEnds: " << "\n"; + } outfile1 << "[" << buf << "," << "(" << visitedBlocks.size() << "," << allblockcount << "," << std::fixed << std::setprecision(2) << blockCoverage << "%)]" << "\n"; outfile2 << diff << " " << std::fixed << std::setprecision(2) << blockCoverage << "\n"; + } + } +} + else + { + haltExecution = true; + } + + - return; - } - } - else - { - return; - } } From 7c74ff6ab1a5ac5f8467e968d23b25ead814a22d Mon Sep 17 00:00:00 2001 From: rasoolmaghareh Date: Thu, 8 Nov 2018 10:32:38 +0800 Subject: [PATCH 09/13] Fixing formatting --- lib/Core/Executor.cpp | 127 ++++++++++++++++++++++-------------------- lib/Core/Executor.h | 1 - 2 files changed, 67 insertions(+), 61 deletions(-) diff --git a/lib/Core/Executor.cpp b/lib/Core/Executor.cpp index 017707ba4..dd935e866 100644 --- a/lib/Core/Executor.cpp +++ b/lib/Core/Executor.cpp @@ -1458,7 +1458,7 @@ void Executor::executeCall(ExecutionState &state, } } -void Executor::transferToBasicBlock(BasicBlock *dst, BasicBlock *src, +void Executor::transferToBasicBlock(BasicBlock *dst, BasicBlock *src, ExecutionState &state) { // Note that in general phi nodes can reuse phi values from the same // block but the incoming value is the eval() result *before* the @@ -1471,74 +1471,81 @@ void Executor::transferToBasicBlock(BasicBlock *dst, BasicBlock *src, // // With that done we simply set an index in the state so that PHI // instructions know which argument to eval, set the pc, and continue. - + // XXX this lookup has to go ? KFunction *kf = state.stack.back().kf; unsigned entry = kf->basicBlockEntry[dst]; state.pc = &kf->instructions[entry]; if (state.pc->inst->getOpcode() == Instruction::PHI) { - PHINode *first = static_cast(state.pc->inst); + PHINode *first = static_cast(state.pc->inst); state.incomingBBIndex = first->getBasicBlockIndex(src); } - if (INTERPOLATION_ENABLED){ + if (INTERPOLATION_ENABLED) { // blockCount increased to count all visited Basic Blocks - TxTree::blockCount++; - } - -if(blockCoverage < 100.00) - { - - if((kf->function->getName() != "klee_div_zero_check") && (kf->function->getName()!= "klee_range") && (kf->function->getName() != "klee_int") && (kf->function->getName() != "klee_overshift_check") && (kf->function->getName() != "memcpy") && (kf->function->getName() != "memmove") && (kf->function->getName() != "mempcpy") && (kf->function->getName() != "memset")) - { - if(visitedBlocks.find(src) == visitedBlocks.end() || visitedBlocks.find(dst) == visitedBlocks.end()) - { - visitedBlocks.insert(src); - visitedBlocks.insert(dst); - std::ofstream outfile1; - outfile1.open ("LogBlockCoverage.txt", std::ofstream::app); - std::ofstream outfile2; - outfile2.open ("record.dat", std::ofstream::app); - std::ofstream outfile3; - outfile3.open ("executedblocks.txt", std::ofstream::app); - - time_t now = time(0); - //time_t now3 = startingTime; - struct tm tstruct; - char buf[80]; - char buf1[80]; - tstruct = *localtime(&now); - - double diff; - diff = now - startingTime; - strftime(buf, sizeof(buf), "%T", &tstruct); - - blockCoverage = ((float)visitedBlocks.size() / (float)allblockcount) * 100; - - for (std::set::iterator it1 = visitedBlocks.begin(), ie1 = - visitedBlocks.end(); it1 != ie1; ++it1) { - outfile3 << "BlockScopeStarts: \n"; - std::string tmp = (*it1)->getParent()->getName(); - BasicBlock *b = (*it1); - std::string Str; - raw_string_ostream OS(Str); - b->print(OS); - outfile3 << "Function:" << tmp << Str <<"\n"; //This logic is to print function name and block name together - outfile3 << "BlockScopeEnds: " << "\n"; - } - outfile1 << "[" << buf << "," << "(" << visitedBlocks.size() << "," << allblockcount << "," << std::fixed << std::setprecision(2) << blockCoverage << "%)]" << "\n"; - outfile2 << diff << " " << std::fixed << std::setprecision(2) << blockCoverage << "\n"; - } - } -} - else - { - haltExecution = true; - } - - - - + TxTree::blockCount++; + } + if (blockCoverage < 100.00) { + + if ((kf->function->getName() != "klee_div_zero_check") && + (kf->function->getName() != "klee_range") && + (kf->function->getName() != "klee_int") && + (kf->function->getName() != "klee_overshift_check") && + (kf->function->getName() != "memcpy") && + (kf->function->getName() != "memmove") && + (kf->function->getName() != "mempcpy") && + (kf->function->getName() != "memset")) { + if (visitedBlocks.find(src) == visitedBlocks.end() || + visitedBlocks.find(dst) == visitedBlocks.end()) { + visitedBlocks.insert(src); + visitedBlocks.insert(dst); + std::ofstream outfile1; + outfile1.open("LogBlockCoverage.txt", std::ofstream::app); + std::ofstream outfile2; + outfile2.open("record.dat", std::ofstream::app); + std::ofstream outfile3; + outfile3.open("executedblocks.txt", std::ofstream::app); + + time_t now = time(0); + // time_t now3 = startingTime; + struct tm tstruct; + char buf[80]; + char buf1[80]; + tstruct = *localtime(&now); + + double diff; + diff = now - startingTime; + strftime(buf, sizeof(buf), "%T", &tstruct); + + blockCoverage = + ((float)visitedBlocks.size() / (float)allblockcount) * 100; + + for (std::set::iterator it1 = visitedBlocks.begin(), + ie1 = visitedBlocks.end(); + it1 != ie1; ++it1) { + outfile3 << "BlockScopeStarts: \n"; + std::string tmp = (*it1)->getParent()->getName(); + BasicBlock *b = (*it1); + std::string Str; + raw_string_ostream OS(Str); + b->print(OS); + outfile3 << "Function:" << tmp << Str + << "\n"; // This logic is to print function name and block + // name together + outfile3 << "BlockScopeEnds: " + << "\n"; + } + outfile1 << "[" << buf << "," + << "(" << visitedBlocks.size() << "," << allblockcount << "," + << std::fixed << std::setprecision(2) << blockCoverage << "%)]" + << "\n"; + outfile2 << diff << " " << std::fixed << std::setprecision(2) + << blockCoverage << "\n"; + } + } + } else { + haltExecution = true; + } } void Executor::printFileLine(ExecutionState &state, KInstruction *ki, diff --git a/lib/Core/Executor.h b/lib/Core/Executor.h index 2c596fe78..794a6863e 100644 --- a/lib/Core/Executor.h +++ b/lib/Core/Executor.h @@ -95,7 +95,6 @@ class Executor : public Interpreter { time_t startingTime; int allblockcount; std::set visitedBlocks; - std::set visitedBlocks1; float blockCoverage = 0; int countFreq = 0; From 376ea239776205f7356fe43e43e7153b3144fc9c Mon Sep 17 00:00:00 2001 From: rasoolmaghareh Date: Thu, 8 Nov 2018 10:53:17 +0800 Subject: [PATCH 10/13] Halting if new BB is not seen in 200 tries --- lib/Core/Executor.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/Core/Executor.cpp b/lib/Core/Executor.cpp index dd935e866..e64fa81ac 100644 --- a/lib/Core/Executor.cpp +++ b/lib/Core/Executor.cpp @@ -1485,7 +1485,7 @@ void Executor::transferToBasicBlock(BasicBlock *dst, BasicBlock *src, TxTree::blockCount++; } - if (blockCoverage < 100.00) { + if (blockCoverage < 100.00 && countFreq <= 200) { if ((kf->function->getName() != "klee_div_zero_check") && (kf->function->getName() != "klee_range") && @@ -1497,6 +1497,7 @@ void Executor::transferToBasicBlock(BasicBlock *dst, BasicBlock *src, (kf->function->getName() != "memset")) { if (visitedBlocks.find(src) == visitedBlocks.end() || visitedBlocks.find(dst) == visitedBlocks.end()) { + countFreq = 0; visitedBlocks.insert(src); visitedBlocks.insert(dst); std::ofstream outfile1; @@ -1541,6 +1542,8 @@ void Executor::transferToBasicBlock(BasicBlock *dst, BasicBlock *src, << "\n"; outfile2 << diff << " " << std::fixed << std::setprecision(2) << blockCoverage << "\n"; + } else { + countFreq++; } } } else { From be386f33059b3af0412ba253c1fe081376b5f7a2 Mon Sep 17 00:00:00 2001 From: sanghu Date: Sat, 10 Nov 2018 16:23:57 +0800 Subject: [PATCH 11/13] Removing the Library BBs --- include/klee/Interpreter.h | 1 + lib/Core/Executor.cpp | 170 ++++++++++++++++++++++++------------- lib/Core/Executor.h | 7 +- tools/klee/main.cpp | 3 + 4 files changed, 120 insertions(+), 61 deletions(-) diff --git a/include/klee/Interpreter.h b/include/klee/Interpreter.h index e936de220..3a534326b 100644 --- a/include/klee/Interpreter.h +++ b/include/klee/Interpreter.h @@ -66,6 +66,7 @@ class InterpreterHandler { class Interpreter { public: + std::string InputFile; /// ModuleOptions - Module level options which can be set when /// registering a module with the interpreter. struct ModuleOptions { diff --git a/lib/Core/Executor.cpp b/lib/Core/Executor.cpp index e64fa81ac..d9343f986 100644 --- a/lib/Core/Executor.cpp +++ b/lib/Core/Executor.cpp @@ -338,6 +338,12 @@ Executor::Executor(const InterpreterOptions &opts, InterpreterHandler *ih) : std::max(MaxCoreSolverTime, MaxInstructionTime)), debugInstFile(0), debugLogBuffer(debugBufferString) { + // Coverage Counters + allBlockCount = 0; + allBlockCollected = false; + blockCoverage = 0; + countFreq = 0; + if (coreSolverTimeout) UseForkedCoreSolver = true; Solver *coreSolver = klee::createCoreSolver(CoreSolverToUse); if (!coreSolver) { @@ -1485,16 +1491,74 @@ void Executor::transferToBasicBlock(BasicBlock *dst, BasicBlock *src, TxTree::blockCount++; } - if (blockCoverage < 100.00 && countFreq <= 200) { - - if ((kf->function->getName() != "klee_div_zero_check") && + //llvm::errs() << "InputFile" << InputFile; + + size_t lastindex = InputFile.find_last_of("."); + std::string InputFile1 = InputFile.substr(0, lastindex); + std::string InputFile2 = InputFile1 + ".c"; + if (!allBlockCollected) { + allBlockCollected = true; + llvm::errs() << "************All Blocks Start****************" << "\n"; + + for (std::map::iterator it = + kmodule->functionMap.begin(), ie = kmodule->functionMap.end(); + it != ie; ++it) { + Function *tmpF = it->first; + KFunction *tmpKF = it->second; + KInstruction *tmpIns = tmpKF->instructions[0]; + const std::string path = tmpIns->info->file; + std::size_t botDirPos = path.find_last_of("/"); + std::string file = path.substr(botDirPos+1, path.length()); + //llvm::errs() << "Filename ===>" << file << "\n"; + + if (file == InputFile2) { + //This logic is to eliminates klee's extra checks to dump in files +// if ((tmpF->getName() != "klee_div_zero_check") +// && (tmpF->getName() != "klee_range") +// && (tmpF->getName() != "klee_int") +// && (tmpF->getName() != "klee_overshift_check") +// && (tmpF->getName() != "memcpy") +// && (tmpF->getName() != "memmove") +// && (tmpF->getName() != "mempcpy") +// && (tmpF->getName() != "memset")) + + for (llvm::Function::iterator b = tmpF->begin(); + b != tmpF->end(); ++b) { //Uncomment later for rem. lib BB + + llvm::errs() << "BlockScopeStarts: " << "\n"; + allBlockCount++; + llvm::errs() << "Block Number: " << allBlockCount << "\n"; + llvm::errs() << "Function:" << (*b->getParent()).getName(); //This logic is to print function name and block name together + (*b).dump(); + llvm::errs() << "BlockScopeEnds: " << "\n"; + } + } + startingTime = time(0); + } + + llvm::errs() << "************All Blocks End****************" << "\n"; + } + + Instruction * lastInst; + const InstructionInfo &ii = getLastNonKleeInternalInstruction(state, &lastInst); + const std::string path = ii.file; + std::size_t botDirPos = path.find_last_of("/"); + std::string file = path.substr(botDirPos+1, path.length()); + //llvm::errs() << "Filename ===>" << file << "\n"; + + + if (blockCoverage < 100.00) { // && countFreq <= 200 + + /*if ((kf->function->getName() != "klee_div_zero_check") && (kf->function->getName() != "klee_range") && (kf->function->getName() != "klee_int") && (kf->function->getName() != "klee_overshift_check") && (kf->function->getName() != "memcpy") && (kf->function->getName() != "memmove") && (kf->function->getName() != "mempcpy") && - (kf->function->getName() != "memset")) { + (kf->function->getName() != "memset"))*/ + if(file == InputFile2) + { if (visitedBlocks.find(src) == visitedBlocks.end() || visitedBlocks.find(dst) == visitedBlocks.end()) { countFreq = 0; @@ -1507,6 +1571,7 @@ void Executor::transferToBasicBlock(BasicBlock *dst, BasicBlock *src, std::ofstream outfile3; outfile3.open("executedblocks.txt", std::ofstream::app); + time_t now = time(0); // time_t now3 = startingTime; struct tm tstruct; @@ -1519,7 +1584,7 @@ void Executor::transferToBasicBlock(BasicBlock *dst, BasicBlock *src, strftime(buf, sizeof(buf), "%T", &tstruct); blockCoverage = - ((float)visitedBlocks.size() / (float)allblockcount) * 100; + ((float)visitedBlocks.size() / (float)allBlockCount) * 100; for (std::set::iterator it1 = visitedBlocks.begin(), ie1 = visitedBlocks.end(); @@ -1537,7 +1602,7 @@ void Executor::transferToBasicBlock(BasicBlock *dst, BasicBlock *src, << "\n"; } outfile1 << "[" << buf << "," - << "(" << visitedBlocks.size() << "," << allblockcount << "," + << "(" << visitedBlocks.size() << "," << allBlockCount << "," << std::fixed << std::setprecision(2) << blockCoverage << "%)]" << "\n"; outfile2 << diff << " " << std::fixed << std::setprecision(2) @@ -3150,9 +3215,43 @@ void Executor::run(ExecutionState &initialState) { } #endif + if (INTERPOLATION_ENABLED && txTree->subsumptionCheck(solver, state, coreSolverTimeout)) { - terminateStateOnSubsumption(state); + //print basic blocks + +// llvm::errs() << "**********Intermeditate Check Visited Blocks starts********* " << "\n"; +// //KFunction *kf = state.stack.back().kf; +// +// for (std::map::iterator it = +// kmodule->functionMap.begin(), ie = kmodule->functionMap.end(); +// it != ie; ++it) { +// Function *tmpF = it->first; +// for (llvm::Function::iterator b = tmpF->begin(); +// b != tmpF->end(); ++b) { //Uncomment later for rem. lib BB +// llvm::errs() << "BlockScopeStarts: " << "\n"; +// llvm::errs() << "Function:" << (*b->getParent()).getName(); //This logic is to print function name and block name together +// (*b).dump(); +// llvm::errs() << "BlockScopeEnds: " << "\n"; +// } +// } +// llvm::errs() << "**********Intermeditate Check Visited Blocks ends********* " << "\n"; + + /*llvm::errs() << "**********Intermeditate Check Visited Blocks starts********* " << "\n"; + KFunction *kf = state.stack.back().kf; + + for (llvm::Function::iterator b = kf->function->begin(); + b != kf->function->end(); ++b) { //Uncomment later for rem. lib BB + llvm::errs() << "BlockScopeStarts: " << "\n"; + llvm::errs() << "Function:" << (*b->getParent()).getName(); //This logic is to print function name and block name together + (*b).dump(); + llvm::errs() << "BlockScopeEnds: " << "\n"; + } + llvm::errs() << "**********Intermeditate Check Visited Blocks ends********* " << "\n";*/ + terminateStateOnSubsumption(state); + + + } else { KInstruction *ki = state.pc; @@ -4037,54 +4136,7 @@ void Executor::runFunctionAsMain(Function *f, assert(kf); //Logic to dump all Branch and ret instructions //int allblockcount = 0; - allblockcount = 0; - llvm::errs() << "************All Blocks Start****************" << "\n"; - - // llvm::errs() << kf << "\n"; - //kf->dump(); - - for (std::map::iterator it= kmodule->functionMap.begin(),ie=kmodule->functionMap.end(); - it!=ie;++it) { - - - Function *tmpF = it->first; - //This logic is to eliminates klee's extra checks to dump in files - if((tmpF->getName() != "klee_div_zero_check") && (tmpF->getName() != "klee_range") && (tmpF->getName() != "klee_int") && (tmpF->getName() != "klee_overshift_check") && (tmpF->getName() != "memcpy") && (tmpF->getName() != "memmove") && (tmpF->getName() != "mempcpy") && (tmpF->getName() != "memset")) - { - for (llvm::Function::iterator b = tmpF->begin(); b != tmpF->end(); ++b) { - - /*for (llvm::BasicBlock::iterator ins = b->begin(); ins != b->end(); - ++ins) { - if (llvm::isa(ins) || llvm::isa(ins)) { - allblockcount++; - llvm::errs() << "All Block count: " << allblockcount << "\n"; - llvm::errs() << *ins << "\n"; - } - }*/ - //tmpF->dump(); - - - llvm::errs() << "BlockScopeStarts: " << "\n"; - allblockcount++; - llvm::errs() << "Block Number: " << allblockcount << "\n"; - llvm::errs() <<"Function:"<< (*b->getParent()).getName(); //This logic is to print function name and block name together - (*b).dump(); - llvm::errs() << "BlockScopeEnds: " << "\n"; - } - - //it->first->dump(); //Uncomment it to dump all blocks - - } - - startingTime = time(0); - - - } - - - - llvm::errs() << "************All Blocks End****************" << "\n"; Function::arg_iterator ai = f->arg_begin(), ae = f->arg_end(); if (ai!=ae) { @@ -4176,6 +4228,7 @@ void Executor::runFunctionAsMain(Function *f, #endif } + llvm::outs() << "Total number executed Basic Blocks at least once: " << visitedBlocks.size() << "\n"; llvm::outs() << "**************\n"; //dst->back().dump(); @@ -4184,8 +4237,8 @@ void Executor::runFunctionAsMain(Function *f, for (std::set::iterator it = visitedBlocks.begin(), ie=visitedBlocks.end(); it!=ie;++it ) { - if(( ((*it)->getParent())->getName()!= "klee_div_zero_check") && (((*it)->getParent())->getName() != "klee_range") && (((*it)->getParent())->getName() != "klee_int") && (((*it)->getParent())->getName() != "klee_overshift_check") && (((*it)->getParent())->getName() != "memcpy") && (((*it)->getParent())->getName() != "memmove") && (((*it)->getParent())->getName() != "mempcpy") && (((*it)->getParent())->getName() != "memset")) - { + //if(( ((*it)->getParent())->getName()!= "klee_div_zero_check") && (((*it)->getParent())->getName() != "klee_range") && (((*it)->getParent())->getName() != "klee_int") && (((*it)->getParent())->getName() != "klee_overshift_check") && (((*it)->getParent())->getName() != "memcpy") && (((*it)->getParent())->getName() != "memmove") && (((*it)->getParent())->getName() != "mempcpy") && (((*it)->getParent())->getName() != "memset")) + { llvm::errs() << "BlockScopeStarts: " << "\n"; (*it)->getParent()->getName(); //llvm::errs() <<";"<< (*BB.getParent()).getName(); @@ -4195,9 +4248,10 @@ void Executor::runFunctionAsMain(Function *f, //kf->function->dump(); //(*it)->back().dump(); //print only branch instructions - } + } } - llvm::errs() << "************Visited Blocks Ends****************" << "\n"; + llvm::errs() << "************Visited Basic Blocks Count:" << visitedBlocks.size() << "\n"; + llvm::errs() << "************Visited Blocks Ends****************" << "\n"; // std::ofstream outfile; diff --git a/lib/Core/Executor.h b/lib/Core/Executor.h index 794a6863e..8f041b357 100644 --- a/lib/Core/Executor.h +++ b/lib/Core/Executor.h @@ -93,10 +93,11 @@ class Executor : public Interpreter { public: time_t startingTime; - int allblockcount; + int allBlockCount; + bool allBlockCollected; std::set visitedBlocks; - float blockCoverage = 0; - int countFreq = 0; + float blockCoverage; + int countFreq; class Timer { public: diff --git a/tools/klee/main.cpp b/tools/klee/main.cpp index 65371f8b2..6297e2cf8 100644 --- a/tools/klee/main.cpp +++ b/tools/klee/main.cpp @@ -1586,6 +1586,7 @@ int main(int argc, char **argv, char **envp) { << " bytes)" << " (" << ++i << "/" << kTestFiles.size() << ")\n"; // XXX should put envp in .ktest ? + interpreter->runFunctionAsMain(mainFn, out->numArgs, out->args, pEnvp); if (interrupted) break; @@ -1636,6 +1637,8 @@ int main(int argc, char **argv, char **envp) { sys::StrError(errno).c_str()); } } + llvm::errs() << "****Input File = " <InputFile = InputFile; interpreter->runFunctionAsMain(mainFn, pArgc, pArgv, pEnvp); while (!seeds.empty()) { From 0d6aeed72df0fd75fe4b00ca729468212351390d Mon Sep 17 00:00:00 2001 From: sanghu Date: Thu, 15 Nov 2018 17:34:58 +0800 Subject: [PATCH 12/13] Excluding the 100% Block Coverage Clause --- lib/Core/Executor.cpp | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/lib/Core/Executor.cpp b/lib/Core/Executor.cpp index d9343f986..1dab1669f 100644 --- a/lib/Core/Executor.cpp +++ b/lib/Core/Executor.cpp @@ -1497,7 +1497,7 @@ void Executor::transferToBasicBlock(BasicBlock *dst, BasicBlock *src, std::string InputFile1 = InputFile.substr(0, lastindex); std::string InputFile2 = InputFile1 + ".c"; if (!allBlockCollected) { - allBlockCollected = true; + allBlockCollected = true; llvm::errs() << "************All Blocks Start****************" << "\n"; for (std::map::iterator it = @@ -1521,10 +1521,11 @@ void Executor::transferToBasicBlock(BasicBlock *dst, BasicBlock *src, // && (tmpF->getName() != "memmove") // && (tmpF->getName() != "mempcpy") // && (tmpF->getName() != "memset")) - + //if(tmpF->getName() != "usage") //added to block usage function + { for (llvm::Function::iterator b = tmpF->begin(); b != tmpF->end(); ++b) { //Uncomment later for rem. lib BB - + llvm::errs() << "BlockScopeStarts: " << "\n"; allBlockCount++; llvm::errs() << "Block Number: " << allBlockCount << "\n"; @@ -1532,6 +1533,7 @@ void Executor::transferToBasicBlock(BasicBlock *dst, BasicBlock *src, (*b).dump(); llvm::errs() << "BlockScopeEnds: " << "\n"; } + } } startingTime = time(0); } @@ -1547,7 +1549,7 @@ void Executor::transferToBasicBlock(BasicBlock *dst, BasicBlock *src, //llvm::errs() << "Filename ===>" << file << "\n"; - if (blockCoverage < 100.00) { // && countFreq <= 200 + //if (blockCoverage < 100.00) { // && countFreq <= 200 /*if ((kf->function->getName() != "klee_div_zero_check") && (kf->function->getName() != "klee_range") && @@ -1557,8 +1559,11 @@ void Executor::transferToBasicBlock(BasicBlock *dst, BasicBlock *src, (kf->function->getName() != "memmove") && (kf->function->getName() != "mempcpy") && (kf->function->getName() != "memset"))*/ + if(file == InputFile2) { + //if(kf->function->getName() != "usage") //added to block usage function + { if (visitedBlocks.find(src) == visitedBlocks.end() || visitedBlocks.find(dst) == visitedBlocks.end()) { countFreq = 0; @@ -1601,6 +1606,8 @@ void Executor::transferToBasicBlock(BasicBlock *dst, BasicBlock *src, outfile3 << "BlockScopeEnds: " << "\n"; } + + klee_warning("Visited Blocks Up to now=========================:%d\n",visitedBlocks.size()); outfile1 << "[" << buf << "," << "(" << visitedBlocks.size() << "," << allBlockCount << "," << std::fixed << std::setprecision(2) << blockCoverage << "%)]" @@ -1611,8 +1618,9 @@ void Executor::transferToBasicBlock(BasicBlock *dst, BasicBlock *src, countFreq++; } } - } else { + /* } else { haltExecution = true; + }*/ } } @@ -4238,7 +4246,8 @@ void Executor::runFunctionAsMain(Function *f, for (std::set::iterator it = visitedBlocks.begin(), ie=visitedBlocks.end(); it!=ie;++it ) { //if(( ((*it)->getParent())->getName()!= "klee_div_zero_check") && (((*it)->getParent())->getName() != "klee_range") && (((*it)->getParent())->getName() != "klee_int") && (((*it)->getParent())->getName() != "klee_overshift_check") && (((*it)->getParent())->getName() != "memcpy") && (((*it)->getParent())->getName() != "memmove") && (((*it)->getParent())->getName() != "mempcpy") && (((*it)->getParent())->getName() != "memset")) - { + //if(((*it)->getParent())->getName()!= "usage") //added to block usage function + { llvm::errs() << "BlockScopeStarts: " << "\n"; (*it)->getParent()->getName(); //llvm::errs() <<";"<< (*BB.getParent()).getName(); From 2d0c28d3348e339e89401c43d0466dc041b1c7e3 Mon Sep 17 00:00:00 2001 From: sanghu Date: Tue, 20 Nov 2018 14:02:14 +0800 Subject: [PATCH 13/13] Writing BB coverage information into info file, Writing AllBB.txt, FinallyBB.txt, VisitedBB.txt, GraphBBC.dat, and LogBBC.txt into klee-out folder. --- lib/Core/Executor.cpp | 268 +++++++++++++++++------------------------- tools/klee/main.cpp | 2 + 2 files changed, 108 insertions(+), 162 deletions(-) diff --git a/lib/Core/Executor.cpp b/lib/Core/Executor.cpp index 1dab1669f..b1db64576 100644 --- a/lib/Core/Executor.cpp +++ b/lib/Core/Executor.cpp @@ -1490,9 +1490,6 @@ void Executor::transferToBasicBlock(BasicBlock *dst, BasicBlock *src, // blockCount increased to count all visited Basic Blocks TxTree::blockCount++; } - - //llvm::errs() << "InputFile" << InputFile; - size_t lastindex = InputFile.find_last_of("."); std::string InputFile1 = InputFile.substr(0, lastindex); std::string InputFile2 = InputFile1 + ".c"; @@ -1509,31 +1506,39 @@ void Executor::transferToBasicBlock(BasicBlock *dst, BasicBlock *src, const std::string path = tmpIns->info->file; std::size_t botDirPos = path.find_last_of("/"); std::string file = path.substr(botDirPos+1, path.length()); - //llvm::errs() << "Filename ===>" << file << "\n"; - + std::string outfile4 = interpreterHandler->getOutputFilename("AllBB.txt"); + if ((klee_message_file = fopen(outfile4.c_str(), "a+")) == NULL) + klee_error("cannot open file \"%s\": %s", outfile4.c_str(), + strerror(errno)); if (file == InputFile2) { - //This logic is to eliminates klee's extra checks to dump in files -// if ((tmpF->getName() != "klee_div_zero_check") -// && (tmpF->getName() != "klee_range") -// && (tmpF->getName() != "klee_int") -// && (tmpF->getName() != "klee_overshift_check") -// && (tmpF->getName() != "memcpy") -// && (tmpF->getName() != "memmove") -// && (tmpF->getName() != "mempcpy") -// && (tmpF->getName() != "memset")) - //if(tmpF->getName() != "usage") //added to block usage function - { + if ((tmpF->getName() != "klee_div_zero_check") + && (tmpF->getName() != "klee_range") + && (tmpF->getName() != "klee_int") + && (tmpF->getName() != "klee_overshift_check") + && (tmpF->getName() != "memcpy") + && (tmpF->getName() != "memmove") + && (tmpF->getName() != "mempcpy") + && (tmpF->getName() != "memset")){ for (llvm::Function::iterator b = tmpF->begin(); - b != tmpF->end(); ++b) { //Uncomment later for rem. lib BB - - llvm::errs() << "BlockScopeStarts: " << "\n"; - allBlockCount++; - llvm::errs() << "Block Number: " << allBlockCount << "\n"; - llvm::errs() << "Function:" << (*b->getParent()).getName(); //This logic is to print function name and block name together - (*b).dump(); - llvm::errs() << "BlockScopeEnds: " << "\n"; + b != tmpF->end(); ++b) { + std::string g4(outfile4.c_str()); + std::ofstream out4(outfile4.c_str(),std::ofstream::app); + if (!out4.fail()) { + out4 << "BlockScopeStarts: \n"; + allBlockCount++; + out4 << "Block Number: " << allBlockCount << "\n"; + std::string tmp1 = (*b->getParent()).getName(); + std::string Str1; + raw_string_ostream OS(Str1); + b->print(OS); + out4 << "Function:" << tmp1 << Str1 + << "\n"; + out4 << "BlockScopeEnds: " + << "\n"; + out4.close(); + } } - } + } } startingTime = time(0); } @@ -1546,44 +1551,38 @@ void Executor::transferToBasicBlock(BasicBlock *dst, BasicBlock *src, const std::string path = ii.file; std::size_t botDirPos = path.find_last_of("/"); std::string file = path.substr(botDirPos+1, path.length()); - //llvm::errs() << "Filename ===>" << file << "\n"; - - - //if (blockCoverage < 100.00) { // && countFreq <= 200 - - /*if ((kf->function->getName() != "klee_div_zero_check") && - (kf->function->getName() != "klee_range") && - (kf->function->getName() != "klee_int") && - (kf->function->getName() != "klee_overshift_check") && - (kf->function->getName() != "memcpy") && - (kf->function->getName() != "memmove") && - (kf->function->getName() != "mempcpy") && - (kf->function->getName() != "memset"))*/ - - if(file == InputFile2) + if(file == InputFile2) { - //if(kf->function->getName() != "usage") //added to block usage function - { + if ((kf->function->getName() != "klee_div_zero_check") && + (kf->function->getName() != "klee_range") && + (kf->function->getName() != "klee_int") && + (kf->function->getName() != "klee_overshift_check") && + (kf->function->getName() != "memcpy") && + (kf->function->getName() != "memmove") && + (kf->function->getName() != "mempcpy") && + (kf->function->getName() != "memset")){ if (visitedBlocks.find(src) == visitedBlocks.end() || visitedBlocks.find(dst) == visitedBlocks.end()) { countFreq = 0; visitedBlocks.insert(src); visitedBlocks.insert(dst); - std::ofstream outfile1; - outfile1.open("LogBlockCoverage.txt", std::ofstream::app); - std::ofstream outfile2; - outfile2.open("record.dat", std::ofstream::app); - std::ofstream outfile3; - outfile3.open("executedblocks.txt", std::ofstream::app); - - + std::string outfile1 = interpreterHandler->getOutputFilename("LogBBC.txt"); + if ((klee_message_file = fopen(outfile1.c_str(), "a+")) == NULL) + klee_error("cannot open file \"%s\": %s", outfile1.c_str(), + strerror(errno)); + std::string outfile2 = interpreterHandler->getOutputFilename("GraphBBC.dat"); + if ((klee_message_file = fopen(outfile2.c_str(), "a+")) == NULL) + klee_error("cannot open file \"%s\": %s", outfile2.c_str(), + strerror(errno)); + std::string outfile3 = interpreterHandler->getOutputFilename("VisitedBB.txt"); + if ((klee_message_file = fopen(outfile3.c_str(), "a+")) == NULL) + klee_error("cannot open file \"%s\": %s", outfile3.c_str(), + strerror(errno)); time_t now = time(0); - // time_t now3 = startingTime; struct tm tstruct; char buf[80]; char buf1[80]; tstruct = *localtime(&now); - double diff; diff = now - startingTime; strftime(buf, sizeof(buf), "%T", &tstruct); @@ -1594,33 +1593,46 @@ void Executor::transferToBasicBlock(BasicBlock *dst, BasicBlock *src, for (std::set::iterator it1 = visitedBlocks.begin(), ie1 = visitedBlocks.end(); it1 != ie1; ++it1) { - outfile3 << "BlockScopeStarts: \n"; + std::string g3(outfile3.c_str()); + std::ofstream out3(outfile3.c_str(),std::ofstream::app); + if (!out3.fail()) { + std::string tmp = (*it1)->getParent()->getName(); BasicBlock *b = (*it1); std::string Str; raw_string_ostream OS(Str); b->print(OS); - outfile3 << "Function:" << tmp << Str - << "\n"; // This logic is to print function name and block - // name together - outfile3 << "BlockScopeEnds: " + out3 << "BlockScopeStarts: \n"; + out3 << "Function:" << tmp << Str << "\n"; + out3 << "BlockScopeEnds: " + << "\n"; + out3.close(); + + } + } - klee_warning("Visited Blocks Up to now=========================:%d\n",visitedBlocks.size()); - outfile1 << "[" << buf << "," - << "(" << visitedBlocks.size() << "," << allBlockCount << "," - << std::fixed << std::setprecision(2) << blockCoverage << "%)]" - << "\n"; - outfile2 << diff << " " << std::fixed << std::setprecision(2) - << blockCoverage << "\n"; - } else { - countFreq++; + klee_warning("Visited Blocks Up to now=========================: %d\n",visitedBlocks.size()); + std::string g1(outfile1.c_str()); + std::ofstream out1(outfile1.c_str(),std::ofstream::app); + if (!out1.fail()) { + out1 << "[" << buf << "," << "(" << visitedBlocks.size() << "," << allBlockCount << "," + << std::fixed << std::setprecision(2) << blockCoverage << "%)]" + << "\n"; + out1.close(); + } + std::string g2(outfile2.c_str()); + std::ofstream out2(outfile2.c_str(),std::ofstream::app); + if (!out2.fail()) { + + out2 << diff << " " << std::fixed << std::setprecision(2) + << blockCoverage << "\n"; + out2.close(); + + } } - } - /* } else { - haltExecution = true; - }*/ + } } } @@ -1718,8 +1730,6 @@ void Executor::executeInstruction(ExecutionState &state, KInstruction *ki) { statsTracker->framePopped(state); if (InvokeInst *ii = dyn_cast(caller)) { -// llvm::outs() << "******Linh-Sanghu**********\n"; -// ii->dump(); transferToBasicBlock(ii->getNormalDest(), caller->getParent(), state); } else { state.pc = kcaller; @@ -3226,40 +3236,7 @@ void Executor::run(ExecutionState &initialState) { if (INTERPOLATION_ENABLED && txTree->subsumptionCheck(solver, state, coreSolverTimeout)) { - //print basic blocks - -// llvm::errs() << "**********Intermeditate Check Visited Blocks starts********* " << "\n"; -// //KFunction *kf = state.stack.back().kf; -// -// for (std::map::iterator it = -// kmodule->functionMap.begin(), ie = kmodule->functionMap.end(); -// it != ie; ++it) { -// Function *tmpF = it->first; -// for (llvm::Function::iterator b = tmpF->begin(); -// b != tmpF->end(); ++b) { //Uncomment later for rem. lib BB -// llvm::errs() << "BlockScopeStarts: " << "\n"; -// llvm::errs() << "Function:" << (*b->getParent()).getName(); //This logic is to print function name and block name together -// (*b).dump(); -// llvm::errs() << "BlockScopeEnds: " << "\n"; -// } -// } -// llvm::errs() << "**********Intermeditate Check Visited Blocks ends********* " << "\n"; - - /*llvm::errs() << "**********Intermeditate Check Visited Blocks starts********* " << "\n"; - KFunction *kf = state.stack.back().kf; - - for (llvm::Function::iterator b = kf->function->begin(); - b != kf->function->end(); ++b) { //Uncomment later for rem. lib BB - llvm::errs() << "BlockScopeStarts: " << "\n"; - llvm::errs() << "Function:" << (*b->getParent()).getName(); //This logic is to print function name and block name together - (*b).dump(); - llvm::errs() << "BlockScopeEnds: " << "\n"; - } - llvm::errs() << "**********Intermeditate Check Visited Blocks ends********* " << "\n";*/ terminateStateOnSubsumption(state); - - - } else { KInstruction *ki = state.pc; @@ -4142,11 +4119,7 @@ void Executor::runFunctionAsMain(Function *f, unsigned NumPtrBytes = Context::get().getPointerWidth() / 8; KFunction *kf = kmodule->functionMap[f]; assert(kf); - //Logic to dump all Branch and ret instructions - //int allblockcount = 0; - - - Function::arg_iterator ai = f->arg_begin(), ae = f->arg_end(); + Function::arg_iterator ai = f->arg_begin(), ae = f->arg_end(); if (ai!=ae) { arguments.push_back(ConstantExpr::alloc(argc, Expr::Int32)); @@ -4236,66 +4209,36 @@ void Executor::runFunctionAsMain(Function *f, #endif } - - llvm::outs() << "Total number executed Basic Blocks at least once: " << visitedBlocks.size() << "\n"; - llvm::outs() << "**************\n"; - //dst->back().dump(); - + interpreterHandler->getInfoStream() << "KLEE: done: Total number of single time Visited Basic Blocks: " << visitedBlocks.size() <<"\n"; + interpreterHandler->getInfoStream() << "KLEE: done: Total number of Basic Blocks: " << allBlockCount <<"\n"; llvm::errs() << "************Visited Blocks Starts****************" << "\n"; + std::string outfile5 = interpreterHandler->getOutputFilename("FinallyBB.txt"); + if ((klee_message_file = fopen(outfile5.c_str(), "a+")) == NULL) + klee_error("cannot open file \"%s\": %s", outfile5.c_str(), + strerror(errno)); for (std::set::iterator it = visitedBlocks.begin(), ie=visitedBlocks.end(); it!=ie;++it ) { - //if(( ((*it)->getParent())->getName()!= "klee_div_zero_check") && (((*it)->getParent())->getName() != "klee_range") && (((*it)->getParent())->getName() != "klee_int") && (((*it)->getParent())->getName() != "klee_overshift_check") && (((*it)->getParent())->getName() != "memcpy") && (((*it)->getParent())->getName() != "memmove") && (((*it)->getParent())->getName() != "mempcpy") && (((*it)->getParent())->getName() != "memset")) - //if(((*it)->getParent())->getName()!= "usage") //added to block usage function - { - llvm::errs() << "BlockScopeStarts: " << "\n"; - (*it)->getParent()->getName(); - //llvm::errs() <<";"<< (*BB.getParent()).getName(); - llvm::errs() <<"Function:"<< ((*it)->getParent())->getName(); //This logic is to print function name and block name together - (*it)->dump(); //print whole visited blocks - llvm::errs() << "BlockScopeEnds: " << "\n"; - - //kf->function->dump(); - //(*it)->back().dump(); //print only branch instructions - } + std::string g5(outfile5.c_str()); + std::ofstream out5(outfile5.c_str(),std::ofstream::app); + if (!out5.fail()) { + out5 << "BlockScopeStarts: \n"; + std::string tmp2 = ((*it)->getParent())->getName(); + std::string Str2; + raw_string_ostream OS(Str2); + (*it)->print(OS); + out5 << "Function:" << tmp2 << Str2 + << "\n"; + out5 << "BlockScopeEnds: " + << "\n"; + out5.close(); + } } - llvm::errs() << "************Visited Basic Blocks Count:" << visitedBlocks.size() << "\n"; + llvm::errs() << "KLEE: done: Total number of single time Visited Basic Blocks: " << visitedBlocks.size() << "\n"; + llvm::errs() << "KLEE: done: Total number of Basic Blocks: " << allBlockCount <<"\n"; llvm::errs() << "************Visited Blocks Ends****************" << "\n"; -// std::ofstream outfile; -// outfile.open("Livecoverage.txt"); -// outfile << "Sanghu"; -// std::error_code OutErrorInfo; -// llvm::raw_fd_ostream() outFile(llvm::StringRef("Livecoverage.txt"), OutErrorInfo, llvm::sys::fs::F_None); -// -// outfile << "************Visited Blocks Starts****************" << "\n"; -// -// for (std::set::iterator it1 = visitedBlocks.begin(), ie1 = -// visitedBlocks.end(); it1 != ie1; ++it1) { -// outfile << "BlockScopeStarts: \n"; -//// (*it)->getParent()->getName(); -// //llvm::errs() <<";"<< (*BB.getParent()).getName(); -// std::string tmp = (*it1)->getParent()->getName(); -// outfile << "Function:" << tmp << "\n"; //This logic is to print function name and block name together -// //(*it)->dump(); //print whole visited blocks -// //std::string tmp1 = (*it); -//// outfile << (*it)->dump() << "\n"; -// outfile << "BlockScopeEnds: " << "\n"; -// -// //kf->function->dump(); -// //(*it)->back().dump(); //print only branch instructions -// } -// outfile << "************Visited Blocks Ends****************" << "\n"; - - //llvm::raw_ostream()* stream; - - - - - //llvm::outs() << "******function********\n"; - //f->dump(); - // hack to clear memory objects delete memory; memory = new MemoryManager(NULL); @@ -4307,6 +4250,7 @@ void Executor::runFunctionAsMain(Function *f, statsTracker->done(); } + unsigned Executor::getPathStreamID(const ExecutionState &state) { assert(pathWriter); return state.pathOS.getID(); diff --git a/tools/klee/main.cpp b/tools/klee/main.cpp index 6297e2cf8..62b799216 100644 --- a/tools/klee/main.cpp +++ b/tools/klee/main.cpp @@ -486,6 +486,8 @@ KleeHandler::KleeHandler(int argc, char **argv) // open info m_infoFile = openOutputFile("info"); + + } KleeHandler::~KleeHandler() {