1 // Copyright 2015 The Crashpad Authors. All rights reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef CRASHPAD_SNAPSHOT_WIN_EXCEPTION_SNAPSHOT_WIN_H_
16 #define CRASHPAD_SNAPSHOT_WIN_EXCEPTION_SNAPSHOT_WIN_H_
17 
18 #include <windows.h>
19 #include <stdint.h>
20 
21 #include <memory>
22 #include <vector>
23 
24 #include "base/macros.h"
25 #include "build/build_config.h"
26 #include "snapshot/cpu_context.h"
27 #include "snapshot/exception_snapshot.h"
28 #include "snapshot/win/thread_snapshot_win.h"
29 #include "util/misc/initialization_state_dcheck.h"
30 #include "util/win/address_types.h"
31 #include "util/win/process_structs.h"
32 
33 namespace crashpad {
34 
35 class ProcessReaderWin;
36 
37 namespace internal {
38 
39 class MemorySnapshotGeneric;
40 
41 union CPUContextUnion {
42 #if defined(ARCH_CPU_X86_FAMILY)
43   CPUContextX86 x86;
44   CPUContextX86_64 x86_64;
45 #elif defined(ARCH_CPU_ARM64)
46   CPUContextARM64 arm64;
47 #endif
48 };
49 
50 class ExceptionSnapshotWin final : public ExceptionSnapshot {
51  public:
52   ExceptionSnapshotWin();
53   ~ExceptionSnapshotWin() override;
54 
55   //! \brief Initializes the object.
56   //!
57   //! \param[in] process_reader A ProcessReaderWin for the process that
58   //!     sustained the exception.
59   //! \param[in] thread_id The thread ID in which the exception occurred.
60   //! \param[in] exception_pointers The address of an `EXCEPTION_POINTERS`
61   //!     record in the target process, passed through from the exception
62   //!     handler.
63   //!
64   //! \note If the exception was triggered by
65   //!     CrashpadClient::DumpAndCrashTargetProcess(), this has the side-effect
66   //!     of correcting the thread suspend counts for \a process_reader.
67   //!
68   //! \return `true` if the snapshot could be created, `false` otherwise with
69   //!     an appropriate message logged.
70   bool Initialize(ProcessReaderWin* process_reader,
71                   DWORD thread_id,
72                   WinVMAddress exception_pointers);
73 
74   // ExceptionSnapshot:
75 
76   const CPUContext* Context() const override;
77   uint64_t ThreadID() const override;
78   uint32_t Exception() const override;
79   uint32_t ExceptionInfo() const override;
80   uint64_t ExceptionAddress() const override;
81   const std::vector<uint64_t>& Codes() const override;
82   std::vector<const MemorySnapshot*> ExtraMemory() const override;
83 
84  private:
85   template <class ExceptionRecordType,
86             class ExceptionPointersType,
87             class ContextType>
88   bool InitializeFromExceptionPointers(
89       ProcessReaderWin* process_reader,
90       WinVMAddress exception_pointers_address,
91       DWORD exception_thread_id,
92       void (*native_to_cpu_context)(const ContextType& context_record,
93                                     CPUContext* context,
94                                     CPUContextUnion* context_union));
95 
96   CPUContextUnion context_union_;
97   CPUContext context_;
98   std::vector<uint64_t> codes_;
99   std::vector<std::unique_ptr<internal::MemorySnapshotGeneric>> extra_memory_;
100   uint64_t thread_id_;
101   uint64_t exception_address_;
102   uint32_t exception_flags_;
103   DWORD exception_code_;
104   InitializationStateDcheck initialized_;
105 
106   DISALLOW_COPY_AND_ASSIGN(ExceptionSnapshotWin);
107 };
108 
109 }  // namespace internal
110 }  // namespace crashpad
111 
112 #endif  // CRASHPAD_SNAPSHOT_WIN_EXCEPTION_SNAPSHOT_WIN_H_
113