backtrace.c 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. /* Copyright (c) 2013, The Tor Project, Inc. */
  2. /* See LICENSE for licensing information */
  3. #include "orconfig.h"
  4. #include "backtrace.h"
  5. #include "compat.h"
  6. #include "util.h"
  7. #include "torlog.h"
  8. #ifdef HAVE_EXECINFO_H
  9. #include <execinfo.h>
  10. #endif
  11. #ifdef HAVE_FCNTL_H
  12. #include <fcntl.h>
  13. #endif
  14. #ifdef HAVE_UNISTD_H
  15. #include <unistd.h>
  16. #endif
  17. #if defined(HAVE_EXECINFO_H) && defined(HAVE_BACKTRACE) && \
  18. defined(HAVE_BACKTRACE_SYMBOLS_FD) && defined(HAVE_SIGACTION)
  19. #define USE_BACKTRACE
  20. #endif
  21. #if !defined(USE_BACKTRACE)
  22. #define NO_BACKTRACE_IMPL
  23. #endif
  24. static char *bt_version = NULL;
  25. #ifdef USE_BACKTRACE
  26. #define MAX_DEPTH 256
  27. static void *cb_buf[MAX_DEPTH];
  28. /**DOCDOC*/
  29. void
  30. dump_backtrace(const char *msg)
  31. {
  32. int depth;
  33. const int *fds;
  34. int n_fds;
  35. int i;
  36. if (!msg) msg = "unspecified crash";
  37. depth = backtrace(cb_buf, MAX_DEPTH);
  38. tor_log_err_sigsafe(bt_version, " died: ", msg, "\n",
  39. NULL);
  40. n_fds = tor_log_get_sigsafe_err_fds(&fds);
  41. for (i=0; i < n_fds; ++i)
  42. backtrace_symbols_fd(cb_buf, depth, fds[i]);
  43. }
  44. /**DOCDOC*/
  45. static int
  46. install_bt_handler(void)
  47. {
  48. /*XXXX add signal handlers */
  49. /*XXXX make this idempotent */
  50. return 0;
  51. }
  52. /**DOCDOC*/
  53. static void
  54. remove_bt_handler(void)
  55. {
  56. }
  57. #endif
  58. #ifdef NO_BACKTRACE_IMPL
  59. /**DOCDOC*/
  60. void
  61. dump_backtrace(const char *msg)
  62. {
  63. tor_log_err_sigsafe(bt_version, " died: ", msg, "\n", NULL);
  64. }
  65. /**DOCDOC*/
  66. static int
  67. install_bt_handler(void)
  68. {
  69. return 0;
  70. }
  71. /**DOCDOC*/
  72. static void
  73. remove_bt_handler(void)
  74. {
  75. }
  76. #endif
  77. /**DOCDOC*/
  78. int
  79. configure_backtrace_handler(const char *tor_version)
  80. {
  81. tor_free(bt_version);
  82. if (!tor_version)
  83. tor_version = "Tor";
  84. bt_version = tor_strdup(tor_version);
  85. return install_bt_handler();
  86. }
  87. /**DOCDOC*/
  88. void
  89. clean_up_backtrace_handler(void)
  90. {
  91. remove_bt_handler();
  92. tor_free(bt_version);
  93. }