| 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 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 98 //! This object must be created and destroyed on the main thread. Access must be | 98 //! This object must be created and destroyed on the main thread. Access must be |
| 99 //! guarded by use of the lock() with the exception of the threadpool wait | 99 //! guarded by use of the lock() with the exception of the threadpool wait |
| 100 //! variables which are accessed only by the main thread. | 100 //! variables which are accessed only by the main thread. |
| 101 class ClientData { | 101 class ClientData { |
| 102 public: | 102 public: |
| 103 ClientData(HANDLE port, | 103 ClientData(HANDLE port, |
| 104 ExceptionHandlerServer::Delegate* delegate, | 104 ExceptionHandlerServer::Delegate* delegate, |
| 105 ScopedKernelHANDLE process, | 105 ScopedKernelHANDLE process, |
| 106 WinVMAddress crash_exception_information_address, | 106 WinVMAddress crash_exception_information_address, |
| 107 WinVMAddress non_crash_exception_information_address, | 107 WinVMAddress non_crash_exception_information_address, |
| 108 WinVMAddress debug_critical_section_address, |
| 108 WAITORTIMERCALLBACK crash_dump_request_callback, | 109 WAITORTIMERCALLBACK crash_dump_request_callback, |
| 109 WAITORTIMERCALLBACK non_crash_dump_request_callback, | 110 WAITORTIMERCALLBACK non_crash_dump_request_callback, |
| 110 WAITORTIMERCALLBACK process_end_callback) | 111 WAITORTIMERCALLBACK process_end_callback) |
| 111 : crash_dump_request_thread_pool_wait_(INVALID_HANDLE_VALUE), | 112 : crash_dump_request_thread_pool_wait_(INVALID_HANDLE_VALUE), |
| 112 non_crash_dump_request_thread_pool_wait_(INVALID_HANDLE_VALUE), | 113 non_crash_dump_request_thread_pool_wait_(INVALID_HANDLE_VALUE), |
| 113 process_end_thread_pool_wait_(INVALID_HANDLE_VALUE), | 114 process_end_thread_pool_wait_(INVALID_HANDLE_VALUE), |
| 114 lock_(), | 115 lock_(), |
| 115 port_(port), | 116 port_(port), |
| 116 delegate_(delegate), | 117 delegate_(delegate), |
| 117 crash_dump_requested_event_( | 118 crash_dump_requested_event_( |
| 118 CreateEvent(nullptr, false /* auto reset */, false, nullptr)), | 119 CreateEvent(nullptr, false /* auto reset */, false, nullptr)), |
| 119 non_crash_dump_requested_event_( | 120 non_crash_dump_requested_event_( |
| 120 CreateEvent(nullptr, false /* auto reset */, false, nullptr)), | 121 CreateEvent(nullptr, false /* auto reset */, false, nullptr)), |
| 121 non_crash_dump_completed_event_( | 122 non_crash_dump_completed_event_( |
| 122 CreateEvent(nullptr, false /* auto reset */, false, nullptr)), | 123 CreateEvent(nullptr, false /* auto reset */, false, nullptr)), |
| 123 process_(process.Pass()), | 124 process_(process.Pass()), |
| 124 crash_exception_information_address_( | 125 crash_exception_information_address_( |
| 125 crash_exception_information_address), | 126 crash_exception_information_address), |
| 126 non_crash_exception_information_address_( | 127 non_crash_exception_information_address_( |
| 127 non_crash_exception_information_address) { | 128 non_crash_exception_information_address), |
| 129 debug_critical_section_address_(debug_critical_section_address) { |
| 128 RegisterThreadPoolWaits(crash_dump_request_callback, | 130 RegisterThreadPoolWaits(crash_dump_request_callback, |
| 129 non_crash_dump_request_callback, | 131 non_crash_dump_request_callback, |
| 130 process_end_callback); | 132 process_end_callback); |
| 131 } | 133 } |
| 132 | 134 |
| 133 ~ClientData() { | 135 ~ClientData() { |
| 134 // It is important that this only access the threadpool waits (it's called | 136 // It is important that this only access the threadpool waits (it's called |
| 135 // from the main thread) until the waits are unregistered, to ensure that | 137 // from the main thread) until the waits are unregistered, to ensure that |
| 136 // any outstanding callbacks are complete. | 138 // any outstanding callbacks are complete. |
| 137 UnregisterThreadPoolWaits(); | 139 UnregisterThreadPoolWaits(); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 148 } | 150 } |
| 149 HANDLE non_crash_dump_completed_event() const { | 151 HANDLE non_crash_dump_completed_event() const { |
| 150 return non_crash_dump_completed_event_.get(); | 152 return non_crash_dump_completed_event_.get(); |
| 151 } | 153 } |
| 152 WinVMAddress crash_exception_information_address() const { | 154 WinVMAddress crash_exception_information_address() const { |
| 153 return crash_exception_information_address_; | 155 return crash_exception_information_address_; |
| 154 } | 156 } |
| 155 WinVMAddress non_crash_exception_information_address() const { | 157 WinVMAddress non_crash_exception_information_address() const { |
| 156 return non_crash_exception_information_address_; | 158 return non_crash_exception_information_address_; |
| 157 } | 159 } |
| 160 WinVMAddress debug_critical_section_address() const { |
| 161 return debug_critical_section_address_; |
| 162 } |
| 158 HANDLE process() const { return process_.get(); } | 163 HANDLE process() const { return process_.get(); } |
| 159 | 164 |
| 160 private: | 165 private: |
| 161 void RegisterThreadPoolWaits( | 166 void RegisterThreadPoolWaits( |
| 162 WAITORTIMERCALLBACK crash_dump_request_callback, | 167 WAITORTIMERCALLBACK crash_dump_request_callback, |
| 163 WAITORTIMERCALLBACK non_crash_dump_request_callback, | 168 WAITORTIMERCALLBACK non_crash_dump_request_callback, |
| 164 WAITORTIMERCALLBACK process_end_callback) { | 169 WAITORTIMERCALLBACK process_end_callback) { |
| 165 if (!RegisterWaitForSingleObject(&crash_dump_request_thread_pool_wait_, | 170 if (!RegisterWaitForSingleObject(&crash_dump_request_thread_pool_wait_, |
| 166 crash_dump_requested_event_.get(), | 171 crash_dump_requested_event_.get(), |
| 167 crash_dump_request_callback, | 172 crash_dump_request_callback, |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 212 base::Lock lock_; | 217 base::Lock lock_; |
| 213 // Access to these fields must be guarded by lock_. | 218 // Access to these fields must be guarded by lock_. |
| 214 HANDLE port_; // weak | 219 HANDLE port_; // weak |
| 215 ExceptionHandlerServer::Delegate* delegate_; // weak | 220 ExceptionHandlerServer::Delegate* delegate_; // weak |
| 216 ScopedKernelHANDLE crash_dump_requested_event_; | 221 ScopedKernelHANDLE crash_dump_requested_event_; |
| 217 ScopedKernelHANDLE non_crash_dump_requested_event_; | 222 ScopedKernelHANDLE non_crash_dump_requested_event_; |
| 218 ScopedKernelHANDLE non_crash_dump_completed_event_; | 223 ScopedKernelHANDLE non_crash_dump_completed_event_; |
| 219 ScopedKernelHANDLE process_; | 224 ScopedKernelHANDLE process_; |
| 220 WinVMAddress crash_exception_information_address_; | 225 WinVMAddress crash_exception_information_address_; |
| 221 WinVMAddress non_crash_exception_information_address_; | 226 WinVMAddress non_crash_exception_information_address_; |
| 227 WinVMAddress debug_critical_section_address_; |
| 222 | 228 |
| 223 DISALLOW_COPY_AND_ASSIGN(ClientData); | 229 DISALLOW_COPY_AND_ASSIGN(ClientData); |
| 224 }; | 230 }; |
| 225 | 231 |
| 226 } // namespace internal | 232 } // namespace internal |
| 227 | 233 |
| 228 ExceptionHandlerServer::Delegate::~Delegate() { | 234 ExceptionHandlerServer::Delegate::~Delegate() { |
| 229 } | 235 } |
| 230 | 236 |
| 231 ExceptionHandlerServer::ExceptionHandlerServer() | 237 ExceptionHandlerServer::ExceptionHandlerServer() |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 405 | 411 |
| 406 internal::ClientData* client; | 412 internal::ClientData* client; |
| 407 { | 413 { |
| 408 base::AutoLock lock(*service_context.clients_lock()); | 414 base::AutoLock lock(*service_context.clients_lock()); |
| 409 client = new internal::ClientData( | 415 client = new internal::ClientData( |
| 410 service_context.port(), | 416 service_context.port(), |
| 411 service_context.delegate(), | 417 service_context.delegate(), |
| 412 ScopedKernelHANDLE(client_process), | 418 ScopedKernelHANDLE(client_process), |
| 413 message.registration.crash_exception_information, | 419 message.registration.crash_exception_information, |
| 414 message.registration.non_crash_exception_information, | 420 message.registration.non_crash_exception_information, |
| 421 message.registration.critical_section_address, |
| 415 &OnCrashDumpEvent, | 422 &OnCrashDumpEvent, |
| 416 &OnNonCrashDumpEvent, | 423 &OnNonCrashDumpEvent, |
| 417 &OnProcessEnd); | 424 &OnProcessEnd); |
| 418 service_context.clients()->insert(client); | 425 service_context.clients()->insert(client); |
| 419 } | 426 } |
| 420 | 427 |
| 421 // Duplicate the events back to the client so they can request a dump. | 428 // Duplicate the events back to the client so they can request a dump. |
| 422 ServerToClientMessage response; | 429 ServerToClientMessage response; |
| 423 response.registration.request_crash_dump_event = | 430 response.registration.request_crash_dump_event = |
| 424 base::checked_cast<uint32_t>(reinterpret_cast<uintptr_t>(DuplicateEvent( | 431 base::checked_cast<uint32_t>(reinterpret_cast<uintptr_t>(DuplicateEvent( |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 458 } | 465 } |
| 459 | 466 |
| 460 // static | 467 // static |
| 461 void __stdcall ExceptionHandlerServer::OnCrashDumpEvent(void* ctx, BOOLEAN) { | 468 void __stdcall ExceptionHandlerServer::OnCrashDumpEvent(void* ctx, BOOLEAN) { |
| 462 // This function is executed on the thread pool. | 469 // This function is executed on the thread pool. |
| 463 internal::ClientData* client = reinterpret_cast<internal::ClientData*>(ctx); | 470 internal::ClientData* client = reinterpret_cast<internal::ClientData*>(ctx); |
| 464 base::AutoLock lock(*client->lock()); | 471 base::AutoLock lock(*client->lock()); |
| 465 | 472 |
| 466 // Capture the exception. | 473 // Capture the exception. |
| 467 unsigned int exit_code = client->delegate()->ExceptionHandlerServerException( | 474 unsigned int exit_code = client->delegate()->ExceptionHandlerServerException( |
| 468 client->process(), client->crash_exception_information_address()); | 475 client->process(), |
| 476 client->crash_exception_information_address(), |
| 477 client->debug_critical_section_address()); |
| 469 | 478 |
| 470 TerminateProcess(client->process(), exit_code); | 479 TerminateProcess(client->process(), exit_code); |
| 471 } | 480 } |
| 472 | 481 |
| 473 // static | 482 // static |
| 474 void __stdcall ExceptionHandlerServer::OnNonCrashDumpEvent(void* ctx, BOOLEAN) { | 483 void __stdcall ExceptionHandlerServer::OnNonCrashDumpEvent(void* ctx, BOOLEAN) { |
| 475 // This function is executed on the thread pool. | 484 // This function is executed on the thread pool. |
| 476 internal::ClientData* client = reinterpret_cast<internal::ClientData*>(ctx); | 485 internal::ClientData* client = reinterpret_cast<internal::ClientData*>(ctx); |
| 477 base::AutoLock lock(*client->lock()); | 486 base::AutoLock lock(*client->lock()); |
| 478 | 487 |
| 479 // Capture the exception. | 488 // Capture the exception. |
| 480 client->delegate()->ExceptionHandlerServerException( | 489 client->delegate()->ExceptionHandlerServerException( |
| 481 client->process(), client->non_crash_exception_information_address()); | 490 client->process(), |
| 491 client->non_crash_exception_information_address(), |
| 492 client->debug_critical_section_address()); |
| 482 | 493 |
| 483 bool result = SetEvent(client->non_crash_dump_completed_event()); | 494 bool result = SetEvent(client->non_crash_dump_completed_event()); |
| 484 PLOG_IF(ERROR, !result) << "SetEvent"; | 495 PLOG_IF(ERROR, !result) << "SetEvent"; |
| 485 } | 496 } |
| 486 | 497 |
| 487 // static | 498 // static |
| 488 void __stdcall ExceptionHandlerServer::OnProcessEnd(void* ctx, BOOLEAN) { | 499 void __stdcall ExceptionHandlerServer::OnProcessEnd(void* ctx, BOOLEAN) { |
| 489 // This function is executed on the thread pool. | 500 // This function is executed on the thread pool. |
| 490 internal::ClientData* client = reinterpret_cast<internal::ClientData*>(ctx); | 501 internal::ClientData* client = reinterpret_cast<internal::ClientData*>(ctx); |
| 491 base::AutoLock lock(*client->lock()); | 502 base::AutoLock lock(*client->lock()); |
| 492 | 503 |
| 493 // Post back to the main thread to have it delete this client record. | 504 // Post back to the main thread to have it delete this client record. |
| 494 PostQueuedCompletionStatus(client->port(), 0, ULONG_PTR(client), nullptr); | 505 PostQueuedCompletionStatus(client->port(), 0, ULONG_PTR(client), nullptr); |
| 495 } | 506 } |
| 496 | 507 |
| 497 } // namespace crashpad | 508 } // namespace crashpad |
| OLD | NEW |