Chromium Code Reviews| Index: client/crashpad_client_win.cc |
| diff --git a/client/crashpad_client_win.cc b/client/crashpad_client_win.cc |
| index 734bedfd84301af5cf81162fe1723d21ba43240e..c6be0131273965a1dd96262468b569ed89abe9bf 100644 |
| --- a/client/crashpad_client_win.cc |
| +++ b/client/crashpad_client_win.cc |
| @@ -17,13 +17,19 @@ |
| #include <windows.h> |
| #include "base/logging.h" |
| +#include "base/strings/string16.h" |
| +#include "base/strings/utf_string_conversions.h" |
| +#include "client/crashpad_info.h" |
| +#include "client/registration_protocol_win.h" |
| +#include "util/file/file_io.h" |
| +#include "util/win/scoped_handle.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 |
| +// 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; |
| @@ -33,7 +39,8 @@ 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. |
| + crashpad::CrashpadInfo::GetCrashpadInfo()->set_exception_pointers( |
|
Mark Mentovai
2015/08/13 13:38:53
Is there a guarantee that this will only be called
scottmg
2015/08/13 22:41:45
Good call. I went back and forth on this for a whi
|
| + reinterpret_cast<crashpad::WinVMAddress>(exception_pointers)); |
| DWORD rv = SignalObjectAndWait(g_signal_exception, |
| g_wait_termination, |
| kMillisecondsUntilTerminate, |
| @@ -51,6 +58,37 @@ LONG WINAPI UnhandledExceptionHandler(EXCEPTION_POINTERS* exception_pointers) { |
| return 0L; |
| } |
| +// Returns a pipe handle connected to the RegistrationServer. |
| +crashpad::ScopedFileHANDLE Connect(const base::string16& pipe_name) { |
| + crashpad::ScopedFileHANDLE pipe; |
| + const int kMaxRetries = 5; |
|
Mark Mentovai
2015/08/13 13:38:53
Since the first try doesn’t count as a REtry, name
scottmg
2015/08/13 22:41:45
Done. ("try" not so good in C++ :)
|
| + for (int retries = 0; !pipe.is_valid() && retries < kMaxRetries; ++retries) { |
| + if (!WaitNamedPipe(pipe_name.c_str(), NMPWAIT_WAIT_FOREVER)) |
| + break; |
| + pipe.reset(CreateFile(pipe_name.c_str(), |
| + GENERIC_READ | GENERIC_WRITE, |
| + 0, |
| + NULL, |
|
Mark Mentovai
2015/08/13 13:38:53
nullptr, line 74 too.
scottmg
2015/08/13 22:41:45
Done.
|
| + OPEN_EXISTING, |
| + SECURITY_SQOS_PRESENT | SECURITY_ANONYMOUS, |
| + NULL)); |
| + if (pipe.is_valid()) { |
| + DWORD mode = PIPE_READMODE_MESSAGE; |
| + if (!SetNamedPipeHandleState(pipe.get(), |
| + &mode, |
| + nullptr, // Don't set maximum bytes. |
| + nullptr)) { // Don't set maximum time. |
| + pipe.reset(); |
| + } |
| + } |
| + } |
| + if (!pipe.is_valid()) { |
| + LOG(ERROR) << "Connect"; |
|
Mark Mentovai
2015/08/13 13:38:53
There are three things that can fail above. Is it
scottmg
2015/08/13 22:41:45
Done.
|
| + return crashpad::ScopedFileHANDLE(); |
| + } |
| + return pipe.Pass(); |
| +} |
| + |
| } // namespace |
| namespace crashpad { |
| @@ -67,14 +105,30 @@ bool CrashpadClient::StartHandler( |
| 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 CrashpadClient::SetHandler(const std::string& ipc_port) { |
| - // TODO (cpu): Contact the handler and obtain g_signal_exception and |
| - // g_wait_termination. |
| - return false; |
| + RegistrationRequest request = {0}; |
| + request.client_process_id = GetCurrentProcessId(); |
| + request.crashpad_info_address = |
| + reinterpret_cast<WinVMAddress>(CrashpadInfo::GetCrashpadInfo()); |
| + |
| + RegistrationResponse response = {0}; |
| + |
| + ScopedFileHANDLE pipe = Connect(base::UTF8ToUTF16(ipc_port)); |
| + if (!pipe.is_valid()) |
| + return false; |
| + bool result = LoggingWriteFile(pipe.get(), &request, sizeof(request)) && |
| + LoggingReadFile(pipe.get(), &response, sizeof(response)); |
| + if (!result) |
| + return result; |
| + |
| + // The server returns these already duplicated to be valid in this process. |
| + g_signal_exception = reinterpret_cast<HANDLE>(response.request_report_event); |
| + g_wait_termination = |
| + reinterpret_cast<HANDLE>(response.report_complete_event); |
| + return true; |
| } |
| bool CrashpadClient::UseHandler() { |