| // Copyright 2015 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef BASE_PROFILER_WIN32_STACK_FRAME_UNWINDER_H_ |
| #define BASE_PROFILER_WIN32_STACK_FRAME_UNWINDER_H_ |
| |
| #include <windows.h> |
| |
| #include <memory> |
| |
| #include "base/base_export.h" |
| #include "base/macros.h" |
| #include "base/win/scoped_handle.h" |
| #include "starboard/types.h" |
| |
| namespace base { |
| |
| #if !defined(_WIN64) |
| // Allows code to compile for x86. Actual support for x86 will require either |
| // refactoring these interfaces or separate architecture-specific interfaces. |
| struct RUNTIME_FUNCTION { |
| DWORD BeginAddress; |
| DWORD EndAddress; |
| }; |
| using PRUNTIME_FUNCTION = RUNTIME_FUNCTION*; |
| #endif // !defined(_WIN64) |
| |
| // Traits class to adapt GenericScopedHandle for HMODULES. |
| class ModuleHandleTraits : public win::HandleTraits { |
| public: |
| using Handle = HMODULE; |
| |
| static bool BASE_EXPORT CloseHandle(HMODULE handle); |
| static bool BASE_EXPORT IsHandleValid(HMODULE handle); |
| static HMODULE BASE_EXPORT NullHandle(); |
| |
| BASE_EXPORT static const HMODULE kNonNullModuleForTesting; |
| |
| private: |
| DISALLOW_IMPLICIT_CONSTRUCTORS(ModuleHandleTraits); |
| }; |
| |
| // HMODULE is not really a handle, and has reference count semantics, so the |
| // standard VerifierTraits does not apply. |
| using ScopedModuleHandle = |
| win::GenericScopedHandle<ModuleHandleTraits, win::DummyVerifierTraits>; |
| |
| // Instances of this class are expected to be created and destroyed for each |
| // stack unwinding. This class is not used while the target thread is suspended, |
| // so may allocate from the default heap. |
| class BASE_EXPORT Win32StackFrameUnwinder { |
| public: |
| // Interface for Win32 unwind-related functionality this class depends |
| // on. Provides a seam for testing. |
| class BASE_EXPORT UnwindFunctions { |
| public: |
| virtual ~UnwindFunctions(); |
| |
| virtual PRUNTIME_FUNCTION LookupFunctionEntry(DWORD64 program_counter, |
| PDWORD64 image_base) = 0; |
| virtual void VirtualUnwind(DWORD64 image_base, |
| DWORD64 program_counter, |
| PRUNTIME_FUNCTION runtime_function, |
| CONTEXT* context) = 0; |
| |
| // Returns the module containing |program_counter|. Can return null if the |
| // module has been unloaded. |
| virtual ScopedModuleHandle GetModuleForProgramCounter( |
| DWORD64 program_counter) = 0; |
| |
| protected: |
| UnwindFunctions(); |
| |
| private: |
| DISALLOW_COPY_AND_ASSIGN(UnwindFunctions); |
| }; |
| |
| Win32StackFrameUnwinder(); |
| ~Win32StackFrameUnwinder(); |
| |
| // Attempts to unwind the frame represented by the stack and instruction |
| // pointers in |context|. If successful, updates |context| and provides the |
| // module associated with the frame in |module|. |
| bool TryUnwind(CONTEXT* context, ScopedModuleHandle* module); |
| |
| private: |
| // This function is for internal and test purposes only. |
| Win32StackFrameUnwinder(std::unique_ptr<UnwindFunctions> unwind_functions); |
| friend class Win32StackFrameUnwinderTest; |
| |
| // State associated with each stack unwinding. |
| bool at_top_frame_; |
| bool unwind_info_present_for_all_frames_; |
| |
| std::unique_ptr<UnwindFunctions> unwind_functions_; |
| |
| DISALLOW_COPY_AND_ASSIGN(Win32StackFrameUnwinder); |
| }; |
| |
| } // namespace base |
| |
| #endif // BASE_PROFILER_WIN32_STACK_FRAME_UNWINDER_H_ |