Chromium Code Reviews| 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 |