win32_stack_frame_unwinder.h 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. // Copyright 2015 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef BASE_PROFILER_WIN32_STACK_FRAME_UNWINDER_H_
  5. #define BASE_PROFILER_WIN32_STACK_FRAME_UNWINDER_H_
  6. #include <windows.h>
  7. #include <memory>
  8. #include "base/base_export.h"
  9. #include "base/macros.h"
  10. #include "base/profiler/module_cache.h"
  11. #include "build/build_config.h"
  12. namespace base {
  13. #if !defined(_WIN64)
  14. // Allows code to compile for x86. Actual support for x86 will require either
  15. // refactoring these interfaces or separate architecture-specific interfaces.
  16. struct RUNTIME_FUNCTION {
  17. DWORD BeginAddress;
  18. DWORD EndAddress;
  19. };
  20. using PRUNTIME_FUNCTION = RUNTIME_FUNCTION*;
  21. #endif // !defined(_WIN64)
  22. inline ULONG64 ContextPC(CONTEXT* context) {
  23. #if defined(ARCH_CPU_X86_64)
  24. return context->Rip;
  25. #elif defined(ARCH_CPU_X86)
  26. return context->Eip;
  27. #elif defined(ARCH_CPU_ARM64)
  28. return context->Pc;
  29. #else
  30. #error Unsupported Windows Arch
  31. #endif
  32. }
  33. // This class is not used while the target thread is suspended, so may allocate
  34. // from the default heap.
  35. class BASE_EXPORT Win32StackFrameUnwinder {
  36. public:
  37. // Interface for Win32 unwind-related functionality this class depends
  38. // on. Provides a seam for testing.
  39. class BASE_EXPORT UnwindFunctions {
  40. public:
  41. virtual ~UnwindFunctions();
  42. virtual PRUNTIME_FUNCTION LookupFunctionEntry(DWORD64 program_counter,
  43. PDWORD64 image_base) = 0;
  44. virtual void VirtualUnwind(DWORD64 image_base,
  45. DWORD64 program_counter,
  46. PRUNTIME_FUNCTION runtime_function,
  47. CONTEXT* context) = 0;
  48. protected:
  49. UnwindFunctions();
  50. private:
  51. DISALLOW_COPY_AND_ASSIGN(UnwindFunctions);
  52. };
  53. explicit Win32StackFrameUnwinder();
  54. ~Win32StackFrameUnwinder();
  55. // Attempts to unwind the frame represented by |context|, where the
  56. // instruction pointer is known to be in |module|. Updates |context| if
  57. // successful.
  58. bool TryUnwind(bool at_top_frame,
  59. CONTEXT* context,
  60. const ModuleCache::Module* module);
  61. private:
  62. // This function is for internal and test purposes only.
  63. Win32StackFrameUnwinder(std::unique_ptr<UnwindFunctions> unwind_functions);
  64. friend class Win32StackFrameUnwinderTest;
  65. std::unique_ptr<UnwindFunctions> unwind_functions_;
  66. DISALLOW_COPY_AND_ASSIGN(Win32StackFrameUnwinder);
  67. };
  68. } // namespace base
  69. #endif // BASE_PROFILER_WIN32_STACK_FRAME_UNWINDER_H_