This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH][RFC] vterminate use of malloc-less demangler
- From: simonb at google dot com (Simon Baldwin)
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 29 Jan 2007 17:07:07 -0800 (PST)
- Subject: [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