klee
UserSearcher.cpp
Go to the documentation of this file.
1//===-- UserSearcher.cpp --------------------------------------------------===//
2//
3// The KLEE Symbolic Virtual Machine
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "UserSearcher.h"
11
12#include "Executor.h"
13#include "MergeHandler.h"
14#include "Searcher.h"
15
17
18#include "llvm/Support/CommandLine.h"
19
20using namespace llvm;
21using namespace klee;
22
23namespace {
24llvm::cl::OptionCategory
25 SearchCat("Search options", "These options control the search heuristic.");
26
27cl::list<Searcher::CoreSearchType> CoreSearch(
28 "search",
29 cl::desc("Specify the search heuristic (default=random-path interleaved "
30 "with nurs:covnew)"),
31 cl::values(
32 clEnumValN(Searcher::DFS, "dfs", "use Depth First Search (DFS)"),
33 clEnumValN(Searcher::BFS, "bfs",
34 "use Breadth First Search (BFS), where scheduling decisions "
35 "are taken at the level of (2-way) forks"),
36 clEnumValN(Searcher::RandomState, "random-state",
37 "randomly select a state to explore"),
38 clEnumValN(Searcher::RandomPath, "random-path",
39 "use Random Path Selection (see OSDI'08 paper)"),
40 clEnumValN(Searcher::NURS_CovNew, "nurs:covnew",
41 "use Non Uniform Random Search (NURS) with Coverage-New"),
42 clEnumValN(Searcher::NURS_MD2U, "nurs:md2u",
43 "use NURS with Min-Dist-to-Uncovered"),
44 clEnumValN(Searcher::NURS_Depth, "nurs:depth", "use NURS with depth"),
45 clEnumValN(Searcher::NURS_RP, "nurs:rp", "use NURS with 1/2^depth"),
46 clEnumValN(Searcher::NURS_ICnt, "nurs:icnt",
47 "use NURS with Instr-Count"),
48 clEnumValN(Searcher::NURS_CPICnt, "nurs:cpicnt",
49 "use NURS with CallPath-Instr-Count"),
50 clEnumValN(Searcher::NURS_QC, "nurs:qc", "use NURS with Query-Cost")),
51 cl::cat(SearchCat));
52
53cl::opt<bool> UseIterativeDeepeningTimeSearch(
54 "use-iterative-deepening-time-search",
55 cl::desc(
56 "Use iterative deepening time search (experimental) (default=false)"),
57 cl::init(false),
58 cl::cat(SearchCat));
59
60cl::opt<bool> UseBatchingSearch(
61 "use-batching-search",
62 cl::desc("Use batching searcher (keep running selected state for N "
63 "instructions/time, see --batch-instructions and --batch-time) "
64 "(default=false)"),
65 cl::init(false),
66 cl::cat(SearchCat));
67
68cl::opt<unsigned> BatchInstructions(
69 "batch-instructions",
70 cl::desc("Number of instructions to batch when using "
71 "--use-batching-search. Set to 0 to disable (default=10000)"),
72 cl::init(10000),
73 cl::cat(SearchCat));
74
75cl::opt<std::string> BatchTime(
76 "batch-time",
77 cl::desc("Amount of time to batch when using "
78 "--use-batching-search. Set to 0s to disable (default=5s)"),
79 cl::init("5s"),
80 cl::cat(SearchCat));
81
82} // namespace
83
85 // default values
86 if (CoreSearch.empty()) {
87 if (UseMerge){
88 CoreSearch.push_back(Searcher::NURS_CovNew);
89 klee_warning("--use-merge enabled. Using NURS_CovNew as default searcher.");
90 } else {
91 CoreSearch.push_back(Searcher::RandomPath);
92 CoreSearch.push_back(Searcher::NURS_CovNew);
93 }
94 }
95}
96
98 return (std::find(CoreSearch.begin(), CoreSearch.end(), Searcher::NURS_MD2U) != CoreSearch.end() ||
99 std::find(CoreSearch.begin(), CoreSearch.end(), Searcher::NURS_CovNew) != CoreSearch.end() ||
100 std::find(CoreSearch.begin(), CoreSearch.end(), Searcher::NURS_ICnt) != CoreSearch.end() ||
101 std::find(CoreSearch.begin(), CoreSearch.end(), Searcher::NURS_CPICnt) != CoreSearch.end() ||
102 std::find(CoreSearch.begin(), CoreSearch.end(), Searcher::NURS_QC) != CoreSearch.end());
103}
104
105
107 Searcher *searcher = nullptr;
108 switch (type) {
109 case Searcher::DFS: searcher = new DFSSearcher(); break;
110 case Searcher::BFS: searcher = new BFSSearcher(); break;
111 case Searcher::RandomState: searcher = new RandomSearcher(rng); break;
112 case Searcher::RandomPath: searcher = new RandomPathSearcher(processTree, rng); break;
113 case Searcher::NURS_CovNew: searcher = new WeightedRandomSearcher(WeightedRandomSearcher::CoveringNew, rng); break;
114 case Searcher::NURS_MD2U: searcher = new WeightedRandomSearcher(WeightedRandomSearcher::MinDistToUncovered, rng); break;
115 case Searcher::NURS_Depth: searcher = new WeightedRandomSearcher(WeightedRandomSearcher::Depth, rng); break;
116 case Searcher::NURS_RP: searcher = new WeightedRandomSearcher(WeightedRandomSearcher::RP, rng); break;
117 case Searcher::NURS_ICnt: searcher = new WeightedRandomSearcher(WeightedRandomSearcher::InstCount, rng); break;
118 case Searcher::NURS_CPICnt: searcher = new WeightedRandomSearcher(WeightedRandomSearcher::CPInstCount, rng); break;
119 case Searcher::NURS_QC: searcher = new WeightedRandomSearcher(WeightedRandomSearcher::QueryCost, rng); break;
120 }
121
122 return searcher;
123}
124
126
127 Searcher *searcher = getNewSearcher(CoreSearch[0], executor.theRNG, *executor.processTree);
128
129 if (CoreSearch.size() > 1) {
130 std::vector<Searcher *> s;
131 s.push_back(searcher);
132
133 for (unsigned i = 1; i < CoreSearch.size(); i++)
134 s.push_back(getNewSearcher(CoreSearch[i], executor.theRNG, *executor.processTree));
135
136 searcher = new InterleavedSearcher(s);
137 }
138
139 if (UseBatchingSearch) {
140 searcher = new BatchingSearcher(searcher, time::Span(BatchTime),
141 BatchInstructions);
142 }
143
144 if (UseIterativeDeepeningTimeSearch) {
145 searcher = new IterativeDeepeningTimeSearcher(searcher);
146 }
147
148 if (UseMerge) {
149 auto *ms = new MergingSearcher(searcher);
150 executor.setMergingSearcher(ms);
151
152 searcher = ms;
153 }
154
155 llvm::raw_ostream &os = executor.getHandler().getInfoStream();
156
157 os << "BEGIN searcher description\n";
158 searcher->printName(os);
159 os << "END searcher description\n";
160
161 return searcher;
162}
Implementation of the region based merging.
Searcher * getNewSearcher(Searcher::CoreSearchType type, RNG &rng, PTree &processTree)
const InterpreterHandler & getHandler()
Definition: Executor.h:487
std::unique_ptr< PTree > processTree
Definition: Executor.h:119
RNG theRNG
The random number generator.
Definition: Executor.h:104
void setMergingSearcher(MergingSearcher *ms)
Definition: Executor.h:553
virtual llvm::raw_ostream & getInfoStream() const =0
Definition: RNG.h:14
RandomSearcher picks a state randomly.
Definition: Searcher.h:109
virtual void printName(llvm::raw_ostream &os)=0
Prints name of searcher as a klee_message().
void klee_warning(char *name)
Definition: klee-replay.c:432
Definition: main.cpp:291
llvm::cl::opt< bool > UseMerge
bool userSearcherRequiresMD2U()
Searcher * constructUserSearcher(Executor &executor)
void initializeSearchOptions()