Chromium Code Reviews| Index: client/crashpad_client_win.cc |
| diff --git a/client/crashpad_client_win.cc b/client/crashpad_client_win.cc |
| index 92529ae18989c002ccb9f507294003daf6799509..1dbda0012064342687ffac13226ebfc875d2e9b6 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); |
|
scottmg
2015/10/30 23:16:31
This was one reason I hadn't done this yet. In ord
Mark Mentovai
2015/10/31 01:22:24
scottmg wrote:
Mark Mentovai
2015/10/31 18:34:29
I wrote:
scottmg
2015/10/31 18:34:59
Not strictly related, but this is where I stopped
|
| + 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(), |
| + const_cast<wchar_t*>(command_line.c_str()), |
|
scottmg
2015/10/30 23:16:31
Does this actually make it mutable? (In practice I
Mark Mentovai
2015/10/31 01:22:24
scottmg wrote:
|
| + 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; |
| } |