From 074695697b14d9d625acb9b62fdd0d74f9173da0 Mon Sep 17 00:00:00 2001 From: Guillermo Ignacio Enriquez Gutierrez Date: Wed, 18 Aug 2021 11:44:31 +0900 Subject: [PATCH 1/2] KSCrashReportFilterAppleFmt now shows correct architecture for arm64e. Various minor aesthetics changes to resemble better Apple crash reports as Xcode12. --- .../Monitors/KSCrashMonitor_System.m | 4 - .../Filters/KSCrashReportFilterAppleFmt.m | 95 +++++++++++++------ .../Sinks/KSCrashReportSinkQuincyHockey.m | 6 +- 3 files changed, 70 insertions(+), 35 deletions(-) diff --git a/Source/KSCrash/Recording/Monitors/KSCrashMonitor_System.m b/Source/KSCrash/Recording/Monitors/KSCrashMonitor_System.m index 0ffed225..e92f3e30 100644 --- a/Source/KSCrash/Recording/Monitors/KSCrashMonitor_System.m +++ b/Source/KSCrash/Recording/Monitors/KSCrashMonitor_System.m @@ -296,19 +296,15 @@ static uint64_t usableMemory(void) } break; } - #ifdef CPU_TYPE_ARM64 case CPU_TYPE_ARM64: { switch (subType) { -#ifdef CPU_SUBTYPE_ARM64E case CPU_SUBTYPE_ARM64E: return "arm64e"; -#endif } return "arm64"; } -#endif case CPU_TYPE_X86: return "x86"; case CPU_TYPE_X86_64: diff --git a/Source/KSCrash/Reporting/Filters/KSCrashReportFilterAppleFmt.m b/Source/KSCrash/Reporting/Filters/KSCrashReportFilterAppleFmt.m index caec1e8e..448fb63e 100644 --- a/Source/KSCrash/Reporting/Filters/KSCrashReportFilterAppleFmt.m +++ b/Source/KSCrash/Reporting/Filters/KSCrashReportFilterAppleFmt.m @@ -30,13 +30,12 @@ #import #import +#include #import "KSCrashReportFields.h" #import "KSJSONCodecObjC.h" #import "KSCrashMonitor_System.h" -#define CPU_SUBTYPE_ARM64E ((cpu_subtype_t) 2) - #if defined(__LP64__) #define FMT_LONG_DIGITS "16" #define FMT_RJ_SPACES "18" @@ -47,9 +46,10 @@ #define FMT_PTR_SHORT @"0x%" PRIxPTR #define FMT_PTR_LONG @"0x%0" FMT_LONG_DIGITS PRIxPTR -#define FMT_PTR_RJ @"%#" FMT_RJ_SPACES PRIxPTR +//#define FMT_PTR_RJ @"%#" FMT_RJ_SPACES PRIxPTR +#define FMT_PTR_RJ @"%#" PRIxPTR #define FMT_OFFSET @"%" PRIuPTR -#define FMT_TRACE_PREAMBLE @"%-4d%-31s " FMT_PTR_LONG +#define FMT_TRACE_PREAMBLE @"%-4d%-30s\t" FMT_PTR_LONG #define FMT_TRACE_UNSYMBOLICATED FMT_PTR_SHORT @" + " FMT_OFFSET #define FMT_TRACE_SYMBOLICATED @"%@ + " FMT_OFFSET @@ -74,9 +74,12 @@ - (NSString*) toAppleFormat:(NSDictionary*) JSONReport; * * @param CPUArch The CPU architecture name. * + * @param isSystemInfoHeader Whether it is going to be used or not for system Information header + * * @return the major CPU type. + */ -- (NSString*) CPUType:(NSString*) CPUArch; +- (NSString*) CPUType:(NSString*) CPUArch isSystemInfoHeader:(BOOL) isSystemInfoHeader; /** Determine the CPU architecture based on major/minor CPU architecture codes. * @@ -98,6 +101,29 @@ - (NSString*) toCompactUUID:(NSString*) uuid; @end +@interface NSString (CompareRegisterNames) + +- (NSComparisonResult)kscrash_compareRegisterName:(NSString *)other; + +@end + +@implementation NSString (CompareRegisterNames) + +- (NSComparisonResult)kscrash_compareRegisterName:(NSString *)other { + BOOL containsNum = [self rangeOfCharacterFromSet:[NSCharacterSet decimalDigitCharacterSet]].location != NSNotFound; + BOOL otherContainsNum = [other rangeOfCharacterFromSet:[NSCharacterSet decimalDigitCharacterSet]].location != NSNotFound; + + if (containsNum && !otherContainsNum) { + return NSOrderedAscending; + } else if (!containsNum && otherContainsNum) { + return NSOrderedDescending; + } else { + return [self localizedStandardCompare:other]; + } +} + +@end + @implementation KSCrashReportFilterAppleFmt @@ -212,8 +238,12 @@ - (void) filterReports:(NSArray*) reports kscrash_callCompletion(onCompletion, filteredReports, YES, nil); } -- (NSString*) CPUType:(NSString*) CPUArch +- (NSString*) CPUType:(NSString*) CPUArch isSystemInfoHeader:(BOOL) isSystemInfoHeader { + if(isSystemInfoHeader && [CPUArch rangeOfString:@"arm64e"].location == 0) + { + return @"ARM-64 (Native)"; + } if([CPUArch rangeOfString:@"arm64"].location == 0) { return @"ARM-64"; @@ -235,6 +265,12 @@ - (NSString*) CPUType:(NSString*) CPUArch - (NSString*) CPUArchForMajor:(cpu_type_t) majorCode minor:(cpu_subtype_t) minorCode { + // In Apple platforms we can use this nice function to get the name of a particular architecture + const NXArchInfo* info = NXGetArchInfoFromCpuType(majorCode, minorCode); + if (info && info->name) { + return [[NSString alloc] initWithUTF8String: info->name]; + } + switch(majorCode) { case CPU_TYPE_ARM: @@ -256,19 +292,15 @@ - (NSString*) CPUArchForMajor:(cpu_type_t) majorCode minor:(cpu_subtype_t) minor } return @"arm"; } -#ifdef CPU_TYPE_ARM64 case CPU_TYPE_ARM64: { switch (minorCode) { -#ifdef CPU_SUBTYPE_ARM64E case CPU_SUBTYPE_ARM64E: return @"arm64e"; -#endif } return @"arm64"; } -#endif case CPU_TYPE_X86: return @"i386"; case CPU_TYPE_X86_64: @@ -438,29 +470,31 @@ - (NSString*)headerStringForSystemInfo:(NSDictionary*)system reportID:(NSString* NSMutableString* str = [NSMutableString string]; NSString* executablePath = [system objectForKey:@KSCrashField_ExecutablePath]; NSString* cpuArch = [system objectForKey:@KSCrashField_CPUArch]; - NSString* cpuArchType = [self CPUType:cpuArch]; + NSString* cpuArchType = [self CPUType:cpuArch isSystemInfoHeader:YES]; + NSString* parentProcess = @"launchd"; // In iOS and most macOS regulard apps "launchd" is always the launcher. This might need a fix for other kind of apps + NSString* processRole = @"Foreground"; // In iOS and most macOS regulard apps the role is "Foreground". This might need a fix for other kind of apps [str appendFormat:@"Incident Identifier: %@\n", reportID]; [str appendFormat:@"CrashReporter Key: %@\n", [system objectForKey:@KSCrashField_DeviceAppHash]]; [str appendFormat:@"Hardware Model: %@\n", [system objectForKey:@KSCrashField_Machine]]; - [str appendFormat:@"Process: %@ [%@]\n", + [str appendFormat:@"Process: %@ [%@]\n", [system objectForKey:@KSCrashField_ProcessName], [system objectForKey:@KSCrashField_ProcessID]]; - [str appendFormat:@"Path: %@\n", executablePath]; - [str appendFormat:@"Identifier: %@\n", [system objectForKey:@KSCrashField_BundleID]]; - [str appendFormat:@"Version: %@ (%@)\n", + [str appendFormat:@"Path: %@\n", executablePath]; + [str appendFormat:@"Identifier: %@\n", [system objectForKey:@KSCrashField_BundleID]]; + [str appendFormat:@"Version: %@ (%@)\n", [system objectForKey:@KSCrashField_BundleVersion], [system objectForKey:@KSCrashField_BundleShortVersion]]; - [str appendFormat:@"Code Type: %@\n", cpuArchType]; - [str appendFormat:@"Parent Process: ? [%@]\n", - [system objectForKey:@KSCrashField_ParentProcessID]]; + [str appendFormat:@"Code Type: %@\n", cpuArchType]; + [str appendFormat:@"Role: %@\n", processRole]; + [str appendFormat:@"Parent Process: %@ [%@]\n", parentProcess, [system objectForKey:@KSCrashField_ParentProcessID]]; [str appendFormat:@"\n"]; - [str appendFormat:@"Date/Time: %@\n", [self stringFromDate:crashTime]]; - [str appendFormat:@"OS Version: %@ %@ (%@)\n", + [str appendFormat:@"Date/Time: %@\n", [self stringFromDate:crashTime]]; + [str appendFormat:@"OS Version: %@ %@ (%@)\n", [system objectForKey:@KSCrashField_SystemName], [system objectForKey:@KSCrashField_SystemVersion], [system objectForKey:@KSCrashField_OSVersion]]; - [str appendFormat:@"Report Version: 104\n"]; + [str appendFormat:@"Report Version: 104\n"]; return str; } @@ -470,8 +504,8 @@ - (NSString*) binaryImagesStringForReport:(NSDictionary*) report NSMutableString* str = [NSMutableString string]; NSArray* binaryImages = [self binaryImagesReport:report]; - NSDictionary* system = [self systemReport:report]; - NSString* executablePath = [system objectForKey:@KSCrashField_ExecutablePath]; + //NSDictionary* system = [self systemReport:report]; + //NSString* executablePath = [system objectForKey:@KSCrashField_ExecutablePath]; [str appendString:@"\nBinary Images:\n"]; if(binaryImages) @@ -496,19 +530,22 @@ - (NSString*) binaryImagesStringForReport:(NSDictionary*) report NSString* path = [image objectForKey:@KSCrashField_Name]; NSString* name = [path lastPathComponent]; NSString* uuid = [self toCompactUUID:[image objectForKey:@KSCrashField_UUID]]; - NSString* isBaseImage = (path && [executablePath isEqualToString:path]) ? @"+" : @" "; - + //NSString* isBaseImage = (path && [executablePath isEqualToString:path]) ? @"+" : @" "; + NSString* isBaseImage = @""; + NSString* arch = [self CPUArchForMajor:cpuType minor:cpuSubtype]; [str appendFormat:FMT_PTR_RJ @" - " FMT_PTR_RJ @" %@%@ %@ <%@> %@\n", imageAddr, imageAddr + imageSize - 1, isBaseImage, name, - [self CPUArchForMajor:cpuType minor:cpuSubtype], + arch, uuid, path]; } } + [str appendString:@"\nEOF\n\n"]; + return str; } @@ -522,7 +559,7 @@ - (NSString*) crashedThreadCPUStateStringForReport:(NSDictionary*) report } int threadIndex = [[thread objectForKey:@KSCrashField_Index] intValue]; - NSString* cpuArchType = [self CPUType:cpuArch]; + NSString* cpuArchType = [self CPUType:cpuArch isSystemInfoHeader:NO]; NSMutableString* str = [NSMutableString string]; @@ -533,7 +570,7 @@ - (NSString*) crashedThreadCPUStateStringForReport:(NSDictionary*) report NSArray* regOrder = [g_registerOrders objectForKey:cpuArch]; if(regOrder == nil) { - regOrder = [[registers allKeys] sortedArrayUsingSelector:@selector(compare:)]; + regOrder = [[registers allKeys] sortedArrayUsingSelector:@selector(kscrash_compareRegisterName:)]; } NSUInteger numRegisters = [regOrder count]; NSUInteger i = 0; @@ -719,7 +756,7 @@ - (NSString*) errorInfoStringForReport:(NSDictionary*) report machCodeName, (uintptr_t)[[error objectForKey:@KSCrashField_Address] longLongValue]]; - [str appendFormat:@"Crashed Thread: %d\n", + [str appendFormat:@"Triggered by Thread: %d\n", [[thread objectForKey:@KSCrashField_Index] intValue]]; if(nsexception != nil) diff --git a/Source/KSCrash/Reporting/Sinks/KSCrashReportSinkQuincyHockey.m b/Source/KSCrash/Reporting/Sinks/KSCrashReportSinkQuincyHockey.m index 0ac8af50..164a89b0 100644 --- a/Source/KSCrash/Reporting/Sinks/KSCrashReportSinkQuincyHockey.m +++ b/Source/KSCrash/Reporting/Sinks/KSCrashReportSinkQuincyHockey.m @@ -226,7 +226,6 @@ - (NSString*) quincyArchFromCpuType:(cpu_type_t)cpuType cpuSubType:(cpu_subtype_ } break; -#ifdef CPU_TYPE_ARM64 case CPU_TYPE_ARM64: switch (cpuSubType) { @@ -234,6 +233,10 @@ - (NSString*) quincyArchFromCpuType:(cpu_type_t)cpuType cpuSubType:(cpu_subtype_ arch = @"arm64"; break; + case CPU_SUBTYPE_ARM64E: + arch = @"arm64e"; + break; + #ifdef CPU_SUBTYPE_ARM_V8 case CPU_SUBTYPE_ARM_V8: arch = @"arm64"; @@ -245,7 +248,6 @@ - (NSString*) quincyArchFromCpuType:(cpu_type_t)cpuType cpuSubType:(cpu_subtype_ break; } break; -#endif case CPU_TYPE_X86: arch = @"i386"; From ba0ae494b5cee3aeeb76c368a500963e4c426160 Mon Sep 17 00:00:00 2001 From: Guillermo Ignacio Enriquez Gutierrez Date: Sat, 25 Nov 2023 10:31:38 +0900 Subject: [PATCH 2/2] Remove comments from apple format --- .../Reporting/Filters/KSCrashReportFilterAppleFmt.m | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/Source/KSCrash/Reporting/Filters/KSCrashReportFilterAppleFmt.m b/Source/KSCrash/Reporting/Filters/KSCrashReportFilterAppleFmt.m index 448fb63e..ca75acbf 100644 --- a/Source/KSCrash/Reporting/Filters/KSCrashReportFilterAppleFmt.m +++ b/Source/KSCrash/Reporting/Filters/KSCrashReportFilterAppleFmt.m @@ -265,11 +265,13 @@ - (NSString*) CPUType:(NSString*) CPUArch isSystemInfoHeader:(BOOL) isSystemInfo - (NSString*) CPUArchForMajor:(cpu_type_t) majorCode minor:(cpu_subtype_t) minorCode { - // In Apple platforms we can use this nice function to get the name of a particular architecture +#ifdef __APPLE__ + // In Apple platforms we can use this function to get the name of a particular architecture const NXArchInfo* info = NXGetArchInfoFromCpuType(majorCode, minorCode); if (info && info->name) { return [[NSString alloc] initWithUTF8String: info->name]; } +#endif switch(majorCode) { @@ -504,8 +506,6 @@ - (NSString*) binaryImagesStringForReport:(NSDictionary*) report NSMutableString* str = [NSMutableString string]; NSArray* binaryImages = [self binaryImagesReport:report]; - //NSDictionary* system = [self systemReport:report]; - //NSString* executablePath = [system objectForKey:@KSCrashField_ExecutablePath]; [str appendString:@"\nBinary Images:\n"]; if(binaryImages) @@ -530,13 +530,10 @@ - (NSString*) binaryImagesStringForReport:(NSDictionary*) report NSString* path = [image objectForKey:@KSCrashField_Name]; NSString* name = [path lastPathComponent]; NSString* uuid = [self toCompactUUID:[image objectForKey:@KSCrashField_UUID]]; - //NSString* isBaseImage = (path && [executablePath isEqualToString:path]) ? @"+" : @" "; - NSString* isBaseImage = @""; NSString* arch = [self CPUArchForMajor:cpuType minor:cpuSubtype]; - [str appendFormat:FMT_PTR_RJ @" - " FMT_PTR_RJ @" %@%@ %@ <%@> %@\n", + [str appendFormat:FMT_PTR_RJ @" - " FMT_PTR_RJ @" %@ %@ <%@> %@\n", imageAddr, imageAddr + imageSize - 1, - isBaseImage, name, arch, uuid,