Merge branch 'refs/heads/feature/v3.1' into develop

This commit is contained in:
Andreas Linde 2013-07-28 01:55:40 +02:00
commit ef1ae02a1e
22 changed files with 883 additions and 619 deletions

View File

@ -218,7 +218,7 @@ NSString *const kBITCrashManagerStatus = @"BITCrashManagerStatus";
[self saveSettings]; [self saveSettings];
} }
- (NSString *) extractAppUUIDs:(PLCrashReport *)report { - (NSString *) extractAppUUIDs:(BITPLCrashReport *)report {
NSMutableString *uuidString = [NSMutableString string]; NSMutableString *uuidString = [NSMutableString string];
NSArray *uuidArray = [BITCrashReportTextFormatter arrayOfAppUUIDsForCrashReport:report]; NSArray *uuidArray = [BITCrashReportTextFormatter arrayOfAppUUIDsForCrashReport:report];
@ -288,7 +288,7 @@ NSString *const kBITCrashManagerStatus = @"BITCrashManagerStatus";
// Called to handle a pending crash report. // Called to handle a pending crash report.
- (void) handleCrashReport { - (void) handleCrashReport {
PLCrashReporter *crashReporter = [PLCrashReporter sharedReporter]; BITPLCrashReporter *crashReporter = [BITPLCrashReporter sharedReporter];
NSError *error = NULL; NSError *error = NULL;
[self loadSettings]; [self loadSettings];
@ -309,11 +309,11 @@ NSString *const kBITCrashManagerStatus = @"BITCrashManagerStatus";
BITHockeyLog(@"ERROR: Could not load crash report: %@", error); BITHockeyLog(@"ERROR: Could not load crash report: %@", error);
} else { } else {
// get the startup timestamp from the crash report, and the file timestamp to calculate the timeinterval when the crash happened after startup // get the startup timestamp from the crash report, and the file timestamp to calculate the timeinterval when the crash happened after startup
PLCrashReport *report = [[PLCrashReport alloc] initWithData:crashData error:&error]; BITPLCrashReport *report = [[BITPLCrashReport alloc] initWithData:crashData error:&error];
if ([report.applicationInfo respondsToSelector:@selector(applicationStartupTimestamp)]) { if ([report.processInfo respondsToSelector:@selector(processStartTime)]) {
if (report.systemInfo.timestamp && report.applicationInfo.applicationStartupTimestamp) { if (report.systemInfo.timestamp && report.processInfo.processStartTime) {
_timeintervalCrashInLastSessionOccured = [report.systemInfo.timestamp timeIntervalSinceDate:report.applicationInfo.applicationStartupTimestamp]; _timeintervalCrashInLastSessionOccured = [report.systemInfo.timestamp timeIntervalSinceDate:report.processInfo.processStartTime];
} }
} }
@ -468,16 +468,9 @@ NSString *const kBITCrashManagerStatus = @"BITCrashManagerStatus";
if (_crashManagerStatus == BITCrashManagerStatusDisabled) return; if (_crashManagerStatus == BITCrashManagerStatusDisabled) return;
if (!_isSetup) { if (!_isSetup) {
PLCrashReporter *crashReporter = [PLCrashReporter sharedReporter]; BITPLCrashReporter *crashReporter = [BITPLCrashReporter sharedReporter];
NSError *error = NULL; NSError *error = NULL;
// Make sure the correct version of PLCrashReporter is linked
id plCrashReportReportInfoClass = NSClassFromString(@"PLCrashReportReportInfo");
if (!plCrashReportReportInfoClass) {
NSLog(@"[HockeySDK] ERROR: An old version of PLCrashReporter framework is linked! Please check the framework search path in the target build settings and remove references to folders that contain an older version of CrashReporter.framework and also delete these files.");
}
// Check if we previously crashed // Check if we previously crashed
if ([crashReporter hasPendingCrashReport]) { if ([crashReporter hasPendingCrashReport]) {
_didCrashInLastSession = YES; _didCrashInLastSession = YES;
@ -544,7 +537,7 @@ NSString *const kBITCrashManagerStatus = @"BITCrashManagerStatus";
NSData *crashData = [NSData dataWithContentsOfFile:filename]; NSData *crashData = [NSData dataWithContentsOfFile:filename];
if ([crashData length] > 0) { if ([crashData length] > 0) {
PLCrashReport *report = [[PLCrashReport alloc] initWithData:crashData error:&error]; BITPLCrashReport *report = [[BITPLCrashReport alloc] initWithData:crashData error:&error];
if (report == nil) { if (report == nil) {
BITHockeyLog(@"WARNING: Could not parse crash report"); BITHockeyLog(@"WARNING: Could not parse crash report");
@ -559,8 +552,8 @@ NSString *const kBITCrashManagerStatus = @"BITCrashManagerStatus";
} }
NSString *crashUUID = @""; NSString *crashUUID = @"";
if ([report respondsToSelector:@selector(reportInfo)]) { if (report.uuidRef != NULL) {
crashUUID = report.reportInfo.reportGUID ?: @""; crashUUID = (NSString *) CFBridgingRelease(CFUUIDCreateString(NULL, report.uuidRef));
} }
NSString *installString = bit_appAnonID() ?: @""; NSString *installString = bit_appAnonID() ?: @"";
NSString *crashLogString = [BITCrashReportTextFormatter stringValueForCrashReport:report crashReporterKey:installString]; NSString *crashLogString = [BITCrashReportTextFormatter stringValueForCrashReport:report crashReporterKey:installString];

View File

@ -35,30 +35,23 @@
#import "BITCrashReportTextFormatter.h" #import "BITCrashReportTextFormatter.h"
#ifndef CPU_SUBTYPE_ARM_V7S /*
#define CPU_SUBTYPE_ARM_V7S ((cpu_subtype_t) 11) /* Swift */ * XXX: The ARM_V7S Mach-O CPU subtype is not defined in the Mac OS X 10.8
#endif * headers.
/**
* Sort PLCrashReportBinaryImageInfo instances by their starting address.
*/ */
static NSInteger binaryImageSort(id binary1, id binary2, void *context) { #ifndef CPU_SUBTYPE_ARM_V7S
uint64_t addr1 = [binary1 imageBaseAddress]; # define CPU_SUBTYPE_ARM_V7S 11
uint64_t addr2 = [binary2 imageBaseAddress]; #elif !TARGET_OS_IPHONE
# error CPU_SUBTYPE_ARM_V7S is now defined by the SDK. Please remove this define.
if (addr1 < addr2) #endif
return NSOrderedAscending;
else if (addr1 > addr2)
return NSOrderedDescending;
else
return NSOrderedSame;
}
@interface BITCrashReportTextFormatter (PrivateAPI) @interface BITCrashReportTextFormatter (PrivateAPI)
+ (NSString *)formatStackFrame:(PLCrashReportStackFrameInfo *)frameInfo NSInteger binaryImageSort(id binary1, id binary2, void *context);
+ (NSString *)formatStackFrame:(BITPLCrashReportStackFrameInfo *)frameInfo
frameIndex:(NSUInteger)frameIndex frameIndex:(NSUInteger)frameIndex
report:(PLCrashReport *)report; report:(BITPLCrashReport *)report
lp64: (BOOL) lp64;
@end @end
@ -73,10 +66,11 @@ static NSInteger binaryImageSort(id binary1, id binary2, void *context) {
* the formatted result as a string. * the formatted result as a string.
* *
* @param report The report to format. * @param report The report to format.
* @param textFormat The text format to use.
* *
* @return Returns the formatted result on success, or nil if an error occurs. * @return Returns the formatted result on success, or nil if an error occurs.
*/ */
+ (NSString *)stringValueForCrashReport:(PLCrashReport *)report crashReporterKey:(NSString *)crashReporterKey { + (NSString *)stringValueForCrashReport:(BITPLCrashReport *)report crashReporterKey:(NSString *)crashReporterKey {
NSMutableString* text = [NSMutableString string]; NSMutableString* text = [NSMutableString string];
boolean_t lp64 = true; // quiesce GCC uninitialized value warning boolean_t lp64 = true; // quiesce GCC uninitialized value warning
@ -103,7 +97,7 @@ static NSInteger binaryImageSort(id binary1, id binary2, void *context) {
NSString *codeType = nil; NSString *codeType = nil;
{ {
/* Attempt to derive the code type from the binary images */ /* Attempt to derive the code type from the binary images */
for (PLCrashReportBinaryImageInfo *image in report.images) { for (BITPLCrashReportBinaryImageInfo *image in report.images) {
/* Skip images with no specified type */ /* Skip images with no specified type */
if (image.codeType == nil) if (image.codeType == nil)
continue; continue;
@ -148,7 +142,6 @@ static NSInteger binaryImageSort(id binary1, id binary2, void *context) {
switch (report.systemInfo.architecture) { switch (report.systemInfo.architecture) {
case PLCrashReportArchitectureARMv6: case PLCrashReportArchitectureARMv6:
case PLCrashReportArchitectureARMv7: case PLCrashReportArchitectureARMv7:
case PLCrashReportArchitectureARMv7s:
codeType = @"ARM"; codeType = @"ARM";
lp64 = false; lp64 = false;
break; break;
@ -173,13 +166,7 @@ static NSInteger binaryImageSort(id binary1, id binary2, void *context) {
} }
{ {
NSString *reportGUID = @"TODO"; NSString *reporterKey = @"???";
if ([report respondsToSelector:@selector(reportInfo)]) {
if (report.hasReportInfo && report.reportInfo.reportGUID != nil)
reportGUID = report.reportInfo.reportGUID;
}
NSString *reporterKey = @"TODO";
if (crashReporterKey && [crashReporterKey length] > 0) if (crashReporterKey && [crashReporterKey length] > 0)
reporterKey = crashReporterKey; reporterKey = crashReporterKey;
@ -187,7 +174,12 @@ static NSInteger binaryImageSort(id binary1, id binary2, void *context) {
if (report.hasMachineInfo && report.machineInfo.modelName != nil) if (report.hasMachineInfo && report.machineInfo.modelName != nil)
hardwareModel = report.machineInfo.modelName; hardwareModel = report.machineInfo.modelName;
[text appendFormat: @"Incident Identifier: %@\n", reportGUID]; NSString *incidentIdentifier = @"???";
if (report.uuidRef != NULL) {
incidentIdentifier = (NSString *) CFBridgingRelease(CFUUIDCreateString(NULL, report.uuidRef));
}
[text appendFormat: @"Incident Identifier: %@\n", incidentIdentifier];
[text appendFormat: @"CrashReporter Key: %@\n", reporterKey]; [text appendFormat: @"CrashReporter Key: %@\n", reporterKey];
[text appendFormat: @"Hardware Model: %@\n", hardwareModel]; [text appendFormat: @"Hardware Model: %@\n", hardwareModel];
} }
@ -226,7 +218,7 @@ static NSInteger binaryImageSort(id binary1, id binary2, void *context) {
parentProcessName = report.processInfo.parentProcessName; parentProcessName = report.processInfo.parentProcessName;
/* Parent Process ID */ /* Parent Process ID */
parentProcessId = [[NSNumber numberWithUnsignedInteger: report.processInfo.parentProcessID] stringValue]; parentProcessId = [@(report.processInfo.parentProcessID) stringValue];
} }
[text appendFormat: @"Process: %@ [%@]\n", processName, processId]; [text appendFormat: @"Process: %@ [%@]\n", processName, processId];
@ -245,13 +237,7 @@ static NSInteger binaryImageSort(id binary1, id binary2, void *context) {
if (report.systemInfo.operatingSystemBuild != nil) if (report.systemInfo.operatingSystemBuild != nil)
osBuild = report.systemInfo.operatingSystemBuild; osBuild = report.systemInfo.operatingSystemBuild;
NSLocale *enUSPOSIXLocale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"]; [text appendFormat: @"Date/Time: %@\n", report.systemInfo.timestamp];
NSDateFormatter *rfc3339Formatter = [[NSDateFormatter alloc] init];
[rfc3339Formatter setLocale:enUSPOSIXLocale];
[rfc3339Formatter setDateFormat:@"yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'"];
[rfc3339Formatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
[text appendFormat: @"Date/Time: %@\n", [rfc3339Formatter stringFromDate:report.systemInfo.timestamp]];
[text appendFormat: @"OS Version: %@ %@ (%@)\n", osName, report.systemInfo.operatingSystemVersion, osBuild]; [text appendFormat: @"OS Version: %@ %@ (%@)\n", osName, report.systemInfo.operatingSystemVersion, osBuild];
[text appendFormat: @"Report Version: 104\n"]; [text appendFormat: @"Report Version: 104\n"];
} }
@ -262,7 +248,7 @@ static NSInteger binaryImageSort(id binary1, id binary2, void *context) {
[text appendFormat: @"Exception Type: %@\n", report.signalInfo.name]; [text appendFormat: @"Exception Type: %@\n", report.signalInfo.name];
[text appendFormat: @"Exception Codes: %@ at 0x%" PRIx64 "\n", report.signalInfo.code, report.signalInfo.address]; [text appendFormat: @"Exception Codes: %@ at 0x%" PRIx64 "\n", report.signalInfo.code, report.signalInfo.address];
for (PLCrashReportThreadInfo *thread in report.threads) { for (BITPLCrashReportThreadInfo *thread in report.threads) {
if (thread.crashed) { if (thread.crashed) {
[text appendFormat: @"Crashed Thread: %ld\n", (long) thread.threadNumber]; [text appendFormat: @"Crashed Thread: %ld\n", (long) thread.threadNumber];
break; break;
@ -280,56 +266,35 @@ static NSInteger binaryImageSort(id binary1, id binary2, void *context) {
[text appendString: @"\n"]; [text appendString: @"\n"];
} }
/* If an exception stack trace is available, output a pseudo-thread to provide the frame info */ /* 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) { if (report.exceptionInfo != nil && report.exceptionInfo.stackFrames != nil && [report.exceptionInfo.stackFrames count] > 0) {
PLCrashReportExceptionInfo *exception = report.exceptionInfo; BITPLCrashReportExceptionInfo *exception = report.exceptionInfo;
/* Write out the frames */ /* Create the header. */
NSUInteger numberBlankStackFrames = 0;
for (NSUInteger frame_idx = 0; frame_idx < [exception.stackFrames count]; frame_idx++) {
PLCrashReportStackFrameInfo *frameInfo = [exception.stackFrames objectAtIndex: frame_idx];
NSString *formattedStackFrame = [self formatStackFrame: frameInfo frameIndex: frame_idx - numberBlankStackFrames report: report];
if (formattedStackFrame) {
if (frame_idx - numberBlankStackFrames == 0) {
/* Create the pseudo-thread header. We use the named thread format to mark this thread */
[text appendString: @"Last Exception Backtrace:\n"]; [text appendString: @"Last Exception Backtrace:\n"];
}
[text appendString: formattedStackFrame]; /* Write out the frames. In raw reports, Apple writes this out as a simple list of PCs. In the minimally
} else { * post-processed report, Apple writes this out as full frame entries. We use the latter format. */
numberBlankStackFrames++; for (NSUInteger frame_idx = 0; frame_idx < [exception.stackFrames count]; frame_idx++) {
BITPLCrashReportStackFrameInfo *frameInfo = [exception.stackFrames objectAtIndex: frame_idx];
[text appendString: [self formatStackFrame: frameInfo frameIndex: frame_idx report: report lp64: lp64]];
} }
} [text appendString: @"\n"];
[text appendString: @"\n\n"];
} }
/* Threads */ /* Threads */
PLCrashReportThreadInfo *crashed_thread = nil; BITPLCrashReportThreadInfo *crashed_thread = nil;
NSInteger maxThreadNum = 0; NSInteger maxThreadNum = 0;
for (PLCrashReportThreadInfo *thread in report.threads) { for (BITPLCrashReportThreadInfo *thread in report.threads) {
/* Write out the frames */
NSUInteger numberBlankStackFrames = 0;
for (NSUInteger frame_idx = 0; frame_idx < [thread.stackFrames count]; frame_idx++) {
PLCrashReportStackFrameInfo *frameInfo = [thread.stackFrames objectAtIndex: frame_idx];
NSString *formattedStackFrame = [self formatStackFrame: frameInfo frameIndex: frame_idx report: report];
if (formattedStackFrame) {
if (frame_idx - numberBlankStackFrames == 0) {
/* Create the thread header. */
if (thread.crashed) { if (thread.crashed) {
[text appendFormat: @"Thread %ld Crashed:\n", (long) thread.threadNumber]; [text appendFormat: @"Thread %ld Crashed:\n", (long) thread.threadNumber];
crashed_thread = thread; crashed_thread = thread;
} else { } else {
[text appendFormat: @"Thread %ld:\n", (long) thread.threadNumber]; [text appendFormat: @"Thread %ld:\n", (long) thread.threadNumber];
} }
} for (NSUInteger frame_idx = 0; frame_idx < [thread.stackFrames count]; frame_idx++) {
BITPLCrashReportStackFrameInfo *frameInfo = [thread.stackFrames objectAtIndex: frame_idx];
[text appendString: formattedStackFrame]; [text appendString: [self formatStackFrame: frameInfo frameIndex: frame_idx report: report lp64: lp64]];
} else {
numberBlankStackFrames++;
}
} }
[text appendString: @"\n"]; [text appendString: @"\n"];
@ -342,7 +307,7 @@ static NSInteger binaryImageSort(id binary1, id binary2, void *context) {
[text appendFormat: @"Thread %ld crashed with %@ Thread State:\n", (long) crashed_thread.threadNumber, codeType]; [text appendFormat: @"Thread %ld crashed with %@ Thread State:\n", (long) crashed_thread.threadNumber, codeType];
int regColumn = 0; int regColumn = 0;
for (PLCrashReportRegisterInfo *reg in crashed_thread.registers) { for (BITPLCrashReportRegisterInfo *reg in crashed_thread.registers) {
NSString *reg_fmt; NSString *reg_fmt;
/* Use 32-bit or 64-bit fixed width format for the register values */ /* Use 32-bit or 64-bit fixed width format for the register values */
@ -379,7 +344,7 @@ static NSInteger binaryImageSort(id binary1, id binary2, void *context) {
/* Images. The iPhone crash report format sorts these in ascending order, by the base address */ /* Images. The iPhone crash report format sorts these in ascending order, by the base address */
[text appendString: @"Binary Images:\n"]; [text appendString: @"Binary Images:\n"];
for (PLCrashReportBinaryImageInfo *imageInfo in [report.images sortedArrayUsingFunction: binaryImageSort context: nil]) { for (BITPLCrashReportBinaryImageInfo *imageInfo in [report.images sortedArrayUsingFunction: binaryImageSort context: nil]) {
NSString *uuid; NSString *uuid;
/* Fetch the UUID if it exists */ /* Fetch the UUID if it exists */
if (imageInfo.hasImageUUID) if (imageInfo.hasImageUUID)
@ -430,9 +395,12 @@ static NSInteger binaryImageSort(id binary1, id binary2, void *context) {
} }
} }
/* Determine if this is the main executable */ /* Determine if this is the main executable or an app specific framework*/
NSString *binaryDesignator = @" "; NSString *binaryDesignator = @" ";
if ([imageInfo.imageName isEqual: report.processInfo.processPath]) NSString *imagePath = [imageInfo.imageName stringByStandardizingPath];
NSString *appBundleContentsPath = [[report.processInfo.processPath stringByDeletingLastPathComponent] stringByDeletingLastPathComponent];
if ([imagePath isEqual: report.processInfo.processPath] || [imagePath hasPrefix:appBundleContentsPath])
binaryDesignator = @"+"; binaryDesignator = @"+";
/* base_address - terminating_address [designator]file_name arch <uuid> file_path */ /* base_address - terminating_address [designator]file_name arch <uuid> file_path */
@ -470,11 +438,11 @@ static NSInteger binaryImageSort(id binary1, id binary2, void *context) {
* *
* @return Returns the formatted result on success, or nil if an error occurs. * @return Returns the formatted result on success, or nil if an error occurs.
*/ */
+ (NSArray *)arrayOfAppUUIDsForCrashReport:(PLCrashReport *)report { + (NSArray *)arrayOfAppUUIDsForCrashReport:(BITPLCrashReport *)report {
NSMutableArray* appUUIDs = [NSMutableArray array]; NSMutableArray* appUUIDs = [NSMutableArray array];
/* Images. The iPhone crash report format sorts these in ascending order, by the base address */ /* Images. The iPhone crash report format sorts these in ascending order, by the base address */
for (PLCrashReportBinaryImageInfo *imageInfo in [report.images sortedArrayUsingFunction: binaryImageSort context: nil]) { for (BITPLCrashReportBinaryImageInfo *imageInfo in [report.images sortedArrayUsingFunction: binaryImageSort context: nil]) {
NSString *uuid; NSString *uuid;
/* Fetch the UUID if it exists */ /* Fetch the UUID if it exists */
if (imageInfo.hasImageUUID) if (imageInfo.hasImageUUID)
@ -537,7 +505,7 @@ static NSInteger binaryImageSort(id binary1, id binary2, void *context) {
} }
if ([imagePath isEqual: report.processInfo.processPath] || [imagePath hasPrefix:appBundleContentsPath]) { if ([imagePath isEqual: report.processInfo.processPath] || [imagePath hasPrefix:appBundleContentsPath]) {
[appUUIDs addObject:[NSDictionary dictionaryWithObjectsAndKeys:uuid, kBITBinaryImageKeyUUID, archName, kBITBinaryImageKeyArch, imageType, kBITBinaryImageKeyType, nil]]; [appUUIDs addObject:@{kBITBinaryImageKeyUUID: uuid, kBITBinaryImageKeyArch: archName, kBITBinaryImageKeyType: imageType}];
} }
} }
@ -557,44 +525,32 @@ static NSInteger binaryImageSort(id binary1, id binary2, void *context) {
* @param frameInfo The stack frame to format * @param frameInfo The stack frame to format
* @param frameIndex The frame's index * @param frameIndex The frame's index
* @param report The report from which this frame was acquired. * @param report The report from which this frame was acquired.
* @param lp64 If YES, the report was generated by an LP64 system.
* *
* @return Returns a formatted frame line. * @return Returns a formatted frame line.
*/ */
+ (NSString *)formatStackFrame: (PLCrashReportStackFrameInfo *) frameInfo + (NSString *)formatStackFrame: (BITPLCrashReportStackFrameInfo *) frameInfo
frameIndex: (NSUInteger) frameIndex frameIndex: (NSUInteger) frameIndex
report: (PLCrashReport *) report report: (BITPLCrashReport *) report
lp64: (BOOL) lp64
{ {
/* Base image address containing instrumention pointer, offset of the IP from that base /* Base image address containing instrumention pointer, offset of the IP from that base
* address, and the associated image name */ * address, and the associated image name */
uint64_t baseAddress = 0x0; uint64_t baseAddress = 0x0;
uint64_t pcOffset = 0x0; uint64_t pcOffset = 0x0;
NSString *imageName = @"\?\?\?"; NSString *imageName = @"\?\?\?";
NSString *symbol = nil; NSString *symbolString = nil;
PLCrashReportBinaryImageInfo *imageInfo = [report imageForAddress: frameInfo.instructionPointer]; BITPLCrashReportBinaryImageInfo *imageInfo = [report imageForAddress: frameInfo.instructionPointer];
if (imageInfo != nil) { if (imageInfo != nil) {
imageName = [imageInfo.imageName lastPathComponent]; imageName = [imageInfo.imageName lastPathComponent];
baseAddress = imageInfo.imageBaseAddress; baseAddress = imageInfo.imageBaseAddress;
pcOffset = frameInfo.instructionPointer - imageInfo.imageBaseAddress; pcOffset = frameInfo.instructionPointer - imageInfo.imageBaseAddress;
NSString *imagePath = [imageInfo.imageName stringByStandardizingPath];
NSString *appBundleContentsPath = [[report.processInfo.processPath stringByDeletingLastPathComponent] stringByDeletingLastPathComponent];
if ([frameInfo respondsToSelector:@selector(symbolName)]) {
if (![imagePath isEqual: report.processInfo.processPath] && ![imagePath hasPrefix:appBundleContentsPath]) {
symbol = frameInfo.symbolName;
pcOffset = frameInfo.instructionPointer - frameInfo.symbolStart;
}
}
}
/* The frame has nothing useful, so return nil so it can be filtered out */
if (frameInfo.instructionPointer == 0 && baseAddress == 0 && pcOffset == 0) {
return nil;
} }
/* Make sure UTF8/16 characters are handled correctly */ /* Make sure UTF8/16 characters are handled correctly */
NSInteger offset = 0; NSInteger offset = 0;
NSUInteger index = 0; NSInteger index = 0;
for (index = 0; index < [imageName length]; index++) { for (index = 0; index < [imageName length]; index++) {
NSRange range = [imageName rangeOfComposedCharacterSequenceAtIndex:index]; NSRange range = [imageName rangeOfComposedCharacterSequenceAtIndex:index];
if (range.length > 1) { if (range.length > 1) {
@ -611,21 +567,62 @@ static NSInteger binaryImageSort(id binary1, id binary2, void *context) {
imageName = [imageName stringByPaddingToLength:36+offset withString:@" " startingAtIndex:0]; imageName = [imageName stringByPaddingToLength:36+offset withString:@" " startingAtIndex:0];
} }
if (symbol) { /* If symbol info is available, the format used in Apple's reports is Sym + OffsetFromSym. Otherwise,
return [NSString stringWithFormat: @"%-4ld%@0x%08" PRIx64 " %@ + %" PRId64 "\n", * the format used is imageBaseAddress + offsetToIP */
(long) frameIndex, NSString *imagePath = [imageInfo.imageName stringByStandardizingPath];
imageName, NSString *appBundleContentsPath = [[report.processInfo.processPath stringByDeletingLastPathComponent] stringByDeletingLastPathComponent];
frameInfo.instructionPointer,
symbol, if (frameInfo.symbolInfo != nil &&
pcOffset]; ![imagePath isEqual: report.processInfo.processPath] &&
} else { ![imagePath hasPrefix:appBundleContentsPath]) {
return [NSString stringWithFormat: @"%-4ld%@0x%08" PRIx64 " 0x%" PRIx64 " + %" PRId64 "\n", NSString *symbolName = frameInfo.symbolInfo.symbolName;
(long) frameIndex,
imageName, /* Apple strips the _ symbol prefix in their reports. Only OS X makes use of an
frameInfo.instructionPointer, * underscore symbol prefix by default. */
baseAddress, if ([symbolName rangeOfString: @"_"].location == 0 && [symbolName length] > 1) {
pcOffset]; switch (report.systemInfo.operatingSystem) {
case PLCrashReportOperatingSystemMacOSX:
case PLCrashReportOperatingSystemiPhoneOS:
case PLCrashReportOperatingSystemiPhoneSimulator:
symbolName = [symbolName substringFromIndex: 1];
break;
default:
NSLog(@"Symbol prefix rules are unknown for this OS!");
break;
} }
} }
uint64_t symOffset = frameInfo.instructionPointer - frameInfo.symbolInfo.startAddress;
symbolString = [NSString stringWithFormat: @"%@ + %" PRId64, symbolName, symOffset];
} else {
symbolString = [NSString stringWithFormat: @"0x%" PRIx64 " + %" PRId64, baseAddress, pcOffset];
}
/* Note that width specifiers are ignored for %@, but work for C strings.
* UTF-8 is not correctly handled with %s (it depends on the system encoding), but
* UTF-16 is supported via %S, so we use it here */
return [NSString stringWithFormat: @"%-4ld%-35S 0x%0*" PRIx64 " %@\n",
(long) frameIndex,
(const uint16_t *)[imageName cStringUsingEncoding: NSUTF16StringEncoding],
lp64 ? 16 : 8, frameInfo.instructionPointer,
symbolString];
}
/**
* Sort PLCrashReportBinaryImageInfo instances by their starting address.
*/
NSInteger binaryImageSort(id binary1, id binary2, void *context) {
uint64_t addr1 = [binary1 imageBaseAddress];
uint64_t addr2 = [binary2 imageBaseAddress];
if (addr1 < addr2)
return NSOrderedAscending;
else if (addr1 > addr2)
return NSOrderedDescending;
else
return NSOrderedSame;
}
@end @end

View File

@ -56,6 +56,8 @@
`BITUpdateManager`: Is automatically deactivated when the SDK detects it is running from a build distributed via the App Store. Otherwise if it is not deactivated manually, it will show an alert after startup informing the user about a pending update, if one is available. If the user then decides to view the update another screen is presented with further details and an option to install the update. `BITUpdateManager`: Is automatically deactivated when the SDK detects it is running from a build distributed via the App Store. Otherwise if it is not deactivated manually, it will show an alert after startup informing the user about a pending update, if one is available. If the user then decides to view the update another screen is presented with further details and an option to install the update.
`BITFeedbackManager`: If this module is deactivated or the user interface is nowhere added into the app, this module will not do anything. It will not fetch the server for data or show any user interface. If it is integrated, activated, and the user already used it to provide feedback, it will show an alert after startup if a new answer has been received from the server with the option to view it. `BITFeedbackManager`: If this module is deactivated or the user interface is nowhere added into the app, this module will not do anything. It will not fetch the server for data or show any user interface. If it is integrated, activated, and the user already used it to provide feedback, it will show an alert after startup if a new answer has been received from the server with the option to view it.
@warning The SDK is **NOT** thread safe and has to be set up on the main thread!
@warning You should **NOT** change any module configuration after calling `startManager`! @warning You should **NOT** change any module configuration after calling `startManager`!
Example: Example:

View File

@ -152,6 +152,8 @@
- (void)startManager { - (void)startManager {
if (!_validAppIdentifier) return; if (!_validAppIdentifier) return;
if (![self isSetUpOnMainThread]) return;
BITHockeyLog(@"INFO: Starting HockeyManager"); BITHockeyLog(@"INFO: Starting HockeyManager");
_startManagerIsInvoked = YES; _startManagerIsInvoked = YES;
@ -242,6 +244,22 @@
#pragma mark - Private Instance Methods #pragma mark - Private Instance Methods
- (BOOL)isSetUpOnMainThread {
NSString *errorString = @"ERROR: This SDK has to be setup on the main thread!";
if (!NSThread.isMainThread) {
if (self.isAppStoreEnvironment) {
BITHockeyLog(@"%@", errorString);
} else {
NSAssert(NSThread.isMainThread, errorString);
}
return NO;
}
return YES;
}
- (BOOL)shouldUseLiveIdentifier { - (BOOL)shouldUseLiveIdentifier {
BOOL delegateResult = NO; BOOL delegateResult = NO;
if ([_delegate respondsToSelector:@selector(shouldUseLiveIdentifierForHockeyManager:)]) { if ([_delegate respondsToSelector:@selector(shouldUseLiveIdentifierForHockeyManager:)]) {
@ -254,6 +272,8 @@
- (void)initializeModules { - (void)initializeModules {
_validAppIdentifier = [self checkValidityOfAppIdentifier:_appIdentifier]; _validAppIdentifier = [self checkValidityOfAppIdentifier:_appIdentifier];
if (![self isSetUpOnMainThread]) return;
_startManagerIsInvoked = NO; _startManagerIsInvoked = NO;
if (_validAppIdentifier) { if (_validAppIdentifier) {

View File

@ -32,6 +32,10 @@
#import <AvailabilityMacros.h> #import <AvailabilityMacros.h>
#endif #endif
// This must be included before any other PLCrashReporter includes, as
// it redefines symbol names
#import "PLCrashReporterNamespace.h"
#import "PLCrashReporter.h" #import "PLCrashReporter.h"
#import "PLCrashReport.h" #import "PLCrashReport.h"
#import "PLCrashReportTextFormatter.h" #import "PLCrashReportTextFormatter.h"
@ -227,3 +231,64 @@ typedef enum {
* *
* @sa PLCrashReporter::setCrashCallbacks: * @sa PLCrashReporter::setCrashCallbacks:
*/ */
/**
* @page mach_exceptions Mach Exceptions on iOS
*
* The APIs required for Mach exception handling are not fully public on iOS. Unfortunately, there are a number
* of crash states that can only be handled with Mach exception handlers:
*
* - Stack overflow. sigaltstack() is broken in later iOS releases, and even if functional, must be configured
* on a per-thread basis.
* - Internal Apple assertions that call libSystem's __assert. These include compiler-checked constraints
* for built-in functions, such as strcpy_chk(). The __abort() implementation actually disables the SIGABRT
* signal handler (resetting it to SIG_DFL) prior to to issueing a SIGABRT, bypassing signal-based crash
* reporters entirely.
*
* After filing a request with Apple DTS to clarify the status of the Mach exception APIs on iOS, and implementing
* a Mach Exception handler using only supported API, they provided the following guidance:
*
* Our engineers have reviewed your request and have determined that this would be best handled as a bug report,
* which you have already filed. <em>There is no documented way of accomplishing this, nor is there a workaround
* possible.</em>
*
* Due to user request, PLCrashReporter provides an optional implementation of Mach exception handling for both
* iOS and Mac OS X.
*
* This implementation uses only supported API on Mac OS X, and depends on limited private API on iOS. The reporter
* may be excluded entirely at build time by modifying the PLCRASH_FEATURE_MACH_EXCEPTIONS build configuration; it
* may also be disabled at runtime by configuring the PLCrashReporter instance appropriately (TODO - define
* configuration API).
*
* The iOS implementation is implemented almost entirely using public API, and links against no actual private API;
* the use of undocumented functionality is limited to assuming the use of specific msgh_id values (see below
* for details). As a result, it may be considered perfectly safe to include the Mach Exception code in the
* standard build, and enable/disable it at runtime.
*
* The following issues exist in the iOS implementation:
* - The msgh_id values required for an exception reply message are not available from the available
* headers and must be hard-coded. This prevents one from safely replying to exception messages, which
* means that it is impossible to (correctly) inform the server that an exception has *not* been
* handled.
*
* Impact:
* This can lead to the process locking up and not dispatching to the host exception handler (eg, Apple's
* crash reporter), depending on the behavior of the kernel exception code.
*
* - The mach_* structure/type variants required by MACH_EXCEPTION_CODES are not publicly defined (on Mac OS X,
* these are provided by mach_exc.defs). This prevents one from forwarding exception messages to an existing
* handler that was registered with a MACH_EXCEPTION_CODES behavior.
*
* Impact:
* This can break forwarding to any task exception handler that registers itself with MACH_EXCEPTION_CODES.
* This is the case with LLDB; it will register a task exception handler with MACH_EXCEPTION_CODES set. Failure
* to correctly forward these exceptions will result in the debugger breaking in interesting ways; for example,
* changes to the set of dyld-loaded images are detected by setting a breakpoint on the dyld image registration
* funtions, and this functionality will break if the exception is not correctly forwarded.
*
* Since Mach exception handling is important for a fully functional crash reporter, we have also filed a radar
* to request that the API be made public:
* Radar: rdar://12939497 RFE: Provide mach_exc.defs for iOS
*
* At the time of this writing, the radar remains open/unresolved.
*/

View File

@ -0,0 +1,58 @@
/*
* Author: Landon Fuller <landonf@plausiblelabs.com>
*
* Copyright (c) 2008-2009 Plausible Labs Cooperative, Inc.
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef PLCRASH_ASYNC_SIGNAL_INFO_H
#define PLCRASH_ASYNC_SIGNAL_INFO_H
#ifdef __cplusplus
extern "C" {
#endif
/**
* @internal
*
* @defgroup plcrash_async_signal_info Signal Information
* @ingroup plcrash_async
*
* Provides mapping of signal number and code to strings.
*
* @{
*/
const char *plcrash_async_signal_signame (int signal);
const char *plcrash_async_signal_sigcode (int signal, int si_code);
/**
* @} plcrash_async_signal_info
*/
#ifdef __cplusplus
}
#endif
#endif /* PLCRASH_ASYNC_SIGNAL_INFO_H */

View File

@ -1,7 +1,7 @@
/* /*
* Author: Landon Fuller <landonf@plausiblelabs.com> * Author: Landon Fuller <landonf@plausiblelabs.com>
* *
* Copyright (c) 2008-2010 Plausible Labs Cooperative, Inc. * Copyright (c) 2008-2013 Plausible Labs Cooperative, Inc.
* All rights reserved. * All rights reserved.
* *
* Permission is hereby granted, free of charge, to any person * Permission is hereby granted, free of charge, to any person
@ -27,15 +27,19 @@
*/ */
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import "PLCrashReportSystemInfo.h"
#import "PLCrashReportMachineInfo.h"
#import "PLCrashReportApplicationInfo.h" #import "PLCrashReportApplicationInfo.h"
#import "PLCrashReportProcessInfo.h"
#import "PLCrashReportSignalInfo.h"
#import "PLCrashReportThreadInfo.h"
#import "PLCrashReportBinaryImageInfo.h" #import "PLCrashReportBinaryImageInfo.h"
#import "PLCrashReportExceptionInfo.h" #import "PLCrashReportExceptionInfo.h"
#import "PLCrashReportReportInfo.h" #import "PLCrashReportMachineInfo.h"
#import "PLCrashReportProcessInfo.h"
#import "PLCrashReportProcessorInfo.h"
#import "PLCrashReportRegisterInfo.h"
#import "PLCrashReportSignalInfo.h"
#import "PLCrashReportStackFrameInfo.h"
#import "PLCrashReportSymbolInfo.h"
#import "PLCrashReportSystemInfo.h"
#import "PLCrashReportThreadInfo.h"
/** /**
* @ingroup constants * @ingroup constants
@ -80,9 +84,6 @@ typedef struct _PLCrashReportDecoder _PLCrashReportDecoder;
/** Private implementation variables (used to hide the underlying protobuf parser) */ /** Private implementation variables (used to hide the underlying protobuf parser) */
_PLCrashReportDecoder *_decoder; _PLCrashReportDecoder *_decoder;
/** Report info (may be nil) */
PLCrashReportReportInfo *_reportInfo;
/** System info */ /** System info */
PLCrashReportSystemInfo *_systemInfo; PLCrashReportSystemInfo *_systemInfo;
@ -106,6 +107,9 @@ typedef struct _PLCrashReportDecoder _PLCrashReportDecoder;
/** Exception information (may be nil) */ /** Exception information (may be nil) */
PLCrashReportExceptionInfo *_exceptionInfo; PLCrashReportExceptionInfo *_exceptionInfo;
/** Report UUID */
CFUUIDRef _uuid;
} }
- (id) initWithData: (NSData *) encodedData error: (NSError **) outError; - (id) initWithData: (NSData *) encodedData error: (NSError **) outError;
@ -171,13 +175,10 @@ typedef struct _PLCrashReportDecoder _PLCrashReportDecoder;
@property(nonatomic, readonly) PLCrashReportExceptionInfo *exceptionInfo; @property(nonatomic, readonly) PLCrashReportExceptionInfo *exceptionInfo;
/** /**
* YES if report information is available. * A client-generated 16-byte UUID. May be used to filter duplicate reports submitted or generated
* by a single client. Only available in later (v1.2+) crash report format versions. If not available,
* will be NULL.
*/ */
@property(nonatomic, readonly) BOOL hasReportInfo; @property(nonatomic, readonly) CFUUIDRef uuidRef;
/**
* Crash report information.
*/
@property(nonatomic, readonly) PLCrashReportReportInfo *reportInfo;
@end @end

View File

@ -1,7 +1,7 @@
/* /*
* Author: Landon Fuller <landonf@plausiblelabs.com> * Author: Landon Fuller <landonf@plausiblelabs.com>
* *
* Copyright (c) 2008-2012 Plausible Labs Cooperative, Inc. * Copyright (c) 2008-2009 Plausible Labs Cooperative, Inc.
* All rights reserved. * All rights reserved.
* *
* Permission is hereby granted, free of charge, to any person * Permission is hereby granted, free of charge, to any person
@ -35,18 +35,10 @@
/** Application version */ /** Application version */
NSString *_applicationVersion; NSString *_applicationVersion;
/** Application short version */
NSString *_applicationShortVersion;
/** Application startup timestamp */
NSDate *_applicationStartupTimestamp;
} }
- (id) initWithApplicationIdentifier: (NSString *) applicationIdentifier - (id) initWithApplicationIdentifier: (NSString *) applicationIdentifier
applicationVersion: (NSString *) applicationVersion applicationVersion: (NSString *) applicationVersion;
applicationShortVersion: (NSString *) applicationShortVersion
applicationStartupTimestamp: (NSDate *) applicationStartupTimestamp;
/** /**
* The application identifier. This is usually the application's CFBundleIdentifier value. * The application identifier. This is usually the application's CFBundleIdentifier value.
@ -58,14 +50,4 @@
*/ */
@property(nonatomic, readonly) NSString *applicationVersion; @property(nonatomic, readonly) NSString *applicationVersion;
/**
* The application short version. This is usually the application's CFBundleShortVersionString value.
*/
@property(nonatomic, readonly) NSString *applicationShortVersion;
/**
* The application startup timestamp. This is set when initializing the crash reporter.
*/
@property(nonatomic, readonly) NSDate *applicationStartupTimestamp;
@end @end

View File

@ -1,7 +1,7 @@
/* /*
* Author: Landon Fuller <landonf@plausiblelabs.com> * Author: Landon Fuller <landonf@plausiblelabs.com>
* *
* Copyright (c) 2008-2010 Plausible Labs Cooperative, Inc. * Copyright (c) 2008-2013 Plausible Labs Cooperative, Inc.
* All rights reserved. * All rights reserved.
* *
* Permission is hereby granted, free of charge, to any person * Permission is hereby granted, free of charge, to any person

View File

@ -1,7 +1,7 @@
/* /*
* Author: Landon Fuller <landonf@plausible.coop> * Author: Landon Fuller <landonf@plausible.coop>
* *
* Copyright (c) 2008-2011 Plausible Labs Cooperative, Inc. * Copyright (c) 2008-2013 Plausible Labs Cooperative, Inc.
* All rights reserved. * All rights reserved.
* *
* Permission is hereby granted, free of charge, to any person * Permission is hereby granted, free of charge, to any person
@ -53,7 +53,7 @@
/** The hardware model name (eg, MacBookPro6,1). This may be unavailable, and this property will be nil. */ /** The hardware model name (eg, MacBookPro6,1). This may be unavailable, and this property will be nil. */
@property(nonatomic, readonly) NSString *modelName; @property(nonatomic, readonly) NSString *modelName;
/** The processor type. */ /** The processor type. This will be unavailable in reports generated prior to PLCrashReporter 1.2, in which case this property will be nil. */
@property(nonatomic, readonly) PLCrashReportProcessorInfo *processorInfo; @property(nonatomic, readonly) PLCrashReportProcessorInfo *processorInfo;
/* /*

View File

@ -2,7 +2,7 @@
* Author: Damian Morris <damian@moso.com.au> * Author: Damian Morris <damian@moso.com.au>
* *
* Copyright (c) 2010 MOSO Corporation, Pty Ltd. * Copyright (c) 2010 MOSO Corporation, Pty Ltd.
* Copyright (c) 2010 Plausible Labs Cooperative, Inc. * Copyright (c) 2010-2013 Plausible Labs Cooperative, Inc.
* *
* All rights reserved. * All rights reserved.
* *
@ -41,6 +41,10 @@
/** Process path */ /** Process path */
NSString* _processPath; NSString* _processPath;
/** Date and time that the crashing process was started. This may be unavailable, and this property
* will be nil. */
NSDate *_processStartTime;
/** Parent process name */ /** Parent process name */
NSString *_parentProcessName; NSString *_parentProcessName;
@ -54,6 +58,7 @@
- (id) initWithProcessName: (NSString *) processName - (id) initWithProcessName: (NSString *) processName
processID: (NSUInteger) processID processID: (NSUInteger) processID
processPath: (NSString *) processPath processPath: (NSString *) processPath
processStartTime: (NSDate *) processStartTime
parentProcessName: (NSString *) parentProcessName parentProcessName: (NSString *) parentProcessName
parentProcessID: (NSUInteger) parentProcessID parentProcessID: (NSUInteger) parentProcessID
native: (BOOL) native; native: (BOOL) native;
@ -75,6 +80,12 @@
*/ */
@property(nonatomic, readonly) NSString *processPath; @property(nonatomic, readonly) NSString *processPath;
/**
* Date and time that the crashing process was started. This value may not be included in the crash report, in which case this property
* will be nil.
*/
@property(nonatomic, readonly) NSDate *processStartTime;
/** /**
* The parent process name. This value may not be included in the crash report, in which case this property * The parent process name. This value may not be included in the crash report, in which case this property
* will be nil. * will be nil.

View File

@ -1,7 +1,7 @@
/* /*
* Author: Landon Fuller <landonf@plausible.coop> * Author: Landon Fuller <landonf@plausible.coop>
* *
* Copyright (c) 2008-2011 Plausible Labs Cooperative, Inc. * Copyright (c) 2008-2013 Plausible Labs Cooperative, Inc.
* All rights reserved. * All rights reserved.
* *
* Permission is hereby granted, free of charge, to any person * Permission is hereby granted, free of charge, to any person

View File

@ -1,8 +1,7 @@
/* /*
* Author: Andreas Linde <mail@andreaslinde.de> * Author: Landon Fuller <landonf@plausible.coop>
* *
* Copyright (c) 2012 Plausible Labs Cooperative, Inc. * Copyright (c) 2008-2013 Plausible Labs Cooperative, Inc.
* Copyright (c) 2012 Andreas Linde
* All rights reserved. * All rights reserved.
* *
* Permission is hereby granted, free of charge, to any person * Permission is hereby granted, free of charge, to any person
@ -29,17 +28,25 @@
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
@interface PLCrashReportReportInfo : NSObject { @interface PLCrashReportRegisterInfo : NSObject {
@private @private
/** Crash Report GUID */ /** Register name */
NSString *_reportGUID; NSString *_registerName;
/** Register value */
uint64_t _registerValue;
} }
- (id) initWithReportGUID: (NSString *) reportGUID; - (id) initWithRegisterName: (NSString *) registerName registerValue: (uint64_t) registerValue;
/** /**
* The crash report GUID. * Register name.
*/ */
@property(nonatomic, readonly) NSString *reportGUID; @property(nonatomic, readonly) NSString *registerName;
/**
* Register value.
*/
@property(nonatomic, readonly) uint64_t registerValue;
@end @end

View File

@ -0,0 +1,52 @@
/*
* Author: Landon Fuller <landonf@plausible.coop>
*
* Copyright (c) 2008-2013 Plausible Labs Cooperative, Inc.
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#import <Foundation/Foundation.h>
#import "PLCrashReportSymbolInfo.h"
@interface PLCrashReportStackFrameInfo : NSObject {
@private
/** Frame instruction pointer. */
uint64_t _instructionPointer;
/** Symbol information, if available. Otherwise, will be nil. */
PLCrashReportSymbolInfo *_symbolInfo;
}
- (id) initWithInstructionPointer: (uint64_t) instructionPointer symbolInfo: (PLCrashReportSymbolInfo *) symbolInfo;
/**
* Frame's instruction pointer.
*/
@property(nonatomic, readonly) uint64_t instructionPointer;
/** Symbol information for this frame.
* This may be unavailable, and this property will be nil. */
@property(nonatomic, readonly) PLCrashReportSymbolInfo *symbolInfo;
@end

View File

@ -0,0 +1,61 @@
/*
* Author: Landon Fuller <landonf@plausible.coop>
*
* Copyright (c) 2012-2013 Plausible Labs Cooperative, Inc.
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#import <Foundation/Foundation.h>
@interface PLCrashReportSymbolInfo : NSObject {
@private
/** The symbol name. */
NSString *_symbolName;
/** The symbol start address. */
uint64_t _startAddress;
/** The symbol end address, if explicitly defined. Will be 0 if unknown. */
uint64_t _endAddress;
}
- (id) initWithSymbolName: (NSString *) symbolName
startAddress: (uint64_t) startAddress
endAddress: (uint64_t) endAddress;
/** The symbol name. */
@property(nonatomic, readonly) NSString *symbolName;
/** The symbol start address. */
@property(nonatomic, readonly) uint64_t startAddress;
/* The symbol end address, if explicitly defined. This will only be included if the end address is
* explicitly defined (eg, by DWARF debugging information), will not be derived by best-guess
* heuristics.
*
* If unknown, the address will be 0.
*/
@property(nonatomic, readonly) uint64_t endAddress;
@end

View File

@ -73,7 +73,8 @@ typedef enum {
/** /**
* ARMv6 * ARMv6
* @deprecated * @deprecated This value has been deprecated in favor of ARM subtype-specific
* values.
* @sa PLCrashReportArchitectureARMv6 * @sa PLCrashReportArchitectureARMv6
*/ */
PLCrashReportArchitectureARM = PLCrashReportArchitectureARMv6, PLCrashReportArchitectureARM = PLCrashReportArchitectureARMv6,
@ -87,11 +88,8 @@ typedef enum {
/** ARMv7 */ /** ARMv7 */
PLCrashReportArchitectureARMv7 = 5, PLCrashReportArchitectureARMv7 = 5,
/** ARMv7s */
PLCrashReportArchitectureARMv7s = 6,
/** Unknown */ /** Unknown */
PLCrashReportArchitectureUnknown = 7 PLCrashReportArchitectureUnknown = 6
} PLCrashReportArchitecture; } PLCrashReportArchitecture;
@ -136,7 +134,9 @@ extern PLCrashReportArchitecture PLCrashReportHostArchitecture;
/** The operating system's build identifier (eg, 10J869). This may be unavailable, and this property will be nil. */ /** The operating system's build identifier (eg, 10J869). This may be unavailable, and this property will be nil. */
@property(nonatomic, readonly) NSString *operatingSystemBuild; @property(nonatomic, readonly) NSString *operatingSystemBuild;
/** Architecture. */ /** Architecture. @deprecated The architecture value has been deprecated in v1.1 and later crash reports. All new reports
* include the CPU type as part of the crash report's machine info structure, using the PLCrashReportProcessorInfo
* extensible encoding. */
@property(nonatomic, readonly) PLCrashReportArchitecture architecture; @property(nonatomic, readonly) PLCrashReportArchitecture architecture;
/** Date and time that the crash report was generated. This may be unavailable, and this property will be nil. */ /** Date and time that the crash report was generated. This may be unavailable, and this property will be nil. */

View File

@ -3,7 +3,7 @@
* Landon Fuller <landonf@plausiblelabs.com> * Landon Fuller <landonf@plausiblelabs.com>
* Damian Morris <damian@moso.com.au> * Damian Morris <damian@moso.com.au>
* *
* Copyright (c) 2008-2010 Plausible Labs Cooperative, Inc. * Copyright (c) 2008-2013 Plausible Labs Cooperative, Inc.
* Copyright (c) 2010 MOSO Corporation, Pty Ltd. * Copyright (c) 2010 MOSO Corporation, Pty Ltd.
* All rights reserved. * All rights reserved.
* *

View File

@ -28,61 +28,8 @@
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
@interface PLCrashReportStackFrameInfo : NSObject { #import "PLCrashReportStackFrameInfo.h"
@private #import "PLCrashReportRegisterInfo.h"
/** Frame instruction pointer. */
uint64_t _instructionPointer;
/** Symbol start address, if any. */
uint64_t _symbolStart;
/** Symbol name, if any. */
NSString *_symbolName;
}
- (id) initWithInstructionPointer: (uint64_t) instructionPointer symbolStart: (uint64_t) symbolStart symbolName: (NSString *) symbolName;
/**
* Frame's instruction pointer.
*/
@property(nonatomic, readonly) uint64_t instructionPointer;
/**
* Frame's symbol address, if determined, otherwise 0.
*/
@property(nonatomic, readonly) uint64_t symbolStart;
/**
* Frame's symbol name, if determined, otherwise 0.
*/
@property(nonatomic, readonly) NSString *symbolName;
@end
@interface PLCrashReportRegisterInfo : NSObject {
@private
/** Register name */
NSString *_registerName;
/** Register value */
uint64_t _registerValue;
}
- (id) initWithRegisterName: (NSString *) registerName registerValue: (uint64_t) registerValue;
/**
* Register name.
*/
@property(nonatomic, readonly) NSString *registerName;
/**
* Register value.
*/
@property(nonatomic, readonly) uint64_t registerValue;
@end
@interface PLCrashReportThreadInfo : NSObject { @interface PLCrashReportThreadInfo : NSObject {
@private @private

View File

@ -27,6 +27,7 @@
*/ */
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import <mach/mach.h>
/** /**
* @ingroup functions * @ingroup functions
@ -75,15 +76,6 @@ typedef struct PLCrashReporterCallbacks {
/** Application version */ /** Application version */
NSString *_applicationVersion; NSString *_applicationVersion;
/** Application short version */
NSString *_applicationShortVersion;
/** Application startup timestamp */
time_t _applicationStartupTimestamp;
/** GUID for the crash report */
NSString *_crashReportGUID;
/** Path to the crash reporter internal data directory */ /** Path to the crash reporter internal data directory */
NSString *_crashReportDirectory; NSString *_crashReportDirectory;
} }
@ -95,6 +87,12 @@ typedef struct PLCrashReporterCallbacks {
- (NSData *) loadPendingCrashReportData; - (NSData *) loadPendingCrashReportData;
- (NSData *) loadPendingCrashReportDataAndReturnError: (NSError **) outError; - (NSData *) loadPendingCrashReportDataAndReturnError: (NSError **) outError;
- (NSData *) generateLiveReportWithThread: (thread_t) thread;
- (NSData *) generateLiveReportWithThread: (thread_t) thread error: (NSError **) outError;
- (NSData *) generateLiveReport;
- (NSData *) generateLiveReportAndReturnError: (NSError **) outError;
- (BOOL) purgePendingCrashReport; - (BOOL) purgePendingCrashReport;
- (BOOL) purgePendingCrashReportAndReturnError: (NSError **) outError; - (BOOL) purgePendingCrashReportAndReturnError: (NSError **) outError;

View File

@ -0,0 +1,70 @@
/*
* Author: Landon Fuller <landonf@plausible.coop>
*
* Copyright (c) 2012-2013 Plausible Labs Cooperative, Inc.
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
/*
* For external library integrators:
*
* Set this value to any valid C symbol prefix. This will automatically
* prepend the given prefix to all external symbols in the library.
*
* This may be used to avoid symbol conflicts between multiple libraries
* that may both incorporate PLCrashReporter.
*/
#define PLCRASHREPORTER_PREFIX BIT
#ifdef PLCRASHREPORTER_PREFIX
// We need two extra layers of indirection to make CPP substitute
// the PLCRASHREPORTER_PREFIX define.
#define PLNS_impl2(prefix, symbol) prefix ## symbol
#define PLNS_impl(prefix, symbol) PLNS_impl2(prefix, symbol)
#define PLNS(symbol) PLNS_impl(PLCRASHREPORTER_PREFIX, symbol)
#define PLCrashMachExceptionServer PLNS(PLCrashMachExceptionServer)
#define PLCrashReport PLNS(PLCrashReport)
#define PLCrashReportApplicationInfo PLNS(PLCrashReportApplicationInfo)
#define PLCrashReportBinaryImageInfo PLNS(PLCrashReportBinaryImageInfo)
#define PLCrashReportExceptionInfo PLNS(PLCrashReportExceptionInfo)
#define PLCrashReportMachineInfo PLNS(PLCrashReportMachineInfo)
#define PLCrashReportProcessInfo PLNS(PLCrashReportProcessInfo)
#define PLCrashReportProcessorInfo PLNS(PLCrashReportProcessorInfo)
#define PLCrashReportRegisterInfo PLNS(PLCrashReportRegisterInfo)
#define PLCrashReportSignalInfo PLNS(PLCrashReportSignalInfo)
#define PLCrashReportStackFrameInfo PLNS(PLCrashReportStackFrameInfo)
#define PLCrashReportSymbolInfo PLNS(PLCrashReportSymbolInfo)
#define PLCrashReportSystemInfo PLNS(PLCrashReportSystemInfo)
#define PLCrashReportTextFormatter PLNS(PLCrashReportTextFormatter)
#define PLCrashReportThreadInfo PLNS(PLCrashReportThreadInfo)
#define PLCrashReporter PLNS(PLCrashReporter)
#define PLCrashSignalHandler PLNS(PLCrashSignalHandler)
#define PLCrashReportHostArchitecture PLNS(PLCrashReportHostArchitecture)
#define PLCrashReportHostOperatingSystem PLNS(PLCrashReportHostOperatingSystem)
#define PLCrashReporterErrorDomain PLNS(PLCrashReporterErrorDomain)
#define PLCrashReporterException PLNS(PLCrashReporterException)
#endif

View File

@ -3,7 +3,7 @@
<plist version="1.0"> <plist version="1.0">
<dict> <dict>
<key>BuildMachineOSBuild</key> <key>BuildMachineOSBuild</key>
<string>12C54</string> <string>12E55</string>
<key>CFBundleDevelopmentRegion</key> <key>CFBundleDevelopmentRegion</key>
<string>English</string> <string>English</string>
<key>CFBundleExecutable</key> <key>CFBundleExecutable</key>
@ -19,20 +19,20 @@
<key>CFBundleSignature</key> <key>CFBundleSignature</key>
<string>????</string> <string>????</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>1.2-beta2</string> <string>1.0</string>
<key>DTCompiler</key> <key>DTCompiler</key>
<string></string> <string></string>
<key>DTPlatformBuild</key> <key>DTPlatformBuild</key>
<string>4G182</string> <string>4H1503</string>
<key>DTPlatformVersion</key> <key>DTPlatformVersion</key>
<string>GM</string> <string>GM</string>
<key>DTSDKBuild</key> <key>DTSDKBuild</key>
<string>12C37</string> <string>12D75</string>
<key>DTSDKName</key> <key>DTSDKName</key>
<string>macosx10.8</string> <string>macosx10.8</string>
<key>DTXcode</key> <key>DTXcode</key>
<string>0450</string> <string>0463</string>
<key>DTXcodeBuild</key> <key>DTXcodeBuild</key>
<string>4G182</string> <string>4H1503</string>
</dict> </dict>
</plist> </plist>