Include a incident UUID in crash reports.

Issue: 64
Submitted by:  Craig Newell <craign [at] ieee.org>
This commit is contained in:
Landon Fuller 2013-07-11 13:42:37 -04:00
Родитель 8257b63929
Коммит db087b6832
8 изменённых файлов: 67 добавлений и 3 удалений

Просмотреть файл

@ -318,6 +318,9 @@ message CrashReport {
message ReportInfo {
/** If true, this report was generated on request, and no crash occured. */
required bool user_requested = 1;
/** UUID unique for this crash */
optional string incident_id = 2;
}
/* Report format information. Required for all v1.1+ crash reports. */

Просмотреть файл

@ -54,6 +54,9 @@ typedef struct plcrash_log_writer {
/** If true, the report should be marked as a 'generated' user-requested report, rather than as a true crash
* report */
bool user_requested;
/** Incident Identifier */
char *incident_id;
} report_info;
/** System data */

Просмотреть файл

@ -233,6 +233,9 @@ enum {
/** CrashReport.report_info.crashed */
PLCRASH_PROTO_REPORT_INFO_USER_REQUESTED_ID = 1,
/** CrashReport.report_info.incident */
PLCRASH_PROTO_REPORT_INFO_INCIDENT_ID = 2,
};
/**
@ -261,6 +264,9 @@ plcrash_error_t plcrash_log_writer_init (plcrash_log_writer_t *writer,
/* Default to false */
writer->report_info.user_requested = user_requested;
/* Generate a UUID for this incident */
writer->report_info.incident_id = strdup([[[NSUUID UUID] UUIDString] UTF8String]);
/* Fetch the application information */
{
writer->application_info.app_identifier = strdup([app_identifier UTF8String]);
@ -1088,6 +1094,9 @@ static size_t plcrash_writer_write_report_info (plcrash_async_file_t *file, plcr
/* Note crashed status */
rv += plcrash_writer_pack(file, PLCRASH_PROTO_REPORT_INFO_USER_REQUESTED_ID, PLPROTOBUF_C_TYPE_BOOL, &writer->report_info.user_requested);
/* Incident Identifier */
rv += plcrash_writer_pack(file, PLCRASH_PROTO_REPORT_INFO_INCIDENT_ID, PLPROTOBUF_C_TYPE_STRING, writer->report_info.incident_id);
return rv;
}

Просмотреть файл

@ -107,6 +107,12 @@ typedef struct _PLCrashReportDecoder _PLCrashReportDecoder;
/** Exception information (may be nil) */
PLCrashReportExceptionInfo *_exceptionInfo;
/** User requested not a crash */
BOOL _userRequested;
/** Report UUID */
NSString *_incidentIdentifier;
}
- (id) initWithData: (NSData *) encodedData error: (NSError **) outError;
@ -171,4 +177,14 @@ typedef struct _PLCrashReportDecoder _PLCrashReportDecoder;
*/
@property(nonatomic, readonly) PLCrashReportExceptionInfo *exceptionInfo;
/**
* YES if this report was user requested not generated because of a crash.
*/
@property(nonatomic, readonly) BOOL userRequested;
/**
* Incident Identifier. A UUID unique to this crash report.
*/
@property(nonatomic, readonly) NSString *incidentIdentifier;
@end

Просмотреть файл

@ -92,6 +92,22 @@ static void populate_nserror (NSError **error, PLCrashReporterError code, NSStri
goto error;
}
/* Report info (optional) */
_userRequested = NO;
_incidentIdentifier = nil;
if (_decoder->crashReport->report_info) {
_userRequested = _decoder->crashReport->report_info->user_requested;
/* Incident Identifier (optional) */
if (_decoder->crashReport->report_info->incident_id) {
_incidentIdentifier = [[NSString stringWithUTF8String:_decoder->crashReport->report_info->incident_id] retain];
}
}
/* If no incident identifier from client, generate one now */
if (_incidentIdentifier == nil) {
_incidentIdentifier = [[[NSUUID UUID] UUIDString] retain];
}
/* System info */
_systemInfo = [[self extractSystemInfo: _decoder->crashReport->system_info error: outError] retain];
@ -156,6 +172,7 @@ error:
[_threads release];
[_images release];
[_exceptionInfo release];
[_incidentIdentifier release];
/* Free the decoder state */
if (_decoder != NULL) {
@ -215,6 +232,8 @@ error:
@synthesize threads = _threads;
@synthesize images = _images;
@synthesize exceptionInfo = _exceptionInfo;
@synthesize userRequested = _userRequested;
@synthesize incidentIdentifier = _incidentIdentifier;
@end
@ -711,4 +730,4 @@ static void populate_nserror (NSError **error, PLCrashReporterError code, NSStri
];
*error = [NSError errorWithDomain: PLCrashReporterErrorDomain code: code userInfo: userInfo];
}
}

Просмотреть файл

@ -121,6 +121,11 @@
PLCrashReport *crashLog = [[[PLCrashReport alloc] initWithData: [NSData dataWithContentsOfMappedFile: _logPath] error: &error] autorelease];
STAssertNotNil(crashLog, @"Could not decode crash log: %@", error);
/* Report info */
STAssertFalse(crashLog.userRequested, @"Crash should not be user requested");
STAssertNotNil(crashLog.incidentIdentifier, @"No incident identifier");
STAssertNotNil([[NSUUID new] initWithUUIDString:crashLog.incidentIdentifier], @"incident identifier not a UUID");
/* System info */
STAssertNotNil(crashLog.systemInfo, @"No system information available");
STAssertNotNil(crashLog.systemInfo.operatingSystemVersion, @"OS version is nil");

Просмотреть файл

@ -168,7 +168,7 @@ NSInteger binaryImageSort(id binary1, id binary2, void *context);
if (report.hasMachineInfo && report.machineInfo.modelName != nil)
hardwareModel = report.machineInfo.modelName;
[text appendFormat: @"Incident Identifier: TODO\n"];
[text appendFormat: @"Incident Identifier: %@\n", report.incidentIdentifier];
[text appendFormat: @"CrashReporter Key: TODO\n"];
[text appendFormat: @"Hardware Model: %@\n", hardwareModel];
}
@ -249,6 +249,13 @@ NSInteger binaryImageSort(id binary1, id binary2, void *context);
[text appendString: @"\n"];
}
/* Was this user requested not a real crash? */
if (report.userRequested) {
[text appendString: @"Application Specific Information:\n"];
[text appendString: @"*** User Requested Crash Report ***\n"];
[text appendString: @"\n"];
}
/* If an exception stack trace is available, output an Apple-compatible backtrace. */
if (report.exceptionInfo != nil && report.exceptionInfo.stackFrames != nil && [report.exceptionInfo.stackFrames count] > 0) {
PLCrashReportExceptionInfo *exception = report.exceptionInfo;

Просмотреть файл

@ -60,6 +60,7 @@
/* Try parsing the result */
PLCrashReport *report = [[PLCrashReport alloc] initWithData: reportData error: &error];
STAssertNotNil(report, @"Could not parse geneated live report: %@", error);
STAssertTrue(report.userRequested, @"Report not marked user requested");
/* Sanity check the signal info */
STAssertEqualStrings([[report signalInfo] name], @"SIGTRAP", @"Incorrect signal name");
@ -76,7 +77,8 @@
PLCrashReport *report = [[PLCrashReport alloc] initWithData: reportData error: &error];
STAssertNotNil(report, @"Could not parse geneated live report: %@", error);
STAssertTrue(report.userRequested, @"Report not marked user requested");
STAssertEqualStrings([[report signalInfo] name], @"SIGTRAP", @"Incorrect signal name");
STAssertEqualStrings([[report signalInfo] code], @"TRAP_TRACE", @"Incorrect signal code");
}