Skip to content

Commit

Permalink
KSCrashReportFilterAppleFmt now shows correct architecture for arm64e…
Browse files Browse the repository at this point in the history
…. Various minor aesthetics changes to resemble better Apple crash reports as Xcode12.
  • Loading branch information
nacho4d committed Sep 4, 2021
1 parent f45a917 commit e817261
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 35 deletions.
4 changes: 0 additions & 4 deletions Source/KSCrash/Recording/Monitors/KSCrashMonitor_System.m
Expand Up @@ -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:
Expand Down
95 changes: 66 additions & 29 deletions Source/KSCrash/Reporting/Filters/KSCrashReportFilterAppleFmt.m
Expand Up @@ -30,13 +30,12 @@

#import <inttypes.h>
#import <mach/machine.h>
#include <mach-o/arch.h>

#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"
Expand All @@ -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

Expand All @@ -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.
*
Expand All @@ -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

Expand Down Expand Up @@ -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";
Expand All @@ -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:
Expand All @@ -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:
Expand Down Expand Up @@ -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;
}
Expand All @@ -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)
Expand All @@ -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;
}

Expand All @@ -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];

Expand All @@ -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;
Expand Down Expand Up @@ -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)
Expand Down
Expand Up @@ -226,14 +226,17 @@ - (NSString*) quincyArchFromCpuType:(cpu_type_t)cpuType cpuSubType:(cpu_subtype_
}
break;

#ifdef CPU_TYPE_ARM64
case CPU_TYPE_ARM64:
switch (cpuSubType)
{
case CPU_SUBTYPE_ARM_ALL:
arch = @"arm64";
break;

case CPU_SUBTYPE_ARM64E:
arch = @"arm64e";
break;

#ifdef CPU_SUBTYPE_ARM_V8
case CPU_SUBTYPE_ARM_V8:
arch = @"arm64";
Expand All @@ -245,7 +248,6 @@ - (NSString*) quincyArchFromCpuType:(cpu_type_t)cpuType cpuSubType:(cpu_subtype_
break;
}
break;
#endif

case CPU_TYPE_X86:
arch = @"i386";
Expand Down

0 comments on commit e817261

Please sign in to comment.