The following code makes it so that a destructor is called twice.
#include <iostream>
#include <memory>
#include <exception>
#include <cstdlib>
void myterminate()
{
std::cout << "terminate\n";
abort();
}
class data
{
int a;
public:
data(int a) : a(a) { std::cout << "ctor " << a << "\n"; }
~data() { std::cout << "dtor " << a << "\n"; }
static data failure(int a) { return data(a); }
};
void main()
{
std::set_terminate(myterminate); //terminate is not called
try
{
std::unique_ptr<data> u;
u.reset(&data::failure(1));
std::cout << "no worries\n"; //this prints
//destructor called at try-block end and attempt to destruct an invalid memory block.
}
catch (...)
{
std::cout << "caught\n"; //this can not catch the error
}
std::cout << "end\n"; //program crash, will not be called
}
How would I catch an error like this in production?
On a Release build the program crashes. On a Debug build it the on my system is:
How would I catch an error like this in production?
You cannot. The standard says that invalid memory access has undefined behaviour. There is no standard way to "catch" UB. Catching and terminate handler are for exceptions, which are defined behaviour.
What you could do, is use the debug build in production, and run it with valgrind or similar tool, so that you can at least analyze the error.