[cfe-dev] Suggested starter bug on clang analyzer codebase
Malhar Thakkar via cfe-dev
cfe-dev at lists.llvm.org
Tue Apr 18 07:53:05 PDT 2017
Test-case:
pthread_mutex_lock(&mtx1);
pthread_mutex_unlock(&mtx1);
int retval = pthread_mutex_destroy(&mtx1);
if(retval != 0){
pthread_mutex_destroy(&mtx1); (1)
}
else
printf("Already destroyed\n");
Regarding my previous query about reverting the LockState, how would I
ensure that the LockState at (1) is Unlocked and not Destroyed?
Following is the code for checkDeadSymbols()
void PthreadLockChecker::checkDeadSymbols(SymbolReaper &SymReaper,
CheckerContext &C) const {
ProgramStateRef State = C.getState();
ConstraintManager &CMgr = State->getConstraintManager();
RetValConstraintTy TrackedSymbols = State->get<RetValConstraint>();
for (RetValConstraintTy::iterator I = TrackedSymbols.begin(),
E = TrackedSymbols.end(); I != E; ++I) {
SymbolRef Sym = I->second;
const MemRegion* lockR = I->first;
bool IsSymDead = SymReaper.isDead(Sym);
const LockState* LState = State->get<LockMap>(lockR);
// Remove the dead symbol from the return value symbols map.
if (IsSymDead){
ConditionTruthVal retZero = CMgr.isNull(State, Sym);
if(retZero.isConstrainedFalse()){
// Update LockMap
State = State->remove<LockMap>(lockR); // I know this is incorrect
but even after removing this entry from
the map, (1) raises a warning saying, "This lock has already been destroyed
".
}
State = State->remove<RetValConstraint>(lockR);
}
}
}
Thank you.
Regards,
Malhar
ᐧ
On Mon, Apr 17, 2017 at 8:34 PM, Devin Coughlin <dcoughlin at apple.com> wrote:
>
> On Apr 17, 2017, at 4:55 AM, Malhar Thakkar <cs13b1031 at iith.ac.in> wrote:
>
> Consider the following test-case:
>
> int retval = pthread_mutex_destroy(&mtx1);
> if(retval == 0){
> pthread_mutex_lock(&mtx1);
> }
>
>
> REGISTER_MAP_WITH_PROGRAMSTATE(RetValConstraint, const MemRegion *,
> SymbolRef)
>
> I have added the following snippet for checkDeadSymbols:
> void PthreadLockChecker::checkDeadSymbols(SymbolReaper &SymReaper,
> CheckerContext &C) const {
> // std::cout<<"Checking dead symbols\n";
> ProgramStateRef State = C.getState();
> ConstraintManager &CMgr = State->getConstraintManager();
>
> RetValConstraintTy TrackedSymbols = State->get<RetValConstraint>();
> // int counter = 0;
> for (RetValConstraintTy::iterator I = TrackedSymbols.begin(),
> E = TrackedSymbols.end(); I != E; ++I) {
> // counter++;
> // std::cout << "Counter: "<<counter<<std::endl;
> SymbolRef Sym = I->second;
> const MemRegion* lockR = I->first;
> bool IsSymDead = SymReaper.isDead(Sym);
>
> // Remove the dead symbol from the return value symbols map.
> if (IsSymDead){
> ConditionTruthVal retZero = CMgr.isNull(State, Sym);
> if(retZero.isConstrainedFalse()){
> std::cout<<"False\n";
> // Update LockMap
> }
> else if(retZero.isConstrainedTrue()){
> std::cout<<"True\n";
> }
> State = State->remove<RetValConstraint>(lockR);
> std::cout<<"Removed\n";
> }
> }
> }
>
> Now, after the execution of PthreadLockChecker::DestroyLock(),
> checkDeadSymbols() is executed twice before PthreadLockChecker::AcquireLock()
> is executed.
>
> When checkDeadSymbols is first executed, there is just one symbol in
> RetValConstraint(trivial). But, this symbol is constrained *not *to be
> NULL. Then, the symbol is removed. During the execution of checkDeadSymbols
> for the second time, there is again one symbol in RetValConstraint(I don't
> understand this. Shouldn't this symbol have been destroyed during the
> previous execution?). Nevertheless, this time, this symbol is constrained
> to be NULL.
>
>
> The static analyzer performs a path-sensitive exploration of the program.
> This means that when it sees a branch it will explore both both sides of
> the branch independently (unless it can tell that one side is infeasible).
> In this case it means the analyzer will explore the path when retval is 0
> and when it is not. If you haven’t read it yet, the “Debugging” section the
> the checker development manual describes some tricks for how to visualize
> the analyzer’s exploration. <https://clang-analyzer.llvm.
> org/checker_dev_manual.html#commands>. I find the debug.ViewExplodedGraph
> checker particularly helpful.
>
> Also, I have one more query. After fixing the above mentioned issue, how
> do I update LockMap in the sense that I'll need to revert the change made
> to it if the symbol is constrained not to be NULL. Apart from keeping track
> of the previous LockState, is there any other way to do it?
>
>
> Since the analyzer keeps its representation of the program state per-path
> and explores paths independently, you shouldn’t need to do any reverting to
> undo the effects of simulating other paths to reaching a particular program
> point.
>
> Devin
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20170418/38b3bcbc/attachment.html>
More information about the cfe-dev
mailing list