...
- When the exception handling mechanism, after completing the initialization of the exception object but before activation of a handler for the exception, calls a function that exits via an exception. ([except.throw], paragraph 7)
- When a throw-expression with no operand attempts to rethrow an exception and no exception is being handled. ([except.throw], paragraph 9)
- When the exception handling mechanism cannot find a handler for a thrown exception. ([except.handle], paragraph 9)
- See ERR31ERR51-CPP. Handle all exceptions for more information.
- When the search for a handler encounters the outermost block of a function with a noexcept-specification that does not allow the exception. ([except.spec], paragraph 9)
- See ERR37ERR55-CPP. Honor exception specifications for more information.
- When the destruction of an object during stack unwinding terminates by throwing an exception. ([except.ctor], paragraph 3)
- See DCL58-CPP. Destructors and deallocation functions must be declared noexcept for more information.
- When initialization of a non-local variable with static or thread storage duration exits via an exception. ([basic.start.init], paragraph 6)
- See ERR41ERR58-CPP. Constructors of objects with static or thread storage duration must not throw exceptions for more information.
- When destruction of an object with static or thread storage duration exits via an exception. ([basic.start.term], paragraph 1)
- When execution of a function registered with
std::atexit()
orstd::at_quick_exit()
exits via an exception. ([support.start.term], paragraphs 8 and 12) - When the implementation’s default unexpected exception handler is called. ([except.unexpected], paragraph 2) Note that
std::unexpected()
is currently deprecated. - When
std::unexpected()
throws an exception which is not allowed by the previously violated dynamic-exception-specification, andstd::bad_exception()
is not included in that dynamic-exception-specification. ([except.unexpected], paragraph 3) - When the function
std::nested_exception::rethrow_nested()
is called for an object that has captured no exception. ([except.nested], paragraph 4) - When execution of the initial function of a thread exits via an exception. ([thread.thread.constr], paragraph 5)
- See ERR31ERR51-CPP. Handle all exceptions for more information.
- When the destructor is invoked on an object of type
std::thread
that refers to a joinable thread. ([thread.thread.destr], paragraph 1) - When the copy assignment operator is invoked on an object of type
std::thread
that refers to a joinable thread. ([thread.thread.assign], paragraph 1) - When calling
condition_variable::wait()
,condition_variable::wait_until()
, orcondition_variable::wait_for()
results in a failure to meet the post-condition:lock.owns_lock() == true
orlock.mutex()
is not locked by the calling thread. ([thread.condition.condvar], paragraphs 11, 16, 21, 28, 33, and 40) - When calling
condition_variable_any::wait()
,condition_variable_any::wait_until()
, orcondition_variable_any::wait_for()
results in a failure to meet the post-condition:lock
is not locked by the calling thread. ([thread.condition.condvarany], paragraphs 11, 16, and 22)
...
Code Block | ||||
---|---|---|---|---|
| ||||
#include <cstdlib> void throwing_func() noexcept(false); void f() { throwing_func(); } int main() { if (0 != std::atexit(f)) { // Handle error } // ... } |
Compliant Solution
In this compliant solution, f()
handles all exceptions thrown by throwing_func()
, and does not rethrow:
Code Block | ||||
---|---|---|---|---|
| ||||
#include <cstdlib> void throwing_func() noexcept(false); void f() { try { throwing_func(); } catch (...) { // Handle error } } int main() { if (0 != std::atexit(f)) { // Handle error } // ... } |
Exceptions
ERR30-CPP-EX1: It is acceptable to explicitly call std::abort()
, std::_Exit()
, or std::terminate()
in response to a critical program error for which no recovery is possible, after indicating the nature of the problem to the operator, as in this example:
...
Note that the assert()
macro is permissible under this exception, as failed assertions will notify the operator on the standard error stream in an implementation-defined manner prior to calling std::abort()
.
Risk Assessment
Allowing the application to abnormally terminate can lead to resources not being freed, closed, etc. It is frequently a vector for denial-of-service attacks.
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
ERR30-CPP | Low | Probable | Medium | P4 | L3 |
Automated Detection
Tool | Version | Checker | Description | ||||||
---|---|---|---|---|---|---|---|---|---|
| 4037, 4038, 4636, 4637 |
Related Vulnerabilities
Search for other vulnerabilities resulting from the violation of this rule on the CERT website.
Related Guidelines
Bibliography
[ISO/IEC 14882-2014] | 15.5.1, "The |
[ISO/IEC 9899:1999] | 7.20.4.1, "The abort Function"7.20.4.4, "The _Exit Function" |
[MISRA 08] | Rule 15-3-2, "There should be at least one exception handler to catch all otherwise unhandled exceptions" Rule 15-3-4, "Each exception explicitly thrown in the code shall have a handler of a compatible type in all call paths that could lead to that point" |
...