40
40
#include " klee/Config/Version.h"
41
41
#include " klee/Config/config.h"
42
42
#include " klee/Core/Interpreter.h"
43
+ #include " klee/Core/TerminationTypes.h"
43
44
#include " klee/Expr/ArrayExprOptimizer.h"
44
45
#include " klee/Expr/ArrayExprVisitor.h"
45
46
#include " klee/Expr/Assignment.h"
@@ -519,9 +520,9 @@ Executor::Executor(LLVMContext &ctx, const InterpreterOptions &opts,
519
520
InterpreterHandler *ih)
520
521
: Interpreter(opts), interpreterHandler(ih), searcher(nullptr ),
521
522
externalDispatcher(new ExternalDispatcher(ctx)), statsTracker(0 ),
522
- pathWriter(0 ), symPathWriter(0 ),
523
- specialFunctionHandler( 0 ), timers{time::Span (TimerInterval)},
524
- guidanceKind (opts.Guidance), codeGraphInfo(new CodeGraphInfo()),
523
+ pathWriter(0 ), symPathWriter(0 ), specialFunctionHandler( 0 ),
524
+ timers{time::Span (TimerInterval)}, guidanceKind(opts.Guidance) ,
525
+ codeGraphInfo(new CodeGraphInfo()),
525
526
distanceCalculator(new DistanceCalculator(*codeGraphInfo)),
526
527
targetCalculator(new TargetCalculator(*codeGraphInfo)),
527
528
targetManager(new TargetManager(guidanceKind, *distanceCalculator,
@@ -2728,6 +2729,7 @@ void Executor::executeInstruction(ExecutionState &state, KInstruction *ki) {
2728
2729
if (bi->getMetadata (" md.ret" )) {
2729
2730
state.stack .forceReturnLocation (locationOf (state));
2730
2731
}
2732
+ state.lastBrConfidently = true ;
2731
2733
2732
2734
transferToBasicBlock (bi->getSuccessor (0 ), bi->getParent (), state);
2733
2735
} else {
@@ -2747,6 +2749,11 @@ void Executor::executeInstruction(ExecutionState &state, KInstruction *ki) {
2747
2749
maxNewStateStackSize =
2748
2750
std::max (maxNewStateStackSize,
2749
2751
branches.first ->stack .stackRegisterSize () * 8 );
2752
+ branches.first ->lastBrConfidently = false ;
2753
+ branches.second ->lastBrConfidently = false ;
2754
+ } else {
2755
+ (branches.first ? branches.first : branches.second )->lastBrConfidently =
2756
+ true ;
2750
2757
}
2751
2758
2752
2759
// NOTE: There is a hidden dependency here, markBranchVisited
@@ -4018,9 +4025,11 @@ void Executor::executeInstruction(ExecutionState &state, KInstruction *ki) {
4018
4025
if (iIdx >= vt->getNumElements ()) {
4019
4026
// Out of bounds write
4020
4027
terminateStateOnProgramError (
4021
- state, new ErrorEvent (locationOf (state),
4022
- StateTerminationType::BadVectorAccess,
4023
- " Out of bounds write when inserting element" ));
4028
+ state,
4029
+ new ErrorEvent (locationOf (state),
4030
+ StateTerminationType::BadVectorAccess,
4031
+ " Out of bounds write when inserting element" ),
4032
+ StateTerminationConfidenceCategory::CONFIDENT);
4024
4033
return ;
4025
4034
}
4026
4035
@@ -4061,9 +4070,11 @@ void Executor::executeInstruction(ExecutionState &state, KInstruction *ki) {
4061
4070
if (iIdx >= vt->getNumElements ()) {
4062
4071
// Out of bounds read
4063
4072
terminateStateOnProgramError (
4064
- state, new ErrorEvent (locationOf (state),
4065
- StateTerminationType::BadVectorAccess,
4066
- " Out of bounds read when extracting element" ));
4073
+ state,
4074
+ new ErrorEvent (locationOf (state),
4075
+ StateTerminationType::BadVectorAccess,
4076
+ " Out of bounds read when extracting element" ),
4077
+ StateTerminationConfidenceCategory::CONFIDENT);
4067
4078
return ;
4068
4079
}
4069
4080
@@ -4967,28 +4978,41 @@ void Executor::terminateStateOnTargetError(ExecutionState &state,
4967
4978
terminationType = StateTerminationType::User;
4968
4979
}
4969
4980
terminateStateOnProgramError (
4970
- state, new ErrorEvent (locationOf (state), terminationType, messaget));
4981
+ state, new ErrorEvent (locationOf (state), terminationType, messaget),
4982
+ StateTerminationConfidenceCategory::CONFIDENT);
4971
4983
}
4972
4984
4973
- void Executor::terminateStateOnError (ExecutionState &state,
4974
- const llvm::Twine &messaget,
4975
- StateTerminationType terminationType,
4976
- const llvm::Twine &info,
4977
- const char *suffix) {
4985
+ void Executor::terminateStateOnError (
4986
+ ExecutionState &state, const llvm::Twine &messaget,
4987
+ StateTerminationType terminationType,
4988
+ StateTerminationConfidenceCategory confidence, const llvm::Twine &info,
4989
+ const char *suffix) {
4978
4990
std::string message = messaget.str ();
4979
- static std::set<std::pair<Instruction *, std::string>> emittedErrors;
4991
+ static std::set<
4992
+ std::pair<Instruction *,
4993
+ std::pair<StateTerminationConfidenceCategory, std::string>>>
4994
+ emittedErrors;
4980
4995
const KInstruction *ki = getLastNonKleeInternalInstruction (state);
4981
4996
Instruction *lastInst = ki->inst ();
4982
4997
4983
- if ((EmitAllErrors ||
4984
- emittedErrors.insert (std::make_pair (lastInst, message)).second ) &&
4998
+ if ((EmitAllErrors || emittedErrors
4999
+ .insert (std::make_pair (
5000
+ lastInst, std::make_pair (confidence, message)))
5001
+ .second ) &&
4985
5002
shouldWriteTest (state, true )) {
4986
5003
std::string filepath = ki->getSourceFilepath ();
5004
+
5005
+ std::string prefix =
5006
+ (confidence == StateTerminationConfidenceCategory::CONFIDENT
5007
+ ? " ERROR"
5008
+ : " POSSIBLE ERROR" );
5009
+
4987
5010
if (!filepath.empty ()) {
4988
- klee_message (" ERROR : %s:%zu: %s" , filepath .c_str (), ki-> getLine (),
4989
- message.c_str ());
5011
+ klee_message ((prefix + " : %s:%zu: %s" ) .c_str (), filepath. c_str (),
5012
+ ki-> getLine (), message.c_str ());
4990
5013
} else {
4991
- klee_message (" ERROR: (location information missing) %s" , message.c_str ());
5014
+ klee_message ((prefix + " : (location information missing) %s" ).c_str (),
5015
+ message.c_str ());
4992
5016
}
4993
5017
if (!EmitAllErrors)
4994
5018
klee_message (" NOTE: now ignoring this error at this location" );
@@ -5034,13 +5058,14 @@ void Executor::terminateStateOnExecError(ExecutionState &state,
5034
5058
assert (reason > StateTerminationType::USERERR &&
5035
5059
reason <= StateTerminationType::EXECERR);
5036
5060
++stats::terminationExecutionError;
5037
- terminateStateOnError (state, message, reason, " " );
5061
+ terminateStateOnError (state, message, reason,
5062
+ StateTerminationConfidenceCategory::CONFIDENT, " " );
5038
5063
}
5039
5064
5040
- void Executor::terminateStateOnProgramError (ExecutionState &state,
5041
- const ref<ErrorEvent> &reason,
5042
- const llvm::Twine &info,
5043
- const char *suffix) {
5065
+ void Executor::terminateStateOnProgramError (
5066
+ ExecutionState &state, const ref<ErrorEvent> &reason,
5067
+ StateTerminationConfidenceCategory confidence, const llvm::Twine &info,
5068
+ const char *suffix) {
5044
5069
assert (reason->ruleID > StateTerminationType::SOLVERERR &&
5045
5070
reason->ruleID <= StateTerminationType::PROGERR);
5046
5071
++stats::terminationProgramError;
@@ -5059,19 +5084,22 @@ void Executor::terminateStateOnProgramError(ExecutionState &state,
5059
5084
}
5060
5085
state.eventsRecorder .record (reason);
5061
5086
5062
- terminateStateOnError (state, reason->message , reason->ruleID , info, suffix);
5087
+ terminateStateOnError (state, reason->message , reason->ruleID , confidence,
5088
+ info, suffix);
5063
5089
}
5064
5090
5065
5091
void Executor::terminateStateOnSolverError (ExecutionState &state,
5066
5092
const llvm::Twine &message) {
5067
5093
++stats::terminationSolverError;
5068
- terminateStateOnError (state, message, StateTerminationType::Solver, " " );
5094
+ terminateStateOnError (state, message, StateTerminationType::Solver,
5095
+ StateTerminationConfidenceCategory::CONFIDENT, " " );
5069
5096
}
5070
5097
5071
5098
void Executor::terminateStateOnUserError (ExecutionState &state,
5072
5099
const llvm::Twine &message) {
5073
5100
++stats::terminationUserError;
5074
- terminateStateOnError (state, message, StateTerminationType::User, " " );
5101
+ terminateStateOnError (state, message, StateTerminationType::User,
5102
+ StateTerminationConfidenceCategory::CONFIDENT, " " );
5075
5103
}
5076
5104
5077
5105
// XXX shoot me
@@ -5442,13 +5470,20 @@ void Executor::executeFree(ExecutionState &state, ref<Expr> address,
5442
5470
new ErrorEvent (new AllocEvent (mo->allocSite ),
5443
5471
locationOf (*it->second ), StateTerminationType::Free,
5444
5472
" free of alloca" ),
5473
+ rl.size () != 1 ? StateTerminationConfidenceCategory::PROBABLY
5474
+ : StateTerminationConfidenceCategory::CONFIDENT,
5445
5475
getAddressInfo (*it->second , address));
5446
5476
} else if (mo->isGlobal ) {
5477
+ if (rl.size () != 1 ) {
5478
+ klee_warning (" Following error if likely false positive" );
5479
+ }
5447
5480
terminateStateOnProgramError (
5448
5481
*it->second ,
5449
5482
new ErrorEvent (new AllocEvent (mo->allocSite ),
5450
5483
locationOf (*it->second ), StateTerminationType::Free,
5451
5484
" free of global" ),
5485
+ rl.size () != 1 ? StateTerminationConfidenceCategory::PROBABLY
5486
+ : StateTerminationConfidenceCategory::CONFIDENT,
5452
5487
getAddressInfo (*it->second , address));
5453
5488
} else {
5454
5489
it->second ->removePointerResolutions (mo);
@@ -5544,6 +5579,8 @@ bool Executor::resolveExact(ExecutionState &estate, ref<Expr> address,
5544
5579
*unbound,
5545
5580
new ErrorEvent (locationOf (*unbound), StateTerminationType::Ptr,
5546
5581
" memory error: invalid pointer: " + name),
5582
+ !results.empty () ? StateTerminationConfidenceCategory::PROBABLY
5583
+ : StateTerminationConfidenceCategory::CONFIDENT,
5547
5584
getAddressInfo (*unbound, address));
5548
5585
}
5549
5586
}
@@ -5633,7 +5670,7 @@ void Executor::concretizeSize(ExecutionState &state, ref<Expr> size,
5633
5670
new ErrorEvent (locationOf (*hugeSize.second ),
5634
5671
StateTerminationType::Model,
5635
5672
" concretized symbolic size" ),
5636
- info.str ());
5673
+ StateTerminationConfidenceCategory::CONFIDENT, info.str ());
5637
5674
}
5638
5675
}
5639
5676
}
@@ -6359,7 +6396,8 @@ void Executor::executeMemoryOperation(
6359
6396
*state,
6360
6397
new ErrorEvent (new AllocEvent (mo->allocSite ), locationOf (*state),
6361
6398
StateTerminationType::ReadOnly,
6362
- " memory error: object read only" ));
6399
+ " memory error: object read only" ),
6400
+ StateTerminationConfidenceCategory::CONFIDENT);
6363
6401
} else {
6364
6402
wos->write (mo->getOffsetExpr (address), value);
6365
6403
}
@@ -6431,6 +6469,10 @@ void Executor::executeMemoryOperation(
6431
6469
return ;
6432
6470
}
6433
6471
6472
+ bool mayBeFalsePositive =
6473
+ resolvedMemoryObjects.size () > 1 ||
6474
+ (resolvedMemoryObjects.size () == 1 && mayBeOutOfBound);
6475
+
6434
6476
ExecutionState *unbound = nullptr ;
6435
6477
if (MergedPointerDereference) {
6436
6478
ref<Expr> guard;
@@ -6488,7 +6530,10 @@ void Executor::executeMemoryOperation(
6488
6530
new ErrorEvent (new AllocEvent (mo->allocSite ),
6489
6531
locationOf (*branches.first ),
6490
6532
StateTerminationType::ReadOnly,
6491
- " memory error: object read only" ));
6533
+ " memory error: object read only" ),
6534
+ mayBeFalsePositive
6535
+ ? StateTerminationConfidenceCategory::PROBABLY
6536
+ : StateTerminationConfidenceCategory::CONFIDENT);
6492
6537
state = branches.second ;
6493
6538
} else {
6494
6539
ref<Expr> result = SelectExpr::create (
@@ -6560,7 +6605,10 @@ void Executor::executeMemoryOperation(
6560
6605
*bound,
6561
6606
new ErrorEvent (new AllocEvent (mo->allocSite ), locationOf (*bound),
6562
6607
StateTerminationType::ReadOnly,
6563
- " memory error: object read only" ));
6608
+ " memory error: object read only" ),
6609
+ mayBeFalsePositive
6610
+ ? StateTerminationConfidenceCategory::PROBABLY
6611
+ : StateTerminationConfidenceCategory::CONFIDENT);
6564
6612
} else {
6565
6613
wos->write (mo->getOffsetExpr (address), value);
6566
6614
}
@@ -6622,6 +6670,8 @@ void Executor::executeMemoryOperation(
6622
6670
new ErrorEvent (new AllocEvent (baseObjectPair.first ->allocSite ),
6623
6671
locationOf (*unbound), StateTerminationType::Ptr,
6624
6672
" memory error: out of bound pointer" ),
6673
+ mayBeFalsePositive ? StateTerminationConfidenceCategory::PROBABLY
6674
+ : StateTerminationConfidenceCategory::CONFIDENT,
6625
6675
getAddressInfo (*unbound, address));
6626
6676
return ;
6627
6677
}
@@ -6631,6 +6681,8 @@ void Executor::executeMemoryOperation(
6631
6681
*unbound,
6632
6682
new ErrorEvent (locationOf (*unbound), StateTerminationType::Ptr,
6633
6683
" memory error: out of bound pointer" ),
6684
+ mayBeFalsePositive ? StateTerminationConfidenceCategory::PROBABLY
6685
+ : StateTerminationConfidenceCategory::CONFIDENT,
6634
6686
getAddressInfo (*unbound, address));
6635
6687
}
6636
6688
}
@@ -6864,8 +6916,7 @@ void Executor::executeMakeSymbolic(ExecutionState &state,
6864
6916
(!AllowSeedTruncation && obj->numBytes > mo->size ))) {
6865
6917
std::stringstream msg;
6866
6918
msg << " replace size mismatch: " << mo->name << " [" << mo->size
6867
- << " ]"
6868
- << " vs " << obj->name << " [" << obj->numBytes << " ]"
6919
+ << " ]" << " vs " << obj->name << " [" << obj->numBytes << " ]"
6869
6920
<< " in test\n " ;
6870
6921
6871
6922
terminateStateOnUserError (state, msg.str ());
@@ -7309,8 +7360,7 @@ void Executor::logState(const ExecutionState &state, int id,
7309
7360
*f << " Address memory object: " << object.first ->address << " \n " ;
7310
7361
*f << " Memory object size: " << object.first ->size << " \n " ;
7311
7362
}
7312
- *f << state.symbolics .size () << " symbolics total. "
7313
- << " Symbolics:\n " ;
7363
+ *f << state.symbolics .size () << " symbolics total. " << " Symbolics:\n " ;
7314
7364
size_t sc = 0 ;
7315
7365
for (const auto &symbolic : state.symbolics ) {
7316
7366
*f << " Symbolic number " << sc++ << " \n " ;
0 commit comments