V3 PATCH to add verbose terminate_handler

Jason Merrill jason@redhat.com
Sun Nov 4 15:50:00 GMT 2001


As discussed, this patch adds an alternative terminate handler which prints
information about the offending exception to stderr; it can be installed
using set_terminate (__gnu_cxx::verbose_terminate_handler).  It also adds a
new ABI hook to get the type of the currently handled exception, so that
the handler doesn't need to know about the EH structures.

2001-11-18  Jason Merrill  <jason@redhat.com>

	* libsupc++/eh_type.cc (__cxa_current_exception_type): New file.
	* libsupc++/cxxabi.h: Declare it.
	* libsupc++/Makefile.am (sources): Add it.
	* src/vterminate.cc (verbose_terminate_handler): New file.
	* libsupc++/exception: Declare it.
	* src/Makefile.am (sources): Add it.

Index: libsupc++/Makefile.am
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/libsupc++/Makefile.am,v
retrieving revision 1.28
diff -c -p -r1.28 Makefile.am
*** libsupc++/Makefile.am	2001/07/13 16:47:55	1.28
--- libsupc++/Makefile.am	2001/11/18 01:59:13
*************** sources = \
*** 78,83 ****
--- 78,84 ----
  	eh_personality.cc \
  	eh_terminate.cc \
  	eh_throw.cc \
+ 	eh_type.cc \
  	new_handler.cc \
  	new_op.cc \
  	new_opnt.cc \
Index: libsupc++/cxxabi.h
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/libsupc++/cxxabi.h,v
retrieving revision 1.4
diff -c -p -r1.4 cxxabi.h
*** libsupc++/cxxabi.h	2001/03/20 16:59:44	1.4
--- libsupc++/cxxabi.h	2001/11/18 01:59:13
*************** char *__cxa_demangle (const char *__mang
*** 509,514 ****
--- 509,519 ----
  		      __SIZE_TYPE__ *__length,
  		      int *__status);
  
+ // Returns the type_info for the currently handled exception [15.3/8], or
+ // null if there is none.
+ extern "C"
+ std::type_info *__cxa_current_exception_type ();
+ 
  } /* namespace __cxxabiv1 */
  
  /* User programs should use the alias `abi'. */
Index: libsupc++/eh_type.cc
===================================================================
RCS file: eh_type.cc
diff -N eh_type.cc
*** /dev/null	Tue May  5 13:32:27 1998
--- libsupc++/eh_type.cc	Sat Nov 17 17:59:14 2001
***************
*** 0 ****
--- 1,49 ----
+ // -*- C++ -*- Exception handling routines for catching.
+ // Copyright (C) 2001 Free Software Foundation, Inc.
+ //
+ // This file is part of GNU CC.
+ //
+ // GNU CC is free software; you can redistribute it and/or modify
+ // it under the terms of the GNU General Public License as published by
+ // the Free Software Foundation; either version 2, or (at your option)
+ // any later version.
+ //
+ // GNU CC is distributed in the hope that it will be useful,
+ // but WITHOUT ANY WARRANTY; without even the implied warranty of
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ // GNU General Public License for more details.
+ //
+ // You should have received a copy of the GNU General Public License
+ // along with GNU CC; see the file COPYING.  If not, write to
+ // the Free Software Foundation, 59 Temple Place - Suite 330,
+ // Boston, MA 02111-1307, USA.
+ 
+ // As a special exception, you may use this file as part of a free software
+ // library without restriction.  Specifically, if other files instantiate
+ // templates or use macros or inline functions from this file, or you compile
+ // this file and link it with other files to produce an executable, this
+ // file does not by itself cause the resulting executable to be covered by
+ // the GNU General Public License.  This exception does not however
+ // invalidate any other reasons why the executable file might be covered by
+ // the GNU General Public License.
+ 
+ 
+ #include <typeinfo>
+ #include "unwind-cxx.h"
+ 
+ namespace __cxxabiv1 {
+ 
+ // Returns the type_info for the currently handled exception [15.3/8], or
+ // null if there is none.
+ extern "C"
+ std::type_info *__cxa_current_exception_type ()
+ {
+   __cxa_eh_globals *globals = __cxa_get_globals ();
+   __cxa_exception *header = globals->caughtExceptions;
+   if (header)
+     return header->exceptionType;
+   else
+     return 0;
+ }
+ 
+ } // namespace __cxxabiv1
Index: libsupc++/exception
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/libsupc++/exception,v
retrieving revision 1.5
diff -c -p -r1.5 exception
*** libsupc++/exception	2001/07/11 19:35:49	1.5
--- libsupc++/exception	2001/11/18 01:59:14
*************** namespace std 
*** 95,100 ****
--- 95,106 ----
    bool uncaught_exception() throw();
  } // namespace std
  
+ namespace __gnu_cxx {
+   /** A replacement for the standard terminate_handler which prints more
+       information about the terminating exception (if any) on stderr.  */
+   void verbose_terminate_handler ();
+ } // namespace __gnu_cxx
+   
  } // extern "C++"
  
  #endif
Index: src/Makefile.am
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/src/Makefile.am,v
retrieving revision 1.99
diff -c -p -r1.99 Makefile.am
*** src/Makefile.am	2001/11/01 15:46:48	1.99
--- src/Makefile.am	2001/11/18 01:59:15
*************** sources = \
*** 65,73 ****
  	locale.cc locale-inst.cc localename.cc \
  	collate.cc messages.cc moneypunct.cc numpunct.cc time.cc \
  	misc-inst.cc stdexcept.cc stl-inst.cc string-inst.cc strstream.cc \
! 	valarray-inst.cc wstring-inst.cc concept-inst.cc
  
! VPATH = $(top_srcdir):$(top_srcdir)/src
  
  libstdc___la_SOURCES = $(sources)
  
--- 65,73 ----
  	locale.cc locale-inst.cc localename.cc \
  	collate.cc messages.cc moneypunct.cc numpunct.cc time.cc \
  	misc-inst.cc stdexcept.cc stl-inst.cc string-inst.cc strstream.cc \
! 	valarray-inst.cc wstring-inst.cc concept-inst.cc vterminate.cc
  
! VPATH = $(top_srcdir)/src:$(top_srcdir)
  
  libstdc___la_SOURCES = $(sources)
  
Index: src/vterminate.cc
===================================================================
RCS file: vterminate.cc
diff -N vterminate.cc
*** /dev/null	Tue May  5 13:32:27 1998
--- src/vterminate.cc	Sat Nov 17 17:59:15 2001
***************
*** 0 ****
--- 1,82 ----
+ // Verbose terminate_handler -*- C++ -*-
+ 
+ // Copyright (C) 2001 Free Software Foundation
+ //
+ // This file is part of GNU CC.
+ //
+ // GNU CC is free software; you can redistribute it and/or modify
+ // it under the terms of the GNU General Public License as published by
+ // the Free Software Foundation; either version 2, or (at your option)
+ // any later version.
+ // 
+ // GNU CC is distributed in the hope that it will be useful,
+ // but WITHOUT ANY WARRANTY; without even the implied warranty of
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ // GNU General Public License for more details.
+ // 
+ // You should have received a copy of the GNU General Public License
+ // along with GNU CC; see the file COPYING.  If not, write to
+ // the Free Software Foundation, 59 Temple Place - Suite 330,
+ // Boston, MA 02111-1307, USA.
+ 
+ // As a special exception, you may use this file as part of a free software
+ // library without restriction.  Specifically, if other files instantiate
+ // templates or use macros or inline functions from this file, or you compile
+ // this file and link it with other files to produce an executable, this
+ // file does not by itself cause the resulting executable to be covered by
+ // the GNU General Public License.  This exception does not however
+ // invalidate any other reasons why the executable file might be covered by
+ // the GNU General Public License.
+ 
+ #include <exception>
+ #include <cstdlib>
+ #include <cstdio>
+ #include <cxxabi.h>
+ 
+ using namespace std;
+ using namespace abi;
+ 
+ namespace __gnu_cxx {
+ 
+ /** This is a replacement for the standard terminate_handler which prints
+     more information about the terminating exception (if any) on stderr.  */
+ 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 = __cxa_current_exception_type ();
+   if (t)
+     {
+       char const *name = t->name ();
+       // Note that "name" is the mangled name.
+ 
+       {
+ 	int status = -1;
+ 	char *dem = 0;
+ 
+ #if 0
+ 	// Disabled until __cxa_demangle gets the runtime GPL exception.
+ 	dem = __cxa_demangle (name, 0, 0, &status);
+ #endif
+ 
+ 	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)
+ 	{ fprintf (stderr, "  what(): %s\n", exc.what()); }
+       catch (...) { }
+     }
+   else
+     fprintf (stderr, "terminate called without an active exception\n");
+ 
+   abort ();
+ }
+ 
+ } // namespace __gnu_cxx



More information about the Libstdc++ mailing list