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 |