| OLD | NEW |
| 1 // Copyright (c) 2007, Google Inc. | 1 // Copyright (c) 2007, Google Inc. |
| 2 // All rights reserved. | 2 // All rights reserved. |
| 3 // | 3 // |
| 4 // Redistribution and use in source and binary forms, with or without | 4 // Redistribution and use in source and binary forms, with or without |
| 5 // modification, are permitted provided that the following conditions are | 5 // modification, are permitted provided that the following conditions are |
| 6 // met: | 6 // met: |
| 7 // | 7 // |
| 8 // * Redistributions of source code must retain the above copyright | 8 // * Redistributions of source code must retain the above copyright |
| 9 // notice, this list of conditions and the following disclaimer. | 9 // notice, this list of conditions and the following disclaimer. |
| 10 // * Redistributions in binary form must reproduce the above | 10 // * Redistributions in binary form must reproduce the above |
| (...skipping 25 matching lines...) Expand all Loading... |
| 36 #include <string.h> | 36 #include <string.h> |
| 37 #include <string> | 37 #include <string> |
| 38 | 38 |
| 39 #import "client/mac/crash_generation/Inspector.h" | 39 #import "client/mac/crash_generation/Inspector.h" |
| 40 | 40 |
| 41 #import "client/mac/Framework/Breakpad.h" | 41 #import "client/mac/Framework/Breakpad.h" |
| 42 #import "client/mac/handler/minidump_generator.h" | 42 #import "client/mac/handler/minidump_generator.h" |
| 43 | 43 |
| 44 #import "common/mac/MachIPC.h" | 44 #import "common/mac/MachIPC.h" |
| 45 #include "common/mac/bootstrap_compat.h" | 45 #include "common/mac/bootstrap_compat.h" |
| 46 #include "common/mac/launch_reporter.h" |
| 46 | 47 |
| 47 #import "GTMDefines.h" | 48 #import "GTMDefines.h" |
| 48 | 49 |
| 49 #import <Foundation/Foundation.h> | 50 #import <Foundation/Foundation.h> |
| 50 | 51 |
| 51 namespace google_breakpad { | 52 namespace google_breakpad { |
| 52 | 53 |
| 53 //============================================================================= | 54 //============================================================================= |
| 54 void Inspector::Inspect(const char *receive_port_name) { | 55 void Inspector::Inspect(const char *receive_port_name) { |
| 55 kern_return_t result = ResetBootstrapPort(); | 56 kern_return_t result = ResetBootstrapPort(); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 69 // Send acknowledgement to the crashed process that the inspection | 70 // Send acknowledgement to the crashed process that the inspection |
| 70 // has finished. It will then be able to cleanly exit. | 71 // has finished. It will then be able to cleanly exit. |
| 71 // The return value is ignored because failure isn't fatal. If the process | 72 // The return value is ignored because failure isn't fatal. If the process |
| 72 // didn't get the message there's nothing we can do, and we still want to | 73 // didn't get the message there's nothing we can do, and we still want to |
| 73 // send the report. | 74 // send the report. |
| 74 SendAcknowledgement(); | 75 SendAcknowledgement(); |
| 75 | 76 |
| 76 if (wrote_minidump) { | 77 if (wrote_minidump) { |
| 77 // Ask the user if he wants to upload the crash report to a server, | 78 // Ask the user if he wants to upload the crash report to a server, |
| 78 // and do so if he agrees. | 79 // and do so if he agrees. |
| 79 LaunchReporter(config_file_.GetFilePath()); | 80 LaunchReporter( |
| 81 config_params_.GetValueForKey(BREAKPAD_REPORTER_EXE_LOCATION), |
| 82 config_file_.GetFilePath()); |
| 80 } else { | 83 } else { |
| 81 fprintf(stderr, "Inspection of crashed process failed\n"); | 84 fprintf(stderr, "Inspection of crashed process failed\n"); |
| 82 } | 85 } |
| 83 | 86 |
| 84 // Now that we're done reading messages, cleanup the service, but only | 87 // Now that we're done reading messages, cleanup the service, but only |
| 85 // if there was an actual exception | 88 // if there was an actual exception |
| 86 // Otherwise, it means the dump was generated on demand and the process | 89 // Otherwise, it means the dump was generated on demand and the process |
| 87 // lives on, and we might be needed again in the future. | 90 // lives on, and we might be needed again in the future. |
| 88 if (exception_code_) { | 91 if (exception_code_) { |
| 89 ServiceCheckOut(receive_port_name); | 92 ServiceCheckOut(receive_port_name); |
| (...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 348 #if VERBOSE | 351 #if VERBOSE |
| 349 PRINT_MACH_RESULT(result, "Inspector: sent acknowledgement"); | 352 PRINT_MACH_RESULT(result, "Inspector: sent acknowledgement"); |
| 350 #endif | 353 #endif |
| 351 | 354 |
| 352 return result; | 355 return result; |
| 353 } | 356 } |
| 354 | 357 |
| 355 return KERN_INVALID_NAME; | 358 return KERN_INVALID_NAME; |
| 356 } | 359 } |
| 357 | 360 |
| 358 //============================================================================= | |
| 359 void Inspector::LaunchReporter(const char *inConfigFilePath) { | |
| 360 // Extract the path to the reporter executable. | |
| 361 const char *reporterExecutablePath = | |
| 362 config_params_.GetValueForKey(BREAKPAD_REPORTER_EXE_LOCATION); | |
| 363 | |
| 364 // Setup and launch the crash dump sender. | |
| 365 const char *argv[3]; | |
| 366 argv[0] = reporterExecutablePath; | |
| 367 argv[1] = inConfigFilePath; | |
| 368 argv[2] = NULL; | |
| 369 | |
| 370 // Launch the reporter | |
| 371 pid_t pid = fork(); | |
| 372 | |
| 373 // If we're in the child, load in our new executable and run. | |
| 374 // The parent will not wait for the child to complete. | |
| 375 if (pid == 0) { | |
| 376 execv(argv[0], (char * const *)argv); | |
| 377 config_file_.Unlink(); // launch failed - get rid of config file | |
| 378 _exit(1); | |
| 379 } | |
| 380 | |
| 381 // Wait until the Reporter child process exits. | |
| 382 // | |
| 383 | |
| 384 // We'll use a timeout of one minute. | |
| 385 int timeoutCount = 60; // 60 seconds | |
| 386 | |
| 387 while (timeoutCount-- > 0) { | |
| 388 int status; | |
| 389 pid_t result = waitpid(pid, &status, WNOHANG); | |
| 390 | |
| 391 if (result == 0) { | |
| 392 // The child has not yet finished. | |
| 393 sleep(1); | |
| 394 } else if (result == -1) { | |
| 395 // error occurred. | |
| 396 break; | |
| 397 } else { | |
| 398 // child has finished | |
| 399 break; | |
| 400 } | |
| 401 } | |
| 402 } | |
| 403 | |
| 404 } // namespace google_breakpad | 361 } // namespace google_breakpad |
| 405 | 362 |
| OLD | NEW |