1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
//===-- ExecutorTimers.cpp ------------------------------------------------===//
//
// The KLEE Symbolic Virtual Machine
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "CoreStats.h"
#include "Executor.h"
#include "ExecutorTimerInfo.h"
#include "PTree.h"
#include "StatsTracker.h"
#include "klee/ExecutionState.h"
#include "klee/Internal/Module/InstructionInfoTable.h"
#include "klee/Internal/Module/KInstruction.h"
#include "klee/Internal/Module/KModule.h"
#include "klee/Internal/Support/ErrorHandling.h"
#include "klee/Internal/System/Time.h"
#include "klee/OptionCategories.h"
#include "llvm/IR/Function.h"
#include "llvm/Support/CommandLine.h"
#include <math.h>
#include <signal.h>
#include <string>
#include <sys/time.h>
#include <unistd.h>
using namespace llvm;
using namespace klee;
namespace klee {
cl::opt<std::string>
MaxTime("max-time",
cl::desc("Halt execution after the specified number of seconds. "
"Set to 0s to disable (default=0s)"),
cl::init("0s"),
cl::cat(TerminationCat));
cl::opt<std::string>
TimerInterval("timer-interval",
cl::desc("Minimum interval to check timers (default=1s)"),
cl::init("1s"),
cl::cat(TerminationCat)); // StatsCat?
}
///
class HaltTimer : public Executor::Timer {
Executor *executor;
public:
HaltTimer(Executor *_executor) : executor(_executor) {}
~HaltTimer() {}
void run() {
klee_message("HaltTimer invoked");
executor->setHaltExecution(true);
}
};
///
void Executor::initTimers() {
const time::Span maxTime(MaxTime);
if (maxTime) {
addTimer(new HaltTimer(this), maxTime);
}
}
///
void Executor::addTimer(Timer *timer, time::Span rate) {
timers.push_back(new TimerInfo(timer, rate));
}
void Executor::processTimers(ExecutionState *current,
time::Span maxInstTime) {
const static time::Span minInterval(TimerInterval);
static time::Point lastCheckedTime;
const auto currentTime = time::getWallTime();
const auto duration = currentTime - lastCheckedTime;
if (duration < minInterval) return;
// check max instruction time
if (maxInstTime && current &&
std::find(removedStates.begin(), removedStates.end(), current) == removedStates.end() &&
duration > maxInstTime) {
klee_warning("max-instruction-time exceeded: %.2fs", duration.toSeconds());
terminateStateEarly(*current, "max-instruction-time exceeded");
}
// check timers
for (auto &timerInfo : timers) {
if (currentTime >= timerInfo->nextFireTime) {
timerInfo->timer->run();
timerInfo->nextFireTime = currentTime + timerInfo->rate;
}
}
lastCheckedTime = currentTime;
}
|