| Index: client/crashpad_client_win.cc
|
| diff --git a/client/crashpad_client_win.cc b/client/crashpad_client_win.cc
|
| index 92529ae18989c002ccb9f507294003daf6799509..5e7346facffc63ad21524932ae1a940ca38fee03 100644
|
| --- a/client/crashpad_client_win.cc
|
| +++ b/client/crashpad_client_win.cc
|
| @@ -19,10 +19,13 @@
|
|
|
| #include "base/atomicops.h"
|
| #include "base/logging.h"
|
| +#include "base/rand_util.h"
|
| #include "base/strings/string16.h"
|
| +#include "base/strings/stringprintf.h"
|
| #include "base/strings/utf_string_conversions.h"
|
| #include "base/synchronization/lock.h"
|
| #include "util/file/file_io.h"
|
| +#include "util/win/command_line.h"
|
| #include "util/win/critical_section_with_debug_info.h"
|
| #include "util/win/registration_protocol_win.h"
|
| #include "util/win/scoped_handle.h"
|
| @@ -102,11 +105,17 @@ LONG WINAPI UnhandledExceptionHandler(EXCEPTION_POINTERS* exception_pointers) {
|
| return EXCEPTION_CONTINUE_SEARCH;
|
| }
|
|
|
| +std::wstring FormatArgumentString(const std::string& name,
|
| + const std::wstring& value) {
|
| + return std::wstring(L"--") + base::UTF8ToUTF16(name) + L"=" + value;
|
| +}
|
| +
|
| } // namespace
|
|
|
| namespace crashpad {
|
|
|
| -CrashpadClient::CrashpadClient() {
|
| +CrashpadClient::CrashpadClient()
|
| + : ipc_port_() {
|
| }
|
|
|
| CrashpadClient::~CrashpadClient() {
|
| @@ -118,11 +127,81 @@ bool CrashpadClient::StartHandler(
|
| const std::string& url,
|
| const std::map<std::string, std::string>& annotations,
|
| const std::vector<std::string>& arguments) {
|
| - LOG(FATAL) << "SetHandler should be used on Windows";
|
| - return false;
|
| + DCHECK(ipc_port_.empty());
|
| +
|
| + ipc_port_ =
|
| + base::StringPrintf("\\\\.\\pipe\\crashpad_%d_", GetCurrentProcessId());
|
| + for (int index = 0; index < 16; ++index) {
|
| + ipc_port_.append(1, static_cast<char>(base::RandInt('A', 'Z')));
|
| + }
|
| +
|
| + std::wstring command_line;
|
| + AppendCommandLineArgument(handler.value(), &command_line);
|
| + for (const std::string& argument : arguments) {
|
| + AppendCommandLineArgument(base::UTF8ToUTF16(argument), &command_line);
|
| + }
|
| + if (!database.value().empty()) {
|
| + AppendCommandLineArgument(FormatArgumentString("database",
|
| + database.value()),
|
| + &command_line);
|
| + }
|
| + if (!url.empty()) {
|
| + AppendCommandLineArgument(FormatArgumentString("url",
|
| + base::UTF8ToUTF16(url)),
|
| + &command_line);
|
| + }
|
| + for (const auto& kv : annotations) {
|
| + AppendCommandLineArgument(
|
| + FormatArgumentString("annotation",
|
| + base::UTF8ToUTF16(kv.first + '=' + kv.second)),
|
| + &command_line);
|
| + }
|
| + AppendCommandLineArgument(FormatArgumentString("pipe-name",
|
| + base::UTF8ToUTF16(ipc_port_)),
|
| + &command_line);
|
| +
|
| + STARTUPINFO startup_info = {};
|
| + startup_info.cb = sizeof(startup_info);
|
| + startup_info.dwFlags = STARTF_USESTDHANDLES;
|
| + startup_info.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
|
| + startup_info.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
|
| + startup_info.hStdError = GetStdHandle(STD_ERROR_HANDLE);
|
| + PROCESS_INFORMATION process_info;
|
| + BOOL rv = CreateProcess(handler.value().c_str(),
|
| + &command_line[0],
|
| + nullptr,
|
| + nullptr,
|
| + true,
|
| + 0,
|
| + nullptr,
|
| + nullptr,
|
| + &startup_info,
|
| + &process_info);
|
| + if (!rv) {
|
| + PLOG(ERROR) << "CreateProcess";
|
| + return false;
|
| + }
|
| +
|
| + rv = CloseHandle(process_info.hThread);
|
| + PLOG_IF(WARNING, !rv) << "CloseHandle thread";
|
| +
|
| + rv = CloseHandle(process_info.hProcess);
|
| + PLOG_IF(WARNING, !rv) << "CloseHandle process";
|
| +
|
| + return true;
|
| }
|
|
|
| bool CrashpadClient::SetHandler(const std::string& ipc_port) {
|
| + DCHECK(ipc_port_.empty());
|
| + DCHECK(!ipc_port.empty());
|
| +
|
| + ipc_port_ = ipc_port;
|
| +
|
| + return true;
|
| +}
|
| +
|
| +bool CrashpadClient::UseHandler() {
|
| + DCHECK(!ipc_port_.empty());
|
| DCHECK_EQ(g_signal_exception, INVALID_HANDLE_VALUE);
|
| DCHECK_EQ(g_signal_non_crash_dump, INVALID_HANDLE_VALUE);
|
| DCHECK_EQ(g_non_crash_dump_done, INVALID_HANDLE_VALUE);
|
| @@ -154,7 +233,7 @@ bool CrashpadClient::SetHandler(const std::string& ipc_port) {
|
| ServerToClientMessage response = {0};
|
|
|
| if (!SendToCrashHandlerServer(
|
| - base::UTF8ToUTF16(ipc_port), message, &response)) {
|
| + base::UTF8ToUTF16(ipc_port_), message, &response)) {
|
| return false;
|
| }
|
|
|
| @@ -168,16 +247,6 @@ bool CrashpadClient::SetHandler(const std::string& ipc_port) {
|
|
|
| g_non_crash_dump_lock = new base::Lock();
|
|
|
| - return true;
|
| -}
|
| -
|
| -bool CrashpadClient::UseHandler() {
|
| - if (g_signal_exception == INVALID_HANDLE_VALUE ||
|
| - g_signal_non_crash_dump == INVALID_HANDLE_VALUE ||
|
| - g_non_crash_dump_done == INVALID_HANDLE_VALUE) {
|
| - return false;
|
| - }
|
| -
|
| // In theory we could store the previous handler but it is not clear what
|
| // use we have for it.
|
| SetUnhandledExceptionFilter(&UnhandledExceptionHandler);
|
| @@ -188,7 +257,7 @@ bool CrashpadClient::UseHandler() {
|
| void CrashpadClient::DumpWithoutCrash(const CONTEXT& context) {
|
| if (g_signal_non_crash_dump == INVALID_HANDLE_VALUE ||
|
| g_non_crash_dump_done == INVALID_HANDLE_VALUE) {
|
| - LOG(ERROR) << "haven't called SetHandler()";
|
| + LOG(ERROR) << "haven't called UseHandler()";
|
| return;
|
| }
|
|
|
|
|