@@ -234,7 +234,14 @@ cl::opt<bool> RunForever("run-forever",
234
234
cl::desc (" Store states when out of memory and explore "
235
235
" them later (default=false)" ),
236
236
cl::init(false ), cl::cat(SeedingCat));
237
-
237
+ cl::list<std::string>
238
+ SeedOutDir (" seed-dir" ,
239
+ cl::desc (" Directory with .ktest files to be used as seeds" ),
240
+ cl::cat(SeedingCat));
241
+
242
+ cl::list<std::string> SeedOutFile (" seed-file" ,
243
+ cl::desc (" .ktest file to be used as seed" ),
244
+ cl::cat(SeedingCat));
238
245
} // namespace klee
239
246
240
247
namespace {
@@ -1222,18 +1229,16 @@ void Executor::branch(ExecutionState &state,
1222
1229
}
1223
1230
1224
1231
if (state.isSeeded ) {
1225
- std::map<ExecutionState *, std::vector<ExecutingSeed>>::iterator it =
1226
- seedMap->find (&state);
1232
+ std::map<ExecutionState *, seeds_ty>::iterator it = seedMap->find (&state);
1227
1233
assert (it != seedMap->end ());
1228
1234
assert (!it->second .empty ());
1229
- std::vector<ExecutingSeed> seeds = it->second ;
1235
+ seeds_ty seeds = it->second ;
1230
1236
seedMap->erase (it);
1231
1237
objectManager->unseed (it->first );
1232
1238
// Assume each seed only satisfies one condition (necessarily true
1233
1239
// when conditions are mutually exclusive and their conjunction is
1234
1240
// a tautology).
1235
- for (std::vector<ExecutingSeed>::iterator siit = seeds.begin (),
1236
- siie = seeds.end ();
1241
+ for (seeds_ty::iterator siit = seeds.begin (), siie = seeds.end ();
1237
1242
siit != siie; ++siit) {
1238
1243
unsigned i;
1239
1244
for (i = 0 ; i < N; ++i) {
@@ -1254,7 +1259,7 @@ void Executor::branch(ExecutionState &state,
1254
1259
1255
1260
// Extra check in case we're replaying seeds with a max-fork
1256
1261
if (result[i]) {
1257
- seedMap->at (result[i]).push_back (*siit);
1262
+ seedMap->at (result[i]).insert (*siit);
1258
1263
}
1259
1264
}
1260
1265
}
@@ -1360,8 +1365,8 @@ Executor::StatePair Executor::fork(ExecutionState ¤t, ref<Expr> condition,
1360
1365
bool isInternal = ifTrueBlock == ifFalseBlock;
1361
1366
PartialValidity res = PartialValidity::None;
1362
1367
bool isSeeding = current.isSeeded ;
1363
- std::vector<ExecutingSeed> trueSeeds;
1364
- std::vector<ExecutingSeed> falseSeeds;
1368
+ seeds_ty trueSeeds;
1369
+ seeds_ty falseSeeds;
1365
1370
time::Span timeout = coreSolverTimeout;
1366
1371
bool shouldCheckTrueBlock = true , shouldCheckFalseBlock = true ;
1367
1372
@@ -1385,13 +1390,11 @@ Executor::StatePair Executor::fork(ExecutionState ¤t, ref<Expr> condition,
1385
1390
}
1386
1391
}
1387
1392
} else {
1388
- std::map<ExecutionState *, std::vector<ExecutingSeed>>::iterator it =
1389
- seedMap->find (¤t);
1393
+ std::map<ExecutionState *, seeds_ty>::iterator it = seedMap->find (¤t);
1390
1394
assert (it != seedMap->end ());
1391
1395
assert (!it->second .empty ());
1392
1396
timeout *= static_cast <unsigned >(it->second .size ());
1393
- for (std::vector<ExecutingSeed>::iterator siit = it->second .begin (),
1394
- siie = it->second .end ();
1397
+ for (seeds_ty::iterator siit = it->second .begin (), siie = it->second .end ();
1395
1398
siit != siie; ++siit) {
1396
1399
ref<ConstantExpr> result;
1397
1400
bool success = solver->getValue (current.constraints .cs (),
@@ -1400,9 +1403,9 @@ Executor::StatePair Executor::fork(ExecutionState ¤t, ref<Expr> condition,
1400
1403
assert (success && " FIXME: Unhandled solver failure" );
1401
1404
(void )success;
1402
1405
if (result->isTrue ()) {
1403
- trueSeeds.push_back (*siit);
1406
+ trueSeeds.insert (*siit);
1404
1407
} else if (result->isFalse ()) {
1405
- falseSeeds.push_back (*siit);
1408
+ falseSeeds.insert (*siit);
1406
1409
}
1407
1410
}
1408
1411
if (!trueSeeds.empty () && falseSeeds.empty ()) {
@@ -1737,13 +1740,11 @@ void Executor::executeGetValue(ExecutionState &state, ref<Expr> e,
1737
1740
(void )success;
1738
1741
bindLocal (target, state, value);
1739
1742
} else {
1740
- std::map<ExecutionState *, std::vector<ExecutingSeed>>::iterator it =
1741
- seedMap->find (&state);
1743
+ std::map<ExecutionState *, seeds_ty>::iterator it = seedMap->find (&state);
1742
1744
assert (it != seedMap->end ());
1743
1745
assert (!it->second .empty ());
1744
1746
std::set<ref<Expr>> values;
1745
- for (std::vector<ExecutingSeed>::iterator siit = it->second .begin (),
1746
- siie = it->second .end ();
1747
+ for (seeds_ty::iterator siit = it->second .begin (), siie = it->second .end ();
1747
1748
siit != siie; ++siit) {
1748
1749
ref<Expr> cond = siit->assignment .evaluate (e);
1749
1750
cond = optimizer.optimizeExpr (cond, true );
@@ -4562,16 +4563,14 @@ std::vector<ExecutingSeed> Executor::uploadNewSeeds() {
4562
4563
4563
4564
void Executor::initialSeed (ExecutionState &initialState,
4564
4565
std::vector<ExecutingSeed> usingSeeds) {
4565
- // FIX: better file managment when seeding + flag if all seeds are completed
4566
-
4567
4566
if (usingSeeds.empty ()) {
4568
4567
return ;
4569
4568
}
4570
- std::vector<ExecutingSeed> &v = seedMap->at (&initialState);
4569
+ seeds_ty &v = seedMap->at (&initialState);
4571
4570
for (std::vector<ExecutingSeed>::const_iterator it = usingSeeds.begin (),
4572
4571
ie = usingSeeds.end ();
4573
4572
it != ie; ++it) {
4574
- v.push_back (*it);
4573
+ v.insert (*it);
4575
4574
}
4576
4575
klee_message (" Seeding began using %ld seeds!\n " , usingSeeds.size ());
4577
4576
objectManager->seed (&initialState);
@@ -4760,27 +4759,38 @@ bool Executor::reachedMaxSeedInstructions(ExecutionState *state) {
4760
4759
assert (state->isSeeded );
4761
4760
auto it = seedMap->find (state);
4762
4761
assert (it != seedMap->end ());
4763
- if (it->second .size () != 1 ) {
4764
- return false ;
4765
- }
4766
4762
4767
- std::vector<ExecutingSeed>::iterator siit = it->second .begin ();
4763
+ seeds_ty &seeds = it->second ;
4764
+
4765
+ assert (!seeds.empty ());
4766
+ assert (seeds.begin ()->maxInstructions >= state->steppedInstructions &&
4767
+ " state stepped instructions exceeded seed max instructions" );
4768
+
4769
+ seeds_ty::iterator siit = seeds.begin ();
4768
4770
if (siit->maxInstructions &&
4769
- siit->maxInstructions <= state->steppedInstructions ) {
4770
- assert (siit->maxInstructions == state->steppedInstructions &&
4771
- " state stepped instructions exceeded seed max instructions" );
4772
- state->coveredNew = siit->coveredNew ;
4773
- if (siit->coveredNewError ) {
4774
- state->coveredNewError = siit->coveredNewError ;
4775
- }
4776
- seedMap->erase (state);
4777
- objectManager->unseed (state);
4778
- if (seedMap->size () == 0 ) {
4779
- klee_message (" Seeding done!\n " );
4771
+ siit->maxInstructions == state->steppedInstructions ) {
4772
+ if (seeds.size () == 1 ) {
4773
+ state->coveredNew = siit->coveredNew ;
4774
+ if (siit->coveredNewError ) {
4775
+ state->coveredNewError = siit->coveredNewError ;
4776
+ }
4780
4777
}
4781
- return true ;
4778
+ seeds. erase (seeds. begin ()) ;
4782
4779
}
4783
- return false ;
4780
+
4781
+ assert (seeds.empty () ||
4782
+ seeds.begin ()->maxInstructions != state->steppedInstructions );
4783
+
4784
+ if (!seeds.empty ()) {
4785
+ return false ;
4786
+ }
4787
+
4788
+ seedMap->erase (state);
4789
+ objectManager->unseed (state);
4790
+ if (seedMap->size () == 0 ) {
4791
+ klee_message (" Seeding done!\n " );
4792
+ }
4793
+ return true ;
4784
4794
}
4785
4795
4786
4796
void Executor::goForward (ref<ForwardAction> action) {
@@ -4799,7 +4809,6 @@ void Executor::goForward(ref<ForwardAction> action) {
4799
4809
if (targetManager) {
4800
4810
targetManager->pullGlobal (state);
4801
4811
}
4802
-
4803
4812
if (targetCalculator && TrackCoverage != TrackCoverageBy::None &&
4804
4813
state.multiplexKF && functionsByModule.modules .size () > 1 &&
4805
4814
targetCalculator->isCovered (state.multiplexKF )) {
@@ -4815,7 +4824,7 @@ void Executor::goForward(ref<ForwardAction> action) {
4815
4824
} else if (state.isSymbolicCycled (MaxSymbolicCycles)) {
4816
4825
terminateStateEarly (state, " max-sym-cycles exceeded." ,
4817
4826
StateTerminationType::MaxCycles);
4818
- } else if (!fa-> state -> isSeeded || !reachedMaxSeedInstructions (fa-> state )) {
4827
+ } else if (!state. isSeeded || !reachedMaxSeedInstructions (& state)) {
4819
4828
maxNewWriteableOSSize = 0 ;
4820
4829
maxNewStateStackSize = 0 ;
4821
4830
@@ -6801,14 +6810,13 @@ void Executor::executeMakeSymbolic(ExecutionState &state,
6801
6810
6802
6811
if (state.isSeeded ) { // In seed mode we need to add this as a
6803
6812
// binding.
6804
- std::map<ExecutionState *, std::vector<ExecutingSeed>>::iterator it =
6805
- seedMap->find (&state);
6813
+ std::map<ExecutionState *, seeds_ty>::iterator it = seedMap->find (&state);
6806
6814
assert (it != seedMap->end ());
6807
6815
assert (!it->second .empty ());
6808
- for (std::vector<ExecutingSeed> ::iterator siit = it->second .begin (),
6809
- siie = it->second .end ();
6816
+ for (seeds_ty ::iterator siit = it->second .begin (),
6817
+ siie = it->second .end ();
6810
6818
siit != siie; ++siit) {
6811
- ExecutingSeed &si = *siit;
6819
+ const ExecutingSeed &si = *siit;
6812
6820
KTestObject *obj = si.getNextInput (mo, NamedSeedMatching);
6813
6821
6814
6822
if (!obj) {
0 commit comments