This is the mail archive of the mailing list for the libstdc++ project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

verbose terminate_handler

I just whipped this up for a customer who requested that a call to
terminate() print some information about the exception which caused it, as
apparently the SunPro C++ does.  It prints the demangled name of the
exception type and, for objects derived from exception, the result of

An awkward thing about this is that currently it needs to look in the
libsupc++ and gcc source directories for the EH unwinder headers.  Another
problem is that __cxa_demangle isn't currently usable in general because
it's under the GPL.

My question is, how much of this should go into the distribution?  I see
several (largely orthogonal) options:

1) Nothing.  Let anyone who wants this functionality reinvent it
   themselves.  This is complicated by its reliance on ABI internals.
2) Install unwind-cxx.h and unwind.h so that users can get at them without
   keeping GCC source trees around.
2) Add current_exception_type to libsupc++, perhaps to the ABI
   specification.  This would avoid the need to look at the unwinder
3) Add verbose_terminate_handler to libsupc++ or libstdc++ and document it;
   people would still need to activate it with set_terminate.



// verbose terminate_handler for IA64/GNU V3 C++ ABI
// Copyright (C) 2001 Red Hat, Inc.

#include <exception>
#include <stdlib.h>
#include <stdio.h>
#include <cxxabi.h>

// This file is found in the libstdc++-v3/libsupc++ source directory, and
// it includes unwind.h from the gcc source directory.
#include <unwind-cxx.h>

using namespace std;
using namespace abi;

// Returns the type_info for the currently handled exception [15.3/8], or
// null if there is none.
type_info *current_exception_type ()
  __cxa_eh_globals *globals = __cxa_get_globals ();
  __cxa_exception *header = globals->caughtExceptions;
  if (header)
    return header->exceptionType;
    return 0;

void verbose_terminate_handler ()
  // Make sure there was an exception; terminate is also called for an
  // attempt to rethrow when there is no suitable exception.
  type_info *t = current_exception_type ();
  if (t)
      char const *name = t->name ();
      // Note that "name" is the mangled name.

	int status;
        // __cxa_demangle is currently disabled in cp-demangle.c, and
        // subject to the GPL (Boo!).
	char *dem = __cxa_demangle (name, 0, 0, &status);

	printf ("terminate called after throwing a `%s'\n",
		status == 0 ? dem : name);

	if (status == 0)
	  free (dem);

      // If the exception is derived from std::exception, we can give more
      // information.
      try { throw; }
      catch (exception &exc) { printf ("  what(): %s\n", exc.what()); }
      catch (...) { }
    printf ("terminate called without an active exception\n");

  abort ();

// EXAMPLE -- cut here

#include <stdexcept>

int main ()
  std::set_terminate (verbose_terminate_handler);
  //throw 1;
  throw std::out_of_range ("not really");

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]