@@ -234,7 +234,14 @@ cl::opt<bool> RunForever("run-forever",
234234 cl::desc (" Store states when out of memory and explore "
235235 " them later (default=false)" ),
236236 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));
238245} // namespace klee
239246
240247namespace {
@@ -1222,18 +1229,16 @@ void Executor::branch(ExecutionState &state,
12221229 }
12231230
12241231 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);
12271233 assert (it != seedMap->end ());
12281234 assert (!it->second .empty ());
1229- std::vector<ExecutingSeed> seeds = it->second ;
1235+ seeds_ty seeds = it->second ;
12301236 seedMap->erase (it);
12311237 objectManager->unseed (it->first );
12321238 // Assume each seed only satisfies one condition (necessarily true
12331239 // when conditions are mutually exclusive and their conjunction is
12341240 // 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 ();
12371242 siit != siie; ++siit) {
12381243 unsigned i;
12391244 for (i = 0 ; i < N; ++i) {
@@ -1254,7 +1259,7 @@ void Executor::branch(ExecutionState &state,
12541259
12551260 // Extra check in case we're replaying seeds with a max-fork
12561261 if (result[i]) {
1257- seedMap->at (result[i]).push_back (*siit);
1262+ seedMap->at (result[i]).insert (*siit);
12581263 }
12591264 }
12601265 }
@@ -1360,8 +1365,8 @@ Executor::StatePair Executor::fork(ExecutionState ¤t, ref<Expr> condition,
13601365 bool isInternal = ifTrueBlock == ifFalseBlock;
13611366 PartialValidity res = PartialValidity::None;
13621367 bool isSeeding = current.isSeeded ;
1363- std::vector<ExecutingSeed> trueSeeds;
1364- std::vector<ExecutingSeed> falseSeeds;
1368+ seeds_ty trueSeeds;
1369+ seeds_ty falseSeeds;
13651370 time::Span timeout = coreSolverTimeout;
13661371 bool shouldCheckTrueBlock = true , shouldCheckFalseBlock = true ;
13671372
@@ -1385,13 +1390,11 @@ Executor::StatePair Executor::fork(ExecutionState ¤t, ref<Expr> condition,
13851390 }
13861391 }
13871392 } 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);
13901394 assert (it != seedMap->end ());
13911395 assert (!it->second .empty ());
13921396 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 ();
13951398 siit != siie; ++siit) {
13961399 ref<ConstantExpr> result;
13971400 bool success = solver->getValue (current.constraints .cs (),
@@ -1400,9 +1403,9 @@ Executor::StatePair Executor::fork(ExecutionState ¤t, ref<Expr> condition,
14001403 assert (success && " FIXME: Unhandled solver failure" );
14011404 (void )success;
14021405 if (result->isTrue ()) {
1403- trueSeeds.push_back (*siit);
1406+ trueSeeds.insert (*siit);
14041407 } else if (result->isFalse ()) {
1405- falseSeeds.push_back (*siit);
1408+ falseSeeds.insert (*siit);
14061409 }
14071410 }
14081411 if (!trueSeeds.empty () && falseSeeds.empty ()) {
@@ -1737,13 +1740,11 @@ void Executor::executeGetValue(ExecutionState &state, ref<Expr> e,
17371740 (void )success;
17381741 bindLocal (target, state, value);
17391742 } 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);
17421744 assert (it != seedMap->end ());
17431745 assert (!it->second .empty ());
17441746 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 ();
17471748 siit != siie; ++siit) {
17481749 ref<Expr> cond = siit->assignment .evaluate (e);
17491750 cond = optimizer.optimizeExpr (cond, true );
@@ -4562,16 +4563,14 @@ std::vector<ExecutingSeed> Executor::uploadNewSeeds() {
45624563
45634564void Executor::initialSeed (ExecutionState &initialState,
45644565 std::vector<ExecutingSeed> usingSeeds) {
4565- // FIX: better file managment when seeding + flag if all seeds are completed
4566-
45674566 if (usingSeeds.empty ()) {
45684567 return ;
45694568 }
4570- std::vector<ExecutingSeed> &v = seedMap->at (&initialState);
4569+ seeds_ty &v = seedMap->at (&initialState);
45714570 for (std::vector<ExecutingSeed>::const_iterator it = usingSeeds.begin (),
45724571 ie = usingSeeds.end ();
45734572 it != ie; ++it) {
4574- v.push_back (*it);
4573+ v.insert (*it);
45754574 }
45764575 klee_message (" Seeding began using %ld seeds!\n " , usingSeeds.size ());
45774576 objectManager->seed (&initialState);
@@ -4760,27 +4759,38 @@ bool Executor::reachedMaxSeedInstructions(ExecutionState *state) {
47604759 assert (state->isSeeded );
47614760 auto it = seedMap->find (state);
47624761 assert (it != seedMap->end ());
4763- if (it->second .size () != 1 ) {
4764- return false ;
4765- }
47664762
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 ();
47684770 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+ }
47804777 }
4781- return true ;
4778+ seeds. erase (seeds. begin ()) ;
47824779 }
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 ;
47844794}
47854795
47864796void Executor::goForward (ref<ForwardAction> action) {
@@ -4799,7 +4809,6 @@ void Executor::goForward(ref<ForwardAction> action) {
47994809 if (targetManager) {
48004810 targetManager->pullGlobal (state);
48014811 }
4802-
48034812 if (targetCalculator && TrackCoverage != TrackCoverageBy::None &&
48044813 state.multiplexKF && functionsByModule.modules .size () > 1 &&
48054814 targetCalculator->isCovered (state.multiplexKF )) {
@@ -4815,7 +4824,7 @@ void Executor::goForward(ref<ForwardAction> action) {
48154824 } else if (state.isSymbolicCycled (MaxSymbolicCycles)) {
48164825 terminateStateEarly (state, " max-sym-cycles exceeded." ,
48174826 StateTerminationType::MaxCycles);
4818- } else if (!fa-> state -> isSeeded || !reachedMaxSeedInstructions (fa-> state )) {
4827+ } else if (!state. isSeeded || !reachedMaxSeedInstructions (& state)) {
48194828 maxNewWriteableOSSize = 0 ;
48204829 maxNewStateStackSize = 0 ;
48214830
@@ -6801,14 +6810,13 @@ void Executor::executeMakeSymbolic(ExecutionState &state,
68016810
68026811 if (state.isSeeded ) { // In seed mode we need to add this as a
68036812 // 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);
68066814 assert (it != seedMap->end ());
68076815 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 ();
68106818 siit != siie; ++siit) {
6811- ExecutingSeed &si = *siit;
6819+ const ExecutingSeed &si = *siit;
68126820 KTestObject *obj = si.getNextInput (mo, NamedSeedMatching);
68136821
68146822 if (!obj) {
0 commit comments