diff --git a/Examples/RollbarDemo/RollbarDemo.xcodeproj/project.pbxproj b/Examples/RollbarDemo/RollbarDemo.xcodeproj/project.pbxproj index aac6f5af..8d97803b 100644 --- a/Examples/RollbarDemo/RollbarDemo.xcodeproj/project.pbxproj +++ b/Examples/RollbarDemo/RollbarDemo.xcodeproj/project.pbxproj @@ -286,7 +286,7 @@ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_ENTITLEMENTS = RollbarDemo/RollbarDemo.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 70; + CURRENT_PROJECT_VERSION = 75; DEAD_CODE_STRIPPING = YES; DEVELOPMENT_ASSET_PATHS = "\"RollbarDemo/Preview Content\""; DEVELOPMENT_TEAM = 9P5JVC2F34; @@ -300,7 +300,7 @@ INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown"; IPHONEOS_DEPLOYMENT_TARGET = 14.0; LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks"; - MARKETING_VERSION = 1.2; + MARKETING_VERSION = 1.3; PRODUCT_BUNDLE_IDENTIFIER = com.rollbar.apple.demo; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = auto; @@ -320,7 +320,7 @@ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_ENTITLEMENTS = RollbarDemo/RollbarDemo.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 70; + CURRENT_PROJECT_VERSION = 75; DEAD_CODE_STRIPPING = YES; DEVELOPMENT_ASSET_PATHS = "\"RollbarDemo/Preview Content\""; DEVELOPMENT_TEAM = 9P5JVC2F34; @@ -334,7 +334,7 @@ INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown"; IPHONEOS_DEPLOYMENT_TARGET = 14.0; LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks"; - MARKETING_VERSION = 1.2; + MARKETING_VERSION = 1.3; PRODUCT_BUNDLE_IDENTIFIER = com.rollbar.apple.demo; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = auto; diff --git a/RollbarNotifier/Sources/RollbarCrash/Recording/RollbarCrashHandler.m b/RollbarNotifier/Sources/RollbarCrash/Recording/RollbarCrashHandler.m index 8a864a5f..95002c71 100644 --- a/RollbarNotifier/Sources/RollbarCrash/Recording/RollbarCrashHandler.m +++ b/RollbarNotifier/Sources/RollbarCrash/Recording/RollbarCrashHandler.m @@ -457,20 +457,70 @@ - (NSData*) loadCrashReportJSONWithID:(int64_t) reportID return nil; } -- (void) doctorReport:(NSMutableDictionary*) report +- (void) finalizeReport:(NSMutableDictionary*) report { - NSMutableDictionary* crashReport = report[@RollbarCrashField_Crash]; - if(crashReport != nil) - { + NSMutableDictionary* crashReport; + + if ((crashReport = report[@RollbarCrashField_Crash]) != NULL) { + [self cleanupReport:crashReport]; crashReport[@RollbarCrashField_Diagnosis] = [[RollbarCrashDoctor doctor] diagnoseCrash:report]; } - crashReport = report[@RollbarCrashField_RecrashReport][@RollbarCrashField_Crash]; - if(crashReport != nil) - { + + if ((crashReport = report[@RollbarCrashField_RecrashReport][@RollbarCrashField_Crash]) != NULL) { crashReport[@RollbarCrashField_Diagnosis] = [[RollbarCrashDoctor doctor] diagnoseCrash:report]; } } +- (void) cleanupReport:(NSMutableDictionary*) crashReport +{ + NSNumber *address = crashReport[@RollbarCrashField_Error][@RollbarCrashField_Address]; + NSNumber *subcode = crashReport[@RollbarCrashField_Error][@RollbarCrashField_Mach][@RollbarCrashField_Subcode]; + if ([address isEqualToNumber:subcode]) { + [self dedupFrames:crashReport forAddress:address]; + } + + [self dedupLinkRegisterFrames:crashReport]; +} + +- (void) dedupFrames:(NSMutableDictionary*) crashReport forAddress:(NSNumber*) address +{ + NSArray *threads = crashReport[@RollbarCrashField_Threads]; + for (NSDictionary *thread in threads) { + NSMutableArray *frames = thread[@RollbarCrashField_Backtrace][@RollbarCrashField_Contents]; + NSIndexSet *indexes = [frames indexesOfObjectsPassingTest:^BOOL(NSDictionary * _Nonnull frame, NSUInteger idx, BOOL *_) { + return [frame[@RollbarCrashField_InstructionAddr] isEqualToNumber:address]; + }]; + + if (indexes.firstIndex == 0 && indexes.lastIndex == 1 + && [frames[indexes.firstIndex] isEqualToDictionary:frames[indexes.lastIndex]]) + { + [frames removeObjectAtIndex:indexes.firstIndex]; + } + } +} + +- (void) dedupLinkRegisterFrames:(NSMutableDictionary*) crashReport +{ + NSArray *threads = crashReport[@RollbarCrashField_Threads]; + for (NSDictionary *thread in threads) { + // Link register, if available, is the second address in the trace. + NSMutableArray *frames = thread[@RollbarCrashField_Backtrace][@RollbarCrashField_Contents]; + NSDictionary *registers = thread[@RollbarCrashField_Registers][@RollbarCrashField_Basic]; + if (frames.count < 2 || !(registers && registers[@"lr"])) { + continue; + } + + NSDictionary *lastFrame = frames[frames.count - 1]; + NSDictionary *penultimateFrame = frames[frames.count - 2]; + + if ([lastFrame[@RollbarCrashField_SymbolAddr] isEqualToNumber:penultimateFrame[@RollbarCrashField_SymbolAddr]] + && [penultimateFrame[@RollbarCrashField_InstructionAddr] isEqualToNumber:registers[@"lr"]]) + { + [frames removeObjectAtIndex:frames.count - 2]; + } + } +} + - (NSArray*)reportIDs { int reportCount = rc_getReportCount(); @@ -512,7 +562,7 @@ - (NSDictionary*) reportWithIntID:(int64_t) reportID RCLOG_ERROR(@"Could not load crash report"); return nil; } - [self doctorReport:crashReport]; + [self finalizeReport:crashReport]; return crashReport; } diff --git a/RollbarNotifier/Sources/RollbarCrash/Recording/RollbarCrashReportFixer.c b/RollbarNotifier/Sources/RollbarCrash/Recording/RollbarCrashReportFixer.c index d5eae02d..ca5720df 100644 --- a/RollbarNotifier/Sources/RollbarCrash/Recording/RollbarCrashReportFixer.c +++ b/RollbarNotifier/Sources/RollbarCrash/Recording/RollbarCrashReportFixer.c @@ -291,7 +291,7 @@ char* rccrf_fixupCrashReport(const char* crashReport) .onNullElement = onNullElement, .onStringElement = onStringElement, }; - int stringBufferLength = 10000; + int stringBufferLength = RCMAX_STRINGBUFFERSIZE; char* stringBuffer = malloc((unsigned)stringBufferLength); int crashReportLength = (int)strlen(crashReport); int fixedReportLength = (int)(crashReportLength * 1.5); diff --git a/RollbarNotifier/Sources/RollbarCrash/Util/RollbarCrashJSONCodec.h b/RollbarNotifier/Sources/RollbarCrash/Util/RollbarCrashJSONCodec.h index de3c4e59..71280f9f 100644 --- a/RollbarNotifier/Sources/RollbarCrash/Util/RollbarCrashJSONCodec.h +++ b/RollbarNotifier/Sources/RollbarCrash/Util/RollbarCrashJSONCodec.h @@ -45,6 +45,8 @@ extern "C" { */ #define RollbarCrashJSON_SIZE_AUTOMATIC -1 +#define RCMAX_STRINGBUFFERSIZE 150000 + enum { /** Encoding or decoding: Everything completed without error */ diff --git a/RollbarNotifier/Sources/RollbarCrash/Util/RollbarCrashJSONCodecObjC.m b/RollbarNotifier/Sources/RollbarCrash/Util/RollbarCrashJSONCodecObjC.m index 9c478f0a..6bea879d 100644 --- a/RollbarNotifier/Sources/RollbarCrash/Util/RollbarCrashJSONCodecObjC.m +++ b/RollbarNotifier/Sources/RollbarCrash/Util/RollbarCrashJSONCodecObjC.m @@ -435,7 +435,7 @@ + (id) decode:(NSData*) JSONData { RollbarCrashJSONCodec* codec = [self codecWithEncodeOptions:0 decodeOptions:decodeOptions]; - NSMutableData* stringData = [NSMutableData dataWithLength:10001]; + NSMutableData* stringData = [NSMutableData dataWithLength:RCMAX_STRINGBUFFERSIZE+1]; int errorOffset; int result = rcjson_decode(JSONData.bytes, (int)JSONData.length,