CON51-CPP. 确保在异常情况下释放被持有的活动的锁
原文链接:
CON51-CPP. Ensure actively held locks are released on exceptional conditions
用于保护共享数据访问的互斥量可以使用 lock()
成员函数进行加锁,并使用 unlock()
成员函数进行解锁。如果在调用lock()
和unlock()
之间发生异常,并且该异常改变了控制流, 使得unlock()
没有被调用,那么互斥锁将被留在锁定状态, 且任何由该互斥锁保护的临界区将无法被执行,这很可能导致死锁。
异常的抛出不能让互斥锁无限期地处于锁定状态。如果互斥量被加锁,并且在受该互斥量保护的临界区中发生异常,这个互斥量必须在异常被再次抛出或者后续任务执行前, 作为异常处理操作的一部分被解锁, 除非后续的控制流将解锁该互斥量。
C++提供了锁类(lock_guard
、unique_lock
和shared_lock
),可用于初始化互斥量。锁对象在其构造函数中锁定互斥量,在析构函数中解锁互斥量。lock_guard
类提供了一个简单的 RAII 包装器。unique_lock
和shared_lock
类也运用了RAII, 提供了另外一些功能,例如手动控制锁定策略。unique_lock
类禁止锁被拷贝,虽然它允许锁的所有权被移动到另一个锁上。shared_lock
类允许互斥量被多个锁共享。对于这三个类,如果发生异常并且控制流跳出锁作用范围,则析构函数将解锁互斥锁,程序可以正常继续工作。这些锁对象是确保在抛出异常时互斥量被正确释放的首选方式。
不合规代码示例
这个不合规的代码示例操作共享数据,并通过锁定互斥对象来保护关键部分。当执行结束时,它会解锁互斥对象。然而,如果在操作共享数据时出现异常,那么互斥对象将保持锁定状态。
1 |
|
合规解决方案 (手动解锁)
该合规方案在捕获任何在共享数据做操作过程中出现的异常, 并且在异常被重复抛出前解锁互斥量.
1 |
|
合规解决方案 (锁定对象)
这个合规方案使用了 lock_guard
对象来确保互斥量被解锁, 即使异常发生, 也不需要依赖异常处理机制来手动资源管理.
1 |
|
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 | 7.3p0 | CONCURRENCY.LOCK.NOUNLOCK | Missing Lock Release |
Helix QAC | 2023.1 | C++5018 | |
Parasoft C/C++test | 2022.2 | CERT_CPP-CON51-a | Do not call lock() directly on a mutex |
PRQA QA-C++ | 4.4 | 5018 |
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.
MITRE CWE | CWE-667, Improper Locking |
---|---|
SEI CERT Oracle Coding Standard for Java | LCK08-J. Ensure actively held locks are released on exceptional conditions |
Bibliography
[ISO/IEC 14882-2014] | Subclause 30.4.2, “Locks” |
---|---|
本文标题:CON51-CPP. 确保在异常情况下释放被持有的活动的锁
文章作者:xwnb
发布时间:2023-04-01
最后更新:2023-04-17
原始链接:https://xwnb.github.io/posts/1519021197/
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!并保留本声明。感谢您的阅读和支持!
分享