Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DEP: Basic Block Coverage (no longer continued) #341

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions include/klee/Interpreter.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
198 changes: 191 additions & 7 deletions lib/Core/Executor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@
#include <vector>
#include <string>


#include <sys/mman.h>

#include <errno.h>
Expand Down Expand Up @@ -337,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) {
Expand Down Expand Up @@ -1457,7 +1464,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
Expand All @@ -1470,18 +1477,163 @@ 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<PHINode*>(state.pc->inst);
PHINode *first = static_cast<PHINode *>(state.pc->inst);
state.incomingBBIndex = first->getBasicBlockIndex(src);
}
if (INTERPOLATION_ENABLED)
if (INTERPOLATION_ENABLED) {
// blockCount increased to count all visited Basic Blocks
TxTree::blockCount++;
}
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<llvm::Function*, KFunction*>::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());
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) {
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) {
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);
}

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());
if(file == InputFile2)
{
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::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);
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<llvm::BasicBlock *>::iterator it1 = visitedBlocks.begin(),
ie1 = visitedBlocks.end();
it1 != ie1; ++it1) {
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);
out3 << "BlockScopeStarts: \n";
out3 << "Function:" << tmp << Str
<< "\n";
out3 << "BlockScopeEnds: "
<< "\n";
out3.close();

}

}

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();

}
}
}
}
}

void Executor::printFileLine(ExecutionState &state, KInstruction *ki,
Expand Down Expand Up @@ -1578,7 +1730,7 @@ void Executor::executeInstruction(ExecutionState &state, KInstruction *ki) {
statsTracker->framePopped(state);

if (InvokeInst *ii = dyn_cast<InvokeInst>(caller)) {
transferToBasicBlock(ii->getNormalDest(), caller->getParent(), state);
transferToBasicBlock(ii->getNormalDest(), caller->getParent(), state);
} else {
state.pc = kcaller;
++state.pc;
Expand Down Expand Up @@ -3081,9 +3233,10 @@ void Executor::run(ExecutionState &initialState) {
}
#endif


if (INTERPOLATION_ENABLED &&
txTree->subsumptionCheck(solver, state, coreSolverTimeout)) {
terminateStateOnSubsumption(state);
terminateStateOnSubsumption(state);
} else
{
KInstruction *ki = state.pc;
Expand Down Expand Up @@ -3966,7 +4119,7 @@ void Executor::runFunctionAsMain(Function *f,
unsigned NumPtrBytes = Context::get().getPointerWidth() / 8;
KFunction *kf = kmodule->functionMap[f];
assert(kf);
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));

Expand Down Expand Up @@ -4053,8 +4206,38 @@ void Executor::runFunctionAsMain(Function *f,
#ifdef ENABLE_Z3
// Print interpolation time statistics
interpreterHandler->assignSubsumptionStats(TxTree::getInterpolationStat());

#endif
}
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<llvm::BasicBlock*>::iterator it = visitedBlocks.begin(), ie=visitedBlocks.end(); it!=ie;++it
) {
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() << "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";


// hack to clear memory objects
delete memory;
Expand All @@ -4067,6 +4250,7 @@ void Executor::runFunctionAsMain(Function *f,
statsTracker->done();
}


unsigned Executor::getPathStreamID(const ExecutionState &state) {
assert(pathWriter);
return state.pathOS.getID();
Expand Down
9 changes: 8 additions & 1 deletion lib/Core/Executor.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 <vector>
Expand Down Expand Up @@ -92,6 +92,13 @@ class Executor : public Interpreter {
friend class StatsTracker;

public:
time_t startingTime;
int allBlockCount;
bool allBlockCollected;
std::set<llvm::BasicBlock*> visitedBlocks;
float blockCoverage;
int countFreq;

class Timer {
public:
Timer();
Expand Down
3 changes: 2 additions & 1 deletion lib/Module/KModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -466,7 +466,8 @@ void KModule::prepare(const Interpreter::ModuleOptions &opts,
llvm::errs() << "KLEE: escaping functions: [";
for (std::set<Function*>::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";
}
Expand Down
3 changes: 3 additions & 0 deletions lib/Module/LowerSwitch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading