Versions Compared

Key

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

The handler functions new_handler, terminate_handler, and unexpected_handler can be globally replaced by custom implementations, as specified by [handler.functions], paragraph 2, of the C++ Standard [ISO/IEC 14882-2014]. For instance, an application could set a custom termination handler by calling std::set_terminate(), and the custom termination handler may log the termination for later auditing. However, the C++ Standard, [res.on.functions], paragraph 1, states the following:

In certain cases (replacement functions, handler functions, operations on types used to instantiate standard library template components), the C++ standard library depends on components supplied by a C++ program. If these components do not meet their requirements, the Standard places no requirements on the implementation.

Paragraph 2 goes on to state, in part, further states the following:

In particular, the effects are undefined in the following cases:
— for handler functions, if the installed handler function does not implement the semantics of the applicable Required behavior: paragraph

A replacement for any of the handler functions must meet the semantic requirements specified by the appropriate Required behavior: clause of the replaced function.

New Handler

The requirements for a replacement new_handler are specified by [new.handler], paragraph 2:

Required behavior: A new_handler shall perform one of the following:
— make more storage available for allocation and then return;
— throw an exception of type bad_alloc or a class derived from bad_alloc;
— terminate execution of the program without returning to the caller;

Terminate Handler

The requirements for a replacement terminate_handler are specified by [terminate.handler], paragraph 2:

Required behavior: A terminate_handler shall terminate execution of the program without returning to the caller.

Unexpected Handler

The requirements for a replacement unexpected_handler are specified by [unexpected.handler], paragraph 2. 

Required behavior: An unexpected_handler shall not return. See also 15.5.2.

unexpected_handler is a deprecated feature of C++.

Noncompliant Code Example

In this noncompliant code example, a replacement new_handler is written to attempt to release salvageable resources when the dynamic memory manager runs out of memory. However, this example does not take into account the situation where in which all salvageable resources have been recovered , and there is still insufficient memory to satisfy the allocation request. Instead of terminating the replacement handler with an exception of type std::bad_alloc, or terminating the execution of the program without returning to the caller, the replacement handler returns as normal. Under low memory conditions, this will result in an infinite loop will occur with the default implementation of ::operator new(). Since Because such conditions are rare in practice, it is likely for this bug to go undiscovered under typical testing scenarios.

Code Block
bgColor#FFcccc
langcpp
#include <new>
 
void custom_new_handler() {
  // Returns number of bytes freed.
  extern std::size_t reclaim_resources();
  reclaim_resources();
}
 
int main() {
  std::set_new_handler(custom_new_handler);
 
  // ...
}

...

In this compliant solution, custom_new_handler() does not disregard  uses the return value from reclaim_resources(), which is returning the number of bytes freed by the reclamation. If it returns 0, then an there will be insufficient memory for operator new to succeed. Hence, an exception of type std::bad_alloc is thrown, meeting the requirements for the replacement handler.

Code Block
bgColor#ccccff
langcpp
#include <new>

void custom_new_handler() noexcept(false) {
  // Returns number of bytes freed.
  extern std::size_t reclaim_resources();
  if (0 == reclaim_resources()) {
    throw std::bad_alloc();
  }
}
 
int main() {
  std::set_new_handler(custom_new_handler);
 
  // ...
}

...

Failing to meet the required behavior for a replacement handler results in undefined behavior.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

OOP56-CPP

Low

Probable

High

P2

L3

Automated Detection

Tool

Version

Checker

Description

   

Helix QAC

Include Page
Helix QAC_V
Helix QAC_V

DF4776, DF4777, DF4778, DF4779


Parasoft C/C++test

Include Page
Parasoft_V
Parasoft_V

CERT_CPP-OOP56-a
CERT_CPP-OOP56-b
CERT_CPP-OOP56-c

Properly define terminate handlers
Properly define unexpected handlers
Properly define new handlers

Polyspace Bug Finder

Include Page
Polyspace Bug Finder_V
Polyspace Bug Finder_V

CERT C++: OOP56-CPP

Checks for replacement handler function that does not meet requirements (rule fully covered)

 

Related Vulnerabilities

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

Related Guidelines

Bibliography

[ISO/IEC 14882-2014]Subclause 17.6.4.8, "Other Functions"
Subclause 18.6.2.3, "Type new_handler
Subclause 18.8.3.1, "Type terminate_handler"
Subclause D.11.1, "Type unexpected_handler


...

Image Modified Image Modified Image Modified