Add more info to error report
This commit is contained in:
Родитель
8fc50baa80
Коммит
516c2cb125
|
@ -135,4 +135,8 @@
|
|||
[coder encodeObject:self.appNamespace forKey:kMSACAppNamespace];
|
||||
}
|
||||
|
||||
- (NSString *)description {
|
||||
return [NSString stringWithFormat:@"%@", [self serializeToDictionary]];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -95,4 +95,9 @@
|
|||
*/
|
||||
@property(nonatomic) MSACExceptionModel *exception;
|
||||
|
||||
/**
|
||||
* Is current CPU type encoding known.
|
||||
*/
|
||||
@property(nonatomic) BOOL isKnownEncodingType;
|
||||
|
||||
@end
|
||||
|
|
|
@ -95,4 +95,8 @@ static NSString *const kMSACArchitectureVariantId = @"architectureVariantId";
|
|||
[coder encodeObject:self.architectureVariantId forKey:kMSACArchitectureVariantId];
|
||||
}
|
||||
|
||||
- (NSString *)description {
|
||||
return [NSString stringWithFormat:@"%@", [self serializeToDictionary]];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
|
||||
static NSString *const kMSACErrorReportKillSignal = @"SIGKILL";
|
||||
|
||||
@class MSACThread, MSACBinary;
|
||||
|
||||
@interface MSACErrorReport ()
|
||||
|
||||
- (instancetype)initWithErrorId:(NSString *)errorId
|
||||
|
@ -14,6 +16,11 @@ static NSString *const kMSACErrorReportKillSignal = @"SIGKILL";
|
|||
exceptionReason:(NSString *)exceptionReason
|
||||
appStartTime:(NSDate *)appStartTime
|
||||
appErrorTime:(NSDate *)appErrorTime
|
||||
codeType:(NSString *)codeType
|
||||
archName:(NSString *)archName
|
||||
applicationPath:(NSString *)applicationPath
|
||||
threads:(NSArray<MSACThread *> *)threads
|
||||
binaries:(NSArray<MSACBinary *> *)binaries
|
||||
device:(MSACDevice *)device
|
||||
appProcessIdentifier:(NSUInteger)appProcessIdentifier;
|
||||
|
||||
|
|
|
@ -80,4 +80,8 @@ static NSString *const kMSACException = @"exception";
|
|||
[coder encodeObject:self.exception forKey:kMSACException];
|
||||
}
|
||||
|
||||
- (NSString *)description {
|
||||
return [NSString stringWithFormat:@"%@", [self serializeToDictionary]];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -230,8 +230,10 @@ static const char *findSEL(const char *imageName, NSString *imageUUID, uint64_t
|
|||
// CPU Type and Subtype for the crash. We need to query the binary images for that.
|
||||
uint64_t type = report.machineInfo.processorInfo.type;
|
||||
uint64_t subtype = report.machineInfo.processorInfo.subtype;
|
||||
BOOL isKnownEncodingType = NO;
|
||||
for (PLCrashReportBinaryImageInfo *image in report.images) {
|
||||
if (image.codeType != nil && image.codeType.typeEncoding == PLCrashReportProcessorTypeEncodingMach) {
|
||||
isKnownEncodingType = image.codeType.typeEncoding == PLCrashReportProcessorTypeEncodingMach;
|
||||
if (image.codeType != nil && isKnownEncodingType) {
|
||||
type = image.codeType.type;
|
||||
subtype = image.codeType.subtype;
|
||||
break;
|
||||
|
@ -240,6 +242,7 @@ static const char *findSEL(const char *imageName, NSString *imageUUID, uint64_t
|
|||
BOOL is64bit = [self isCodeType64bit:type];
|
||||
errorLog.primaryArchitectureId = @(type);
|
||||
errorLog.architectureVariantId = @(subtype);
|
||||
errorLog.isKnownEncodingType = isKnownEncodingType;
|
||||
|
||||
/*
|
||||
* errorLog.architecture is an optional. The Android SDK will set it while for
|
||||
|
@ -312,6 +315,20 @@ static const char *findSEL(const char *imageName, NSString *imageUUID, uint64_t
|
|||
NSString *exceptionName = errorLog.exceptionType;
|
||||
NSDate *appStartTime = errorLog.appLaunchTimestamp;
|
||||
NSDate *appErrorTime = errorLog.timestamp;
|
||||
NSString *codeType = unknownString;
|
||||
NSString *archName = unknownString;
|
||||
if (errorLog.primaryArchitectureId != nil) {
|
||||
codeType = [self convertCodeTypeToString:errorLog.primaryArchitectureId.longValue typeEncode:errorLog.isKnownEncodingType];
|
||||
if (errorLog.architectureVariantId != nil) {
|
||||
archName = [self convertArchNameToString:errorLog.primaryArchitectureId.longValue
|
||||
subtype:errorLog.architectureVariantId.intValue
|
||||
typeEncode:errorLog.isKnownEncodingType];
|
||||
}
|
||||
}
|
||||
|
||||
NSString *applicationPath = errorLog.applicationPath;
|
||||
NSArray<MSACThread *> *threads = errorLog.threads;
|
||||
NSArray<MSACBinary *> *binaries = errorLog.binaries;
|
||||
|
||||
// Retrieve the process' id.
|
||||
NSUInteger processId = [errorLog.processId unsignedIntegerValue];
|
||||
|
@ -324,6 +341,11 @@ static const char *findSEL(const char *imageName, NSString *imageUUID, uint64_t
|
|||
exceptionReason:exceptionReason
|
||||
appStartTime:appStartTime
|
||||
appErrorTime:appErrorTime
|
||||
codeType:codeType
|
||||
archName:archName
|
||||
applicationPath:applicationPath
|
||||
threads:threads
|
||||
binaries:binaries
|
||||
device:errorLog.device
|
||||
appProcessIdentifier:processId];
|
||||
|
||||
|
@ -373,6 +395,107 @@ static const char *findSEL(const char *imageName, NSString *imageUUID, uint64_t
|
|||
return errorLog;
|
||||
}
|
||||
|
||||
+ (NSString *)convertArchNameToString:(long)type subtype:(int)subtype typeEncode:(BOOL)isKnownEncodingType {
|
||||
NSString *archName = @"???";
|
||||
if (isKnownEncodingType) {
|
||||
switch (type) {
|
||||
case CPU_TYPE_ARM:
|
||||
switch (subtype & ~CPU_SUBTYPE_MASK) {
|
||||
case CPU_SUBTYPE_ARM_V6:
|
||||
archName = @"armv6";
|
||||
break;
|
||||
|
||||
case CPU_SUBTYPE_ARM_V7:
|
||||
archName = @"armv7";
|
||||
break;
|
||||
|
||||
case CPU_SUBTYPE_ARM_V7S:
|
||||
archName = @"armv7s";
|
||||
break;
|
||||
|
||||
default:
|
||||
archName = @"arm-unknown";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case CPU_TYPE_ARM64:
|
||||
/* Apple includes subtype for ARM64 binaries. */
|
||||
switch (subtype & ~CPU_SUBTYPE_MASK) {
|
||||
case CPU_SUBTYPE_ARM64_ALL:
|
||||
archName = @"arm64";
|
||||
break;
|
||||
|
||||
case CPU_SUBTYPE_ARM64_V8:
|
||||
archName = @"armv8";
|
||||
break;
|
||||
|
||||
case CPU_SUBTYPE_ARM64E:
|
||||
archName = @"arm64e";
|
||||
break;
|
||||
|
||||
default:
|
||||
archName = @"arm64-unknown";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case CPU_TYPE_X86:
|
||||
archName = @"i386";
|
||||
break;
|
||||
|
||||
case CPU_TYPE_X86_64:
|
||||
archName = @"x86_64";
|
||||
break;
|
||||
|
||||
case CPU_TYPE_POWERPC:
|
||||
archName = @"powerpc";
|
||||
break;
|
||||
|
||||
default:
|
||||
// Use the default archName value (initialized above).
|
||||
break;
|
||||
}
|
||||
}
|
||||
return archName;
|
||||
}
|
||||
|
||||
+ (NSString *)convertCodeTypeToString:(long)type typeEncode:(BOOL)isKnownEncodingType {
|
||||
|
||||
NSString *codeType = nil;
|
||||
if (isKnownEncodingType) {
|
||||
switch (type) {
|
||||
case CPU_TYPE_ARM:
|
||||
codeType = @"ARM";
|
||||
break;
|
||||
|
||||
case CPU_TYPE_ARM64:
|
||||
codeType = @"ARM-64";
|
||||
break;
|
||||
|
||||
case CPU_TYPE_X86:
|
||||
codeType = @"X86";
|
||||
break;
|
||||
|
||||
case CPU_TYPE_X86_64:
|
||||
codeType = @"X86-64";
|
||||
break;
|
||||
|
||||
case CPU_TYPE_POWERPC:
|
||||
codeType = @"PPC";
|
||||
break;
|
||||
|
||||
default:
|
||||
codeType = [NSString stringWithFormat:@"Unknown (%lu)", type];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (codeType == nil) {
|
||||
codeType = @"Unknown";
|
||||
}
|
||||
return codeType;
|
||||
}
|
||||
|
||||
+ (NSDate *)getAppLaunchTimeFromReport:(PLCrashReport *)report {
|
||||
return report.processInfo ? report.processInfo.processStartTime : report.systemInfo.timestamp;
|
||||
}
|
||||
|
|
|
@ -1420,6 +1420,11 @@ __attribute__((noreturn)) static void uncaught_cxx_exception_handler(const MSACC
|
|||
exceptionReason:nil
|
||||
appStartTime:self.appStartTime
|
||||
appErrorTime:[NSDate date]
|
||||
codeType:nil
|
||||
archName:nil
|
||||
applicationPath:nil
|
||||
threads:nil
|
||||
binaries:nil
|
||||
device:[[MSACDeviceTracker sharedInstance] device]
|
||||
appProcessIdentifier:0];
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@class MSACDevice;
|
||||
@class MSACThread, MSACBinary, MSACDevice;
|
||||
|
||||
NS_SWIFT_NAME(ErrorReport)
|
||||
@interface MSACErrorReport : NSObject
|
||||
|
@ -43,6 +43,31 @@ NS_SWIFT_NAME(ErrorReport)
|
|||
*/
|
||||
@property(nonatomic, readonly, strong) NSDate *appErrorTime;
|
||||
|
||||
/**
|
||||
* CPU architecture variant.
|
||||
*/
|
||||
@property(nonatomic) NSString *archName;
|
||||
|
||||
/**
|
||||
* CPU primary architecture.
|
||||
*/
|
||||
@property(nonatomic) NSString *codeType;
|
||||
|
||||
/**
|
||||
* Path to the application.
|
||||
*/
|
||||
@property(nonatomic, copy) NSString *applicationPath;
|
||||
|
||||
/**
|
||||
* Thread stack frames associated to the error.
|
||||
*/
|
||||
@property(nonatomic) NSArray<MSACThread *> *threads;
|
||||
|
||||
/**
|
||||
* Binaries associated to the error.
|
||||
*/
|
||||
@property(nonatomic) NSArray<MSACBinary *> *binaries;
|
||||
|
||||
/**
|
||||
* Device information of the app when it crashed.
|
||||
*/
|
||||
|
|
|
@ -4,6 +4,21 @@
|
|||
#import "MSACErrorReport.h"
|
||||
#import "MSACErrorReportPrivate.h"
|
||||
|
||||
static NSString *const kMSACIncidentIdentifier = @"incidentIdentifier";
|
||||
static NSString *const kMSACReporterKey = @"reporterKey";
|
||||
static NSString *const kMSACSignal = @"signal";
|
||||
static NSString *const kMSACExceptionName = @"exceptionName";
|
||||
static NSString *const kMSACExceptionReason = @"exceptionReason";
|
||||
static NSString *const kMSACAppStartTime = @"appStartTime";
|
||||
static NSString *const kMSACAppErrorTime = @"appErrorTime";
|
||||
static NSString *const kMSACDevice = @"device";
|
||||
static NSString *const kMSACThreads = @"threads";
|
||||
static NSString *const kMSACBinaries = @"binaries";
|
||||
static NSString *const kMSACArchName = @"archName";
|
||||
static NSString *const kMSACCodeType = @"codeType";
|
||||
static NSString *const kMSACApplicationPath = @"applicationPath";
|
||||
static NSString *const kMSACAppProcessIdentifier = @"appProcessIdentifier";
|
||||
|
||||
@interface MSACErrorReport ()
|
||||
|
||||
@property(nonatomic, copy) NSString *signal;
|
||||
|
@ -19,6 +34,11 @@
|
|||
exceptionReason:(NSString *)exceptionReason
|
||||
appStartTime:(NSDate *)appStartTime
|
||||
appErrorTime:(NSDate *)appErrorTime
|
||||
codeType:(NSString *)codeType
|
||||
archName:(NSString *)archName
|
||||
applicationPath:(NSString *)applicationPath
|
||||
threads:(NSArray<MSACThread *> *)threads
|
||||
binaries:(NSArray<MSACBinary *> *)binaries
|
||||
device:(MSACDevice *)device
|
||||
appProcessIdentifier:(NSUInteger)appProcessIdentifier {
|
||||
|
||||
|
@ -30,6 +50,11 @@
|
|||
_exceptionReason = exceptionReason;
|
||||
_appStartTime = appStartTime;
|
||||
_appErrorTime = appErrorTime;
|
||||
_codeType = codeType;
|
||||
_archName = archName;
|
||||
_applicationPath = applicationPath;
|
||||
_threads = threads;
|
||||
_binaries = binaries;
|
||||
_device = device;
|
||||
_appProcessIdentifier = appProcessIdentifier;
|
||||
}
|
||||
|
@ -45,4 +70,55 @@
|
|||
return result;
|
||||
}
|
||||
|
||||
- (NSMutableDictionary *)serializeToDictionary {
|
||||
NSMutableDictionary *dict = [NSMutableDictionary new];
|
||||
if (self.incidentIdentifier) {
|
||||
dict[kMSACIncidentIdentifier] = self.incidentIdentifier;
|
||||
}
|
||||
if (self.reporterKey) {
|
||||
dict[kMSACReporterKey] = self.reporterKey;
|
||||
}
|
||||
if (self.signal) {
|
||||
dict[kMSACSignal] = self.signal;
|
||||
}
|
||||
if (self.exceptionName) {
|
||||
dict[kMSACExceptionName] = self.exceptionName;
|
||||
}
|
||||
if (self.exceptionReason) {
|
||||
dict[kMSACExceptionReason] = self.exceptionReason;
|
||||
}
|
||||
if (self.appStartTime) {
|
||||
dict[kMSACAppStartTime] = self.appStartTime;
|
||||
}
|
||||
if (self.appErrorTime) {
|
||||
dict[kMSACAppErrorTime] = self.appErrorTime;
|
||||
}
|
||||
if (self.codeType) {
|
||||
dict[kMSACCodeType] = self.codeType;
|
||||
}
|
||||
if (self.archName) {
|
||||
dict[kMSACArchName] = self.archName;
|
||||
}
|
||||
if (self.applicationPath) {
|
||||
dict[kMSACApplicationPath] = self.applicationPath;
|
||||
}
|
||||
if (self.threads) {
|
||||
dict[kMSACThreads] = self.threads;
|
||||
}
|
||||
if (self.binaries) {
|
||||
dict[kMSACBinaries] = self.binaries;
|
||||
}
|
||||
if (self.device) {
|
||||
dict[kMSACDevice] = self.device;
|
||||
}
|
||||
if (self.appProcessIdentifier) {
|
||||
dict[kMSACAppProcessIdentifier] = [NSString stringWithFormat:@"%lu",(unsigned long) self.appProcessIdentifier];
|
||||
}
|
||||
return dict;
|
||||
}
|
||||
|
||||
- (NSString *)description {
|
||||
return [NSString stringWithFormat:@"%@", [self serializeToDictionary]];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
Загрузка…
Ссылка в новой задаче