OLD | NEW |
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, |
(...skipping 14 matching lines...) Expand all Loading... |
25 #include <vector> | 25 #include <vector> |
26 | 26 |
27 #include "base/basictypes.h" | 27 #include "base/basictypes.h" |
28 #include "base/logging.h" | 28 #include "base/logging.h" |
29 #include "base/files/file_path.h" | 29 #include "base/files/file_path.h" |
30 #include "base/memory/scoped_ptr.h" | 30 #include "base/memory/scoped_ptr.h" |
31 #include "base/numerics/safe_conversions.h" | 31 #include "base/numerics/safe_conversions.h" |
32 #include "client/crash_report_database.h" | 32 #include "client/crash_report_database.h" |
33 #include "client/settings.h" | 33 #include "client/settings.h" |
34 #include "tools/tool_support.h" | 34 #include "tools/tool_support.h" |
| 35 #include "util/file/file_io.h" |
| 36 #include "util/file/file_reader.h" |
35 #include "util/misc/uuid.h" | 37 #include "util/misc/uuid.h" |
36 | 38 |
37 namespace crashpad { | 39 namespace crashpad { |
38 namespace { | 40 namespace { |
39 | 41 |
40 void Usage(const std::string& me) { | 42 void Usage(const std::string& me) { |
41 fprintf(stderr, | 43 fprintf(stderr, |
42 "Usage: %s [OPTION]... PID\n" | 44 "Usage: %s [OPTION]... PID\n" |
43 "Operate on Crashpad crash report databases.\n" | 45 "Operate on Crashpad crash report databases.\n" |
44 "\n" | 46 "\n" |
45 " -d, --database=PATH operate on the crash report database at PATH\
n" | 47 " -d, --database=PATH operate on the crash report database at PATH\
n" |
46 " --show-client-id show the client ID\n" | 48 " --show-client-id show the client ID\n" |
47 " --show-uploads-enabled show whether uploads are enabled\n" | 49 " --show-uploads-enabled show whether uploads are enabled\n" |
48 " --show-last-upload-attempt-time\n" | 50 " --show-last-upload-attempt-time\n" |
49 " show the last-upload-attempt time\n" | 51 " show the last-upload-attempt time\n" |
50 " --show-pending-reports show reports eligible for upload\n" | 52 " --show-pending-reports show reports eligible for upload\n" |
51 " --show-completed-reports show reports not eligible for upload\n" | 53 " --show-completed-reports show reports not eligible for upload\n" |
52 " --show-all-report-info with --show-*-reports, show more information\
n" | 54 " --show-all-report-info with --show-*-reports, show more information\
n" |
53 " --show-report=UUID show report stored under UUID\n" | 55 " --show-report=UUID show report stored under UUID\n" |
54 " --set-uploads-enabled=BOOL enable or disable uploads\n" | 56 " --set-uploads-enabled=BOOL enable or disable uploads\n" |
55 " --set-last-upload-attempt-time=TIME\n" | 57 " --set-last-upload-attempt-time=TIME\n" |
56 " set the last-upload-attempt time to TIME\n" | 58 " set the last-upload-attempt time to TIME\n" |
| 59 " --new-report=PATH submit a new report at PATH\n" |
57 " --utc show and set UTC times instead of local\n" | 60 " --utc show and set UTC times instead of local\n" |
58 " --help display this help and exit\n" | 61 " --help display this help and exit\n" |
59 " --version output version information and exit\n", | 62 " --version output version information and exit\n", |
60 me.c_str()); | 63 me.c_str()); |
61 ToolSupport::UsageTail(me); | 64 ToolSupport::UsageTail(me); |
62 } | 65 } |
63 | 66 |
64 struct Options { | 67 struct Options { |
65 std::vector<UUID> show_reports; | 68 std::vector<UUID> show_reports; |
| 69 std::vector<base::FilePath> new_report_paths; |
66 const char* database; | 70 const char* database; |
67 const char* set_last_upload_attempt_time_string; | 71 const char* set_last_upload_attempt_time_string; |
68 time_t set_last_upload_attempt_time; | 72 time_t set_last_upload_attempt_time; |
69 bool show_client_id; | 73 bool show_client_id; |
70 bool show_uploads_enabled; | 74 bool show_uploads_enabled; |
71 bool show_last_upload_attempt_time; | 75 bool show_last_upload_attempt_time; |
72 bool show_pending_reports; | 76 bool show_pending_reports; |
73 bool show_completed_reports; | 77 bool show_completed_reports; |
74 bool show_all_report_info; | 78 bool show_all_report_info; |
75 bool set_uploads_enabled; | 79 bool set_uploads_enabled; |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
245 kOptionLastChar = 255, | 249 kOptionLastChar = 255, |
246 kOptionShowClientID, | 250 kOptionShowClientID, |
247 kOptionShowUploadsEnabled, | 251 kOptionShowUploadsEnabled, |
248 kOptionShowLastUploadAttemptTime, | 252 kOptionShowLastUploadAttemptTime, |
249 kOptionShowPendingReports, | 253 kOptionShowPendingReports, |
250 kOptionShowCompletedReports, | 254 kOptionShowCompletedReports, |
251 kOptionShowAllReportInfo, | 255 kOptionShowAllReportInfo, |
252 kOptionShowReport, | 256 kOptionShowReport, |
253 kOptionSetUploadsEnabled, | 257 kOptionSetUploadsEnabled, |
254 kOptionSetLastUploadAttemptTime, | 258 kOptionSetLastUploadAttemptTime, |
| 259 kOptionNewReport, |
255 kOptionUTC, | 260 kOptionUTC, |
256 | 261 |
257 // Standard options. | 262 // Standard options. |
258 kOptionHelp = -2, | 263 kOptionHelp = -2, |
259 kOptionVersion = -3, | 264 kOptionVersion = -3, |
260 }; | 265 }; |
261 | 266 |
262 const option long_options[] = { | 267 const option long_options[] = { |
263 {"database", required_argument, nullptr, kOptionDatabase}, | 268 {"database", required_argument, nullptr, kOptionDatabase}, |
264 {"show-client-id", no_argument, nullptr, kOptionShowClientID}, | 269 {"show-client-id", no_argument, nullptr, kOptionShowClientID}, |
(...skipping 10 matching lines...) Expand all Loading... |
275 {"show-all-report-info", no_argument, nullptr, kOptionShowAllReportInfo}, | 280 {"show-all-report-info", no_argument, nullptr, kOptionShowAllReportInfo}, |
276 {"show-report", required_argument, nullptr, kOptionShowReport}, | 281 {"show-report", required_argument, nullptr, kOptionShowReport}, |
277 {"set-uploads-enabled", | 282 {"set-uploads-enabled", |
278 required_argument, | 283 required_argument, |
279 nullptr, | 284 nullptr, |
280 kOptionSetUploadsEnabled}, | 285 kOptionSetUploadsEnabled}, |
281 {"set-last-upload-attempt-time", | 286 {"set-last-upload-attempt-time", |
282 required_argument, | 287 required_argument, |
283 nullptr, | 288 nullptr, |
284 kOptionSetLastUploadAttemptTime}, | 289 kOptionSetLastUploadAttemptTime}, |
| 290 {"new-report", required_argument, nullptr, kOptionNewReport}, |
285 {"utc", no_argument, nullptr, kOptionUTC}, | 291 {"utc", no_argument, nullptr, kOptionUTC}, |
286 {"help", no_argument, nullptr, kOptionHelp}, | 292 {"help", no_argument, nullptr, kOptionHelp}, |
287 {"version", no_argument, nullptr, kOptionVersion}, | 293 {"version", no_argument, nullptr, kOptionVersion}, |
288 {nullptr, 0, nullptr, 0}, | 294 {nullptr, 0, nullptr, 0}, |
289 }; | 295 }; |
290 | 296 |
291 Options options = {}; | 297 Options options = {}; |
292 | 298 |
293 int opt; | 299 int opt; |
294 while ((opt = getopt_long(argc, argv, "d:", long_options, nullptr)) != -1) { | 300 while ((opt = getopt_long(argc, argv, "d:", long_options, nullptr)) != -1) { |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
335 ToolSupport::UsageHint(me, "--set-uploads-enabled requires a BOOL"); | 341 ToolSupport::UsageHint(me, "--set-uploads-enabled requires a BOOL"); |
336 return EXIT_FAILURE; | 342 return EXIT_FAILURE; |
337 } | 343 } |
338 options.has_set_uploads_enabled = true; | 344 options.has_set_uploads_enabled = true; |
339 break; | 345 break; |
340 } | 346 } |
341 case kOptionSetLastUploadAttemptTime: { | 347 case kOptionSetLastUploadAttemptTime: { |
342 options.set_last_upload_attempt_time_string = optarg; | 348 options.set_last_upload_attempt_time_string = optarg; |
343 break; | 349 break; |
344 } | 350 } |
| 351 case kOptionNewReport: { |
| 352 options.new_report_paths.push_back(base::FilePath(optarg)); |
| 353 break; |
| 354 } |
345 case kOptionUTC: { | 355 case kOptionUTC: { |
346 options.utc = true; | 356 options.utc = true; |
347 break; | 357 break; |
348 } | 358 } |
349 case kOptionHelp: { | 359 case kOptionHelp: { |
350 Usage(me); | 360 Usage(me); |
351 return EXIT_SUCCESS; | 361 return EXIT_SUCCESS; |
352 } | 362 } |
353 case kOptionVersion: { | 363 case kOptionVersion: { |
354 ToolSupport::Version(me); | 364 ToolSupport::Version(me); |
(...skipping 19 matching lines...) Expand all Loading... |
374 if (options.set_last_upload_attempt_time_string) { | 384 if (options.set_last_upload_attempt_time_string) { |
375 if (!StringToTime(options.set_last_upload_attempt_time_string, | 385 if (!StringToTime(options.set_last_upload_attempt_time_string, |
376 &options.set_last_upload_attempt_time, | 386 &options.set_last_upload_attempt_time, |
377 options.utc)) { | 387 options.utc)) { |
378 ToolSupport::UsageHint(me, | 388 ToolSupport::UsageHint(me, |
379 "--set-last-upload-attempt-time requires a TIME"); | 389 "--set-last-upload-attempt-time requires a TIME"); |
380 return EXIT_FAILURE; | 390 return EXIT_FAILURE; |
381 } | 391 } |
382 } | 392 } |
383 | 393 |
| 394 // --new-report is treated as a show operation because it produces output. |
384 const size_t show_operations = options.show_client_id + | 395 const size_t show_operations = options.show_client_id + |
385 options.show_uploads_enabled + | 396 options.show_uploads_enabled + |
386 options.show_last_upload_attempt_time + | 397 options.show_last_upload_attempt_time + |
387 options.show_pending_reports + | 398 options.show_pending_reports + |
388 options.show_completed_reports + | 399 options.show_completed_reports + |
389 options.show_reports.size(); | 400 options.show_reports.size() + |
| 401 options.new_report_paths.size(); |
390 const size_t set_operations = | 402 const size_t set_operations = |
391 options.has_set_uploads_enabled + | 403 options.has_set_uploads_enabled + |
392 (options.set_last_upload_attempt_time_string != nullptr); | 404 (options.set_last_upload_attempt_time_string != nullptr); |
393 | 405 |
394 if (show_operations + set_operations == 0) { | 406 if (show_operations + set_operations == 0) { |
395 ToolSupport::UsageHint(me, "nothing to do"); | 407 ToolSupport::UsageHint(me, "nothing to do"); |
396 return EXIT_FAILURE; | 408 return EXIT_FAILURE; |
397 } | 409 } |
398 | 410 |
399 scoped_ptr<CrashReportDatabase> database( | 411 scoped_ptr<CrashReportDatabase> database( |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
498 !settings->SetUploadsEnabled(options.set_uploads_enabled)) { | 510 !settings->SetUploadsEnabled(options.set_uploads_enabled)) { |
499 return EXIT_FAILURE; | 511 return EXIT_FAILURE; |
500 } | 512 } |
501 | 513 |
502 if (options.set_last_upload_attempt_time_string && | 514 if (options.set_last_upload_attempt_time_string && |
503 !settings->SetLastUploadAttemptTime( | 515 !settings->SetLastUploadAttemptTime( |
504 options.set_last_upload_attempt_time)) { | 516 options.set_last_upload_attempt_time)) { |
505 return EXIT_FAILURE; | 517 return EXIT_FAILURE; |
506 } | 518 } |
507 | 519 |
| 520 for (const base::FilePath new_report_path : options.new_report_paths) { |
| 521 FileReader file_reader; |
| 522 if (!file_reader.Open(new_report_path)) { |
| 523 return EXIT_FAILURE; |
| 524 } |
| 525 |
| 526 CrashReportDatabase::NewReport* new_report; |
| 527 CrashReportDatabase::OperationStatus status = |
| 528 database->PrepareNewCrashReport(&new_report); |
| 529 if (status != CrashReportDatabase::kNoError) { |
| 530 return EXIT_FAILURE; |
| 531 } |
| 532 |
| 533 CrashReportDatabase::CallErrorWritingCrashReport |
| 534 call_error_writing_crash_report(database.get(), new_report); |
| 535 |
| 536 char buf[4096]; |
| 537 ssize_t read_result; |
| 538 while ((read_result = file_reader.Read(buf, sizeof(buf))) > 0) { |
| 539 if (!LoggingWriteFile(new_report->handle, buf, read_result)) { |
| 540 return EXIT_FAILURE; |
| 541 } |
| 542 } |
| 543 if (read_result < 0) { |
| 544 return EXIT_FAILURE; |
| 545 } |
| 546 |
| 547 call_error_writing_crash_report.Disarm(); |
| 548 |
| 549 UUID uuid; |
| 550 status = database->FinishedWritingCrashReport(new_report, &uuid); |
| 551 if (status != CrashReportDatabase::kNoError) { |
| 552 return EXIT_FAILURE; |
| 553 } |
| 554 |
| 555 const char* prefix = (show_operations > 1) ? "New report ID: " : ""; |
| 556 printf("%s%s\n", prefix, uuid.ToString().c_str()); |
| 557 } |
| 558 |
508 return EXIT_SUCCESS; | 559 return EXIT_SUCCESS; |
509 } | 560 } |
510 | 561 |
511 } // namespace | 562 } // namespace |
512 } // namespace crashpad | 563 } // namespace crashpad |
513 | 564 |
514 int main(int argc, char* argv[]) { | 565 int main(int argc, char* argv[]) { |
515 return crashpad::DatabaseUtilMain(argc, argv); | 566 return crashpad::DatabaseUtilMain(argc, argv); |
516 } | 567 } |
OLD | NEW |