Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Mutexes that are used to protect accesses to shared data may be locked using the lock() member function , and unlocked using the unlock() member function. If an exception occurs between the call to lock() and the call to unlock(), and the exception changes control flow such that unlock() is not called, the mutex will be left in the locked state and no critical sections protected by that mutex will be allowed to execute.  This This is likely to lead to deadlock.

The throwing of an exception must not allow a mutex to remain locked indefinitely. If a mutex was locked and an exception occurs within the critical section protected by that mutex, the mutex must be unlocked as part of exception handling before rethrowing the exception or continuing execution unless subsequent control flow will unlock the mutex.

C++ supplies a the lock classes lock_guard class that , unique_lock, and shared_lock, which can be initialized with a mutex.  In In its constructor, a lock_guard object the lock object locks the mutex, and in its destructor, it unlocks the mutex. The lock_guard class provides a simple RAII wrapper around a mutex. The unique_lock and shared_lock classes also use RAII and provide additional functionality, such as manual control over the locking strategy. The unique_lock class prevents the lock from being copied, although it allows the lock ownership to be moved to another lock. The shared_lock class allows the mutex .  If to be shared by several locks. For all three classes, if an exception occurs and takes control flow out of the scope of the lock_guard object, its the destructor will unlock the mutex and the program can continue working normally. Mutexes should always be locked with a lock_guard object to protect against unanticipated control flow caused by exceptionsThese lock objects are the preferred way to ensure that a mutex is properly released when an exception is thrown.

Noncompliant Code Example

This noncompliant code example manipulates shared data and protects the critical the critical section by locking the mutex.  When When it is finished, it unlocks the mutex. However, if an exception occurs while manipulating the shared data, the mutex will remain locked.

Code Block
bgColor#ffcccc
langc
#include <mutex>

void manipulate_shared_data(std::mutex *pm)
 &pm) {
  pm.lock();

  // Perform work on shared data.

  pm.unlock();
}

Compliant Solution (Manual Unlock)

This compliant solution catches any exceptions thrown when performing work on the shared data and unlocks the mutex before rethrowing the exception.

Code Block
bgColor#ccccff
langc
#include <mutex>

void manipulate_shared_data(std::mutex &pm) {
  pm->lock.lock();
  try {
    // Perform work on shared data.
  } catch (...) {
    pm->unlock.unlock();
    throw;
  }
  pm.unlock(); // in case no exceptions occur
}

Compliant Solution (Lock Object)

This compliant solution uses a lock_guard object to ensure that the mutex will be unlocked, even if an exception occurs, without relying on exception handling machinery and manual resource management.

Code Block
bgColor#ccccff
langc
#include <mutex>

void manipulate_shared_data(std::mutex *&pm)
 {
  std::lock_guard<std::mutex> guardlk(*pm);

  // Perform work on shared data.
}

Risk Assessment

If an exception occurs while a mutex is locked, deadlock may result.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

CON51-CPP

Low

Probable

Low

P6

L2

Automated Detection

Tool

Version

Checker

Description

 

       

CodeSonar
Include Page
CodeSonar_V
CodeSonar_V

CONCURRENCY.LOCK.NOUNLOCK

Missing Lock Release

Helix QAC

Include Page
Helix QAC_V
Helix QAC_V

C++5018
Parasoft C/C++test

Include Page
Parasoft_V
Parasoft_V

CERT_CPP-CON51-aDo not call lock() directly on a mutex
Polyspace Bug Finder

Include Page
Polyspace Bug Finder_V
Polyspace Bug Finder_V

CERT C++: CON51-CPPChecks for lock possibly not released on exception (rule fully covered)

Related Vulnerabilities

Search for vulnerabilities resulting from the violation of this rule on the CERT website.

Related Guidelines

This rule is a subset of ERR56-CPP. Guarantee exception safety.

Bibliography

[ISO/IEC 14882-2014]
[thread.lock]
Subclause 30.4.2, "Locks"


...

Image Added Image Modified Image Removed  Image Modified