stacktrace_linux.cpp 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. /*
  2. * Copyright (c) 2012-2015 Daniele Bartolini and individual contributors.
  3. * License: https://github.com/taylor001/crown/blob/master/LICENSE
  4. */
  5. #include "config.h"
  6. #if CROWN_PLATFORM_LINUX && CROWN_COMPILER_GCC
  7. #include "macros.h"
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <cxxabi.h>
  11. #include <execinfo.h>
  12. #include <string.h> // strchr
  13. namespace crown
  14. {
  15. void print_callstack()
  16. {
  17. void* array[64];
  18. int size = backtrace(array, CE_COUNTOF(array));
  19. char** messages = backtrace_symbols(array, size);
  20. // skip first stack frame (points here)
  21. for (int i = 1; i < size && messages != NULL; ++i)
  22. {
  23. char* msg = messages[i];
  24. char* mangled_name = strchr(msg, '(');
  25. char* offset_begin = strchr(msg, '+');
  26. char* offset_end = strchr(msg, ')');
  27. // if the line could be processed, attempt to demangle the symbol
  28. if (mangled_name && offset_begin && offset_end && mangled_name < offset_begin)
  29. {
  30. *mangled_name++ = '\0';
  31. *offset_begin++ = '\0';
  32. *offset_end++ = '\0';
  33. int status;
  34. char* real_name = abi::__cxa_demangle(mangled_name, 0, 0, &status);
  35. printf("\t[%d] %s: (%s)+%s %s\n", i, messages[i], (status == 0 ? real_name : mangled_name), offset_begin, offset_end);
  36. free(real_name);
  37. }
  38. // otherwise, print the whole line
  39. else
  40. {
  41. printf("\t[%d] %s\n", i, messages[i]);
  42. }
  43. }
  44. free(messages);
  45. }
  46. } // namespace crown
  47. #endif // CROWN_PLATFORM_LINUX && CROWN_COMPILER_GCC