Back to success stories

Sample of Defect

Project Name CID Checker Category Developer Description
cryfs/cryfs 1361500 ORDER_REVERSAL Program hangs We had some spurious hangs and never knew why. I would never have thought of looking at this piece of code if coverity hadn't found it.
File: /home/heinzi/workspace_cpp/cryfs/src/cpp-utils/lock/LockPool.h
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
        LockPool();
        ~LockPool();
        void lock(const LockName &lock, std::unique_lock<std::mutex> *lockToFreeWhileWaiting = nullptr);
        void release(const LockName &lock);

    private:
        bool _isLocked(const LockName &lock) const;

        std::vector<LockName> _lockedLocks;
        std::mutex _mutex;
        std::condition_variable_any _cv;

        DISALLOW_COPY_AND_ASSIGN(LockPool);
    };
    template<class LockName>
    inline LockPool<LockName>::LockPool(): _lockedLocks(), _mutex(), _cv() {}

    template<class LockName>
    inline LockPool<LockName>::~LockPool() {
        ASSERT(_lockedLocks.size() == 0, "Still locks open");
    }

    template<class LockName>
    inline void LockPool<LockName>::lock(const LockName &lock, std::unique_lock<std::mutex> *lockToFreeWhileWaiting) {
 <<< CID 1361500: Program hangs ORDER_REVERSAL
 <<< 1. Calling "unique_lock" acquires lock "cpputils::LockPool<cpputils::FixedSizeData<16ul> >._mutex".
45
        std::unique_lock<std::mutex> mutexLock(_mutex); // TODO Is shared_lock enough here?
 < 2. Condition "this->_isLocked(lock)", taking true branch.
46
47
48
49
50
        if (_isLocked(lock)) {
            // Order of locking/unlocking is important and should be the same order as everywhere else to prevent deadlocks.
            // Since when entering the function, lockToFreeWhileWaiting is already locked and mutexLock is locked afterwards,
            // the condition variable should do it in the same order. We use combinedLock for this.
            CombinedLock combinedLock(lockToFreeWhileWaiting, &mutexLock);
 <<< CID 1361500: Program hangs ORDER_REVERSAL
 <<< 3. Calling "wait" acquires lock "std::unique_lock<std::mutex>._M_device" while holding lock "cpputils::LockPool<cpputils::FixedSizeData<16ul> >._mutex" (count: 1 / 2).
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
            _cv.wait(combinedLock, [this, &lock]{
                return !_isLocked(lock);
            });
            ASSERT(mutexLock.owns_lock() && lockToFreeWhileWaiting->owns_lock(), "Locks haven't been correctly relocked");
        }
        _lockedLocks.push_back(lock);
    }

    template<class LockName>
    inline bool LockPool<LockName>::_isLocked(const LockName &lock) const {
        return std::find(_lockedLocks.begin(), _lockedLocks.end(), lock) != _lockedLocks.end();
    }

    template<class LockName>
    inline void LockPool<LockName>::release(const LockName &lock) {
        std::unique_lock<std::mutex> mutexLock(_mutex);
        auto found = std::find(_lockedLocks.begin(), _lockedLocks.end(), lock);
        ASSERT(found != _lockedLocks.end(), "Lock given to release() was not locked");
        _lockedLocks.erase(found);
        _cv.notify_all();
    }
}

#endif
Events:
1. lock_acquire Cache.h:114
2. example_lock_order Cache.h:115
1. lock_acquire LockPool.h:45
3. lock_order LockPool.h:51