This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC 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]

[PATCH][RFC] vterminate use of malloc-less demangler


Attached is a proposed patch to libstdc++'s __verbose_terminate_handler.
It changes the handler to use the new non-allocating interface to the C++
name demangler.  This allows it to operate in conditions where the heap or
the malloc arena has been corrupted by a problem in user code.  This patch
builds upon, and depends upon, the earlier work of revision 121305.

Primary testing is by a constructed test program that throws an unhandled
exception after deliberately corrupting the heap.  With the original
libstdc++, the program SIGSEGVs before printing the demangled exception
string; with the patch, however, the exception details are printed out
correctly before abort().  Tested on i686-pc-linux-gnu.


2007-01-26  Simon Baldwin <simonb@google.com>

	* vterminate.cc (__verbose_terminate_callback): New function,
	outputs demangled elements as each is generated.
	(__verbose_terminate): Replaced call to __cxa_demangle() by a
	call to the non-allocating __gcclibcxx_demangle_callback().


*** orig/libstdc++-v3/libsupc++/vterminate.cc	Tue Aug 16 19:28:44 2005
--- new/libstdc++-v3/libsupc++/vterminate.cc	Fri Jan 26 10:28:03 2007
***************
*** 38,45 ****
--- 38,63 ----
  using namespace std;
  using namespace abi;
  
+ // Callback-based demangler, used as an alternative to __cxa_demangle().
+ // This demangler avoids allocations, and so does not require that the
+ // heap is intact.
+ extern "C" {
+ extern int __gcclibcxx_demangle_callback(const char *,
+                                          void (*)
+                                            (const char *, size_t, void *),
+                                          void *);
+ };
+ 
  namespace __gnu_cxx
  {
+   // Callback function for __verbose_terminate_handler().  Prints the
+   // strings returned by demangling to the file stream held in 'opaque'.
+   void __verbose_terminate_callback(const char *string, size_t, void *opaque)
+   {
+     FILE *stream = reinterpret_cast<FILE*>(opaque);
+     fputs(string, stream);
+   }
+ 
    // A replacement for the standard terminate_handler which prints
    // more information about the terminating exception (if any) on
    // stderr.
*************** namespace __gnu_cxx
*** 61,80 ****
  	// Note that "name" is the mangled name.
  	char const *name = t->name();
  	{
- 	  int status = -1;
- 	  char *dem = 0;
- 	  
- 	  dem = __cxa_demangle(name, 0, 0, &status);
- 
  	  fputs("terminate called after throwing an instance of '", stderr);
! 	  if (status == 0)
! 	    fputs(dem, stderr);
! 	  else
  	    fputs(name, stderr);
  	  fputs("'\n", stderr);
- 
- 	  if (status == 0)
- 	    free(dem);
  	}
  
  	// If the exception is derived from std::exception, we can
--- 79,92 ----
  	// Note that "name" is the mangled name.
  	char const *name = t->name();
  	{
  	  fputs("terminate called after throwing an instance of '", stderr);
! 	  const int status =
!               __gcclibcxx_demangle_callback(name,
!                                             &__verbose_terminate_callback,
!                                             stderr);
! 	  if (status != 0)
  	    fputs(name, stderr);
  	  fputs("'\n", stderr);
  	}
  
  	// If the exception is derived from std::exception, we can


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