40
40
#include " klee/Config/config.h"
41
41
#include " klee/Core/Interpreter.h"
42
42
#include " klee/Core/MockBuilder.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"
@@ -2724,6 +2725,7 @@ void Executor::executeInstruction(ExecutionState &state, KInstruction *ki) {
2724
2725
if (bi->getMetadata (" md.ret" )) {
2725
2726
state.stack .forceReturnLocation (locationOf (state));
2726
2727
}
2728
+ state.lastBrConfidently = true ;
2727
2729
2728
2730
transferToBasicBlock (bi->getSuccessor (0 ), bi->getParent (), state);
2729
2731
} else {
@@ -2743,6 +2745,11 @@ void Executor::executeInstruction(ExecutionState &state, KInstruction *ki) {
2743
2745
maxNewStateStackSize =
2744
2746
std::max (maxNewStateStackSize,
2745
2747
branches.first ->stack .stackRegisterSize () * 8 );
2748
+ branches.first ->lastBrConfidently = false ;
2749
+ branches.second ->lastBrConfidently = false ;
2750
+ } else {
2751
+ (branches.first ? branches.first : branches.second )->lastBrConfidently =
2752
+ true ;
2746
2753
}
2747
2754
2748
2755
// NOTE: There is a hidden dependency here, markBranchVisited
@@ -4014,9 +4021,11 @@ void Executor::executeInstruction(ExecutionState &state, KInstruction *ki) {
4014
4021
if (iIdx >= vt->getNumElements ()) {
4015
4022
// Out of bounds write
4016
4023
terminateStateOnProgramError (
4017
- state, new ErrorEvent (locationOf (state),
4018
- StateTerminationType::BadVectorAccess,
4019
- " Out of bounds write when inserting element" ));
4024
+ state,
4025
+ new ErrorEvent (locationOf (state),
4026
+ StateTerminationType::BadVectorAccess,
4027
+ " Out of bounds write when inserting element" ),
4028
+ StateTerminationConfidenceCategory::CONFIDENT);
4020
4029
return ;
4021
4030
}
4022
4031
@@ -4057,9 +4066,11 @@ void Executor::executeInstruction(ExecutionState &state, KInstruction *ki) {
4057
4066
if (iIdx >= vt->getNumElements ()) {
4058
4067
// Out of bounds read
4059
4068
terminateStateOnProgramError (
4060
- state, new ErrorEvent (locationOf (state),
4061
- StateTerminationType::BadVectorAccess,
4062
- " Out of bounds read when extracting element" ));
4069
+ state,
4070
+ new ErrorEvent (locationOf (state),
4071
+ StateTerminationType::BadVectorAccess,
4072
+ " Out of bounds read when extracting element" ),
4073
+ StateTerminationConfidenceCategory::CONFIDENT);
4063
4074
return ;
4064
4075
}
4065
4076
@@ -4963,28 +4974,41 @@ void Executor::terminateStateOnTargetError(ExecutionState &state,
4963
4974
terminationType = StateTerminationType::User;
4964
4975
}
4965
4976
terminateStateOnProgramError (
4966
- state, new ErrorEvent (locationOf (state), terminationType, messaget));
4977
+ state, new ErrorEvent (locationOf (state), terminationType, messaget),
4978
+ StateTerminationConfidenceCategory::CONFIDENT);
4967
4979
}
4968
4980
4969
- void Executor::terminateStateOnError (ExecutionState &state,
4970
- const llvm::Twine &messaget,
4971
- StateTerminationType terminationType,
4972
- const llvm::Twine &info,
4973
- const char *suffix) {
4981
+ void Executor::terminateStateOnError (
4982
+ ExecutionState &state, const llvm::Twine &messaget,
4983
+ StateTerminationType terminationType,
4984
+ StateTerminationConfidenceCategory confidence, const llvm::Twine &info,
4985
+ const char *suffix) {
4974
4986
std::string message = messaget.str ();
4975
- static std::set<std::pair<Instruction *, std::string>> emittedErrors;
4987
+ static std::set<
4988
+ std::pair<Instruction *,
4989
+ std::pair<StateTerminationConfidenceCategory, std::string>>>
4990
+ emittedErrors;
4976
4991
const KInstruction *ki = getLastNonKleeInternalInstruction (state);
4977
4992
Instruction *lastInst = ki->inst ();
4978
4993
4979
- if ((EmitAllErrors ||
4980
- emittedErrors.insert (std::make_pair (lastInst, message)).second ) &&
4994
+ if ((EmitAllErrors || emittedErrors
4995
+ .insert (std::make_pair (
4996
+ lastInst, std::make_pair (confidence, message)))
4997
+ .second ) &&
4981
4998
shouldWriteTest (state, true )) {
4982
4999
std::string filepath = ki->getSourceFilepath ();
5000
+
5001
+ std::string prefix =
5002
+ (confidence == StateTerminationConfidenceCategory::CONFIDENT
5003
+ ? " ERROR"
5004
+ : " POSSIBLE ERROR" );
5005
+
4983
5006
if (!filepath.empty ()) {
4984
- klee_message (" ERROR : %s:%zu: %s" , filepath .c_str (), ki-> getLine (),
4985
- message.c_str ());
5007
+ klee_message ((prefix + " : %s:%zu: %s" ) .c_str (), filepath. c_str (),
5008
+ ki-> getLine (), message.c_str ());
4986
5009
} else {
4987
- klee_message (" ERROR: (location information missing) %s" , message.c_str ());
5010
+ klee_message ((prefix + " : (location information missing) %s" ).c_str (),
5011
+ message.c_str ());
4988
5012
}
4989
5013
if (!EmitAllErrors)
4990
5014
klee_message (" NOTE: now ignoring this error at this location" );
@@ -5030,13 +5054,14 @@ void Executor::terminateStateOnExecError(ExecutionState &state,
5030
5054
assert (reason > StateTerminationType::USERERR &&
5031
5055
reason <= StateTerminationType::EXECERR);
5032
5056
++stats::terminationExecutionError;
5033
- terminateStateOnError (state, message, reason, " " );
5057
+ terminateStateOnError (state, message, reason,
5058
+ StateTerminationConfidenceCategory::CONFIDENT, " " );
5034
5059
}
5035
5060
5036
- void Executor::terminateStateOnProgramError (ExecutionState &state,
5037
- const ref<ErrorEvent> &reason,
5038
- const llvm::Twine &info,
5039
- const char *suffix) {
5061
+ void Executor::terminateStateOnProgramError (
5062
+ ExecutionState &state, const ref<ErrorEvent> &reason,
5063
+ StateTerminationConfidenceCategory confidence, const llvm::Twine &info,
5064
+ const char *suffix) {
5040
5065
assert (reason->ruleID > StateTerminationType::SOLVERERR &&
5041
5066
reason->ruleID <= StateTerminationType::PROGERR);
5042
5067
++stats::terminationProgramError;
@@ -5055,19 +5080,22 @@ void Executor::terminateStateOnProgramError(ExecutionState &state,
5055
5080
}
5056
5081
state.eventsRecorder .record (reason);
5057
5082
5058
- terminateStateOnError (state, reason->message , reason->ruleID , info, suffix);
5083
+ terminateStateOnError (state, reason->message , reason->ruleID , confidence,
5084
+ info, suffix);
5059
5085
}
5060
5086
5061
5087
void Executor::terminateStateOnSolverError (ExecutionState &state,
5062
5088
const llvm::Twine &message) {
5063
5089
++stats::terminationSolverError;
5064
- terminateStateOnError (state, message, StateTerminationType::Solver, " " );
5090
+ terminateStateOnError (state, message, StateTerminationType::Solver,
5091
+ StateTerminationConfidenceCategory::CONFIDENT, " " );
5065
5092
}
5066
5093
5067
5094
void Executor::terminateStateOnUserError (ExecutionState &state,
5068
5095
const llvm::Twine &message) {
5069
5096
++stats::terminationUserError;
5070
- terminateStateOnError (state, message, StateTerminationType::User, " " );
5097
+ terminateStateOnError (state, message, StateTerminationType::User,
5098
+ StateTerminationConfidenceCategory::CONFIDENT, " " );
5071
5099
}
5072
5100
5073
5101
// XXX shoot me
@@ -5416,13 +5444,20 @@ void Executor::executeFree(ExecutionState &state, ref<Expr> address,
5416
5444
new ErrorEvent (new AllocEvent (mo->allocSite ),
5417
5445
locationOf (*it->second ), StateTerminationType::Free,
5418
5446
" free of alloca" ),
5447
+ rl.size () != 1 ? StateTerminationConfidenceCategory::PROBABLY
5448
+ : StateTerminationConfidenceCategory::CONFIDENT,
5419
5449
getAddressInfo (*it->second , address));
5420
5450
} else if (mo->isGlobal ) {
5451
+ if (rl.size () != 1 ) {
5452
+ klee_warning (" Following error if likely false positive" );
5453
+ }
5421
5454
terminateStateOnProgramError (
5422
5455
*it->second ,
5423
5456
new ErrorEvent (new AllocEvent (mo->allocSite ),
5424
5457
locationOf (*it->second ), StateTerminationType::Free,
5425
5458
" free of global" ),
5459
+ rl.size () != 1 ? StateTerminationConfidenceCategory::PROBABLY
5460
+ : StateTerminationConfidenceCategory::CONFIDENT,
5426
5461
getAddressInfo (*it->second , address));
5427
5462
} else {
5428
5463
it->second ->removePointerResolutions (mo);
@@ -5518,6 +5553,8 @@ bool Executor::resolveExact(ExecutionState &estate, ref<Expr> address,
5518
5553
*unbound,
5519
5554
new ErrorEvent (locationOf (*unbound), StateTerminationType::Ptr,
5520
5555
" memory error: invalid pointer: " + name),
5556
+ !results.empty () ? StateTerminationConfidenceCategory::PROBABLY
5557
+ : StateTerminationConfidenceCategory::CONFIDENT,
5521
5558
getAddressInfo (*unbound, address));
5522
5559
}
5523
5560
}
@@ -5607,7 +5644,7 @@ void Executor::concretizeSize(ExecutionState &state, ref<Expr> size,
5607
5644
new ErrorEvent (locationOf (*hugeSize.second ),
5608
5645
StateTerminationType::Model,
5609
5646
" concretized symbolic size" ),
5610
- info.str ());
5647
+ StateTerminationConfidenceCategory::CONFIDENT, info.str ());
5611
5648
}
5612
5649
}
5613
5650
}
@@ -6309,7 +6346,8 @@ void Executor::executeMemoryOperation(
6309
6346
*state,
6310
6347
new ErrorEvent (new AllocEvent (mo->allocSite ), locationOf (*state),
6311
6348
StateTerminationType::ReadOnly,
6312
- " memory error: object read only" ));
6349
+ " memory error: object read only" ),
6350
+ StateTerminationConfidenceCategory::CONFIDENT);
6313
6351
} else {
6314
6352
wos->write (mo->getOffsetExpr (address), value);
6315
6353
}
@@ -6371,6 +6409,10 @@ void Executor::executeMemoryOperation(
6371
6409
return ;
6372
6410
}
6373
6411
6412
+ bool mayBeFalsePositive =
6413
+ resolvedMemoryObjects.size () > 1 ||
6414
+ (resolvedMemoryObjects.size () == 1 && mayBeOutOfBound);
6415
+
6374
6416
ExecutionState *unbound = nullptr ;
6375
6417
if (MergedPointerDereference) {
6376
6418
ref<Expr> guard;
@@ -6428,7 +6470,10 @@ void Executor::executeMemoryOperation(
6428
6470
new ErrorEvent (new AllocEvent (mo->allocSite ),
6429
6471
locationOf (*branches.first ),
6430
6472
StateTerminationType::ReadOnly,
6431
- " memory error: object read only" ));
6473
+ " memory error: object read only" ),
6474
+ mayBeFalsePositive
6475
+ ? StateTerminationConfidenceCategory::PROBABLY
6476
+ : StateTerminationConfidenceCategory::CONFIDENT);
6432
6477
state = branches.second ;
6433
6478
} else {
6434
6479
ref<Expr> result = SelectExpr::create (
@@ -6500,7 +6545,10 @@ void Executor::executeMemoryOperation(
6500
6545
*bound,
6501
6546
new ErrorEvent (new AllocEvent (mo->allocSite ), locationOf (*bound),
6502
6547
StateTerminationType::ReadOnly,
6503
- " memory error: object read only" ));
6548
+ " memory error: object read only" ),
6549
+ mayBeFalsePositive
6550
+ ? StateTerminationConfidenceCategory::PROBABLY
6551
+ : StateTerminationConfidenceCategory::CONFIDENT);
6504
6552
} else {
6505
6553
wos->write (mo->getOffsetExpr (address), value);
6506
6554
}
@@ -6552,6 +6600,8 @@ void Executor::executeMemoryOperation(
6552
6600
new ErrorEvent (new AllocEvent (baseObjectPair.first ->allocSite ),
6553
6601
locationOf (*unbound), StateTerminationType::Ptr,
6554
6602
" memory error: out of bound pointer" ),
6603
+ mayBeFalsePositive ? StateTerminationConfidenceCategory::PROBABLY
6604
+ : StateTerminationConfidenceCategory::CONFIDENT,
6555
6605
getAddressInfo (*unbound, address));
6556
6606
return ;
6557
6607
}
@@ -6561,6 +6611,8 @@ void Executor::executeMemoryOperation(
6561
6611
*unbound,
6562
6612
new ErrorEvent (locationOf (*unbound), StateTerminationType::Ptr,
6563
6613
" memory error: out of bound pointer" ),
6614
+ mayBeFalsePositive ? StateTerminationConfidenceCategory::PROBABLY
6615
+ : StateTerminationConfidenceCategory::CONFIDENT,
6564
6616
getAddressInfo (*unbound, address));
6565
6617
}
6566
6618
}
0 commit comments