main.cpp

Go to the documentation of this file.
00001 /* -*- mode: c++; c-basic-offset: 2; -*- */
00002 
00003 // FIXME: This does not belong here.
00004 #include "../lib/Core/Common.h"
00005 
00006 #include "klee/ExecutionState.h"
00007 #include "klee/Expr.h"
00008 #include "klee/Interpreter.h"
00009 #include "klee/Statistics.h"
00010 #include "klee/Config/config.h"
00011 #include "klee/Internal/ADT/KTest.h"
00012 #include "klee/Internal/ADT/TreeStream.h"
00013 #include "klee/Internal/Support/ModuleUtil.h"
00014 #include "klee/Internal/System/Time.h"
00015 
00016 #include "llvm/Constants.h"
00017 #include "llvm/Module.h"
00018 #include "llvm/ModuleProvider.h"
00019 #include "llvm/Type.h"
00020 #include "llvm/InstrTypes.h"
00021 #include "llvm/Instruction.h"
00022 #include "llvm/Instructions.h"
00023 #include "llvm/Bitcode/ReaderWriter.h"
00024 #include "llvm/Support/CommandLine.h"
00025 #include "llvm/Support/ManagedStatic.h"
00026 #include "llvm/Support/MemoryBuffer.h"
00027 #include "llvm/System/Signals.h"
00028 #include <iostream>
00029 #include <fstream>
00030 #include <cerrno>
00031 #include <dirent.h>
00032 #include <errno.h>
00033 #include <sys/stat.h>
00034 #include <sys/wait.h>
00035 #include <signal.h>
00036 
00037 #include <iostream>
00038 #include <iterator>
00039 #include <fstream>
00040 #include <sstream>
00041 
00042 using namespace llvm;
00043 using namespace klee;
00044 
00045 namespace {
00046   cl::opt<std::string>
00047   InputFile(cl::desc("<input bytecode>"), cl::Positional, cl::init("-"));
00048 
00049   cl::opt<std::string>
00050   RunInDir("run-in", cl::desc("Change to the given directory prior to executing"));
00051 
00052   cl::opt<std::string>
00053   Environ("environ", cl::desc("Parse environ from given file (in \"env\" format)"));
00054 
00055   cl::list<std::string>
00056   InputArgv(cl::ConsumeAfter, 
00057             cl::desc("<program arguments>..."));
00058 
00059   cl::opt<bool>
00060   NoOutput("no-output", 
00061            cl::desc("Don't generate test files"));
00062     
00063   cl::opt<bool>
00064   WarnAllExternals("warn-all-externals", 
00065                    cl::desc("Give initial warning for all externals."));
00066     
00067   cl::opt<bool>
00068   WriteCVCs("write-cvcs", 
00069             cl::desc("Write .cvc files for each test case"));
00070 
00071   cl::opt<bool>
00072   WritePCs("write-pcs", 
00073             cl::desc("Write .pc files for each test case"));
00074   
00075   cl::opt<bool>
00076   WriteCov("write-cov", 
00077            cl::desc("Write coverage information for each test case"));
00078   
00079   cl::opt<bool>
00080   WriteTestInfo("write-test-info", 
00081                 cl::desc("Write additional test case information"));
00082   
00083   cl::opt<bool>
00084   WritePaths("write-paths", 
00085                 cl::desc("Write .path files for each test case"));
00086     
00087   cl::opt<bool>
00088   WriteSymPaths("write-sym-paths", 
00089                 cl::desc("Write .sym.path files for each test case"));
00090     
00091   cl::opt<bool>
00092   ExitOnError("exit-on-error", 
00093               cl::desc("Exit if errors occur"));
00094     
00095 
00096   enum LibcType {
00097     NoLibc, KleeLibc, UcLibc
00098   };
00099 
00100   cl::opt<LibcType>
00101   Libc("libc", 
00102        cl::desc("Choose libc version (none by default)."),
00103        cl::values(clEnumValN(NoLibc, "none", "Don't link in a libc"),
00104                   clEnumValN(KleeLibc, "klee", "Link in klee libc"),
00105                   clEnumValN(UcLibc, "uclibc", "Link in uclibc (adapted for klee)"),
00106                   clEnumValEnd),
00107        cl::init(NoLibc));
00108 
00109     
00110   cl::opt<bool>
00111   WithPOSIXRuntime("posix-runtime", 
00112                 cl::desc("Link with POSIX runtime"),
00113                 cl::init(false));
00114     
00115   cl::opt<bool>
00116   OptimizeModule("optimize", 
00117                  cl::desc("Optimize before execution"));
00118 
00119   cl::opt<bool>
00120   CheckDivZero("check-div-zero", 
00121                cl::desc("Inject checks for division-by-zero"),
00122                cl::init(true));
00123     
00124   cl::opt<std::string>
00125   OutputDir("output-dir", 
00126             cl::desc("Directory to write results in (defaults to klee-out-N)"),
00127             cl::init(""));
00128 
00129   // this is a fake entry, its automagically handled
00130   cl::list<std::string>
00131   ReadArgsFilesFake("read-args", 
00132                     cl::desc("File to read arguments from (one arg per line)"));
00133     
00134   cl::opt<bool>
00135   ReplayKeepSymbolic("replay-keep-symbolic", 
00136                      cl::desc("Replay the test cases only by asserting"
00137                               "the bytes, not necessarily making them concrete."));
00138     
00139   cl::list<std::string>
00140   ReplayOutFile("replay-out",
00141                 cl::desc("Specify an out file to replay"),
00142                 cl::value_desc("out file"));
00143 
00144   cl::list<std::string>
00145   ReplayOutDir("replay-out-dir",
00146                cl::desc("Specify a directory to replay .out files from"),
00147                cl::value_desc("output directory"));
00148 
00149   cl::opt<std::string>
00150   ReplayPathFile("replay-path",
00151                  cl::desc("Specify a path file to replay"),
00152                  cl::value_desc("path file"));
00153 
00154   cl::list<std::string>
00155   SeedOutFile("seed-out");
00156   
00157   cl::list<std::string>
00158   SeedOutDir("seed-out-dir");
00159   
00160   cl::opt<unsigned>
00161   MakeConcreteSymbolic("make-concrete-symbolic",
00162                        cl::desc("Rate at which to make concrete reads symbolic (0=off)"),
00163                        cl::init(0));
00164 
00165   cl::opt<bool>
00166   InitEnv("init-env",
00167           cl::desc("Create custom environment.  Options that can be passed as arguments to the programs are: --sym-argv <max-len>  --sym-argvs <min-argvs> <max-argvs> <max-len> + file model options"));
00168  
00169   cl::opt<unsigned>
00170   StopAfterNTests("stop-after-n-tests",
00171              cl::desc("Stop execution after generating the given number of tests.  Extra tests corresponding to partially explored paths will also be dumped."),
00172              cl::init(0));
00173 
00174   cl::opt<bool>
00175   Watchdog("watchdog",
00176            cl::desc("Use a watchdog process to enforce --max-time."),
00177            cl::init(0));
00178 }
00179 
00180 extern bool WriteTraces;
00181 extern cl::opt<double> MaxTime;
00182 
00183 /***/
00184 
00185 class KleeHandler : public InterpreterHandler {
00186 private:
00187   Interpreter *m_interpreter;
00188   TreeStreamWriter *m_pathWriter, *m_symPathWriter;
00189   std::ostream *m_infoFile;
00190 
00191   char m_outputDirectory[1024];
00192   unsigned m_testIndex;  // number of tests written so far
00193   unsigned m_pathsExplored; // number of paths explored so far
00194 
00195   // used for writing .ktest files
00196   int m_argc;
00197   char **m_argv;
00198 
00199 public:
00200   KleeHandler(int argc, char **argv);
00201   ~KleeHandler();
00202 
00203   std::ostream &getInfoStream() const { return *m_infoFile; }
00204   unsigned getNumTestCases() { return m_testIndex; }
00205   unsigned getNumPathsExplored() { return m_pathsExplored; }
00206   void incPathsExplored() { m_pathsExplored++; }
00207 
00208   void setInterpreter(Interpreter *i);
00209 
00210   void processTestCase(const ExecutionState  &state,
00211                        const char *errorMessage, 
00212                        const char *errorSuffix);
00213 
00214   std::string getOutputFilename(const std::string &filename);
00215   std::ostream *openOutputFile(const std::string &filename);
00216   std::string getTestFilename(const std::string &suffix, unsigned id);
00217   std::ostream *openTestFile(const std::string &suffix, unsigned id);
00218 
00219   // load a .out file
00220   static void loadOutFile(std::string name, 
00221                           std::vector<unsigned char> &buffer);
00222 
00223   // load a .path file
00224   static void loadPathFile(std::string name, 
00225                            std::vector<bool> &buffer);
00226 
00227   static void getOutFiles(std::string path,
00228                           std::vector<std::string> &results);
00229 };
00230 
00231 KleeHandler::KleeHandler(int argc, char **argv) 
00232   : m_interpreter(0),
00233     m_pathWriter(0),
00234     m_symPathWriter(0),
00235     m_infoFile(0),
00236     m_testIndex(0),
00237     m_pathsExplored(0),
00238     m_argc(argc),
00239     m_argv(argv) {
00240   std::string theDir;
00241 
00242   if (OutputDir=="") {
00243     llvm::sys::Path directory(InputFile);
00244     std::string dirname = "";
00245     directory.eraseComponent();
00246     
00247     if (directory.isEmpty())
00248       directory.set(".");
00249     
00250     for (int i = 0; ; i++) {
00251       char buf[256], tmp[64];
00252       sprintf(tmp, "klee-out-%d", i);
00253       dirname = tmp;
00254       sprintf(buf, "%s/%s", directory.c_str(), tmp);
00255       theDir = buf;
00256       
00257       if (DIR *dir = opendir(theDir.c_str())) {
00258         closedir(dir);
00259       } else {
00260         break;
00261       }
00262     }    
00263 
00264     llvm::cerr << "KLEE: output directory = \"" << dirname << "\"\n";
00265 
00266     llvm::sys::Path klee_last(directory);
00267     klee_last.appendComponent("klee-last");
00268       
00269     if ((unlink(klee_last.c_str()) < 0) && (errno != ENOENT)) {
00270       perror("Cannot unlink klee-last");
00271       assert(0 && "exiting.");
00272     }
00273     
00274     if (symlink(dirname.c_str(), klee_last.c_str()) < 0) {
00275       perror("Cannot make symlink");
00276       assert(0 && "exiting.");
00277     }
00278   } else {
00279     theDir = OutputDir;
00280   }
00281   
00282   sys::Path p(theDir);
00283   if (!p.isAbsolute()) {
00284     sys::Path cwd = sys::Path::GetCurrentDirectory();
00285     cwd.appendComponent(theDir);
00286     p = cwd;
00287   }
00288   strcpy(m_outputDirectory, p.c_str());
00289 
00290   if (mkdir(m_outputDirectory, 0775) < 0) {
00291     llvm::cerr << "KLEE: ERROR: Unable to make output directory: \"" 
00292                << m_outputDirectory 
00293                << "\", refusing to overwrite.\n";
00294     exit(1);
00295   }
00296 
00297   char fname[1024];
00298   snprintf(fname, sizeof(fname), "%s/warnings.txt", m_outputDirectory);
00299   klee_warning_file = fopen(fname, "w");
00300   assert(klee_warning_file);
00301 
00302   snprintf(fname, sizeof(fname), "%s/messages.txt", m_outputDirectory);
00303   klee_message_file = fopen(fname, "w");
00304   assert(klee_message_file);
00305 
00306   m_infoFile = openOutputFile("info");
00307 }
00308 
00309 KleeHandler::~KleeHandler() {
00310   if (m_pathWriter) delete m_pathWriter;
00311   if (m_symPathWriter) delete m_symPathWriter;
00312   delete m_infoFile;
00313 }
00314 
00315 void KleeHandler::setInterpreter(Interpreter *i) {
00316   m_interpreter = i;
00317 
00318   if (WritePaths) {
00319     m_pathWriter = new TreeStreamWriter(getOutputFilename("paths.ts"));
00320     assert(m_pathWriter->good());
00321     m_interpreter->setPathWriter(m_pathWriter);
00322   }
00323 
00324   if (WriteSymPaths) {
00325     m_symPathWriter = new TreeStreamWriter(getOutputFilename("symPaths.ts"));
00326     assert(m_symPathWriter->good());
00327     m_interpreter->setSymbolicPathWriter(m_symPathWriter);
00328   }
00329 }
00330 
00331 std::string KleeHandler::getOutputFilename(const std::string &filename) {
00332   char outfile[1024];
00333   sprintf(outfile, "%s/%s", m_outputDirectory, filename.c_str());
00334   return outfile;
00335 }
00336 
00337 std::ostream *KleeHandler::openOutputFile(const std::string &filename) {
00338   std::ios::openmode io_mode = std::ios::out | std::ios::trunc 
00339                              | std::ios::binary;
00340   std::ostream *f;
00341   std::string path = getOutputFilename(filename);
00342   f = new std::ofstream(path.c_str(), io_mode);
00343   if (!f) {
00344     klee_warning("out of memory");
00345   } else if (!f->good()) {
00346     klee_warning("error opening: %s", filename.c_str());
00347     delete f;
00348     f = NULL;
00349   }
00350 
00351   return f;
00352 }
00353 
00354 std::string KleeHandler::getTestFilename(const std::string &suffix, unsigned id) {
00355   char filename[1024];
00356   sprintf(filename, "test%06d.%s", id, suffix.c_str());
00357   return getOutputFilename(filename);
00358 }
00359 
00360 std::ostream *KleeHandler::openTestFile(const std::string &suffix, unsigned id) {
00361   char filename[1024];
00362   sprintf(filename, "test%06d.%s", id, suffix.c_str());
00363   return openOutputFile(filename);
00364 }
00365 
00366 
00367 /* Outputs all files (.ktest, .pc, .cov etc.) describing a test case */
00368 void KleeHandler::processTestCase(const ExecutionState &state,
00369                                   const char *errorMessage, 
00370                                   const char *errorSuffix) {
00371   if (errorMessage && ExitOnError) {
00372     llvm::cerr << "EXITING ON ERROR: " << errorMessage << "\n";
00373     abort();
00374   }
00375 
00376   if (!NoOutput) {
00377     std::vector< std::pair<std::string, std::vector<unsigned char> > > out;
00378     bool success = m_interpreter->getSymbolicSolution(state, out);
00379 
00380     if (!success)
00381       klee_warning("unable to get symbolic solution, losing test case");
00382 
00383     double start_time = util::getWallTime();
00384 
00385     unsigned id = ++m_testIndex;
00386 
00387     if (success) {
00388       KTest b;      
00389       b.numArgs = m_argc;
00390       b.args = m_argv;
00391       b.symArgvs = 0;
00392       b.symArgvLen = 0;
00393       b.numObjects = out.size();
00394       b.objects = new KTestObject[b.numObjects];
00395       assert(b.objects);
00396       for (unsigned i=0; i<b.numObjects; i++) {
00397         KTestObject *o = &b.objects[i];
00398         o->name = const_cast<char*>(out[i].first.c_str());
00399         o->numBytes = out[i].second.size();
00400         o->bytes = new unsigned char[o->numBytes];
00401         assert(o->bytes);
00402         std::copy(out[i].second.begin(), out[i].second.end(), o->bytes);
00403       }
00404       
00405       if (!kTest_toFile(&b, getTestFilename("ktest", id).c_str())) {
00406         klee_warning("unable to write output test case, losing it");
00407       }
00408       
00409       for (unsigned i=0; i<b.numObjects; i++)
00410         delete[] b.objects[i].bytes;
00411       delete[] b.objects;
00412     }
00413 
00414     if (errorMessage) {
00415       std::ostream *f = openTestFile(errorSuffix, id);
00416       *f << errorMessage;
00417       delete f;
00418     }
00419     
00420     if (m_pathWriter) {
00421       std::vector<unsigned char> concreteBranches;
00422       m_pathWriter->readStream(m_interpreter->getPathStreamID(state),
00423                                concreteBranches);
00424       std::ostream *f = openTestFile("path", id);
00425       std::copy(concreteBranches.begin(), concreteBranches.end(), 
00426                 std::ostream_iterator<unsigned char>(*f, "\n"));
00427       delete f;
00428     }
00429    
00430     if (errorMessage || WritePCs) {
00431       std::string constraints;
00432       m_interpreter->getConstraintLog(state, constraints);
00433       std::ostream *f = openTestFile("pc", id);
00434       *f << constraints;
00435       delete f;
00436     }
00437 
00438     if (WriteCVCs) {
00439       std::string constraints;
00440       m_interpreter->getConstraintLog(state, constraints, true);
00441       std::ostream *f = openTestFile("cvc", id);
00442       *f << constraints;
00443       delete f;
00444     }
00445     
00446     if (m_symPathWriter) {
00447       std::vector<unsigned char> symbolicBranches;
00448       m_symPathWriter->readStream(m_interpreter->getSymbolicPathStreamID(state),
00449                                   symbolicBranches);
00450       std::ostream *f = openTestFile("sym.path", id);
00451       std::copy(symbolicBranches.begin(), symbolicBranches.end(), 
00452                 std::ostream_iterator<unsigned char>(*f, "\n"));
00453       delete f;
00454     }
00455 
00456     if (WriteCov) {
00457       std::map<const std::string*, std::set<unsigned> > cov;
00458       m_interpreter->getCoveredLines(state, cov);
00459       std::ostream *f = openTestFile("cov", id);
00460       for (std::map<const std::string*, std::set<unsigned> >::iterator
00461              it = cov.begin(), ie = cov.end();
00462            it != ie; ++it) {
00463         for (std::set<unsigned>::iterator
00464                it2 = it->second.begin(), ie = it->second.end();
00465              it2 != ie; ++it2)
00466           *f << *it->first << ":" << *it2 << "\n";
00467       }
00468       delete f;
00469     }
00470 
00471     if (WriteTraces) {
00472       std::ostream *f = openTestFile("trace", id);
00473       state.exeTraceMgr.printAllEvents(*f);
00474       delete f;
00475     }
00476 
00477     if (m_testIndex == StopAfterNTests)
00478       m_interpreter->setHaltExecution(true);
00479 
00480     if (WriteTestInfo) {
00481       double elapsed_time = util::getWallTime() - start_time;
00482       std::ostream *f = openTestFile("info", id);
00483       *f << "Time to generate test case: " 
00484          << elapsed_time << "s\n";
00485       delete f;
00486     }
00487   }
00488 }
00489 
00490   // load a .path file
00491 void KleeHandler::loadPathFile(std::string name, 
00492                                      std::vector<bool> &buffer) {
00493   std::ifstream f(name.c_str(), std::ios::in | std::ios::binary);
00494 
00495   if (!f.good())
00496     assert(0 && "unable to open path file");
00497 
00498   while (f.good()) {
00499     unsigned value;
00500     f >> value;
00501     buffer.push_back(!!value);
00502     f.get();
00503   }
00504 }
00505 
00506 void KleeHandler::getOutFiles(std::string path,
00507                               std::vector<std::string> &results) {
00508   llvm::sys::Path p(path);
00509   std::set<llvm::sys::Path> contents;
00510   std::string error;
00511   if (p.getDirectoryContents(contents, &error)) {
00512     llvm::cerr << "ERROR: unable to read output directory: " << path 
00513                << ": " << error << "\n";
00514     exit(1);
00515   }
00516   for (std::set<llvm::sys::Path>::iterator it = contents.begin(),
00517          ie = contents.end(); it != ie; ++it) {
00518     std::string f = it->toString();
00519     if (f.substr(f.size()-6,f.size()) == ".ktest") {
00520       results.push_back(f);
00521     }
00522   }
00523 }
00524 
00525 //===----------------------------------------------------------------------===//
00526 // main Driver function
00527 //
00528 #if ENABLE_STPLOG == 1
00529 extern "C" void STPLOG_init(const char *);
00530 #endif
00531 
00532 static std::string strip(std::string &in) {
00533   unsigned len = in.size();
00534   unsigned lead = 0, trail = len;
00535   while (lead<len && isspace(in[lead]))
00536     ++lead;
00537   while (trail>lead && isspace(in[trail-1]))
00538     --trail;
00539   return in.substr(lead, trail-lead);
00540 }
00541 
00542 static void readArgumentsFromFile(char *file, std::vector<std::string> &results) {
00543   std::ifstream f(file);
00544   assert(f.is_open() && "unable to open input for reading arguments");
00545   while (!f.eof()) {
00546     std::string line;
00547     std::getline(f, line);
00548     line = strip(line);
00549     if (!line.empty())
00550       results.push_back(line);
00551   }
00552   f.close();
00553 }
00554 
00555 static void parseArguments(int argc, char **argv) {
00556   std::vector<std::string> arguments;
00557 
00558   for (int i=1; i<argc; i++) {
00559     if (!strcmp(argv[i],"--read-args") && i+1<argc) {
00560       readArgumentsFromFile(argv[++i], arguments);
00561     } else {
00562       arguments.push_back(argv[i]);
00563     }
00564   }
00565     
00566   int numArgs = arguments.size() + 1;
00567   const char **argArray = new const char*[numArgs+1];
00568   argArray[0] = argv[0];
00569   argArray[numArgs] = 0;
00570   for (int i=1; i<numArgs; i++) {
00571     argArray[i] = arguments[i-1].c_str();
00572   }
00573 
00574   cl::ParseCommandLineOptions(numArgs, (char**) argArray, " klee\n");
00575   delete[] argArray;
00576 }
00577 
00578 
00579 
00580 static int initEnv(Module *mainModule) {
00581 
00582   /*
00583     nArgcP = alloc oldArgc->getType()
00584     nArgvV = alloc oldArgv->getType()
00585     store oldArgc nArgcP
00586     store oldArgv nArgvP
00587     klee_init_environment(nArgcP, nArgvP)
00588     nArgc = load nArgcP
00589     nArgv = load nArgvP
00590     oldArgc->replaceAllUsesWith(nArgc)
00591     oldArgv->replaceAllUsesWith(nArgv)
00592   */
00593 
00594   Function *mainFn = mainModule->getFunction("main");
00595     
00596   if (mainFn->arg_size() < 2) {
00597     llvm::cerr << "Cannot handle ""-init-env"" when main() has less than two arguments.\n";
00598     return -1;
00599   }
00600 
00601   Instruction* firstInst = mainFn->begin()->begin();
00602 
00603   Value* oldArgc = mainFn->arg_begin();
00604   Value* oldArgv = ++mainFn->arg_begin();
00605   
00606   AllocaInst* argcPtr = new AllocaInst(oldArgc->getType(), "argcPtr", firstInst);
00607   AllocaInst* argvPtr = new AllocaInst(oldArgv->getType(), "argvPtr", firstInst);
00608 
00609   /* Insert void klee_init_env(int* argc, char*** argv) */
00610   std::vector<const Type*> params;
00611   params.push_back(Type::Int32Ty);
00612   params.push_back(Type::Int32Ty);
00613   Function* initEnvFn = 
00614     cast<Function>(mainModule->getOrInsertFunction("klee_init_env",
00615                                                    Type::VoidTy,
00616                                                    argcPtr->getType(),
00617                                                    argvPtr->getType(),
00618                                                    NULL));
00619   assert(initEnvFn);    
00620   std::vector<Value*> args;
00621   args.push_back(argcPtr);
00622   args.push_back(argvPtr);
00623   Instruction* initEnvCall = CallInst::Create(initEnvFn, args.begin(), args.end(), 
00624                                               "", firstInst);
00625   Value *argc = new LoadInst(argcPtr, "newArgc", firstInst);
00626   Value *argv = new LoadInst(argvPtr, "newArgv", firstInst);
00627   
00628   oldArgc->replaceAllUsesWith(argc);
00629   oldArgv->replaceAllUsesWith(argv);
00630 
00631   new StoreInst(oldArgc, argcPtr, initEnvCall);
00632   new StoreInst(oldArgv, argvPtr, initEnvCall);
00633 
00634   return 0;
00635 }
00636 
00637 
00638 // This is a terrible hack until we get some real modelling of the
00639 // system. All we do is check the undefined symbols and m and warn about
00640 // any "unrecognized" externals and about any obviously unsafe ones.
00641 
00642 // Symbols we explicitly support
00643 static const char *modelledExternals[] = {
00644   "_ZTVN10__cxxabiv117__class_type_infoE",
00645   "_ZTVN10__cxxabiv120__si_class_type_infoE",
00646   "_ZTVN10__cxxabiv121__vmi_class_type_infoE",
00647 
00648   // special functions
00649   "_assert", 
00650   "__assert_fail", 
00651   "__assert_rtn", 
00652   "calloc", 
00653   "_exit", 
00654   "exit", 
00655   "free", 
00656   "abort", 
00657   "klee_abort", 
00658   "klee_assume", 
00659   "klee_check_memory_access",
00660   "klee_define_fixed_object",
00661   "klee_get_errno", 
00662   "klee_get_value",
00663   "klee_get_obj_size", 
00664   "klee_is_symbolic", 
00665   "klee_make_symbolic", 
00666   "klee_mark_global", 
00667   "klee_merge", 
00668   "klee_prefer_cex",
00669   "klee_print_expr", 
00670   "klee_print_range", 
00671   "klee_report_error", 
00672   "klee_revirt_objects", 
00673   "klee_set_forking",
00674   "klee_silent_exit", 
00675   "klee_under_constrained", 
00676   "klee_warning", 
00677   "klee_warning_once", 
00678   "klee_alias_function",
00679   "llvm.dbg.stoppoint", 
00680   "llvm.va_start", 
00681   "llvm.va_end", 
00682   "malloc", 
00683   "realloc", 
00684   "_ZdaPv", 
00685   "_ZdlPv", 
00686   "_Znaj", 
00687   "_Znwj", 
00688   "_Znam", 
00689   "_Znwm", 
00690 };
00691 // Symbols we aren't going to warn about
00692 static const char *dontCareExternals[] = {
00693 #if 0
00694   // stdio
00695   "fprintf",
00696   "fflush",
00697   "fopen",
00698   "fclose",
00699   "fputs_unlocked",
00700   "putchar_unlocked",
00701   "vfprintf",
00702   "fwrite",
00703   "puts",
00704   "printf",
00705   "stdin",
00706   "stdout",
00707   "stderr",
00708   "_stdio_term",
00709   "__errno_location",
00710   "fstat",
00711 #endif
00712 
00713   // static information, pretty ok to return
00714   "getegid",
00715   "geteuid",
00716   "getgid",
00717   "getuid",
00718   "getpid",
00719   "gethostname",
00720   "getpgrp",
00721   "getppid",
00722   "getpagesize",
00723   "getpriority",
00724   "getgroups",
00725   "getdtablesize",
00726   "getrlimit",
00727   "getrlimit64",
00728   "getcwd",
00729   "getwd",
00730   "gettimeofday",
00731   "uname",
00732 
00733   // fp stuff we just don't worry about yet
00734   "frexp",  
00735   "ldexp",
00736   "__isnan",
00737   "__signbit",
00738 };
00739 // Extra symbols we aren't going to warn about with klee-libc
00740 static const char *dontCareKlee[] = {
00741   "__ctype_b_loc",
00742   "__ctype_get_mb_cur_max",
00743 
00744   // io system calls
00745   "open",
00746   "write",
00747   "read",
00748   "close",
00749 };
00750 // Extra symbols we aren't going to warn about with uclibc
00751 static const char *dontCareUclibc[] = {
00752   "__dso_handle",
00753 
00754   // Don't warn about these since we explicitly commented them out of
00755   // uclibc.
00756   "printf",
00757   "vprintf"
00758 };
00759 // Symbols we consider unsafe
00760 static const char *unsafeExternals[] = {
00761   "fork", // oh lord
00762   "exec", // heaven help us
00763   "error", // calls _exit
00764   "raise", // yeah
00765   "kill", // mmmhmmm
00766 };
00767 #define NELEMS(array) (sizeof(array)/sizeof(array[0]))
00768 void externalsAndGlobalsCheck(const Module *m) {
00769   std::map<std::string, bool> externals;
00770   std::set<std::string> modelled(modelledExternals, 
00771                                  modelledExternals+NELEMS(modelledExternals));
00772   std::set<std::string> dontCare(dontCareExternals, 
00773                                  dontCareExternals+NELEMS(dontCareExternals));
00774   std::set<std::string> unsafe(unsafeExternals, 
00775                                unsafeExternals+NELEMS(unsafeExternals));
00776 
00777   switch (Libc) {
00778   case KleeLibc: 
00779     dontCare.insert(dontCareKlee, dontCareKlee+NELEMS(dontCareKlee));
00780     break;
00781   case UcLibc:
00782     dontCare.insert(dontCareUclibc,
00783                     dontCareUclibc+NELEMS(dontCareUclibc));
00784     break;
00785   case NoLibc: /* silence compiler warning */
00786     break;
00787   }
00788   
00789 
00790   if (WithPOSIXRuntime)
00791     dontCare.insert("syscall");
00792 
00793   for (Module::const_iterator fnIt = m->begin(), fn_ie = m->end(); 
00794        fnIt != fn_ie; ++fnIt) {
00795     if (fnIt->isDeclaration() && !fnIt->use_empty())
00796       externals.insert(std::make_pair(fnIt->getName(), false));
00797     for (Function::const_iterator bbIt = fnIt->begin(), bb_ie = fnIt->end(); 
00798          bbIt != bb_ie; ++bbIt) {
00799       for (BasicBlock::const_iterator it = bbIt->begin(), ie = bbIt->end(); 
00800            it != it; ++it) {
00801         if (const CallInst *ci = dyn_cast<CallInst>(it)) {
00802           if (isa<InlineAsm>(ci->getCalledValue())) {
00803             klee_warning_once(&*fnIt,
00804                               "function \"%s\" has inline asm", 
00805                               fnIt->getName().c_str());
00806           }
00807         }
00808       }
00809     }
00810   }
00811   for (Module::const_global_iterator 
00812          it = m->global_begin(), ie = m->global_end(); 
00813        it != ie; ++it)
00814     if (it->isDeclaration() && !it->use_empty())
00815       externals.insert(std::make_pair(it->getName(), true));
00816   // and remove aliases (they define the symbol after global
00817   // initialization)
00818   for (Module::const_alias_iterator 
00819          it = m->alias_begin(), ie = m->alias_end(); 
00820        it != ie; ++it) {
00821     std::map<std::string, bool>::iterator it2 = 
00822       externals.find(it->getName());
00823     if (it2!=externals.end())
00824       externals.erase(it2);
00825   }
00826 
00827   std::map<std::string, bool> foundUnsafe;
00828   for (std::map<std::string, bool>::iterator
00829          it = externals.begin(), ie = externals.end();
00830        it != ie; ++it) {
00831     const std::string &ext = it->first;
00832     if (!modelled.count(ext) && (WarnAllExternals || 
00833                                  !dontCare.count(ext))) {
00834       if (unsafe.count(ext)) {
00835         foundUnsafe.insert(*it);
00836       } else {
00837         klee_warning("undefined reference to %s: %s",
00838                      it->second ? "variable" : "function",
00839                      ext.c_str());
00840       }
00841     }
00842   }
00843 
00844   for (std::map<std::string, bool>::iterator
00845          it = foundUnsafe.begin(), ie = foundUnsafe.end();
00846        it != ie; ++it) {
00847     const std::string &ext = it->first;
00848     klee_warning("undefined reference to %s: %s (UNSAFE)!",
00849                  it->second ? "variable" : "function",
00850                  ext.c_str());
00851   }
00852 }
00853 
00854 static Interpreter *theInterpreter = 0;
00855 
00856 static bool interrupted = false;
00857 
00858 // Pulled out so it can be easily called from a debugger.
00859 extern "C"
00860 void halt_execution() {
00861   theInterpreter->setHaltExecution(true);
00862 }
00863 
00864 extern "C"
00865 void stop_forking() {
00866   theInterpreter->setInhibitForking(true);
00867 }
00868 
00869 static void interrupt_handle() {
00870   if (!interrupted && theInterpreter) {
00871     llvm::cerr << "KLEE: ctrl-c detected, requesting interpreter to halt.\n";
00872     halt_execution();
00873     sys::SetInterruptFunction(interrupt_handle);
00874   } else {
00875     llvm::cerr << "KLEE: ctrl-c detected, exiting.\n";
00876     exit(1);
00877   }
00878   interrupted = true;
00879 }
00880 
00881 // This is a temporary hack. If the running process has access to
00882 // externals then it can disable interrupts, which screws up the
00883 // normal "nice" watchdog termination process. We try to request the
00884 // interpreter to halt using this mechanism as a last resort to save
00885 // the state data before going ahead and killing it.
00886 static void halt_via_gdb(int pid) {
00887   char buffer[256];
00888   sprintf(buffer, 
00889           "gdb --batch --eval-command=\"p halt_execution()\" "
00890           "--eval-command=detach --pid=%d &> /dev/null",
00891           pid);
00892   //  fprintf(stderr, "KLEE: WATCHDOG: running: %s\n", buffer);
00893   if (system(buffer)==-1) 
00894     perror("system");
00895 }
00896 
00897 // returns the end of the string put in buf
00898 static char *format_tdiff(char *buf, long seconds)
00899 {
00900   assert(seconds >= 0);
00901 
00902   long minutes = seconds / 60;  seconds %= 60;
00903   long hours   = minutes / 60;  minutes %= 60;
00904   long days    = hours   / 24;  hours   %= 24;
00905 
00906   buf = strrchr(buf, '\0');
00907   if (days > 0) buf += sprintf(buf, "%ld days, ", days);
00908   buf += sprintf(buf, "%02ld:%02ld:%02ld", hours, minutes, seconds);
00909   return buf;
00910 }
00911 
00912 #ifndef KLEE_UCLIBC
00913 static llvm::Module *linkWithUclibc(llvm::Module *mainModule) {
00914   fprintf(stderr, "error: invalid libc, no uclibc support!\n");
00915   exit(1);
00916   return 0;
00917 }
00918 #else
00919 static llvm::Module *linkWithUclibc(llvm::Module *mainModule) {
00920   Function *f;
00921   // force import of __uClibc_main
00922   mainModule->getOrInsertFunction("__uClibc_main",
00923                                   FunctionType::get(Type::VoidTy,
00924                                                     std::vector<const Type*>(),
00925                                                     true));
00926   
00927   // force various imports
00928   if (WithPOSIXRuntime) {
00929     mainModule->getOrInsertFunction("realpath",
00930                                     PointerType::getUnqual(Type::Int8Ty),
00931                                     PointerType::getUnqual(Type::Int8Ty),
00932                                     PointerType::getUnqual(Type::Int8Ty),
00933                                     NULL);
00934     mainModule->getOrInsertFunction("getutent",
00935                                     PointerType::getUnqual(Type::Int8Ty),
00936                                     NULL);
00937     mainModule->getOrInsertFunction("__fgetc_unlocked",
00938                                     Type::Int32Ty,
00939                                     PointerType::getUnqual(Type::Int8Ty),
00940                                     NULL);
00941     mainModule->getOrInsertFunction("__fputc_unlocked",
00942                                     Type::Int32Ty,
00943                                     Type::Int32Ty,
00944                                     PointerType::getUnqual(Type::Int8Ty),
00945                                     NULL);
00946   }
00947 
00948   f = mainModule->getFunction("__ctype_get_mb_cur_max");
00949   if (f) f->setName("_stdlib_mb_cur_max");
00950 
00951   // Strip of asm prefixes for 64 bit versions because they are not
00952   // present in uclibc and we want to make sure stuff will get
00953   // linked. In the off chance that both prefixed and unprefixed
00954   // versions are present in the module, make sure we don't create a
00955   // naming conflict.
00956   for (Module::iterator fi = mainModule->begin(), fe = mainModule->end();
00957        fi != fe;) {
00958     Function *f = fi;
00959     ++fi;
00960     const std::string &name = f->getName();
00961     if (name[0]=='\01') {
00962       unsigned size = name.size();
00963       if (name[size-2]=='6' && name[size-1]=='4') {
00964         std::string unprefixed = name.substr(1);
00965 
00966         // See if the unprefixed version exists.
00967         if (Function *f2 = mainModule->getFunction(unprefixed)) {
00968           f->replaceAllUsesWith(f2);
00969           f->eraseFromParent();
00970         } else {
00971           f->setName(unprefixed);
00972         }
00973       }
00974     }
00975   }
00976   
00977   mainModule = klee::linkWithLibrary(mainModule, 
00978                                      KLEE_UCLIBC "/lib/libc.a");
00979   assert(mainModule && "unable to link with uclibc");
00980 
00981   // more sighs, this is horrible but just a temp hack
00982   //    f = mainModule->getFunction("__fputc_unlocked");
00983   //    if (f) f->setName("fputc_unlocked");
00984   //    f = mainModule->getFunction("__fgetc_unlocked");
00985   //    if (f) f->setName("fgetc_unlocked");
00986   
00987   Function *f2;
00988   f = mainModule->getFunction("open");
00989   f2 = mainModule->getFunction("__libc_open");
00990   if (f2) {
00991     if (f) {
00992       f2->replaceAllUsesWith(f);
00993       f2->eraseFromParent();
00994     } else {
00995       f2->setName("open");
00996       assert(f2->getName() == "open");
00997     }
00998   }
00999 
01000   f = mainModule->getFunction("fcntl");
01001   f2 = mainModule->getFunction("__libc_fcntl");
01002   if (f2) {
01003     if (f) {
01004       f2->replaceAllUsesWith(f);
01005       f2->eraseFromParent();
01006     } else {
01007       f2->setName("fcntl");
01008       assert(f2->getName() == "fcntl");
01009     }
01010   }
01011 
01012   // XXX we need to rearchitect so this can also be used with
01013   // programs externally linked with uclibc.
01014 
01015   // We now need to swap things so that __uClibc_main is the entry
01016   // point, in such a way that the arguments are passed to
01017   // __uClibc_main correctly. We do this by renaming the user main
01018   // and generating a stub function to call __uClibc_main. There is
01019   // also an implicit cooperation in that runFunctionAsMain sets up
01020   // the environment arguments to what uclibc expects (following
01021   // argv), since it does not explicitly take an envp argument.
01022   Function *userMainFn = mainModule->getFunction("main");
01023   assert(userMainFn && "unable to get user main");    
01024   Function *uclibcMainFn = mainModule->getFunction("__uClibc_main");
01025   assert(uclibcMainFn && "unable to get uclibc main");    
01026   userMainFn->setName("__user_main");
01027 
01028   const FunctionType *ft = uclibcMainFn->getFunctionType();
01029   assert(ft->getNumParams() == 7);
01030 
01031   std::vector<const Type*> fArgs;
01032   fArgs.push_back(ft->getParamType(1)); // argc
01033   fArgs.push_back(ft->getParamType(2)); // argv
01034   Function *stub = Function::Create(FunctionType::get(Type::Int32Ty, fArgs, false),
01035                               GlobalVariable::ExternalLinkage,
01036                               "main",
01037                               mainModule);
01038   BasicBlock *bb = BasicBlock::Create("entry", stub);
01039 
01040   std::vector<llvm::Value*> args;
01041   args.push_back(llvm::ConstantExpr::getBitCast(userMainFn, 
01042                                                 ft->getParamType(0)));
01043   args.push_back(stub->arg_begin()); // argc
01044   args.push_back(++stub->arg_begin()); // argv    
01045   args.push_back(Constant::getNullValue(ft->getParamType(3))); // app_init
01046   args.push_back(Constant::getNullValue(ft->getParamType(4))); // app_fini
01047   args.push_back(Constant::getNullValue(ft->getParamType(5))); // rtld_fini
01048   args.push_back(Constant::getNullValue(ft->getParamType(6))); // stack_end
01049   CallInst::Create(uclibcMainFn, args.begin(), args.end(), "", bb);
01050   
01051   new UnreachableInst(bb);
01052 
01053   return mainModule;
01054 }
01055 #endif
01056 
01057 int main(int argc, char **argv, char **envp) {  
01058 #if ENABLE_STPLOG == 1
01059   STPLOG_init("stplog.c");
01060 #endif
01061 
01062   atexit(llvm_shutdown);  // Call llvm_shutdown() on exit.
01063   parseArguments(argc, argv);
01064   sys::PrintStackTraceOnErrorSignal();
01065 
01066   if (Watchdog) {
01067     if (MaxTime==0) {
01068       klee_error("--watchdog used without --max-time");
01069     }
01070 
01071     int pid = fork();
01072     if (pid<0) {
01073       klee_error("unable to fork watchdog");
01074     } else if (pid) {
01075       fprintf(stderr, "KLEE: WATCHDOG: watching %d\n", pid);
01076       fflush(stderr);
01077 
01078       double nextStep = util::getWallTime() + MaxTime*1.1;
01079       int level = 0;
01080 
01081       // Simple stupid code...
01082       while (1) {
01083         sleep(1);
01084 
01085         int status, res = waitpid(pid, &status, WNOHANG);
01086 
01087         if (res < 0) {
01088           if (errno==ECHILD) { // No child, no need to watch but
01089                                // return error since we didn't catch
01090                                // the exit.
01091             fprintf(stderr, "KLEE: watchdog exiting (no child)\n");
01092             return 1;
01093           } else if (errno!=EINTR) {
01094             perror("watchdog waitpid");
01095             exit(1);
01096           }
01097         } else if (res==pid && WIFEXITED(status)) {
01098           return WEXITSTATUS(status);
01099         } else {
01100           double time = util::getWallTime();
01101 
01102           if (time > nextStep) {
01103             ++level;
01104             
01105             if (level==1) {
01106               fprintf(stderr, "KLEE: WATCHDOG: time expired, attempting halt via INT\n");
01107               kill(pid, SIGINT);
01108             } else if (level==2) {
01109               fprintf(stderr, "KLEE: WATCHDOG: time expired, attempting halt via gdb\n");
01110               halt_via_gdb(pid);
01111             } else {
01112               fprintf(stderr, "KLEE: WATCHDOG: kill(9)ing child (I tried to be nice)\n");
01113               kill(pid, SIGKILL);
01114               return 1; // what more can we do
01115             }
01116 
01117             // Ideally this triggers a dump, which may take a while,
01118             // so try and give the process extra time to clean up.
01119             nextStep = util::getWallTime() + std::max(15., MaxTime*.1);
01120           }
01121         }
01122       }
01123 
01124       return 0;
01125     }
01126   }
01127 
01128   sys::SetInterruptFunction(interrupt_handle);
01129 
01130   // Load the bytecode...
01131   std::string ErrorMsg;
01132   ModuleProvider *MP = 0;
01133   if (MemoryBuffer *Buffer = MemoryBuffer::getFileOrSTDIN(InputFile, &ErrorMsg)) {
01134     MP = getBitcodeModuleProvider(Buffer, &ErrorMsg);
01135     if (!MP) delete Buffer;
01136   }
01137   
01138   if (!MP)
01139     klee_error("error loading program '%s': %s", InputFile.c_str(), ErrorMsg.c_str());
01140 
01141   Module *mainModule = MP->materializeModule();
01142   MP->releaseModule();
01143   delete MP;
01144 
01145   assert(mainModule && "unable to materialize");
01146   
01147   if (WithPOSIXRuntime)
01148     InitEnv = true;
01149 
01150   if (InitEnv) {
01151     int r = initEnv(mainModule);
01152     if (r != 0)
01153       return r;
01154   }
01155 
01156   llvm::sys::Path LibraryDir(KLEE_DIR "/" RUNTIME_CONFIGURATION "/lib");
01157   Interpreter::ModuleOptions Opts(LibraryDir.c_str(),
01158                                   /*Optimize=*/OptimizeModule, 
01159                                   /*CheckDivZero=*/CheckDivZero);
01160   
01161   switch (Libc) {
01162   case NoLibc: /* silence compiler warning */
01163     break;
01164 
01165   case KleeLibc: {
01166     // FIXME: Find a reasonable solution for this.
01167     llvm::sys::Path Path(Opts.LibraryDir);
01168     Path.appendComponent("libklee-libc.bca");
01169     mainModule = klee::linkWithLibrary(mainModule, Path.c_str());
01170     assert(mainModule && "unable to link with klee-libc");
01171     break;
01172   }
01173 
01174   case UcLibc:
01175     mainModule = linkWithUclibc(mainModule);
01176     break;
01177   }
01178 
01179   if (WithPOSIXRuntime) {
01180     llvm::sys::Path Path(Opts.LibraryDir);
01181     Path.appendComponent("libkleeRuntimePOSIX.bca");
01182     klee_message("NOTE: Using model: %s", Path.c_str());
01183     mainModule = klee::linkWithLibrary(mainModule, Path.c_str());
01184     assert(mainModule && "unable to link with simple model");
01185   }  
01186 
01187   // Get the desired main function.  klee_main initializes uClibc
01188   // locale and other data and then calls main.
01189   Function *mainFn = mainModule->getFunction("main");
01190   if (!mainFn) {
01191     llvm::cerr << "'main' function not found in module.\n";
01192     return -1;
01193   }
01194 
01195   // FIXME: Change me to std types.
01196   int pArgc;
01197   char **pArgv;
01198   char **pEnvp;
01199   if (Environ != "") {
01200     std::vector<std::string> items;
01201     std::ifstream f(Environ.c_str());
01202     if (!f.good())
01203       klee_error("unable to open --environ file: %s", Environ.c_str());
01204     while (!f.eof()) {
01205       std::string line;
01206       std::getline(f, line);
01207       line = strip(line);
01208       if (!line.empty())
01209         items.push_back(line);
01210     }
01211     f.close();
01212     pEnvp = new char *[items.size()+1];
01213     unsigned i=0;
01214     for (; i != items.size(); ++i)
01215       pEnvp[i] = strdup(items[i].c_str());
01216     pEnvp[i] = 0;
01217   } else {
01218     pEnvp = envp;
01219   }
01220 
01221   pArgc = InputArgv.size() + 1; 
01222   pArgv = new char *[pArgc];
01223   for (unsigned i=0; i<InputArgv.size()+1; i++) {
01224     std::string &arg = (i==0 ? InputFile : InputArgv[i-1]);
01225     unsigned size = arg.size() + 1;
01226     char *pArg = new char[size];
01227     
01228     std::copy(arg.begin(), arg.end(), pArg);
01229     pArg[size - 1] = 0;
01230     
01231     pArgv[i] = pArg;
01232   }
01233 
01234   std::vector<bool> replayPath;
01235 
01236   if (ReplayPathFile != "") {
01237     KleeHandler::loadPathFile(ReplayPathFile, replayPath);
01238   }
01239 
01240   Interpreter::InterpreterOptions IOpts;
01241   IOpts.MakeConcreteSymbolic = MakeConcreteSymbolic;
01242   KleeHandler *handler = new KleeHandler(pArgc, pArgv);
01243   Interpreter *interpreter = 
01244     theInterpreter = Interpreter::create(IOpts, handler);
01245   handler->setInterpreter(interpreter);
01246   
01247   std::ostream &infoFile = handler->getInfoStream();
01248   for (int i=0; i<argc; i++) {
01249     infoFile << argv[i] << (i+1<argc ? " ":"\n");
01250   }
01251   infoFile << "PID: " << getpid() << "\n";
01252 
01253   const Module *finalModule = 
01254     interpreter->setModule(mainModule, Opts);
01255   externalsAndGlobalsCheck(finalModule);
01256 
01257   if (ReplayPathFile != "") {
01258     interpreter->setReplayPath(&replayPath);
01259   }
01260 
01261   char buf[256];
01262   time_t t[2];
01263   t[0] = time(NULL);
01264   strftime(buf, sizeof(buf), "Started: %Y-%m-%d %H:%M:%S\n", localtime(&t[0]));
01265   infoFile << buf;
01266   infoFile.flush();
01267 
01268   if (!ReplayOutDir.empty() || !ReplayOutFile.empty()) {
01269     assert(SeedOutFile.empty());
01270     assert(SeedOutDir.empty());
01271 
01272     std::vector<std::string> outFiles = ReplayOutFile;
01273     for (std::vector<std::string>::iterator
01274            it = ReplayOutDir.begin(), ie = ReplayOutDir.end();
01275          it != ie; ++it)
01276       KleeHandler::getOutFiles(*it, outFiles);    
01277     std::vector<KTest*> kTests;
01278     for (std::vector<std::string>::iterator
01279            it = outFiles.begin(), ie = outFiles.end();
01280          it != ie; ++it) {
01281       KTest *out = kTest_fromFile(it->c_str());
01282       if (out) {
01283         kTests.push_back(out);
01284       } else {
01285         llvm::cerr << "KLEE: unable to open: " << *it << "\n";
01286       }
01287     }
01288 
01289     if (RunInDir != "") {
01290       int res = chdir(RunInDir.c_str());
01291       if (res < 0) {
01292         klee_error("Unable to change directory to: %s", RunInDir.c_str());
01293       }
01294     }
01295 
01296     unsigned i=0;
01297     for (std::vector<KTest*>::iterator
01298            it = kTests.begin(), ie = kTests.end();
01299          it != ie; ++it) {
01300       KTest *out = *it;
01301       interpreter->setReplayOut(out);
01302       llvm::cerr << "KLEE: replaying: " << *it << " (" << kTest_numBytes(out) << " bytes)"
01303                  << " (" << ++i << "/" << outFiles.size() << ")\n";
01304       // XXX should put envp in .ktest ?
01305       interpreter->runFunctionAsMain(mainFn, out->numArgs, out->args, pEnvp);
01306       if (interrupted) break;
01307     }
01308     interpreter->setReplayOut(0);
01309     while (!kTests.empty()) {
01310       kTest_free(kTests.back());
01311       kTests.pop_back();
01312     }
01313   } else {
01314     std::vector<KTest *> seeds;
01315     for (std::vector<std::string>::iterator
01316            it = SeedOutFile.begin(), ie = SeedOutFile.end();
01317          it != ie; ++it) {
01318       KTest *out = kTest_fromFile(it->c_str());
01319       if (!out) {
01320         llvm::cerr << "KLEE: unable to open: " << *it << "\n";
01321         exit(1);
01322       }
01323       seeds.push_back(out);
01324     } 
01325     for (std::vector<std::string>::iterator
01326            it = SeedOutDir.begin(), ie = SeedOutDir.end();
01327          it != ie; ++it) {
01328       std::vector<std::string> outFiles;
01329       KleeHandler::getOutFiles(*it, outFiles);
01330       for (std::vector<std::string>::iterator
01331              it2 = outFiles.begin(), ie = outFiles.end();
01332            it2 != ie; ++it2) {
01333         KTest *out = kTest_fromFile(it2->c_str());
01334         if (!out) {
01335           llvm::cerr << "KLEE: unable to open: " << *it2 << "\n";
01336           exit(1);
01337         }
01338         seeds.push_back(out);
01339       }
01340       if (outFiles.empty()) {
01341         llvm::cerr << "KLEE: seeds directory is empty: " << *it << "\n";
01342         exit(1);
01343       }
01344     }
01345        
01346     if (!seeds.empty()) {
01347       llvm::cerr << "KLEE: using " << seeds.size() << " seeds\n";
01348       interpreter->useSeeds(&seeds);
01349     }
01350     if (RunInDir != "") {
01351       int res = chdir(RunInDir.c_str());
01352       if (res < 0) {
01353         klee_error("Unable to change directory to: %s", RunInDir.c_str());
01354       }
01355     }
01356     interpreter->runFunctionAsMain(mainFn, pArgc, pArgv, pEnvp);
01357 
01358     while (!seeds.empty()) {
01359       kTest_free(seeds.back());
01360       seeds.pop_back();
01361     }
01362   }
01363       
01364   t[1] = time(NULL);
01365   strftime(buf, sizeof(buf), "Finished: %Y-%m-%d %H:%M:%S\n", localtime(&t[1]));
01366   infoFile << buf;
01367 
01368   strcpy(buf, "Elapsed: ");
01369   strcpy(format_tdiff(buf, t[1] - t[0]), "\n");
01370   infoFile << buf;
01371 
01372   // Free all the args.
01373   for (unsigned i=0; i<InputArgv.size()+1; i++)
01374     delete[] pArgv[i];
01375   delete[] pArgv;
01376 
01377   delete interpreter;
01378 
01379   uint64_t queries = 
01380     *theStatisticManager->getStatisticByName("Queries");
01381   uint64_t queriesValid = 
01382     *theStatisticManager->getStatisticByName("QueriesValid");
01383   uint64_t queriesInvalid = 
01384     *theStatisticManager->getStatisticByName("QueriesInvalid");
01385   uint64_t queryCounterexamples = 
01386     *theStatisticManager->getStatisticByName("QueriesCEX");
01387   uint64_t queryConstructs = 
01388     *theStatisticManager->getStatisticByName("QueriesConstructs");
01389   uint64_t instructions = 
01390     *theStatisticManager->getStatisticByName("Instructions");
01391   uint64_t forks = 
01392     *theStatisticManager->getStatisticByName("Forks");
01393 
01394   handler->getInfoStream() 
01395     << "KLEE: done: explored paths = " << 1 + forks << "\n";
01396 
01397   // Write some extra information in the info file which users won't
01398   // necessarily care about or understand.
01399   if (queries)
01400     handler->getInfoStream() 
01401       << "KLEE: done: avg. constructs per query = " 
01402                              << queryConstructs / queries << "\n";  
01403   handler->getInfoStream() 
01404     << "KLEE: done: total queries = " << queries << "\n"
01405     << "KLEE: done: valid queries = " << queriesValid << "\n"
01406     << "KLEE: done: invalid queriers = " << queriesInvalid << "\n"
01407     << "KLEE: done: query cex = " << queryCounterexamples << "\n";
01408 
01409   std::stringstream stats;
01410   stats << "KLEE: done: total instructions = " 
01411              << instructions << "\n";
01412   stats << "KLEE: done: completed paths = " 
01413              << handler->getNumPathsExplored() << "\n";
01414   stats << "KLEE: done: generated tests = " 
01415              << handler->getNumTestCases() << "\n";
01416   llvm::cerr << stats.str();
01417   handler->getInfoStream() << stats.str();
01418 
01419   delete handler;
01420 
01421   return 0;
01422 }

Generated on Fri Jun 5 03:31:32 2009 for klee by  doxygen 1.5.8