<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Apr 17, 2017, at 4:55 AM, Malhar Thakkar <<a href="mailto:cs13b1031@iith.ac.in" class="">cs13b1031@iith.ac.in</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">Consider the following test-case:<div class=""><br class=""></div><div class=""><div class=""><font face="monospace, monospace" class="">int retval = pthread_mutex_destroy(&mtx1);</font></div><div class=""><font face="monospace, monospace" class="">if(retval == 0){</font></div><div class=""><font face="monospace, monospace" class=""><span class="gmail-Apple-tab-span" style="white-space:pre">     </span>pthread_mutex_lock(&mtx1);</font></div><div class=""><font face="monospace, monospace" class="">}</font></div></div><div class=""><font face="monospace, monospace" class=""><br class=""></font></div><div class=""><font face="monospace, monospace" class=""><br class=""></font></div><div class=""><font face="monospace, monospace" class="">REGISTER_MAP_WITH_PROGRAMSTATE(RetValConstraint, const MemRegion *, SymbolRef)<br class=""></font></div><div class=""><font face="monospace, monospace" class=""><br class=""></font></div><div class=""><font face="arial, helvetica, sans-serif" class="">I have added the following snippet for checkDeadSymbols:</font></div><div class=""><div class=""><font face="monospace, monospace" class="">void PthreadLockChecker::checkDeadSymbols(SymbolReaper &SymReaper,</font></div><div class=""><font face="monospace, monospace" class="">                                           CheckerContext &C) const {</font></div><div class=""><font face="monospace, monospace" class="">  // std::cout<<"Checking dead symbols\n";</font></div><div class=""><font face="monospace, monospace" class="">  ProgramStateRef State = C.getState();</font></div><div class=""><font face="monospace, monospace" class="">  ConstraintManager &CMgr = State->getConstraintManager();</font></div><div class=""><font face="monospace, monospace" class=""><br class=""></font></div><div class=""><font face="monospace, monospace" class="">  RetValConstraintTy TrackedSymbols = State->get<RetValConstraint>();</font></div><div class=""><font face="monospace, monospace" class="">  // int counter = 0;</font></div><div class=""><font face="monospace, monospace" class="">  for (RetValConstraintTy::iterator I = TrackedSymbols.begin(),</font></div><div class=""><font face="monospace, monospace" class="">                             E = TrackedSymbols.end(); I != E; ++I) {</font></div><div class=""><font face="monospace, monospace" class="">    // counter++;</font></div><div class=""><font face="monospace, monospace" class="">    // std::cout << "Counter: "<<counter<<std::endl;</font></div><div class=""><font face="monospace, monospace" class="">    SymbolRef Sym = I->second;</font></div><div class=""><font face="monospace, monospace" class="">    const MemRegion* lockR = I->first;</font></div><div class=""><font face="monospace, monospace" class="">    bool IsSymDead = SymReaper.isDead(Sym);</font></div><div class=""><font face="monospace, monospace" class=""><br class=""></font></div><div class=""><font face="monospace, monospace" class="">    // Remove the dead symbol from the return value symbols map.</font></div><div class=""><font face="monospace, monospace" class="">    if (IsSymDead){</font></div><div class=""><font face="monospace, monospace" class="">      ConditionTruthVal retZero = CMgr.isNull(State, Sym);</font></div><div class=""><font face="monospace, monospace" class="">      if(retZero.isConstrainedFalse()){</font></div><div class=""><font face="monospace, monospace" class="">        std::cout<<"False\n";</font></div><div class=""><font face="monospace, monospace" class="">        // Update LockMap</font></div><div class=""><font face="monospace, monospace" class="">      }</font></div><div class=""><font face="monospace, monospace" class="">      else if(retZero.isConstrainedTrue()){</font></div><div class=""><font face="monospace, monospace" class="">        std::cout<<"True\n";</font></div><div class=""><font face="monospace, monospace" class="">      }</font></div><div class=""><font face="monospace, monospace" class="">      State = State->remove<RetValConstraint>(lockR);</font></div><div class=""><font face="monospace, monospace" class="">      std::cout<<"Removed\n";</font></div><div class=""><font face="monospace, monospace" class="">    }</font></div><div class=""><font face="monospace, monospace" class="">  }</font></div><div class=""><font face="monospace, monospace" class="">}</font></div></div><div class=""><font face="monospace, monospace" class=""><br class=""></font></div><div class=""><font face="arial, helvetica, sans-serif" class="">Now, after the execution of PthreadLockChecker::DestroyLock(), checkDeadSymbols() is executed twice before PthreadLockChecker::AcquireLock() is executed.</font></div><div class=""><br class=""></div><div class=""><font face="arial, helvetica, sans-serif" class="">When checkDeadSymbols is first executed, there is just one symbol in RetValConstraint(trivial). But, this symbol is constrained <i class="">not </i>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.</font></div></div></div></blockquote><div><br class=""></div><div>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. <<a href="https://clang-analyzer.llvm.org/checker_dev_manual.html#commands" class="">https://clang-analyzer.llvm.org/checker_dev_manual.html#commands</a>>. I find the debug.ViewExplodedGraph checker particularly helpful.</div><div><br class=""></div><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class=""><span style="font-family:arial,helvetica,sans-serif" class="">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?</span></div></div></div></blockquote><div><br class=""></div><div>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.</div><div><br class=""></div></div>Devin</body></html>