Skip to content

Commit b6979c3

Browse files
jasminlapalmeRay Lillywhitelandonf
authored
Added caught exception logging to PLCrashReporter (#277)
* Added caught exception logging to PLCrashReporter Signed-off-by: Landon Fuller <[email protected]> Issue: PLCR-459 * Add documentation and tests for the new live report generation functions. Issue: PLCR-459 * Remove the use of autorelease --------- Signed-off-by: Landon Fuller <[email protected]> Co-authored-by: Ray Lillywhite <[email protected]> Co-authored-by: Landon Fuller <[email protected]>
1 parent a494faa commit b6979c3

File tree

3 files changed

+65
-3
lines changed

3 files changed

+65
-3
lines changed

Source/PLCrashReporter.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,9 +130,11 @@ typedef struct PLCrashReporterCallbacks {
130130

131131
- (NSData *) generateLiveReportWithThread: (thread_t) thread;
132132
- (NSData *) generateLiveReportWithThread: (thread_t) thread error: (NSError **) outError;
133+
- (NSData *) generateLiveReportWithThread: (thread_t) thread exception: (NSException *) exception error: (NSError **) outError;
133134

134135
- (NSData *) generateLiveReport;
135136
- (NSData *) generateLiveReportAndReturnError: (NSError **) outError;
137+
- (NSData *) generateLiveReportWithException: (NSException *) exception error: (NSError **) outError;
136138

137139
- (BOOL) purgePendingCrashReport;
138140
- (BOOL) purgePendingCrashReportAndReturnError: (NSError **) outError;

Source/PLCrashReporter.m

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -653,12 +653,31 @@ - (BOOL) enableCrashReporterAndReturnError: (NSError **) outError {
653653
*
654654
* @return Returns nil if the crash report data could not be generated.
655655
*
656-
* @sa PLCrashReporter::generateLiveReportWithMachThread:error:
656+
* @sa PLCrashReporter::generateLiveReportWithThread:exception:error:
657657
*/
658658
- (NSData *) generateLiveReportWithThread: (thread_t) thread {
659659
return [self generateLiveReportWithThread: thread error: NULL];
660660
}
661661

662+
/**
663+
* Generate a live crash report for a given @a thread, without triggering an actual crash condition.
664+
* This may be used to log current process state without actually crashing. The crash report data will be
665+
* returned on success.
666+
*
667+
* @param thread The thread which will be marked as the failing thread in the generated report.
668+
* @param outError A pointer to an NSError object variable. If an error occurs, this pointer
669+
* will contain an error object indicating why the crash report could not be generated or loaded. If no
670+
* error occurs, this parameter will be left unmodified. You may specify nil for this parameter, and no
671+
* error information will be provided.
672+
*
673+
* @return Returns nil if the crash report data could not be loaded.
674+
*
675+
* @sa PLCrashReporter::generateLiveReportWithThread:exception:error:
676+
*/
677+
- (NSData *) generateLiveReportWithThread: (thread_t) thread error: (NSError **) outError {
678+
return [self generateLiveReportWithThread: thread exception: nil error: outError];
679+
}
680+
662681

663682
/* State and callback used by -generateLiveReportWithThread */
664683
struct plcr_live_report_context {
@@ -678,6 +697,7 @@ static plcrash_error_t plcr_live_report_callback (plcrash_async_thread_state_t *
678697
* returned on success.
679698
*
680699
* @param thread The thread which will be marked as the failing thread in the generated report.
700+
* @param exception An exception to be included as the report's uncaught exception, or nil.
681701
* @param outError A pointer to an NSError object variable. If an error occurs, this pointer
682702
* will contain an error object indicating why the crash report could not be generated or loaded. If no
683703
* error occurs, this parameter will be left unmodified. You may specify nil for this parameter, and no
@@ -687,7 +707,7 @@ static plcrash_error_t plcr_live_report_callback (plcrash_async_thread_state_t *
687707
*
688708
* @todo Implement in-memory, rather than requiring writing of the report to disk.
689709
*/
690-
- (NSData *) generateLiveReportWithThread: (thread_t) thread error: (NSError **) outError {
710+
- (NSData *) generateLiveReportWithThread: (thread_t) thread exception: (NSException *) exception error: (NSError **) outError {
691711
plcrash_log_writer_t writer;
692712
plcrash_async_file_t file;
693713
plcrash_error_t err;
@@ -713,6 +733,9 @@ - (NSData *) generateLiveReportWithThread: (thread_t) thread error: (NSError **)
713733
plcrash_log_writer_set_custom_data(&writer, self.customData);
714734
}
715735

736+
if (exception != nil)
737+
plcrash_log_writer_set_exception(&writer, exception);
738+
716739
/* Mock up a SIGTRAP-based signal info */
717740
plcrash_log_bsd_signal_info_t bsd_signal_info;
718741
plcrash_log_signal_info_t signal_info;
@@ -797,10 +820,14 @@ - (NSData *) generateLiveReport {
797820
* @return Returns nil if the crash report data could not be loaded.
798821
*/
799822
- (NSData *) generateLiveReportAndReturnError: (NSError **) outError {
800-
return [self generateLiveReportWithThread: pl_mach_thread_self() error: outError];
823+
return [self generateLiveReportWithException: nil error: outError];
801824
}
802825

803826

827+
- (NSData *) generateLiveReportWithException: (NSException *)exception error: (NSError **) outError {
828+
return [self generateLiveReportWithThread: pl_mach_thread_self() exception: exception error: outError];
829+
}
830+
804831
/**
805832
* Set the callbacks that will be executed by the receiver after a crash has occured and been recorded by PLCrashReporter.
806833
*

Tests/PLCrashReporterTests.m

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,39 @@ - (void) testSingleton {
4646
#pragma clang diagnostic pop
4747
}
4848

49+
/**
50+
* Test generation of a 'live' crash report with a provided exception.
51+
*/
52+
- (void) testGenerateLiveReportWithException {
53+
NSError *error;
54+
NSData *reportData;
55+
plcrash_test_thread_t thr;
56+
57+
/* Spawn a thread and generate a report for it */
58+
plcrash_test_thread_spawn(&thr);
59+
60+
NSException *exc = [NSException exceptionWithName: NSInvalidArgumentException reason: @"Testing" userInfo: nil];
61+
PLCrashReporter *reporter = [[PLCrashReporter alloc] initWithConfiguration: [PLCrashReporterConfig defaultConfiguration]];
62+
reportData = [reporter generateLiveReportWithThread: pthread_mach_thread_np(thr.thread)
63+
exception: exc
64+
error: &error];
65+
plcrash_test_thread_stop(&thr);
66+
STAssertNotNil(reportData, @"Failed to generate live report: %@", error);
67+
68+
/* Try parsing the result */
69+
PLCrashReport *report = [[PLCrashReport alloc] initWithData: reportData error: &error];
70+
STAssertNotNil(report, @"Could not parse geneated live report: %@", error);
71+
72+
/* Sanity check the signal info */
73+
STAssertEqualStrings([[report signalInfo] name], @"SIGTRAP", @"Incorrect signal name");
74+
STAssertEqualStrings([[report signalInfo] code], @"TRAP_TRACE", @"Incorrect signal code");
75+
76+
/* Sanity check the exception info */
77+
STAssertNotNil(report.exceptionInfo, @"Missing exception info");
78+
STAssertEqualStrings(report.exceptionInfo.exceptionName, exc.name, @"Incorrect exception name");
79+
STAssertEqualStrings(report.exceptionInfo.exceptionReason, exc.reason, @"Incorrect exception reason");
80+
}
81+
4982
/**
5083
* Test generation of a 'live' crash report for a specific thread.
5184
*/

0 commit comments

Comments
 (0)