Index: third_party/breakpad/src/client/windows/crash_generation/crash_generation_client.cc |
diff --git a/third_party/breakpad/src/client/windows/crash_generation/crash_generation_client.cc b/third_party/breakpad/src/client/windows/crash_generation/crash_generation_client.cc |
deleted file mode 100644 |
index 5e4e3cb9ee05419ab3630f6a8a890363a08cc79e..0000000000000000000000000000000000000000 |
--- a/third_party/breakpad/src/client/windows/crash_generation/crash_generation_client.cc |
+++ /dev/null |
@@ -1,328 +0,0 @@ |
-// Copyright (c) 2008, Google Inc. |
-// All rights reserved. |
-// |
-// Redistribution and use in source and binary forms, with or without |
-// modification, are permitted provided that the following conditions are |
-// met: |
-// |
-// * Redistributions of source code must retain the above copyright |
-// notice, this list of conditions and the following disclaimer. |
-// * Redistributions in binary form must reproduce the above |
-// copyright notice, this list of conditions and the following disclaimer |
-// in the documentation and/or other materials provided with the |
-// distribution. |
-// * Neither the name of Google Inc. nor the names of its |
-// contributors may be used to endorse or promote products derived from |
-// this software without specific prior written permission. |
-// |
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
- |
-#include "client/windows/crash_generation/crash_generation_client.h" |
-#include <cassert> |
-#include <utility> |
-#include "client/windows/common/ipc_protocol.h" |
- |
-namespace google_breakpad { |
- |
-const int kPipeBusyWaitTimeoutMs = 2000; |
- |
-#ifdef _DEBUG |
-const DWORD kWaitForServerTimeoutMs = INFINITE; |
-#else |
-const DWORD kWaitForServerTimeoutMs = 15000; |
-#endif |
- |
-const int kPipeConnectMaxAttempts = 2; |
- |
-const DWORD kPipeDesiredAccess = FILE_READ_DATA | |
- FILE_WRITE_DATA | |
- FILE_WRITE_ATTRIBUTES; |
- |
-const DWORD kPipeFlagsAndAttributes = SECURITY_IDENTIFICATION | |
- SECURITY_SQOS_PRESENT; |
- |
-const DWORD kPipeMode = PIPE_READMODE_MESSAGE; |
- |
-const size_t kWaitEventCount = 2; |
- |
-// This function is orphan for production code. It can be used |
-// for debugging to help repro some scenarios like the client |
-// is slow in writing to the pipe after connecting, the client |
-// is slow in reading from the pipe after writing, etc. The parameter |
-// overlapped below is not used and it is present to match the signature |
-// of this function to TransactNamedPipe Win32 API. Uncomment if needed |
-// for debugging. |
-/** |
-static bool TransactNamedPipeDebugHelper(HANDLE pipe, |
- const void* in_buffer, |
- DWORD in_size, |
- void* out_buffer, |
- DWORD out_size, |
- DWORD* bytes_count, |
- LPOVERLAPPED) { |
- // Uncomment the next sleep to create a gap before writing |
- // to pipe. |
- // Sleep(5000); |
- |
- if (!WriteFile(pipe, |
- in_buffer, |
- in_size, |
- bytes_count, |
- NULL)) { |
- return false; |
- } |
- |
- // Uncomment the next sleep to create a gap between write |
- // and read. |
- // Sleep(5000); |
- |
- return ReadFile(pipe, out_buffer, out_size, bytes_count, NULL) != FALSE; |
-} |
-**/ |
- |
-CrashGenerationClient::CrashGenerationClient( |
- const wchar_t* pipe_name, |
- MINIDUMP_TYPE dump_type, |
- const CustomClientInfo* custom_info) |
- : pipe_name_(pipe_name), |
- dump_type_(dump_type), |
- thread_id_(0), |
- server_process_id_(0), |
- crash_event_(NULL), |
- crash_generated_(NULL), |
- server_alive_(NULL), |
- exception_pointers_(NULL), |
- custom_info_() { |
- memset(&assert_info_, 0, sizeof(assert_info_)); |
- if (custom_info) { |
- custom_info_ = *custom_info; |
- } |
-} |
- |
-CrashGenerationClient::~CrashGenerationClient() { |
- if (crash_event_) { |
- CloseHandle(crash_event_); |
- } |
- |
- if (crash_generated_) { |
- CloseHandle(crash_generated_); |
- } |
- |
- if (server_alive_) { |
- CloseHandle(server_alive_); |
- } |
-} |
- |
-// Performs the registration step with the server process. |
-// The registration step involves communicating with the server |
-// via a named pipe. The client sends the following pieces of |
-// data to the server: |
-// |
-// * Message tag indicating the client is requesting registration. |
-// * Process id of the client process. |
-// * Address of a DWORD variable in the client address space |
-// that will contain the thread id of the client thread that |
-// caused the crash. |
-// * Address of a EXCEPTION_POINTERS* variable in the client |
-// address space that will point to an instance of EXCEPTION_POINTERS |
-// when the crash happens. |
-// * Address of an instance of MDRawAssertionInfo that will contain |
-// relevant information in case of non-exception crashes like assertion |
-// failures and pure calls. |
-// |
-// In return the client expects the following information from the server: |
-// |
-// * Message tag indicating successful registration. |
-// * Server process id. |
-// * Handle to an object that client can signal to request dump |
-// generation from the server. |
-// * Handle to an object that client can wait on after requesting |
-// dump generation for the server to finish dump generation. |
-// * Handle to a mutex object that client can wait on to make sure |
-// server is still alive. |
-// |
-// If any step of the expected behavior mentioned above fails, the |
-// registration step is not considered successful and hence out-of-process |
-// dump generation service is not available. |
-// |
-// Returns true if the registration is successful; false otherwise. |
-bool CrashGenerationClient::Register() { |
- HANDLE pipe = ConnectToServer(); |
- if (!pipe) { |
- return false; |
- } |
- |
- bool success = RegisterClient(pipe); |
- CloseHandle(pipe); |
- return success; |
-} |
- |
-HANDLE CrashGenerationClient::ConnectToServer() { |
- HANDLE pipe = ConnectToPipe(pipe_name_.c_str(), |
- kPipeDesiredAccess, |
- kPipeFlagsAndAttributes); |
- if (!pipe) { |
- return NULL; |
- } |
- |
- DWORD mode = kPipeMode; |
- if (!SetNamedPipeHandleState(pipe, &mode, NULL, NULL)) { |
- CloseHandle(pipe); |
- pipe = NULL; |
- } |
- |
- return pipe; |
-} |
- |
-bool CrashGenerationClient::RegisterClient(HANDLE pipe) { |
- ProtocolMessage msg(MESSAGE_TAG_REGISTRATION_REQUEST, |
- GetCurrentProcessId(), |
- dump_type_, |
- &thread_id_, |
- &exception_pointers_, |
- &assert_info_, |
- custom_info_, |
- NULL, |
- NULL, |
- NULL); |
- ProtocolMessage reply; |
- DWORD bytes_count = 0; |
- // The call to TransactNamedPipe below can be changed to a call |
- // to TransactNamedPipeDebugHelper to help repro some scenarios. |
- // For details see comments for TransactNamedPipeDebugHelper. |
- if (!TransactNamedPipe(pipe, |
- &msg, |
- sizeof(msg), |
- &reply, |
- sizeof(ProtocolMessage), |
- &bytes_count, |
- NULL)) { |
- return false; |
- } |
- |
- if (!ValidateResponse(reply)) { |
- return false; |
- } |
- |
- ProtocolMessage ack_msg; |
- ack_msg.tag = MESSAGE_TAG_REGISTRATION_ACK; |
- |
- if (!WriteFile(pipe, &ack_msg, sizeof(ack_msg), &bytes_count, NULL)) { |
- return false; |
- } |
- crash_event_ = reply.dump_request_handle; |
- crash_generated_ = reply.dump_generated_handle; |
- server_alive_ = reply.server_alive_handle; |
- server_process_id_ = reply.pid; |
- |
- return true; |
-} |
- |
-HANDLE CrashGenerationClient::ConnectToPipe(const wchar_t* pipe_name, |
- DWORD pipe_access, |
- DWORD flags_attrs) { |
- for (int i = 0; i < kPipeConnectMaxAttempts; ++i) { |
- HANDLE pipe = CreateFile(pipe_name, |
- pipe_access, |
- 0, |
- NULL, |
- OPEN_EXISTING, |
- flags_attrs, |
- NULL); |
- if (pipe != INVALID_HANDLE_VALUE) { |
- return pipe; |
- } |
- |
- // Cannot continue retrying if error is something other than |
- // ERROR_PIPE_BUSY. |
- if (GetLastError() != ERROR_PIPE_BUSY) { |
- break; |
- } |
- |
- // Cannot continue retrying if wait on pipe fails. |
- if (!WaitNamedPipe(pipe_name, kPipeBusyWaitTimeoutMs)) { |
- break; |
- } |
- } |
- |
- return NULL; |
-} |
- |
-bool CrashGenerationClient::ValidateResponse( |
- const ProtocolMessage& msg) const { |
- return (msg.tag == MESSAGE_TAG_REGISTRATION_RESPONSE) && |
- (msg.pid != 0) && |
- (msg.dump_request_handle != NULL) && |
- (msg.dump_generated_handle != NULL) && |
- (msg.server_alive_handle != NULL); |
-} |
- |
-bool CrashGenerationClient::IsRegistered() const { |
- return crash_event_ != NULL; |
-} |
- |
-bool CrashGenerationClient::RequestDump(EXCEPTION_POINTERS* ex_info, |
- MDRawAssertionInfo* assert_info) { |
- if (!IsRegistered()) { |
- return false; |
- } |
- |
- exception_pointers_ = ex_info; |
- thread_id_ = GetCurrentThreadId(); |
- |
- if (assert_info) { |
- memcpy(&assert_info_, assert_info, sizeof(assert_info_)); |
- } else { |
- memset(&assert_info_, 0, sizeof(assert_info_)); |
- } |
- |
- return SignalCrashEventAndWait(); |
-} |
- |
-bool CrashGenerationClient::RequestDump(EXCEPTION_POINTERS* ex_info) { |
- return RequestDump(ex_info, NULL); |
-} |
- |
-bool CrashGenerationClient::RequestDump(MDRawAssertionInfo* assert_info) { |
- return RequestDump(NULL, assert_info); |
-} |
- |
-bool CrashGenerationClient::SignalCrashEventAndWait() { |
- assert(crash_event_); |
- assert(crash_generated_); |
- assert(server_alive_); |
- |
- // Reset the dump generated event before signaling the crash |
- // event so that the server can set the dump generated event |
- // once it is done generating the event. |
- if (!ResetEvent(crash_generated_)) { |
- return false; |
- } |
- |
- if (!SetEvent(crash_event_)) { |
- return false; |
- } |
- |
- HANDLE wait_handles[kWaitEventCount] = {crash_generated_, server_alive_}; |
- |
- DWORD result = WaitForMultipleObjects(kWaitEventCount, |
- wait_handles, |
- FALSE, |
- kWaitForServerTimeoutMs); |
- |
- // Crash dump was successfully generated only if the server |
- // signaled the crash generated event. |
- return result == WAIT_OBJECT_0; |
-} |
- |
-} // namespace google_breakpad |