If you are having difficulty with uncaught exceptions and want a little bit of help debugging the causes of the core dumps, you can make use of a GNU extension, the verbose terminate handler.
#include <exception>
  
int main()
{
  std::set_terminate(__gnu_cxx::__verbose_terminate_handler);
  ...
  throw anything;
}
     The __verbose_terminate_handler function
     obtains the name of the current exception, attempts to demangle
     it, and prints it to stderr.  If the exception is derived from
     exception then the output from
     what() will be included.
   
Any replacement termination function is required to kill the program without returning; this one calls abort.
For example:
#include <exception>
#include <stdexcept>
struct argument_error : public std::runtime_error
{  
  argument_error(const std::string& s): std::runtime_error(s) { }
};
int main(int argc)
{
  std::set_terminate(__gnu_cxx::__verbose_terminate_handler);
  if (argc > 5)
    throw argument_error(“argc is greater than 5!”);
  else
    throw argc;
}
With the verbose terminate handler active, this gives:
   
   % ./a.out
   terminate called after throwing a `int'
   Aborted
   % ./a.out f f f f f f f f f f f
   terminate called after throwing an instance of `argument_error'
   what(): argc is greater than 5!
   Aborted
   
   
     The 'Aborted' line comes from the call to
     abort(), of course.
   
     This is the default termination handler; nothing need be done to
     use it.  To go back to the previous “silent death”
     method, simply include exception and
     cstdlib, and call
   
     std::set_terminate(std::abort);
    
     After this, all calls to terminate will use
     abort as the terminate handler.
   
     Note: the verbose terminate handler will attempt to write to
     stderr.  If your application closes stderr or redirects it to an
     inappropriate location,
     __verbose_terminate_handler will behave in
     an unspecified manner.