vterminate.cc 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. // Verbose terminate_handler -*- C++ -*-
  2. // Copyright (C) 2001-2022 Free Software Foundation, Inc.
  3. //
  4. // This file is part of the GNU ISO C++ Library. This library is free
  5. // software; you can redistribute it and/or modify it under the
  6. // terms of the GNU General Public License as published by the
  7. // Free Software Foundation; either version 3, or (at your option)
  8. // any later version.
  9. // This library is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. // Under Section 7 of GPL version 3, you are granted additional
  14. // permissions described in the GCC Runtime Library Exception, version
  15. // 3.1, as published by the Free Software Foundation.
  16. // You should have received a copy of the GNU General Public License and
  17. // a copy of the GCC Runtime Library Exception along with this program;
  18. // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
  19. // <http://www.gnu.org/licenses/>.
  20. #include <bits/c++config.h>
  21. #if _GLIBCXX_HOSTED
  22. #include <cstdlib>
  23. #include <exception>
  24. #include <bits/exception_defines.h>
  25. #include <cxxabi.h>
  26. # include <cstdio>
  27. using namespace std;
  28. using namespace abi;
  29. namespace __gnu_cxx
  30. {
  31. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  32. // A replacement for the standard terminate_handler which prints
  33. // more information about the terminating exception (if any) on
  34. // stderr.
  35. void __verbose_terminate_handler()
  36. {
  37. static bool terminating;
  38. if (terminating)
  39. {
  40. fputs("terminate called recursively\n", stderr);
  41. abort ();
  42. }
  43. terminating = true;
  44. // Make sure there was an exception; terminate is also called for an
  45. // attempt to rethrow when there is no suitable exception.
  46. type_info *t = __cxa_current_exception_type();
  47. if (t)
  48. {
  49. // Note that "name" is the mangled name.
  50. char const *name = t->name();
  51. {
  52. int status = -1;
  53. char *dem = 0;
  54. dem = __cxa_demangle(name, 0, 0, &status);
  55. fputs("terminate called after throwing an instance of '", stderr);
  56. if (status == 0)
  57. fputs(dem, stderr);
  58. else
  59. fputs(name, stderr);
  60. fputs("'\n", stderr);
  61. if (status == 0)
  62. free(dem);
  63. }
  64. // If the exception is derived from std::exception, we can
  65. // give more information.
  66. __try { __throw_exception_again; }
  67. #if __cpp_exceptions
  68. __catch(const exception& exc)
  69. {
  70. char const *w = exc.what();
  71. fputs(" what(): ", stderr);
  72. fputs(w, stderr);
  73. fputs("\n", stderr);
  74. }
  75. #endif
  76. __catch(...) { }
  77. }
  78. else
  79. fputs("terminate called without an active exception\n", stderr);
  80. abort();
  81. }
  82. _GLIBCXX_END_NAMESPACE_VERSION
  83. } // namespace
  84. #endif