mirror of
https://github.com/chromium/crashpad.git
synced 2025-01-14 17:30:09 +08:00
crashpad client for windows
Introduces CrashpadClient::SetHandler() The code in the cc plays it fast and loose but helps ground the intention. BUG=crashpad:1 R=mark@chromium.org, scottmg@chromium.org Review URL: https://codereview.chromium.org/1095273003
This commit is contained in:
parent
7b7205fe52
commit
dd3c20667d
@ -37,6 +37,7 @@
|
||||
'crash_report_database_win.cc',
|
||||
'crashpad_client.h',
|
||||
'crashpad_client_mac.cc',
|
||||
'crashpad_client_win.cc',
|
||||
'crashpad_info.cc',
|
||||
'crashpad_info.h',
|
||||
'settings.cc',
|
||||
|
@ -49,6 +49,9 @@ class CrashpadClient {
|
||||
//! send right corresponding to a receive right held by the handler process.
|
||||
//! The handler process runs an exception server on this port.
|
||||
//!
|
||||
//! On Windows, SetHandler() is normally used instead since the handler is
|
||||
//! started by other means.
|
||||
//!
|
||||
//! \param[in] handler The path to a Crashpad handler executable.
|
||||
//! \param[in] database The path to a Crashpad database. The handler will be
|
||||
//! started with this path as its `--database` argument.
|
||||
@ -69,9 +72,27 @@ class CrashpadClient {
|
||||
const std::map<std::string, std::string>& annotations,
|
||||
const std::vector<std::string>& arguments);
|
||||
|
||||
#if defined(OS_WIN) || DOXYGEN
|
||||
//! \brief Sets the IPC port of a presumably-running Crashpad handler process
|
||||
//! which was started with StartHandler() or by other compatible means
|
||||
//! and does an IPC message exchange to register this process with the
|
||||
//! handler. However, just like StartHandler(), crashes are not serviced
|
||||
//! until UseHandler() is called.
|
||||
//!
|
||||
//! The IPC port name (somehow) encodes enough information so that
|
||||
//! registration is done with a crash handler using the appropriate database
|
||||
//! and upload server.
|
||||
//!
|
||||
//! \param[in] ipc_port The full name of the crash handler IPC port.
|
||||
//!
|
||||
//! \return `true` on success and `false` on failure.
|
||||
bool SetHandler(const std::string& ipc_port);
|
||||
#endif
|
||||
|
||||
//! \brief Configures the process to direct its crashes to a Crashpad handler.
|
||||
//!
|
||||
//! The Crashpad handler must previously have been started by StartHandler().
|
||||
//! The Crashpad handler must previously have been started by StartHandler()
|
||||
//! or configured by SetHandler().
|
||||
//!
|
||||
//! On Mac OS X, this method sets the task’s exception port for `EXC_CRASH`,
|
||||
//! `EXC_RESOURCE`, and `EXC_GUARD` exceptions to the Mach send right obtained
|
||||
@ -85,6 +106,10 @@ class CrashpadClient {
|
||||
//! have inherited it as their exception handler even after the process that
|
||||
//! called StartHandler() exits.
|
||||
//!
|
||||
//! On Windows, this method sets the unhandled exception handler to a local
|
||||
//! function that when reached will "signal and wait" for the crash handler
|
||||
//! process to create the dump.
|
||||
//!
|
||||
//! \return `true` on success, `false` on failure with a message logged.
|
||||
bool UseHandler();
|
||||
|
||||
|
91
client/crashpad_client_win.cc
Normal file
91
client/crashpad_client_win.cc
Normal file
@ -0,0 +1,91 @@
|
||||
// Copyright 2015 The Crashpad Authors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "client/crashpad_client.h"
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include "base/logging.h"
|
||||
|
||||
namespace {
|
||||
// Time to wait for the handler to create a dump. This is tricky to figure out.
|
||||
const DWORD kMillisecondsUntilTerminate = 5000;
|
||||
|
||||
// This is the exit code that the process will return to the system once the
|
||||
// crash has been handled by Crashpad. We don't want to clash with the
|
||||
// application-defined exit codes but we don't know them so we use one that is
|
||||
// unlikely to be used.
|
||||
const UINT kCrashExitCode = 0xffff7001;
|
||||
|
||||
// These two handles to events are leaked.
|
||||
HANDLE g_signal_exception = nullptr;
|
||||
HANDLE g_wait_termination = nullptr;
|
||||
|
||||
LONG WINAPI UnhandledExceptionHandler(EXCEPTION_POINTERS* exception_pointers) {
|
||||
// TODO (cpu): Here write |exception_pointers| to g_crashpad_info.
|
||||
DWORD rv = SignalObjectAndWait(g_signal_exception,
|
||||
g_wait_termination,
|
||||
kMillisecondsUntilTerminate,
|
||||
FALSE);
|
||||
if (rv != WAIT_OBJECT_0) {
|
||||
// Something went wrong. It is likely that a dump has not been created.
|
||||
if (rv == WAIT_TIMEOUT) {
|
||||
LOG(WARNING) << "SignalObjectAndWait timed out";
|
||||
} else {
|
||||
PLOG(WARNING) << "SignalObjectAndWait error";
|
||||
}
|
||||
}
|
||||
// We don't want to generate more exceptions, so we take the fast route.
|
||||
TerminateProcess(GetCurrentProcess(), kCrashExitCode);
|
||||
return 0L;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace crashpad {
|
||||
|
||||
CrashpadClient::CrashpadClient() {
|
||||
}
|
||||
|
||||
CrashpadClient::~CrashpadClient() {
|
||||
}
|
||||
|
||||
bool CrashpadClient::StartHandler(
|
||||
const base::FilePath& handler,
|
||||
const base::FilePath& database,
|
||||
const std::string& url,
|
||||
const std::map<std::string, std::string>& annotations,
|
||||
const std::vector<std::string>& arguments) {
|
||||
// TODO(cpu): Provide a reference implementation.
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SetHandler(const std::string& ipc_port) {
|
||||
// TODO (cpu): Contact the handler and obtain g_signal_exception and
|
||||
// g_wait_termination.
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CrashpadClient::UseHandler() {
|
||||
if (!g_signal_exception)
|
||||
return false;
|
||||
if (!g_wait_termination)
|
||||
return false;
|
||||
// In theory we could store the previous handler but it is not clear what
|
||||
// use we have for it.
|
||||
SetUnhandledExceptionFilter(&UnhandledExceptionHandler);
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace crashpad
|
Loading…
x
Reference in New Issue
Block a user