Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(117)

Side by Side Diff: client/crashpad_client_win.cc

Issue 1287073002: Implement more of CrashpadClient on Windows (Closed) Base URL: https://chromium.googlesource.com/crashpad/crashpad@master
Patch Set: ident- Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Crashpad Authors. All rights reserved. 1 // Copyright 2015 The Crashpad Authors. All rights reserved.
2 // 2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); 3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License. 4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at 5 // You may obtain a copy of the License at
6 // 6 //
7 // http://www.apache.org/licenses/LICENSE-2.0 7 // http://www.apache.org/licenses/LICENSE-2.0
8 // 8 //
9 // Unless required by applicable law or agreed to in writing, software 9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, 10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and 12 // See the License for the specific language governing permissions and
13 // limitations under the License. 13 // limitations under the License.
14 14
15 #include "client/crashpad_client.h" 15 #include "client/crashpad_client.h"
16 16
17 #include <windows.h> 17 #include <windows.h>
18 18
19 #include "base/logging.h" 19 #include "base/logging.h"
20 #include "base/strings/string16.h"
21 #include "base/strings/utf_string_conversions.h"
22 #include "client/crashpad_info.h"
23 #include "client/registration_protocol_win.h"
24 #include "util/file/file_io.h"
25 #include "util/win/scoped_handle.h"
20 26
21 namespace { 27 namespace {
22 // Time to wait for the handler to create a dump. This is tricky to figure out. 28 // Time to wait for the handler to create a dump. This is tricky to figure out.
23 const DWORD kMillisecondsUntilTerminate = 5000; 29 const DWORD kMillisecondsUntilTerminate = 5000;
24 30
25 // This is the exit code that the process will return to the system once the 31 // This is the exit code that the process will return to the system once the
26 // crash has been handled by Crashpad. We don't want to clash with the 32 // crash has been handled by Crashpad. We don't want to clash with the
27 // application-defined exit codes but we don't know them so we use one that is 33 // application-defined exit codes but we don't know them so we use one that is
28 // unlikely to be used. 34 // unlikely to be used.
29 const UINT kCrashExitCode = 0xffff7001; 35 const UINT kCrashExitCode = 0xffff7001;
30 36
31 // These two handles to events are leaked. 37 // These two handles to events are leaked.
32 HANDLE g_signal_exception = nullptr; 38 HANDLE g_signal_exception = nullptr;
33 HANDLE g_wait_termination = nullptr; 39 HANDLE g_wait_termination = nullptr;
34 40
35 LONG WINAPI UnhandledExceptionHandler(EXCEPTION_POINTERS* exception_pointers) { 41 LONG WINAPI UnhandledExceptionHandler(EXCEPTION_POINTERS* exception_pointers) {
36 // TODO (cpu): Here write |exception_pointers| to g_crashpad_info. 42 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
43 reinterpret_cast<crashpad::WinVMAddress>(exception_pointers));
37 DWORD rv = SignalObjectAndWait(g_signal_exception, 44 DWORD rv = SignalObjectAndWait(g_signal_exception,
38 g_wait_termination, 45 g_wait_termination,
39 kMillisecondsUntilTerminate, 46 kMillisecondsUntilTerminate,
40 FALSE); 47 FALSE);
41 if (rv != WAIT_OBJECT_0) { 48 if (rv != WAIT_OBJECT_0) {
42 // Something went wrong. It is likely that a dump has not been created. 49 // Something went wrong. It is likely that a dump has not been created.
43 if (rv == WAIT_TIMEOUT) { 50 if (rv == WAIT_TIMEOUT) {
44 LOG(WARNING) << "SignalObjectAndWait timed out"; 51 LOG(WARNING) << "SignalObjectAndWait timed out";
45 } else { 52 } else {
46 PLOG(WARNING) << "SignalObjectAndWait error"; 53 PLOG(WARNING) << "SignalObjectAndWait error";
47 } 54 }
48 } 55 }
49 // We don't want to generate more exceptions, so we take the fast route. 56 // We don't want to generate more exceptions, so we take the fast route.
50 TerminateProcess(GetCurrentProcess(), kCrashExitCode); 57 TerminateProcess(GetCurrentProcess(), kCrashExitCode);
51 return 0L; 58 return 0L;
52 } 59 }
53 60
61 // Returns a pipe handle connected to the RegistrationServer.
62 crashpad::ScopedFileHANDLE Connect(const base::string16& pipe_name) {
63 crashpad::ScopedFileHANDLE pipe;
64 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++ :)
65 for (int retries = 0; !pipe.is_valid() && retries < kMaxRetries; ++retries) {
66 if (!WaitNamedPipe(pipe_name.c_str(), NMPWAIT_WAIT_FOREVER))
67 break;
68 pipe.reset(CreateFile(pipe_name.c_str(),
69 GENERIC_READ | GENERIC_WRITE,
70 0,
71 NULL,
Mark Mentovai 2015/08/13 13:38:53 nullptr, line 74 too.
scottmg 2015/08/13 22:41:45 Done.
72 OPEN_EXISTING,
73 SECURITY_SQOS_PRESENT | SECURITY_ANONYMOUS,
74 NULL));
75 if (pipe.is_valid()) {
76 DWORD mode = PIPE_READMODE_MESSAGE;
77 if (!SetNamedPipeHandleState(pipe.get(),
78 &mode,
79 nullptr, // Don't set maximum bytes.
80 nullptr)) { // Don't set maximum time.
81 pipe.reset();
82 }
83 }
84 }
85 if (!pipe.is_valid()) {
86 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.
87 return crashpad::ScopedFileHANDLE();
88 }
89 return pipe.Pass();
90 }
91
54 } // namespace 92 } // namespace
55 93
56 namespace crashpad { 94 namespace crashpad {
57 95
58 CrashpadClient::CrashpadClient() { 96 CrashpadClient::CrashpadClient() {
59 } 97 }
60 98
61 CrashpadClient::~CrashpadClient() { 99 CrashpadClient::~CrashpadClient() {
62 } 100 }
63 101
64 bool CrashpadClient::StartHandler( 102 bool CrashpadClient::StartHandler(
65 const base::FilePath& handler, 103 const base::FilePath& handler,
66 const base::FilePath& database, 104 const base::FilePath& database,
67 const std::string& url, 105 const std::string& url,
68 const std::map<std::string, std::string>& annotations, 106 const std::map<std::string, std::string>& annotations,
69 const std::vector<std::string>& arguments) { 107 const std::vector<std::string>& arguments) {
70 // TODO(cpu): Provide a reference implementation.
71 return false; 108 return false;
72 } 109 }
73 110
74 bool CrashpadClient::SetHandler(const std::string& ipc_port) { 111 bool CrashpadClient::SetHandler(const std::string& ipc_port) {
75 // TODO (cpu): Contact the handler and obtain g_signal_exception and 112 RegistrationRequest request = {0};
76 // g_wait_termination. 113 request.client_process_id = GetCurrentProcessId();
77 return false; 114 request.crashpad_info_address =
115 reinterpret_cast<WinVMAddress>(CrashpadInfo::GetCrashpadInfo());
116
117 RegistrationResponse response = {0};
118
119 ScopedFileHANDLE pipe = Connect(base::UTF8ToUTF16(ipc_port));
120 if (!pipe.is_valid())
121 return false;
122 bool result = LoggingWriteFile(pipe.get(), &request, sizeof(request)) &&
123 LoggingReadFile(pipe.get(), &response, sizeof(response));
124 if (!result)
125 return result;
126
127 // The server returns these already duplicated to be valid in this process.
128 g_signal_exception = reinterpret_cast<HANDLE>(response.request_report_event);
129 g_wait_termination =
130 reinterpret_cast<HANDLE>(response.report_complete_event);
131 return true;
78 } 132 }
79 133
80 bool CrashpadClient::UseHandler() { 134 bool CrashpadClient::UseHandler() {
81 if (!g_signal_exception) 135 if (!g_signal_exception)
82 return false; 136 return false;
83 if (!g_wait_termination) 137 if (!g_wait_termination)
84 return false; 138 return false;
85 // In theory we could store the previous handler but it is not clear what 139 // In theory we could store the previous handler but it is not clear what
86 // use we have for it. 140 // use we have for it.
87 SetUnhandledExceptionFilter(&UnhandledExceptionHandler); 141 SetUnhandledExceptionFilter(&UnhandledExceptionHandler);
88 return true; 142 return true;
89 } 143 }
90 144
91 } // namespace crashpad 145 } // namespace crashpad
OLDNEW
« no previous file with comments | « client/crashpad_client_mac.cc ('k') | client/crashpad_info.h » ('j') | client/crashpad_info.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698