OLD | NEW |
1 // Copyright 2014 The Crashpad Authors. All rights reserved. | 1 // Copyright 2014 The Crashpad Authors. All rights reserved. |
2 // | 2 // |
3 // Licensed under the Apache License, Version 2.0 (the "License"); | 3 // Licensed under the Apache License, Version 2.0 (the "License"); |
4 // you may not use this file except in compliance with 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 | 5 // You may obtain a copy of the License at |
6 // | 6 // |
7 // http://www.apache.org/licenses/LICENSE-2.0 | 7 // http://www.apache.org/licenses/LICENSE-2.0 |
8 // | 8 // |
9 // Unless required by applicable law or agreed to in writing, software | 9 // Unless required by applicable law or agreed to in writing, software |
10 // distributed under the License is distributed on an "AS IS" BASIS, | 10 // distributed under the License is distributed on an "AS IS" BASIS, |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
52 //! handler. If `false`, this will be suppressed, even when \a behavior | 52 //! handler. If `false`, this will be suppressed, even when \a behavior |
53 //! indicates that the handler receives and returns a thread state. | 53 //! indicates that the handler receives and returns a thread state. |
54 //! | 54 //! |
55 //! \return `true` if the exception was delivered to the handler and the handler | 55 //! \return `true` if the exception was delivered to the handler and the handler |
56 //! indicated success. `false` otherwise, with a warning message logged. | 56 //! indicated success. `false` otherwise, with a warning message logged. |
57 bool DeliverException(thread_t thread, | 57 bool DeliverException(thread_t thread, |
58 task_t task, | 58 task_t task, |
59 exception_type_t exception, | 59 exception_type_t exception, |
60 const mach_exception_data_t code, | 60 const mach_exception_data_t code, |
61 mach_msg_type_number_t code_count, | 61 mach_msg_type_number_t code_count, |
62 const NativeCPUContext* cpu_context, | 62 const NativeCPUContext& cpu_context, |
63 const ExceptionPorts::ExceptionHandler& handler, | 63 const ExceptionPorts::ExceptionHandler& handler, |
64 bool set_state) { | 64 bool set_state) { |
65 kern_return_t kr; | 65 kern_return_t kr; |
66 | 66 |
67 bool handler_wants_state = ExceptionBehaviorHasState(handler.behavior); | 67 bool handler_wants_state = ExceptionBehaviorHasState(handler.behavior); |
68 if (!handler_wants_state) { | 68 if (!handler_wants_state) { |
69 // Regardless of the passed-in value of |set_state|, if the handler won’t be | 69 // Regardless of the passed-in value of |set_state|, if the handler won’t be |
70 // dealing with any state at all, no state should be set. | 70 // dealing with any state at all, no state should be set. |
71 set_state = false; | 71 set_state = false; |
72 } | 72 } |
73 | 73 |
74 // old_state is only used if the context already captured doesn’t match (or | 74 // old_state is only used if the context already captured doesn’t match (or |
75 // can’t be converted to) what’s registered for the handler. | 75 // can’t be converted to) what’s registered for the handler. |
76 thread_state_data_t old_state; | 76 thread_state_data_t old_state; |
77 | 77 |
78 thread_state_flavor_t flavor = handler.flavor; | 78 thread_state_flavor_t flavor = handler.flavor; |
79 ConstThreadState state; | 79 ConstThreadState state; |
80 mach_msg_type_number_t state_count; | 80 mach_msg_type_number_t state_count; |
81 switch (flavor) { | 81 switch (flavor) { |
82 #if defined(ARCH_CPU_X86_FAMILY) | 82 #if defined(ARCH_CPU_X86_FAMILY) |
83 case x86_THREAD_STATE: | 83 case x86_THREAD_STATE: |
84 state = reinterpret_cast<ConstThreadState>(cpu_context); | 84 state = reinterpret_cast<ConstThreadState>(&cpu_context); |
85 state_count = x86_THREAD_STATE_COUNT; | 85 state_count = x86_THREAD_STATE_COUNT; |
86 break; | 86 break; |
87 #if defined(ARCH_CPU_X86) | 87 #if defined(ARCH_CPU_X86) |
88 case x86_THREAD_STATE32: | 88 case x86_THREAD_STATE32: |
89 state = reinterpret_cast<ConstThreadState>(&cpu_context->uts.ts32); | 89 state = reinterpret_cast<ConstThreadState>(&cpu_context.uts.ts32); |
90 state_count = cpu_context->tsh.count; | 90 state_count = cpu_context.tsh.count; |
91 break; | 91 break; |
92 #elif defined(ARCH_CPU_X86_64) | 92 #elif defined(ARCH_CPU_X86_64) |
93 case x86_THREAD_STATE64: | 93 case x86_THREAD_STATE64: |
94 state = reinterpret_cast<ConstThreadState>(&cpu_context->uts.ts64); | 94 state = reinterpret_cast<ConstThreadState>(&cpu_context.uts.ts64); |
95 state_count = cpu_context->tsh.count; | 95 state_count = cpu_context.tsh.count; |
96 break; | 96 break; |
97 #endif | 97 #endif |
98 #else | 98 #else |
99 #error Port to your CPU architecture | 99 #error Port to your CPU architecture |
100 #endif | 100 #endif |
101 | 101 |
102 case THREAD_STATE_NONE: | 102 case THREAD_STATE_NONE: |
103 // This is only acceptable if the handler doesn’t have one of the “state” | 103 // This is only acceptable if the handler doesn’t have one of the “state” |
104 // behaviors. Otherwise, if the kernel were attempting to send an | 104 // behaviors. Otherwise, if the kernel were attempting to send an |
105 // exception message to this port, it would call thread_getstatus() (known | 105 // exception message to this port, it would call thread_getstatus() (known |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
169 if (kr == KERN_SUCCESS && set_state) { | 169 if (kr == KERN_SUCCESS && set_state) { |
170 kr = thread_set_state(thread, flavor, new_state, new_state_count); | 170 kr = thread_set_state(thread, flavor, new_state, new_state_count); |
171 MACH_LOG_IF(WARNING, kr != KERN_SUCCESS, kr) << "thread_set_state"; | 171 MACH_LOG_IF(WARNING, kr != KERN_SUCCESS, kr) << "thread_set_state"; |
172 } | 172 } |
173 | 173 |
174 return success; | 174 return success; |
175 } | 175 } |
176 | 176 |
177 } // namespace | 177 } // namespace |
178 | 178 |
179 void SimulateCrash(const NativeCPUContext* cpu_context) { | 179 void SimulateCrash(const NativeCPUContext& cpu_context) { |
180 #if defined(ARCH_CPU_X86) | 180 #if defined(ARCH_CPU_X86) |
181 DCHECK_EQ(cpu_context->tsh.flavor, | 181 DCHECK_EQ(cpu_context.tsh.flavor, |
182 implicit_cast<thread_state_flavor_t>(x86_THREAD_STATE32)); | 182 implicit_cast<thread_state_flavor_t>(x86_THREAD_STATE32)); |
183 DCHECK_EQ(implicit_cast<mach_msg_type_number_t>(cpu_context->tsh.count), | 183 DCHECK_EQ(implicit_cast<mach_msg_type_number_t>(cpu_context.tsh.count), |
184 x86_THREAD_STATE32_COUNT); | 184 x86_THREAD_STATE32_COUNT); |
185 #elif defined(ARCH_CPU_X86_64) | 185 #elif defined(ARCH_CPU_X86_64) |
186 DCHECK_EQ(cpu_context->tsh.flavor, | 186 DCHECK_EQ(cpu_context.tsh.flavor, |
187 implicit_cast<thread_state_flavor_t>(x86_THREAD_STATE64)); | 187 implicit_cast<thread_state_flavor_t>(x86_THREAD_STATE64)); |
188 DCHECK_EQ(implicit_cast<mach_msg_type_number_t>(cpu_context->tsh.count), | 188 DCHECK_EQ(implicit_cast<mach_msg_type_number_t>(cpu_context.tsh.count), |
189 x86_THREAD_STATE64_COUNT); | 189 x86_THREAD_STATE64_COUNT); |
190 #endif | 190 #endif |
191 | 191 |
192 base::mac::ScopedMachSendRight thread(mach_thread_self()); | 192 base::mac::ScopedMachSendRight thread(mach_thread_self()); |
193 exception_type_t exception = kMachExceptionSimulated; | 193 exception_type_t exception = kMachExceptionSimulated; |
194 mach_exception_data_type_t codes[] = {0, 0}; | 194 mach_exception_data_type_t codes[] = {0, 0}; |
195 mach_msg_type_number_t code_count = arraysize(codes); | 195 mach_msg_type_number_t code_count = arraysize(codes); |
196 | 196 |
197 // Look up the handler for EXC_CRASH exceptions in the same way that the | 197 // Look up the handler for EXC_CRASH exceptions in the same way that the |
198 // kernel would: try a thread handler, then a task handler, and finally a host | 198 // kernel would: try a thread handler, then a task handler, and finally a host |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
233 false); | 233 false); |
234 } | 234 } |
235 } | 235 } |
236 } | 236 } |
237 | 237 |
238 LOG_IF(WARNING, !success) | 238 LOG_IF(WARNING, !success) |
239 << "SimulateCrash did not find an appropriate exception handler"; | 239 << "SimulateCrash did not find an appropriate exception handler"; |
240 } | 240 } |
241 | 241 |
242 } // namespace crashpad | 242 } // namespace crashpad |
OLD | NEW |