klee
QueryLoggingSolver.cpp
Go to the documentation of this file.
1//===-- QueryLoggingSolver.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//===----------------------------------------------------------------------===//
10
11#include "klee/Config/config.h"
16#include "klee/System/Time.h"
17
18namespace {
19llvm::cl::opt<bool> DumpPartialQueryiesEarly(
20 "log-partial-queries-early", llvm::cl::init(false),
21 llvm::cl::desc("Log queries before calling the solver (default=false)"),
22 llvm::cl::cat(klee::SolvingCat));
23
24#ifdef HAVE_ZLIB_H
25llvm::cl::opt<bool> CreateCompressedQueryLog(
26 "compress-query-log", llvm::cl::init(false),
27 llvm::cl::desc("Compress query log files (default=false)"),
28 llvm::cl::cat(klee::SolvingCat));
29#endif
30} // namespace
31
33 const std::string &commentSign,
34 time::Span queryTimeToLog,
35 bool logTimedOut)
36 : solver(_solver), BufferString(""), logBuffer(BufferString), queryCount(0),
37 minQueryTimeToLog(queryTimeToLog), logTimedOutQueries(logTimedOut),
38 queryCommentSign(commentSign) {
39 std::string error;
40#ifdef HAVE_ZLIB_H
41 if (!CreateCompressedQueryLog) {
42#endif
43 os = klee_open_output_file(path, error);
44#ifdef HAVE_ZLIB_H
45 } else {
46 path.append(".gz");
47 os = klee_open_compressed_output_file(path, error);
48 }
49#endif
50 if (!os) {
51 klee_error("Could not open file %s : %s", path.c_str(), error.c_str());
52 }
53 assert(0 != solver);
54}
55
57 delete solver;
58}
59
61 logBuffer.flush();
62 if (writeToFile) {
63 *os << logBuffer.str();
64 os->flush();
65 }
66 // prepare the buffer for reuse
67 BufferString = "";
68}
69
70void QueryLoggingSolver::startQuery(const Query &query, const char *typeName,
71 const Query *falseQuery,
72 const std::vector<const Array *> *objects) {
74 uint64_t instructions = S ? S->getValue() : 0;
75
76 logBuffer << queryCommentSign << " Query " << queryCount++ << " -- "
77 << "Type: " << typeName << ", "
78 << "Instructions: " << instructions << "\n";
79
80 printQuery(query, falseQuery, objects);
81
82 if (DumpPartialQueryiesEarly) {
84 }
86}
87
90 logBuffer << queryCommentSign << " " << (success ? "OK" : "FAIL") << " -- "
91 << "Elapsed: " << lastQueryDuration << "\n";
92
93 if (false == success) {
94 logBuffer << queryCommentSign << " Failure reason: "
95 << SolverImpl::getOperationStatusString(
97 }
98}
99
101 // we either do not limit logging queries
102 // or the query time is larger than threshold
103 // or we log a timed out query
104 bool writeToFile = (!minQueryTimeToLog)
106 || (logTimedOutQueries &&
108
109 flushBufferConditionally(writeToFile);
110}
111
112bool QueryLoggingSolver::computeTruth(const Query &query, bool &isValid) {
113 startQuery(query, "Truth");
114
115 bool success = solver->impl->computeTruth(query, isValid);
116
117 finishQuery(success);
118
119 if (success) {
121 << " Is Valid: " << (isValid ? "true" : "false") << "\n";
122 }
123 logBuffer << "\n";
124
125 flushBuffer();
126
127 return success;
128}
129
131 Solver::Validity &result) {
132 startQuery(query, "Validity");
133
134 bool success = solver->impl->computeValidity(query, result);
135
136 finishQuery(success);
137
138 if (success) {
139 logBuffer << queryCommentSign << " Validity: " << result << "\n";
140 }
141 logBuffer << "\n";
142
143 flushBuffer();
144
145 return success;
146}
147
149 Query withFalse = query.withFalse();
150 startQuery(query, "Value", &withFalse);
151
152 bool success = solver->impl->computeValue(query, result);
153
154 finishQuery(success);
155
156 if (success) {
157 logBuffer << queryCommentSign << " Result: " << result << "\n";
158 }
159 logBuffer << "\n";
160
161 flushBuffer();
162
163 return success;
164}
165
167 const Query &query, const std::vector<const Array *> &objects,
168 std::vector<std::vector<unsigned char> > &values, bool &hasSolution) {
169 startQuery(query, "InitialValues", 0, &objects);
170
171 bool success =
172 solver->impl->computeInitialValues(query, objects, values, hasSolution);
173
174 finishQuery(success);
175
176 if (success) {
178 << " Solvable: " << (hasSolution ? "true" : "false") << "\n";
179 if (hasSolution) {
180 std::vector<std::vector<unsigned char> >::iterator values_it =
181 values.begin();
182
183 for (std::vector<const Array *>::const_iterator i = objects.begin(),
184 e = objects.end();
185 i != e; ++i, ++values_it) {
186 const Array *array = *i;
187 std::vector<unsigned char> &data = *values_it;
188 logBuffer << queryCommentSign << " " << array->name << " = [";
189
190 for (unsigned j = 0; j < array->size; j++) {
191 logBuffer << (int)data[j];
192
193 if (j + 1 < array->size) {
194 logBuffer << ",";
195 }
196 }
197 logBuffer << "]\n";
198 }
199 }
200 }
201 logBuffer << "\n";
202
203 flushBuffer();
204
205 return success;
206}
207
210}
211
213 return solver->impl->getConstraintLog(query);
214}
215
218}
SolverRunStatus getOperationStatusCode()
getOperationStatusCode - get the status of the last solver operation
bool computeTruth(const Query &query, bool &isValid)
implementation of the SolverImpl interface
std::unique_ptr< llvm::raw_ostream > os
virtual void printQuery(const Query &query, const Query *falseQuery=0, const std::vector< const Array * > *objects=0)=0
virtual void startQuery(const Query &query, const char *typeName, const Query *falseQuery=0, const std::vector< const Array * > *objects=0)
time::Span lastQueryDuration
char * getConstraintLog(const Query &)
time::Span minQueryTimeToLog
bool computeValue(const Query &query, ref< Expr > &result)
void setCoreSolverTimeout(time::Span timeout)
const std::string queryCommentSign
llvm::raw_string_ostream logBuffer
bool computeValidity(const Query &query, Solver::Validity &result)
QueryLoggingSolver(Solver *_solver, std::string path, const std::string &commentSign, time::Span queryTimeToLog, bool logTimedOut)
virtual void finishQuery(bool success)
void flushBufferConditionally(bool writeToFile)
bool computeInitialValues(const Query &query, const std::vector< const Array * > &objects, std::vector< std::vector< unsigned char > > &values, bool &hasSolution)
const unsigned size
Definition: Expr.h:489
const std::string name
Definition: Expr.h:486
virtual void setCoreSolverTimeout(time::Span timeout)
Definition: SolverImpl.h:109
virtual bool computeTruth(const Query &query, bool &isValid)=0
virtual bool computeInitialValues(const Query &query, const std::vector< const Array * > &objects, std::vector< std::vector< unsigned char > > &values, bool &hasSolution)=0
@ SOLVER_RUN_STATUS_TIMEOUT
Definition: SolverImpl.h:37
virtual bool computeValue(const Query &query, ref< Expr > &result)=0
virtual char * getConstraintLog(const Query &query)
Definition: SolverImpl.h:104
virtual bool computeValidity(const Query &query, Solver::Validity &result)
Definition: SolverImpl.cpp:17
virtual SolverRunStatus getOperationStatusCode()=0
getOperationStatusCode - get the status of the last solver operation
SolverImpl * impl
Definition: Solver.h:77
Statistic * getStatisticByName(const std::string &name) const
Definition: Statistics.cpp:50
std::uint64_t getValue() const
getValue - Get the current primary statistic value.
Definition: Statistics.cpp:77
Statistic instructions
Point getWallTime()
Returns point in time using a monotonic steady clock.
Definition: Time.cpp:206
std::unique_ptr< llvm::raw_fd_ostream > klee_open_output_file(const std::string &path, std::string &error)
void klee_error(const char *msg,...) __attribute__((format(printf
llvm::cl::OptionCategory SolvingCat
StatisticManager * theStatisticManager
Definition: Statistics.cpp:57
Query withFalse() const
withFalse - Return a copy of the query with a false expression.
Definition: Solver.h:47