Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

KSCrashReportFilterAppleFmt now shows correct architecture in header and libraries list (arm64e) #415

Merged
merged 2 commits into from Nov 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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
96 changes: 65 additions & 31 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,14 @@ - (NSString*) CPUType:(NSString*) CPUArch

- (NSString*) CPUArchForMajor:(cpu_type_t) majorCode minor:(cpu_subtype_t) minorCode
{
#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)
{
case CPU_TYPE_ARM:
Expand All @@ -256,19 +294,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 +472,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 +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)
Expand All @@ -496,19 +530,19 @@ - (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]) ? @"+" : @" ";

[str appendFormat:FMT_PTR_RJ @" - " FMT_PTR_RJ @" %@%@ %@ <%@> %@\n",
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 +556,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 +567,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 +753,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