1 // Copyright 2014 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 #include "snapshot/mac/thread_snapshot_mac.h"
16
17 #include "base/logging.h"
18 #include "snapshot/mac/cpu_context_mac.h"
19 #include "snapshot/mac/process_reader_mac.h"
20
21 namespace crashpad {
22 namespace internal {
23
ThreadSnapshotMac()24 ThreadSnapshotMac::ThreadSnapshotMac()
25 : ThreadSnapshot(),
26 context_union_(),
27 context_(),
28 stack_(),
29 thread_id_(0),
30 thread_specific_data_address_(0),
31 thread_(MACH_PORT_NULL),
32 suspend_count_(0),
33 priority_(0),
34 initialized_() {
35 }
36
~ThreadSnapshotMac()37 ThreadSnapshotMac::~ThreadSnapshotMac() {
38 }
39
Initialize(ProcessReaderMac * process_reader,const ProcessReaderMac::Thread & process_reader_thread)40 bool ThreadSnapshotMac::Initialize(
41 ProcessReaderMac* process_reader,
42 const ProcessReaderMac::Thread& process_reader_thread) {
43 INITIALIZATION_STATE_SET_INITIALIZING(initialized_);
44
45 thread_ = process_reader_thread.port;
46 thread_id_ = process_reader_thread.id;
47 suspend_count_ = process_reader_thread.suspend_count;
48 priority_ = process_reader_thread.priority;
49 thread_specific_data_address_ =
50 process_reader_thread.thread_specific_data_address;
51
52 stack_.Initialize(process_reader->Memory(),
53 process_reader_thread.stack_region_address,
54 process_reader_thread.stack_region_size);
55
56 #if defined(ARCH_CPU_X86_FAMILY)
57 if (process_reader->Is64Bit()) {
58 context_.architecture = kCPUArchitectureX86_64;
59 context_.x86_64 = &context_union_.x86_64;
60 InitializeCPUContextX86_64(context_.x86_64,
61 THREAD_STATE_NONE,
62 nullptr,
63 0,
64 &process_reader_thread.thread_context.t64,
65 &process_reader_thread.float_context.f64,
66 &process_reader_thread.debug_context.d64);
67 } else {
68 context_.architecture = kCPUArchitectureX86;
69 context_.x86 = &context_union_.x86;
70 InitializeCPUContextX86(context_.x86,
71 THREAD_STATE_NONE,
72 nullptr,
73 0,
74 &process_reader_thread.thread_context.t32,
75 &process_reader_thread.float_context.f32,
76 &process_reader_thread.debug_context.d32);
77 }
78 #endif
79
80 INITIALIZATION_STATE_SET_VALID(initialized_);
81 return true;
82 }
83
Context() const84 const CPUContext* ThreadSnapshotMac::Context() const {
85 INITIALIZATION_STATE_DCHECK_VALID(initialized_);
86 return &context_;
87 }
88
Stack() const89 const MemorySnapshot* ThreadSnapshotMac::Stack() const {
90 INITIALIZATION_STATE_DCHECK_VALID(initialized_);
91 return &stack_;
92 }
93
ThreadID() const94 uint64_t ThreadSnapshotMac::ThreadID() const {
95 INITIALIZATION_STATE_DCHECK_VALID(initialized_);
96 return thread_id_;
97 }
98
SuspendCount() const99 int ThreadSnapshotMac::SuspendCount() const {
100 INITIALIZATION_STATE_DCHECK_VALID(initialized_);
101 return suspend_count_;
102 }
103
Priority() const104 int ThreadSnapshotMac::Priority() const {
105 INITIALIZATION_STATE_DCHECK_VALID(initialized_);
106 return priority_;
107 }
108
ThreadSpecificDataAddress() const109 uint64_t ThreadSnapshotMac::ThreadSpecificDataAddress() const {
110 INITIALIZATION_STATE_DCHECK_VALID(initialized_);
111 return thread_specific_data_address_;
112 }
113
ExtraMemory() const114 std::vector<const MemorySnapshot*> ThreadSnapshotMac::ExtraMemory() const {
115 return std::vector<const MemorySnapshot*>();
116 }
117
118 } // namespace internal
119 } // namespace crashpad
120