StackBackTrace.cpp 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. //-------------------------------------------------------------------------------------------------------
  2. // Copyright (C) Microsoft. All rights reserved.
  3. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  4. //-------------------------------------------------------------------------------------------------------
  5. #include "CommonCorePch.h"
  6. #ifdef STACK_BACK_TRACE
  7. #include "Core/StackBackTrace.h"
  8. #include "Core/DbgHelpSymbolManager.h"
  9. StackBackTrace::StackBackTrace(ULONG framesToSkip, ULONG framesToCapture) : requestedFramesToCapture(framesToCapture)
  10. {
  11. this->Capture(framesToSkip);
  12. }
  13. // Don't capture, just remember requestedFramesToCapture/allocate buffer for them.
  14. StackBackTrace::StackBackTrace(ULONG framesToCaptureLater) : requestedFramesToCapture(framesToCaptureLater), framesCount(0)
  15. {
  16. }
  17. StackBackTrace *
  18. StackBackTrace::Capture(char* buffer, size_t bufSize, ULONG framesToSkip)
  19. {
  20. return new (buffer) StackBackTrace(framesToSkip, (ULONG)(bufSize - offsetof(StackBackTrace, stackBackTrace)) / sizeof(void*));
  21. }
  22. // This can be called multiple times, together with Create, in which case we will use (overwrite) same buffer.
  23. ULONG StackBackTrace::Capture(ULONG framesToSkip)
  24. {
  25. this->framesCount = CaptureStackBackTrace(framesToSkip + BaseFramesToSkip, this->requestedFramesToCapture, this->stackBackTrace, NULL);
  26. return this->framesCount;
  27. }
  28. size_t
  29. StackBackTrace::Print()
  30. {
  31. size_t retValue = 0;
  32. #ifdef DBGHELP_SYMBOL_MANAGER
  33. DbgHelpSymbolManager::EnsureInitialized();
  34. for(ULONG i = 0; i < this->framesCount; i++)
  35. {
  36. PVOID address = this->stackBackTrace[i];
  37. retValue += Output::Print(_u(" "));
  38. retValue += DbgHelpSymbolManager::PrintSymbol(address);
  39. retValue += Output::Print(_u("\n"));
  40. }
  41. #else
  42. char** f = backtrace_symbols(this->stackBackTrace, this->framesCount);
  43. if (f)
  44. {
  45. for (ULONG i = 0; i < this->framesCount; i++)
  46. {
  47. retValue += Output::Print(_u(" %S\n"), f[i]);
  48. }
  49. free(f);
  50. }
  51. #endif
  52. retValue += Output::Print(_u("\n"));
  53. return retValue;
  54. }
  55. #if ENABLE_DEBUG_CONFIG_OPTIONS
  56. static uint _s_trace_ring_id = 0;
  57. uint _trace_ring_next_id()
  58. {
  59. return InterlockedIncrement(&_s_trace_ring_id);
  60. }
  61. #endif // ENABLE_DEBUG_CONFIG_OPTIONS
  62. #endif