You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

88 lines
2.1 KiB

  1. //
  2. // Lol Engine
  3. //
  4. // Copyright © 2010—2015 Sam Hocevar <sam@hocevar.net>
  5. //
  6. // Lol Engine is free software. It comes without any warranty, to
  7. // the extent permitted by applicable law. You can redistribute it
  8. // and/or modify it under the terms of the Do What the Fuck You Want
  9. // to Public License, Version 2, as published by the WTFPL Task Force.
  10. // See http://www.wtfpl.net/ for more details.
  11. //
  12. #include <lol/engine-internal.h>
  13. #if HAVE_CXXABI_H
  14. # include <cxxabi.h>
  15. #endif
  16. #if HAVE_EXECINFO_H
  17. # include <execinfo.h>
  18. #endif
  19. #if EMSCRIPTEN
  20. # include <emscripten.h>
  21. #endif
  22. namespace lol
  23. {
  24. void DumpStack()
  25. {
  26. #if EMSCRIPTEN
  27. /* This would require demangling but we don't care yet. */
  28. msg::debug("%s\n", emscripten_run_script_string("(new Error).stack"));
  29. #elif HAVE_CXA_DEMANGLE && HAVE_BACKTRACE_SYMBOLS
  30. /* Get current stack frames */
  31. void *stack_ptrs[50];
  32. size_t size = backtrace(stack_ptrs, 50);
  33. char **callstack = backtrace_symbols(stack_ptrs, size);
  34. if (size > 1)
  35. msg::debug("%d functions in stack trace:\n", (int)size - 1);
  36. /* Parse stack frames, skipping the first element (because
  37. * that’s ourselves) and print information. */
  38. for (size_t i = 1; i < size; ++i)
  39. {
  40. char *name = 0, *offset = 0, *address = 0;
  41. for (char *p = callstack[i]; *p; ++p)
  42. {
  43. if (*p == '(')
  44. name = p;
  45. else if (*p == '+')
  46. offset = p;
  47. else if (*p == ')')
  48. {
  49. address = p;
  50. break;
  51. }
  52. }
  53. if (name && offset && address && name < offset)
  54. {
  55. *name++ = *offset++ = *address++ = '\0';
  56. int ret;
  57. char *realname = abi::__cxa_demangle(name, 0, 0, &ret);
  58. if (ret == 0)
  59. name = realname;
  60. msg::debug("#%d %s: %s+%s %s\n", (int)i,
  61. callstack[i], name, offset, address);
  62. free(realname);
  63. }
  64. else
  65. {
  66. msg::debug("#%d %s\n", (int)i, callstack[i]);
  67. }
  68. }
  69. free(callstack);
  70. #endif
  71. }
  72. } /* namespace lol */