OLD | NEW |
1 // Copyright 2014 The Crashpad Authors. All rights reserved. | 1 // Copyright 2014 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, |
(...skipping 20 matching lines...) Expand all Loading... |
31 #include "util/stdlib/string_number_conversion.h" | 31 #include "util/stdlib/string_number_conversion.h" |
32 #include "util/string/split_string.h" | 32 #include "util/string/split_string.h" |
33 #include "util/synchronization/semaphore.h" | 33 #include "util/synchronization/semaphore.h" |
34 | 34 |
35 #if defined(OS_MACOSX) | 35 #if defined(OS_MACOSX) |
36 #include <libgen.h> | 36 #include <libgen.h> |
37 #include "base/mac/scoped_mach_port.h" | 37 #include "base/mac/scoped_mach_port.h" |
38 #include "handler/mac/crash_report_exception_handler.h" | 38 #include "handler/mac/crash_report_exception_handler.h" |
39 #include "handler/mac/exception_handler_server.h" | 39 #include "handler/mac/exception_handler_server.h" |
40 #include "util/mach/child_port_handshake.h" | 40 #include "util/mach/child_port_handshake.h" |
| 41 #include "util/mach/mach_extensions.h" |
41 #include "util/posix/close_stdio.h" | 42 #include "util/posix/close_stdio.h" |
42 #elif defined(OS_WIN) | 43 #elif defined(OS_WIN) |
43 #include <windows.h> | 44 #include <windows.h> |
44 #include "handler/win/crash_report_exception_handler.h" | 45 #include "handler/win/crash_report_exception_handler.h" |
45 #include "util/win/exception_handler_server.h" | 46 #include "util/win/exception_handler_server.h" |
46 #endif // OS_MACOSX | 47 #endif // OS_MACOSX |
47 | 48 |
48 namespace crashpad { | 49 namespace crashpad { |
49 namespace { | 50 namespace { |
50 | 51 |
51 void Usage(const base::FilePath& me) { | 52 void Usage(const base::FilePath& me) { |
52 fprintf(stderr, | 53 fprintf(stderr, |
53 "Usage: %" PRFilePath " [OPTION]...\n" | 54 "Usage: %" PRFilePath " [OPTION]...\n" |
54 "Crashpad's exception handler server.\n" | 55 "Crashpad's exception handler server.\n" |
55 "\n" | 56 "\n" |
56 " --annotation=KEY=VALUE set a process annotation in each crash report\n" | 57 " --annotation=KEY=VALUE set a process annotation in each crash report\n" |
57 " --database=PATH store the crash report database at PATH\n" | 58 " --database=PATH store the crash report database at PATH\n" |
58 #if defined(OS_MACOSX) | 59 #if defined(OS_MACOSX) |
59 " --handshake-fd=FD establish communication with the client over FD\n
" | 60 " --handshake-fd=FD establish communication with the client over FD\n
" |
| 61 " --mach-service=SERVICE register SERVICE with the bootstrap server\n" |
60 " --reset-own-crash-exception-port-to-system-default\n" | 62 " --reset-own-crash-exception-port-to-system-default\n" |
61 " reset the server's exception handler to default\n
" | 63 " reset the server's exception handler to default\n
" |
62 #elif defined(OS_WIN) | 64 #elif defined(OS_WIN) |
63 " --persistent continue running after all clients exit\n" | 65 " --persistent continue running after all clients exit\n" |
64 " --pipe-name=PIPE communicate with the client over PIPE\n" | 66 " --pipe-name=PIPE communicate with the client over PIPE\n" |
65 #endif // OS_MACOSX | 67 #endif // OS_MACOSX |
66 " --url=URL send crash reports to this Breakpad server URL,\n
" | 68 " --url=URL send crash reports to this Breakpad server URL,\n
" |
67 " only if uploads are enabled for the database\n" | 69 " only if uploads are enabled for the database\n" |
68 " --help display this help and exit\n" | 70 " --help display this help and exit\n" |
69 " --version output version information and exit\n", | 71 " --version output version information and exit\n", |
70 me.value().c_str()); | 72 me.value().c_str()); |
71 ToolSupport::UsageTail(me); | 73 ToolSupport::UsageTail(me); |
72 } | 74 } |
73 | 75 |
74 int HandlerMain(int argc, char* argv[]) { | 76 int HandlerMain(int argc, char* argv[]) { |
75 const base::FilePath argv0( | 77 const base::FilePath argv0( |
76 ToolSupport::CommandLineArgumentToFilePathStringType(argv[0])); | 78 ToolSupport::CommandLineArgumentToFilePathStringType(argv[0])); |
77 const base::FilePath me(argv0.BaseName()); | 79 const base::FilePath me(argv0.BaseName()); |
78 | 80 |
79 enum OptionFlags { | 81 enum OptionFlags { |
80 // Long options without short equivalents. | 82 // Long options without short equivalents. |
81 kOptionLastChar = 255, | 83 kOptionLastChar = 255, |
82 kOptionAnnotation, | 84 kOptionAnnotation, |
83 kOptionDatabase, | 85 kOptionDatabase, |
84 #if defined(OS_MACOSX) | 86 #if defined(OS_MACOSX) |
85 kOptionHandshakeFD, | 87 kOptionHandshakeFD, |
| 88 kOptionMachService, |
86 kOptionResetOwnCrashExceptionPortToSystemDefault, | 89 kOptionResetOwnCrashExceptionPortToSystemDefault, |
87 #elif defined(OS_WIN) | 90 #elif defined(OS_WIN) |
88 kOptionPersistent, | 91 kOptionPersistent, |
89 kOptionPipeName, | 92 kOptionPipeName, |
90 #endif // OS_MACOSX | 93 #endif // OS_MACOSX |
91 kOptionURL, | 94 kOptionURL, |
92 | 95 |
93 // Standard options. | 96 // Standard options. |
94 kOptionHelp = -2, | 97 kOptionHelp = -2, |
95 kOptionVersion = -3, | 98 kOptionVersion = -3, |
96 }; | 99 }; |
97 | 100 |
98 struct { | 101 struct { |
99 std::map<std::string, std::string> annotations; | 102 std::map<std::string, std::string> annotations; |
100 std::string url; | 103 std::string url; |
101 const char* database; | 104 const char* database; |
102 #if defined(OS_MACOSX) | 105 #if defined(OS_MACOSX) |
103 int handshake_fd; | 106 int handshake_fd; |
| 107 std::string mach_service; |
104 bool reset_own_crash_exception_port_to_system_default; | 108 bool reset_own_crash_exception_port_to_system_default; |
105 #elif defined(OS_WIN) | 109 #elif defined(OS_WIN) |
106 bool persistent; | 110 bool persistent; |
107 std::string pipe_name; | 111 std::string pipe_name; |
108 #endif // OS_MACOSX | 112 #endif // OS_MACOSX |
109 } options = {}; | 113 } options = {}; |
110 #if defined(OS_MACOSX) | 114 #if defined(OS_MACOSX) |
111 options.handshake_fd = -1; | 115 options.handshake_fd = -1; |
112 options.reset_own_crash_exception_port_to_system_default = false; | 116 options.reset_own_crash_exception_port_to_system_default = false; |
113 #endif | 117 #endif |
114 | 118 |
115 const option long_options[] = { | 119 const option long_options[] = { |
116 {"annotation", required_argument, nullptr, kOptionAnnotation}, | 120 {"annotation", required_argument, nullptr, kOptionAnnotation}, |
117 {"database", required_argument, nullptr, kOptionDatabase}, | 121 {"database", required_argument, nullptr, kOptionDatabase}, |
118 #if defined(OS_MACOSX) | 122 #if defined(OS_MACOSX) |
119 {"handshake-fd", required_argument, nullptr, kOptionHandshakeFD}, | 123 {"handshake-fd", required_argument, nullptr, kOptionHandshakeFD}, |
| 124 {"mach-service", required_argument, nullptr, kOptionMachService}, |
120 {"reset-own-crash-exception-port-to-system-default", | 125 {"reset-own-crash-exception-port-to-system-default", |
121 no_argument, | 126 no_argument, |
122 nullptr, | 127 nullptr, |
123 kOptionResetOwnCrashExceptionPortToSystemDefault}, | 128 kOptionResetOwnCrashExceptionPortToSystemDefault}, |
124 #elif defined(OS_WIN) | 129 #elif defined(OS_WIN) |
125 {"persistent", no_argument, nullptr, kOptionPersistent}, | 130 {"persistent", no_argument, nullptr, kOptionPersistent}, |
126 {"pipe-name", required_argument, nullptr, kOptionPipeName}, | 131 {"pipe-name", required_argument, nullptr, kOptionPipeName}, |
127 #endif // OS_MACOSX | 132 #endif // OS_MACOSX |
128 {"url", required_argument, nullptr, kOptionURL}, | 133 {"url", required_argument, nullptr, kOptionURL}, |
129 {"help", no_argument, nullptr, kOptionHelp}, | 134 {"help", no_argument, nullptr, kOptionHelp}, |
(...skipping 25 matching lines...) Expand all Loading... |
155 #if defined(OS_MACOSX) | 160 #if defined(OS_MACOSX) |
156 case kOptionHandshakeFD: { | 161 case kOptionHandshakeFD: { |
157 if (!StringToNumber(optarg, &options.handshake_fd) || | 162 if (!StringToNumber(optarg, &options.handshake_fd) || |
158 options.handshake_fd < 0) { | 163 options.handshake_fd < 0) { |
159 ToolSupport::UsageHint(me, | 164 ToolSupport::UsageHint(me, |
160 "--handshake-fd requires a file descriptor"); | 165 "--handshake-fd requires a file descriptor"); |
161 return EXIT_FAILURE; | 166 return EXIT_FAILURE; |
162 } | 167 } |
163 break; | 168 break; |
164 } | 169 } |
| 170 case kOptionMachService: { |
| 171 options.mach_service = optarg; |
| 172 break; |
| 173 } |
165 case kOptionResetOwnCrashExceptionPortToSystemDefault: { | 174 case kOptionResetOwnCrashExceptionPortToSystemDefault: { |
166 options.reset_own_crash_exception_port_to_system_default = true; | 175 options.reset_own_crash_exception_port_to_system_default = true; |
167 break; | 176 break; |
168 } | 177 } |
169 #elif defined(OS_WIN) | 178 #elif defined(OS_WIN) |
170 case kOptionPersistent: { | 179 case kOptionPersistent: { |
171 options.persistent = true; | 180 options.persistent = true; |
172 break; | 181 break; |
173 } | 182 } |
174 case kOptionPipeName: { | 183 case kOptionPipeName: { |
(...skipping 16 matching lines...) Expand all Loading... |
191 default: { | 200 default: { |
192 ToolSupport::UsageHint(me, nullptr); | 201 ToolSupport::UsageHint(me, nullptr); |
193 return EXIT_FAILURE; | 202 return EXIT_FAILURE; |
194 } | 203 } |
195 } | 204 } |
196 } | 205 } |
197 argc -= optind; | 206 argc -= optind; |
198 argv += optind; | 207 argv += optind; |
199 | 208 |
200 #if defined(OS_MACOSX) | 209 #if defined(OS_MACOSX) |
201 if (options.handshake_fd < 0) { | 210 if (options.handshake_fd < 0 && options.mach_service.empty()) { |
202 ToolSupport::UsageHint(me, "--handshake-fd is required"); | 211 ToolSupport::UsageHint(me, "--handshake-fd or --mach-service is required"); |
| 212 return EXIT_FAILURE; |
| 213 } |
| 214 if (options.handshake_fd >= 0 && !options.mach_service.empty()) { |
| 215 ToolSupport::UsageHint( |
| 216 me, "--handshake-fd and --mach-service are incompatible"); |
203 return EXIT_FAILURE; | 217 return EXIT_FAILURE; |
204 } | 218 } |
205 #elif defined(OS_WIN) | 219 #elif defined(OS_WIN) |
206 if (options.pipe_name.empty()) { | 220 if (options.pipe_name.empty()) { |
207 ToolSupport::UsageHint(me, "--pipe-name is required"); | 221 ToolSupport::UsageHint(me, "--pipe-name is required"); |
208 return EXIT_FAILURE; | 222 return EXIT_FAILURE; |
209 } | 223 } |
210 #endif | 224 #endif |
211 | 225 |
212 if (!options.database) { | 226 if (!options.database) { |
213 ToolSupport::UsageHint(me, "--database is required"); | 227 ToolSupport::UsageHint(me, "--database is required"); |
214 return EXIT_FAILURE; | 228 return EXIT_FAILURE; |
215 } | 229 } |
216 | 230 |
217 if (argc) { | 231 if (argc) { |
218 ToolSupport::UsageHint(me, nullptr); | 232 ToolSupport::UsageHint(me, nullptr); |
219 return EXIT_FAILURE; | 233 return EXIT_FAILURE; |
220 } | 234 } |
221 | 235 |
222 #if defined(OS_MACOSX) | 236 #if defined(OS_MACOSX) |
223 CloseStdinAndStdout(); | 237 if (options.mach_service.empty()) { |
| 238 // Don’t do this when being run by launchd. See launchd.plist(5). |
| 239 CloseStdinAndStdout(); |
| 240 } |
224 | 241 |
225 if (options.reset_own_crash_exception_port_to_system_default) { | 242 if (options.reset_own_crash_exception_port_to_system_default) { |
226 CrashpadClient::UseSystemDefaultHandler(); | 243 CrashpadClient::UseSystemDefaultHandler(); |
227 } | 244 } |
228 | 245 |
229 base::mac::ScopedMachReceiveRight receive_right( | 246 base::mac::ScopedMachReceiveRight receive_right; |
230 ChildPortHandshake::RunServerForFD( | 247 |
231 base::ScopedFD(options.handshake_fd), | 248 if (options.handshake_fd >= 0) { |
232 ChildPortHandshake::PortRightType::kReceiveRight)); | 249 receive_right.reset( |
| 250 ChildPortHandshake::RunServerForFD( |
| 251 base::ScopedFD(options.handshake_fd), |
| 252 ChildPortHandshake::PortRightType::kReceiveRight)); |
| 253 } else if (!options.mach_service.empty()) { |
| 254 receive_right = BootstrapCheckIn(options.mach_service); |
| 255 } |
| 256 |
233 if (!receive_right.is_valid()) { | 257 if (!receive_right.is_valid()) { |
234 return EXIT_FAILURE; | 258 return EXIT_FAILURE; |
235 } | 259 } |
236 | 260 |
237 ExceptionHandlerServer exception_handler_server(receive_right.Pass()); | 261 ExceptionHandlerServer exception_handler_server( |
| 262 receive_right.Pass(), !options.mach_service.empty()); |
238 #elif defined(OS_WIN) | 263 #elif defined(OS_WIN) |
239 ExceptionHandlerServer exception_handler_server(options.pipe_name, | 264 ExceptionHandlerServer exception_handler_server(options.pipe_name, |
240 options.persistent); | 265 options.persistent); |
241 #endif // OS_MACOSX | 266 #endif // OS_MACOSX |
242 | 267 |
243 scoped_ptr<CrashReportDatabase> database(CrashReportDatabase::Initialize( | 268 scoped_ptr<CrashReportDatabase> database(CrashReportDatabase::Initialize( |
244 base::FilePath(ToolSupport::CommandLineArgumentToFilePathStringType( | 269 base::FilePath(ToolSupport::CommandLineArgumentToFilePathStringType( |
245 options.database)))); | 270 options.database)))); |
246 if (!database) { | 271 if (!database) { |
247 return EXIT_FAILURE; | 272 return EXIT_FAILURE; |
(...skipping 17 matching lines...) Expand all Loading... |
265 | 290 |
266 #if defined(OS_MACOSX) | 291 #if defined(OS_MACOSX) |
267 int main(int argc, char* argv[]) { | 292 int main(int argc, char* argv[]) { |
268 return crashpad::HandlerMain(argc, argv); | 293 return crashpad::HandlerMain(argc, argv); |
269 } | 294 } |
270 #elif defined(OS_WIN) | 295 #elif defined(OS_WIN) |
271 int wmain(int argc, wchar_t* argv[]) { | 296 int wmain(int argc, wchar_t* argv[]) { |
272 return crashpad::ToolSupport::Wmain(argc, argv, crashpad::HandlerMain); | 297 return crashpad::ToolSupport::Wmain(argc, argv, crashpad::HandlerMain); |
273 } | 298 } |
274 #endif // OS_MACOSX | 299 #endif // OS_MACOSX |
OLD | NEW |