| Index: util/win/exception_handler_server.cc
|
| diff --git a/util/win/exception_handler_server.cc b/util/win/exception_handler_server.cc
|
| index bcdec6a21d43b10ed14b077bc0b6f2d69ebb5038..840b1767f9724b0fde6ebd4405110584c98d41e2 100644
|
| --- a/util/win/exception_handler_server.cc
|
| +++ b/util/win/exception_handler_server.cc
|
| @@ -103,19 +103,31 @@ class ClientData {
|
| ClientData(HANDLE port,
|
| ExceptionHandlerServer::Delegate* delegate,
|
| ScopedKernelHANDLE process,
|
| - WinVMAddress exception_information_address,
|
| - WAITORTIMERCALLBACK dump_request_callback,
|
| + WinVMAddress crash_exception_information_address,
|
| + WinVMAddress non_crash_exception_information_address,
|
| + WAITORTIMERCALLBACK crash_dump_request_callback,
|
| + WAITORTIMERCALLBACK non_crash_dump_request_callback,
|
| WAITORTIMERCALLBACK process_end_callback)
|
| - : dump_request_thread_pool_wait_(INVALID_HANDLE_VALUE),
|
| + : crash_dump_request_thread_pool_wait_(INVALID_HANDLE_VALUE),
|
| + non_crash_dump_request_thread_pool_wait_(INVALID_HANDLE_VALUE),
|
| process_end_thread_pool_wait_(INVALID_HANDLE_VALUE),
|
| lock_(),
|
| port_(port),
|
| delegate_(delegate),
|
| - dump_requested_event_(
|
| + crash_dump_requested_event_(
|
| + CreateEvent(nullptr, false /* auto reset */, false, nullptr)),
|
| + non_crash_dump_requested_event_(
|
| + CreateEvent(nullptr, false /* auto reset */, false, nullptr)),
|
| + non_crash_dump_completed_event_(
|
| CreateEvent(nullptr, false /* auto reset */, false, nullptr)),
|
| process_(process.Pass()),
|
| - exception_information_address_(exception_information_address) {
|
| - RegisterThreadPoolWaits(dump_request_callback, process_end_callback);
|
| + crash_exception_information_address_(
|
| + crash_exception_information_address),
|
| + non_crash_exception_information_address_(
|
| + non_crash_exception_information_address) {
|
| + RegisterThreadPoolWaits(crash_dump_request_callback,
|
| + non_crash_dump_request_callback,
|
| + process_end_callback);
|
| }
|
|
|
| ~ClientData() {
|
| @@ -128,22 +140,44 @@ class ClientData {
|
| base::Lock* lock() { return &lock_; }
|
| HANDLE port() const { return port_; }
|
| ExceptionHandlerServer::Delegate* delegate() const { return delegate_; }
|
| - HANDLE dump_requested_event() const { return dump_requested_event_.get(); }
|
| - WinVMAddress exception_information_address() const {
|
| - return exception_information_address_;
|
| + HANDLE crash_dump_requested_event() const {
|
| + return crash_dump_requested_event_.get();
|
| + }
|
| + HANDLE non_crash_dump_requested_event() const {
|
| + return non_crash_dump_requested_event_.get();
|
| + }
|
| + HANDLE non_crash_dump_completed_event() const {
|
| + return non_crash_dump_completed_event_.get();
|
| + }
|
| + WinVMAddress crash_exception_information_address() const {
|
| + return crash_exception_information_address_;
|
| + }
|
| + WinVMAddress non_crash_exception_information_address() const {
|
| + return non_crash_exception_information_address_;
|
| }
|
| HANDLE process() const { return process_.get(); }
|
|
|
| private:
|
| - void RegisterThreadPoolWaits(WAITORTIMERCALLBACK dump_request_callback,
|
| - WAITORTIMERCALLBACK process_end_callback) {
|
| - if (!RegisterWaitForSingleObject(&dump_request_thread_pool_wait_,
|
| - dump_requested_event_.get(),
|
| - dump_request_callback,
|
| + void RegisterThreadPoolWaits(
|
| + WAITORTIMERCALLBACK crash_dump_request_callback,
|
| + WAITORTIMERCALLBACK non_crash_dump_request_callback,
|
| + WAITORTIMERCALLBACK process_end_callback) {
|
| + if (!RegisterWaitForSingleObject(&crash_dump_request_thread_pool_wait_,
|
| + crash_dump_requested_event_.get(),
|
| + crash_dump_request_callback,
|
| + this,
|
| + INFINITE,
|
| + WT_EXECUTEDEFAULT)) {
|
| + LOG(ERROR) << "RegisterWaitForSingleObject crash dump requested";
|
| + }
|
| +
|
| + if (!RegisterWaitForSingleObject(&non_crash_dump_request_thread_pool_wait_,
|
| + non_crash_dump_requested_event_.get(),
|
| + non_crash_dump_request_callback,
|
| this,
|
| INFINITE,
|
| WT_EXECUTEDEFAULT)) {
|
| - LOG(ERROR) << "RegisterWaitForSingleObject dump requested";
|
| + LOG(ERROR) << "RegisterWaitForSingleObject non-crash dump requested";
|
| }
|
|
|
| if (!RegisterWaitForSingleObject(&process_end_thread_pool_wait_,
|
| @@ -160,23 +194,31 @@ class ClientData {
|
| // delete this object. Because of this, it must be executed on the main
|
| // thread, not a threadpool thread.
|
| void UnregisterThreadPoolWaits() {
|
| - UnregisterWaitEx(dump_request_thread_pool_wait_, INVALID_HANDLE_VALUE);
|
| - dump_request_thread_pool_wait_ = INVALID_HANDLE_VALUE;
|
| + UnregisterWaitEx(crash_dump_request_thread_pool_wait_,
|
| + INVALID_HANDLE_VALUE);
|
| + crash_dump_request_thread_pool_wait_ = INVALID_HANDLE_VALUE;
|
| + UnregisterWaitEx(non_crash_dump_request_thread_pool_wait_,
|
| + INVALID_HANDLE_VALUE);
|
| + non_crash_dump_request_thread_pool_wait_ = INVALID_HANDLE_VALUE;
|
| UnregisterWaitEx(process_end_thread_pool_wait_, INVALID_HANDLE_VALUE);
|
| process_end_thread_pool_wait_ = INVALID_HANDLE_VALUE;
|
| }
|
|
|
| // These are only accessed on the main thread.
|
| - HANDLE dump_request_thread_pool_wait_;
|
| + HANDLE crash_dump_request_thread_pool_wait_;
|
| + HANDLE non_crash_dump_request_thread_pool_wait_;
|
| HANDLE process_end_thread_pool_wait_;
|
|
|
| base::Lock lock_;
|
| // Access to these fields must be guarded by lock_.
|
| HANDLE port_; // weak
|
| ExceptionHandlerServer::Delegate* delegate_; // weak
|
| - ScopedKernelHANDLE dump_requested_event_;
|
| + ScopedKernelHANDLE crash_dump_requested_event_;
|
| + ScopedKernelHANDLE non_crash_dump_requested_event_;
|
| + ScopedKernelHANDLE non_crash_dump_completed_event_;
|
| ScopedKernelHANDLE process_;
|
| - WinVMAddress exception_information_address_;
|
| + WinVMAddress crash_exception_information_address_;
|
| + WinVMAddress non_crash_exception_information_address_;
|
|
|
| DISALLOW_COPY_AND_ASSIGN(ClientData);
|
| };
|
| @@ -364,21 +406,29 @@ bool ExceptionHandlerServer::ServiceClientConnection(
|
| internal::ClientData* client;
|
| {
|
| base::AutoLock lock(*service_context.clients_lock());
|
| - client =
|
| - new internal::ClientData(service_context.port(),
|
| - service_context.delegate(),
|
| - ScopedKernelHANDLE(client_process),
|
| - message.registration.exception_information,
|
| - &OnDumpEvent,
|
| - &OnProcessEnd);
|
| + client = new internal::ClientData(
|
| + service_context.port(),
|
| + service_context.delegate(),
|
| + ScopedKernelHANDLE(client_process),
|
| + message.registration.crash_exception_information,
|
| + message.registration.non_crash_exception_information,
|
| + &OnCrashDumpEvent,
|
| + &OnNonCrashDumpEvent,
|
| + &OnProcessEnd);
|
| service_context.clients()->insert(client);
|
| }
|
|
|
| // Duplicate the events back to the client so they can request a dump.
|
| ServerToClientMessage response;
|
| - response.registration.request_report_event =
|
| - base::checked_cast<uint32_t>(reinterpret_cast<uintptr_t>(
|
| - DuplicateEvent(client->process(), client->dump_requested_event())));
|
| + response.registration.request_crash_dump_event =
|
| + base::checked_cast<uint32_t>(reinterpret_cast<uintptr_t>(DuplicateEvent(
|
| + client->process(), client->crash_dump_requested_event())));
|
| + response.registration.request_non_crash_dump_event =
|
| + base::checked_cast<uint32_t>(reinterpret_cast<uintptr_t>(DuplicateEvent(
|
| + client->process(), client->non_crash_dump_requested_event())));
|
| + response.registration.non_crash_dump_completed_event =
|
| + base::checked_cast<uint32_t>(reinterpret_cast<uintptr_t>(DuplicateEvent(
|
| + client->process(), client->non_crash_dump_completed_event())));
|
|
|
| if (!LoggingWriteFile(service_context.pipe(), &response, sizeof(response)))
|
| return false;
|
| @@ -408,19 +458,33 @@ DWORD __stdcall ExceptionHandlerServer::PipeServiceProc(void* ctx) {
|
| }
|
|
|
| // static
|
| -void __stdcall ExceptionHandlerServer::OnDumpEvent(void* ctx, BOOLEAN) {
|
| +void __stdcall ExceptionHandlerServer::OnCrashDumpEvent(void* ctx, BOOLEAN) {
|
| // This function is executed on the thread pool.
|
| internal::ClientData* client = reinterpret_cast<internal::ClientData*>(ctx);
|
| base::AutoLock lock(*client->lock());
|
|
|
| // Capture the exception.
|
| unsigned int exit_code = client->delegate()->ExceptionHandlerServerException(
|
| - client->process(), client->exception_information_address());
|
| + client->process(), client->crash_exception_information_address());
|
|
|
| TerminateProcess(client->process(), exit_code);
|
| }
|
|
|
| // static
|
| +void __stdcall ExceptionHandlerServer::OnNonCrashDumpEvent(void* ctx, BOOLEAN) {
|
| + // This function is executed on the thread pool.
|
| + internal::ClientData* client = reinterpret_cast<internal::ClientData*>(ctx);
|
| + base::AutoLock lock(*client->lock());
|
| +
|
| + // Capture the exception.
|
| + client->delegate()->ExceptionHandlerServerException(
|
| + client->process(), client->non_crash_exception_information_address());
|
| +
|
| + bool result = SetEvent(client->non_crash_dump_completed_event());
|
| + PLOG_IF(ERROR, !result) << "SetEvent";
|
| +}
|
| +
|
| +// static
|
| void __stdcall ExceptionHandlerServer::OnProcessEnd(void* ctx, BOOLEAN) {
|
| // This function is executed on the thread pool.
|
| internal::ClientData* client = reinterpret_cast<internal::ClientData*>(ctx);
|
|
|