/src/backtrace.cc

http://ext3grep.googlecode.com/ · C++ · 101 lines · 63 code · 10 blank · 28 comment · 6 complexity · d5c2872c6f1bbe03b1cc5ed38b2f744e MD5 · raw file

  1. // ext3grep -- An ext3 file system investigation and undelete tool
  2. //
  3. //! @file backtrace.cc Support for printing a backtrace.
  4. //
  5. // Copyright (C) 2008, by
  6. //
  7. // Carlo Wood, Run on IRC <carlo@alinoe.com>
  8. // RSA-1024 0x624ACAD5 1997-01-26 Sign & Encrypt
  9. // Fingerprint16 = 32 EC A7 B6 AC DB 65 A6 F6 F6 55 DD 1C DC FF 61
  10. //
  11. // This program is free software: you can redistribute it and/or modify
  12. // it under the terms of the GNU General Public License as published by
  13. // the Free Software Foundation, either version 2 of the License, or
  14. // (at your option) any later version.
  15. //
  16. // This program is distributed in the hope that it will be useful,
  17. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. // GNU General Public License for more details.
  20. //
  21. // You should have received a copy of the GNU General Public License
  22. // along with this program. If not, see <http://www.gnu.org/licenses/>.
  23. #ifndef DEBUG
  24. // This is a bug in src/Makefile.am.
  25. #error : This source file shouldn't be included at all when DEBUG isn't set.
  26. #endif
  27. #ifdef __OPTIMIZE__
  28. // It makes no sense to dump backtraces if optimization is being used.
  29. #error : Please add --disable-optimize to your configure options.
  30. #endif
  31. #ifndef USE_PCH
  32. #include "sys.h"
  33. #include <cstdio>
  34. #include <iostream>
  35. #include <iomanip>
  36. #include <cstdlib>
  37. #include <sstream>
  38. #include <unistd.h>
  39. #include "debug.h"
  40. #endif
  41. #include <execinfo.h>
  42. #include "backtrace.h"
  43. extern char const* progname;
  44. extern char* reserved_memory;
  45. static size_t const BACKTRACE_SIZE = 256;
  46. static void* return_addresses[BACKTRACE_SIZE];
  47. void dump_backtrace_on(std::ostream& os)
  48. {
  49. // Free some memory to make this work.
  50. delete [] reserved_memory;
  51. reserved_memory = NULL;
  52. // Get the backtrace.
  53. int nptrs = backtrace(return_addresses, BACKTRACE_SIZE);
  54. // Print it.
  55. #ifdef CWDEBUG
  56. for (int j = 0; j < nptrs; ++j)
  57. {
  58. libcwd::location_ct loc((char*)return_addresses[j] + libcwd::builtin_return_address_offset);
  59. os << '#' << std::left << std::setw(3) << j;
  60. os << std::left << std::setw(16) << return_addresses[j] << ' ' << loc << "\n in ";
  61. char const* mangled_function_name = loc.mangled_function_name();
  62. if (mangled_function_name != libcwd::unknown_function_c)
  63. {
  64. std::string demangled_function_name;
  65. libcwd::demangle_symbol(mangled_function_name, demangled_function_name);
  66. os << demangled_function_name << '\n';
  67. }
  68. else
  69. os << mangled_function_name << '\n';
  70. }
  71. #else
  72. char** symbols = backtrace_symbols(return_addresses, BACKTRACE_SIZE);
  73. if (symbols == NULL)
  74. {
  75. perror("backtrace_symbols");
  76. // Attempt to write to stderr directly.
  77. backtrace_symbols_fd(return_addresses, nptrs, STDERR_FILENO);
  78. exit(EXIT_FAILURE);
  79. }
  80. for (int j = 0; j < nptrs; ++j)
  81. {
  82. std::cout << '#' << std::left << std::setw(3) << j;
  83. std::cout << symbols[j] << std::endl;
  84. std::ostringstream command;
  85. command << "addr2line -e " << progname << ' ' << return_addresses[j];
  86. std::cout << " " << std::flush;
  87. system(command.str().c_str());
  88. }
  89. free(symbols);
  90. #endif
  91. }