How to Detect Stack Unwinding?
In a destructor, stack unwinding can be detected by looking for signs of cleanup activity, such as the following:
- Invoking functions that release resources (e.g. close files or free memory)
- Logging messages
- Setting flags
If any of these activities are observed in a destructor, it is likely that stack unwinding is taking place.
Using the std::uncaught_exception()
You can use the std::uncaught_exception() function which returns true if an exception is currently being handled (i.e. thrown but not yet caught). So, in your destructor, you would check if std::uncaught_exception() returns true or false and take appropriate action accordingly.
Example:
C++
#include <bits/stdc++.h> using namespace std; class MyClass { public : MyClass() { // allocate some resource } ~MyClass() { if (!std::uncaught_exception()) { // release resource } }; }; |
Overriding std::terminate() function
In order to detect when stack unwinding is occurring, you can override the std::terminate() function. The runtime calls this function when it cannot find a suitable exception handler. By overriding std::terminate(), you can set a breakpoint or log a message to help debug your program.
Here is an example of how you would override std::terminate():
C++
void my_terminate() { // Set breakpoint here or log message std::cerr << "Stack unwinding detected!" << std::endl; // Call original terminate function std::terminate(); } int main() { // Install our custom terminate handler std::set_terminate(my_terminate); try { // Code that might throw an exception goes here... } catch (...) { // Exception handlers go here... } return 0; } |
By setting a flag in the constructor:
Set a flag in the constructor and check that flag in the destructor. If the flag is set, then you know that the destructor was called because of an exception. Here is an example:
C++
class MyClass { public : MyClass() : m_isUnwinding( false ) { // Constructor } ~MyClass() { if (m_isUnwinding) { // The stack is unwinding because of an // exception } else { // No exception is being handled } }; }; |
Related Articles: