Added caught exception logging to PLCrashReporter (#277)
* Added caught exception logging to PLCrashReporter Signed-off-by: Landon Fuller <landonf@plausible.coop> 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 <landonf@plausible.coop> Co-authored-by: Ray Lillywhite <rayll@umich.edu> Co-authored-by: Landon Fuller <landonf@plausible.coop>
This commit is contained in:
Родитель
a494faa23e
Коммит
b6979c3c34
|
@ -130,9 +130,11 @@ typedef struct PLCrashReporterCallbacks {
|
|||
|
||||
- (NSData *) generateLiveReportWithThread: (thread_t) thread;
|
||||
- (NSData *) generateLiveReportWithThread: (thread_t) thread error: (NSError **) outError;
|
||||
- (NSData *) generateLiveReportWithThread: (thread_t) thread exception: (NSException *) exception error: (NSError **) outError;
|
||||
|
||||
- (NSData *) generateLiveReport;
|
||||
- (NSData *) generateLiveReportAndReturnError: (NSError **) outError;
|
||||
- (NSData *) generateLiveReportWithException: (NSException *) exception error: (NSError **) outError;
|
||||
|
||||
- (BOOL) purgePendingCrashReport;
|
||||
- (BOOL) purgePendingCrashReportAndReturnError: (NSError **) outError;
|
||||
|
|
|
@ -653,12 +653,31 @@ static PLCrashReporter *sharedReporter = nil;
|
|||
*
|
||||
* @return Returns nil if the crash report data could not be generated.
|
||||
*
|
||||
* @sa PLCrashReporter::generateLiveReportWithMachThread:error:
|
||||
* @sa PLCrashReporter::generateLiveReportWithThread:exception:error:
|
||||
*/
|
||||
- (NSData *) generateLiveReportWithThread: (thread_t) thread {
|
||||
return [self generateLiveReportWithThread: thread error: NULL];
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a live crash report for a given @a thread, without triggering an actual crash condition.
|
||||
* This may be used to log current process state without actually crashing. The crash report data will be
|
||||
* returned on success.
|
||||
*
|
||||
* @param thread The thread which will be marked as the failing thread in the generated report.
|
||||
* @param outError A pointer to an NSError object variable. If an error occurs, this pointer
|
||||
* will contain an error object indicating why the crash report could not be generated or loaded. If no
|
||||
* error occurs, this parameter will be left unmodified. You may specify nil for this parameter, and no
|
||||
* error information will be provided.
|
||||
*
|
||||
* @return Returns nil if the crash report data could not be loaded.
|
||||
*
|
||||
* @sa PLCrashReporter::generateLiveReportWithThread:exception:error:
|
||||
*/
|
||||
- (NSData *) generateLiveReportWithThread: (thread_t) thread error: (NSError **) outError {
|
||||
return [self generateLiveReportWithThread: thread exception: nil error: outError];
|
||||
}
|
||||
|
||||
|
||||
/* State and callback used by -generateLiveReportWithThread */
|
||||
struct plcr_live_report_context {
|
||||
|
@ -678,6 +697,7 @@ static plcrash_error_t plcr_live_report_callback (plcrash_async_thread_state_t *
|
|||
* returned on success.
|
||||
*
|
||||
* @param thread The thread which will be marked as the failing thread in the generated report.
|
||||
* @param exception An exception to be included as the report's uncaught exception, or nil.
|
||||
* @param outError A pointer to an NSError object variable. If an error occurs, this pointer
|
||||
* will contain an error object indicating why the crash report could not be generated or loaded. If no
|
||||
* 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 *
|
|||
*
|
||||
* @todo Implement in-memory, rather than requiring writing of the report to disk.
|
||||
*/
|
||||
- (NSData *) generateLiveReportWithThread: (thread_t) thread error: (NSError **) outError {
|
||||
- (NSData *) generateLiveReportWithThread: (thread_t) thread exception: (NSException *) exception error: (NSError **) outError {
|
||||
plcrash_log_writer_t writer;
|
||||
plcrash_async_file_t file;
|
||||
plcrash_error_t err;
|
||||
|
@ -713,6 +733,9 @@ static plcrash_error_t plcr_live_report_callback (plcrash_async_thread_state_t *
|
|||
plcrash_log_writer_set_custom_data(&writer, self.customData);
|
||||
}
|
||||
|
||||
if (exception != nil)
|
||||
plcrash_log_writer_set_exception(&writer, exception);
|
||||
|
||||
/* Mock up a SIGTRAP-based signal info */
|
||||
plcrash_log_bsd_signal_info_t bsd_signal_info;
|
||||
plcrash_log_signal_info_t signal_info;
|
||||
|
@ -797,10 +820,14 @@ cleanup:
|
|||
* @return Returns nil if the crash report data could not be loaded.
|
||||
*/
|
||||
- (NSData *) generateLiveReportAndReturnError: (NSError **) outError {
|
||||
return [self generateLiveReportWithThread: pl_mach_thread_self() error: outError];
|
||||
return [self generateLiveReportWithException: nil error: outError];
|
||||
}
|
||||
|
||||
|
||||
- (NSData *) generateLiveReportWithException: (NSException *)exception error: (NSError **) outError {
|
||||
return [self generateLiveReportWithThread: pl_mach_thread_self() exception: exception error: outError];
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the callbacks that will be executed by the receiver after a crash has occured and been recorded by PLCrashReporter.
|
||||
*
|
||||
|
|
|
@ -46,6 +46,39 @@
|
|||
#pragma clang diagnostic pop
|
||||
}
|
||||
|
||||
/**
|
||||
* Test generation of a 'live' crash report with a provided exception.
|
||||
*/
|
||||
- (void) testGenerateLiveReportWithException {
|
||||
NSError *error;
|
||||
NSData *reportData;
|
||||
plcrash_test_thread_t thr;
|
||||
|
||||
/* Spawn a thread and generate a report for it */
|
||||
plcrash_test_thread_spawn(&thr);
|
||||
|
||||
NSException *exc = [NSException exceptionWithName: NSInvalidArgumentException reason: @"Testing" userInfo: nil];
|
||||
PLCrashReporter *reporter = [[PLCrashReporter alloc] initWithConfiguration: [PLCrashReporterConfig defaultConfiguration]];
|
||||
reportData = [reporter generateLiveReportWithThread: pthread_mach_thread_np(thr.thread)
|
||||
exception: exc
|
||||
error: &error];
|
||||
plcrash_test_thread_stop(&thr);
|
||||
STAssertNotNil(reportData, @"Failed to generate live report: %@", error);
|
||||
|
||||
/* Try parsing the result */
|
||||
PLCrashReport *report = [[PLCrashReport alloc] initWithData: reportData error: &error];
|
||||
STAssertNotNil(report, @"Could not parse geneated live report: %@", error);
|
||||
|
||||
/* Sanity check the signal info */
|
||||
STAssertEqualStrings([[report signalInfo] name], @"SIGTRAP", @"Incorrect signal name");
|
||||
STAssertEqualStrings([[report signalInfo] code], @"TRAP_TRACE", @"Incorrect signal code");
|
||||
|
||||
/* Sanity check the exception info */
|
||||
STAssertNotNil(report.exceptionInfo, @"Missing exception info");
|
||||
STAssertEqualStrings(report.exceptionInfo.exceptionName, exc.name, @"Incorrect exception name");
|
||||
STAssertEqualStrings(report.exceptionInfo.exceptionReason, exc.reason, @"Incorrect exception reason");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test generation of a 'live' crash report for a specific thread.
|
||||
*/
|
||||
|
|
Загрузка…
Ссылка в новой задаче