OLD | NEW |
---|---|
1 // Copyright 2015 The Crashpad Authors. All rights reserved. | 1 // Copyright 2015 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 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
106 WinVMAddress exception_information_address, | 106 WinVMAddress exception_information_address, |
107 WAITORTIMERCALLBACK dump_request_callback, | 107 WAITORTIMERCALLBACK dump_request_callback, |
108 WAITORTIMERCALLBACK process_end_callback) | 108 WAITORTIMERCALLBACK process_end_callback) |
109 : dump_request_thread_pool_wait_(INVALID_HANDLE_VALUE), | 109 : dump_request_thread_pool_wait_(INVALID_HANDLE_VALUE), |
110 process_end_thread_pool_wait_(INVALID_HANDLE_VALUE), | 110 process_end_thread_pool_wait_(INVALID_HANDLE_VALUE), |
111 lock_(), | 111 lock_(), |
112 port_(port), | 112 port_(port), |
113 delegate_(delegate), | 113 delegate_(delegate), |
114 dump_requested_event_( | 114 dump_requested_event_( |
115 CreateEvent(nullptr, false /* auto reset */, false, nullptr)), | 115 CreateEvent(nullptr, false /* auto reset */, false, nullptr)), |
116 dump_completed_event_( | |
117 CreateEvent(nullptr, false /* auto reset */, false, nullptr)), | |
116 process_(process.Pass()), | 118 process_(process.Pass()), |
117 exception_information_address_(exception_information_address) { | 119 exception_information_address_(exception_information_address) { |
118 RegisterThreadPoolWaits(dump_request_callback, process_end_callback); | 120 RegisterThreadPoolWaits(dump_request_callback, process_end_callback); |
119 } | 121 } |
120 | 122 |
121 ~ClientData() { | 123 ~ClientData() { |
122 // It is important that this only access the threadpool waits (it's called | 124 // It is important that this only access the threadpool waits (it's called |
123 // from the main thread) until the waits are unregistered, to ensure that | 125 // from the main thread) until the waits are unregistered, to ensure that |
124 // any outstanding callbacks are complete. | 126 // any outstanding callbacks are complete. |
125 UnregisterThreadPoolWaits(); | 127 UnregisterThreadPoolWaits(); |
126 } | 128 } |
127 | 129 |
128 base::Lock* lock() { return &lock_; } | 130 base::Lock* lock() { return &lock_; } |
129 HANDLE port() const { return port_; } | 131 HANDLE port() const { return port_; } |
130 ExceptionHandlerServer::Delegate* delegate() const { return delegate_; } | 132 ExceptionHandlerServer::Delegate* delegate() const { return delegate_; } |
131 HANDLE dump_requested_event() const { return dump_requested_event_.get(); } | 133 HANDLE dump_requested_event() const { return dump_requested_event_.get(); } |
134 HANDLE dump_completed_event() const { return dump_completed_event_.get(); } | |
132 WinVMAddress exception_information_address() const { | 135 WinVMAddress exception_information_address() const { |
133 return exception_information_address_; | 136 return exception_information_address_; |
134 } | 137 } |
135 HANDLE process() const { return process_.get(); } | 138 HANDLE process() const { return process_.get(); } |
136 | 139 |
137 private: | 140 private: |
138 void RegisterThreadPoolWaits(WAITORTIMERCALLBACK dump_request_callback, | 141 void RegisterThreadPoolWaits(WAITORTIMERCALLBACK dump_request_callback, |
139 WAITORTIMERCALLBACK process_end_callback) { | 142 WAITORTIMERCALLBACK process_end_callback) { |
140 if (!RegisterWaitForSingleObject(&dump_request_thread_pool_wait_, | 143 if (!RegisterWaitForSingleObject(&dump_request_thread_pool_wait_, |
141 dump_requested_event_.get(), | 144 dump_requested_event_.get(), |
(...skipping 26 matching lines...) Expand all Loading... | |
168 | 171 |
169 // These are only accessed on the main thread. | 172 // These are only accessed on the main thread. |
170 HANDLE dump_request_thread_pool_wait_; | 173 HANDLE dump_request_thread_pool_wait_; |
171 HANDLE process_end_thread_pool_wait_; | 174 HANDLE process_end_thread_pool_wait_; |
172 | 175 |
173 base::Lock lock_; | 176 base::Lock lock_; |
174 // Access to these fields must be guarded by lock_. | 177 // Access to these fields must be guarded by lock_. |
175 HANDLE port_; // weak | 178 HANDLE port_; // weak |
176 ExceptionHandlerServer::Delegate* delegate_; // weak | 179 ExceptionHandlerServer::Delegate* delegate_; // weak |
177 ScopedKernelHANDLE dump_requested_event_; | 180 ScopedKernelHANDLE dump_requested_event_; |
181 ScopedKernelHANDLE dump_completed_event_; | |
178 ScopedKernelHANDLE process_; | 182 ScopedKernelHANDLE process_; |
179 WinVMAddress exception_information_address_; | 183 WinVMAddress exception_information_address_; |
180 | 184 |
181 DISALLOW_COPY_AND_ASSIGN(ClientData); | 185 DISALLOW_COPY_AND_ASSIGN(ClientData); |
182 }; | 186 }; |
183 | 187 |
184 } // namespace internal | 188 } // namespace internal |
185 | 189 |
186 ExceptionHandlerServer::Delegate::~Delegate() { | 190 ExceptionHandlerServer::Delegate::~Delegate() { |
187 } | 191 } |
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
372 &OnDumpEvent, | 376 &OnDumpEvent, |
373 &OnProcessEnd); | 377 &OnProcessEnd); |
374 service_context.clients()->insert(client); | 378 service_context.clients()->insert(client); |
375 } | 379 } |
376 | 380 |
377 // Duplicate the events back to the client so they can request a dump. | 381 // Duplicate the events back to the client so they can request a dump. |
378 ServerToClientMessage response; | 382 ServerToClientMessage response; |
379 response.registration.request_report_event = | 383 response.registration.request_report_event = |
380 base::checked_cast<uint32_t>(reinterpret_cast<uintptr_t>( | 384 base::checked_cast<uint32_t>(reinterpret_cast<uintptr_t>( |
381 DuplicateEvent(client->process(), client->dump_requested_event()))); | 385 DuplicateEvent(client->process(), client->dump_requested_event()))); |
386 response.registration.report_completed_event = | |
387 base::checked_cast<uint32_t>(reinterpret_cast<uintptr_t>( | |
388 DuplicateEvent(client->process(), client->dump_completed_event()))); | |
382 | 389 |
383 if (!LoggingWriteFile(service_context.pipe(), &response, sizeof(response))) | 390 if (!LoggingWriteFile(service_context.pipe(), &response, sizeof(response))) |
384 return false; | 391 return false; |
385 | 392 |
386 return false; | 393 return false; |
387 } | 394 } |
388 | 395 |
389 // static | 396 // static |
390 DWORD __stdcall ExceptionHandlerServer::PipeServiceProc(void* ctx) { | 397 DWORD __stdcall ExceptionHandlerServer::PipeServiceProc(void* ctx) { |
391 internal::PipeServiceContext* service_context = | 398 internal::PipeServiceContext* service_context = |
(...skipping 15 matching lines...) Expand all Loading... | |
407 return 0; | 414 return 0; |
408 } | 415 } |
409 | 416 |
410 // static | 417 // static |
411 void __stdcall ExceptionHandlerServer::OnDumpEvent(void* ctx, BOOLEAN) { | 418 void __stdcall ExceptionHandlerServer::OnDumpEvent(void* ctx, BOOLEAN) { |
412 // This function is executed on the thread pool. | 419 // This function is executed on the thread pool. |
413 internal::ClientData* client = reinterpret_cast<internal::ClientData*>(ctx); | 420 internal::ClientData* client = reinterpret_cast<internal::ClientData*>(ctx); |
414 base::AutoLock lock(*client->lock()); | 421 base::AutoLock lock(*client->lock()); |
415 | 422 |
416 // Capture the exception. | 423 // Capture the exception. |
417 unsigned int exit_code = client->delegate()->ExceptionHandlerServerException( | 424 client->delegate()->ExceptionHandlerServerException( |
418 client->process(), client->exception_information_address()); | 425 client->process(), client->exception_information_address()); |
419 | 426 |
420 TerminateProcess(client->process(), exit_code); | 427 // Release the client. |
428 SetEvent(client->dump_completed_event()); | |
Mark Mentovai
2015/09/23 20:00:52
PLOG_IF this fails.
scottmg
2015/09/24 19:16:52
Done.
| |
421 } | 429 } |
422 | 430 |
423 // static | 431 // static |
424 void __stdcall ExceptionHandlerServer::OnProcessEnd(void* ctx, BOOLEAN) { | 432 void __stdcall ExceptionHandlerServer::OnProcessEnd(void* ctx, BOOLEAN) { |
425 // This function is executed on the thread pool. | 433 // This function is executed on the thread pool. |
426 internal::ClientData* client = reinterpret_cast<internal::ClientData*>(ctx); | 434 internal::ClientData* client = reinterpret_cast<internal::ClientData*>(ctx); |
427 base::AutoLock lock(*client->lock()); | 435 base::AutoLock lock(*client->lock()); |
428 | 436 |
429 // Post back to the main thread to have it delete this client record. | 437 // Post back to the main thread to have it delete this client record. |
430 PostQueuedCompletionStatus(client->port(), 0, ULONG_PTR(client), nullptr); | 438 PostQueuedCompletionStatus(client->port(), 0, ULONG_PTR(client), nullptr); |
431 } | 439 } |
432 | 440 |
433 } // namespace crashpad | 441 } // namespace crashpad |
OLD | NEW |