diff --git a/CHANGELOG.md b/CHANGELOG.md index aed2f073374..443743e1fdd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ### Fixes - Cleanup AppHangTracking properly when closing SDK (#2671) +- Add EXC_BAD_ACCESS subtypes to events (#2667) ## 8.1.0 diff --git a/Sentry.xcodeproj/project.pbxproj b/Sentry.xcodeproj/project.pbxproj index 96d758d41a2..030ffd13939 100644 --- a/Sentry.xcodeproj/project.pbxproj +++ b/Sentry.xcodeproj/project.pbxproj @@ -422,7 +422,7 @@ 7B9657252683104C00C66E25 /* NSData+Sentry.h in Headers */ = {isa = PBXBuildFile; fileRef = 7B9657232683104C00C66E25 /* NSData+Sentry.h */; }; 7B9657262683104C00C66E25 /* NSData+Sentry.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B9657242683104C00C66E25 /* NSData+Sentry.m */; }; 7B965728268321CD00C66E25 /* SentryCrashScopeObserverTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B965727268321CD00C66E25 /* SentryCrashScopeObserverTests.swift */; }; - 7B984A9F28E572AF001F4BEE /* CrashReportWriter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B984A9E28E572AF001F4BEE /* CrashReportWriter.swift */; }; + 7B984A9F28E572AF001F4BEE /* CrashReport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B984A9E28E572AF001F4BEE /* CrashReport.swift */; }; 7B98D7BC25FB607300C5A389 /* SentryWatchdogTerminationTracker.h in Headers */ = {isa = PBXBuildFile; fileRef = 7B98D7BB25FB607300C5A389 /* SentryWatchdogTerminationTracker.h */; }; 7B98D7CB25FB64EC00C5A389 /* SentryWatchdogTerminationTrackingIntegration.h in Headers */ = {isa = PBXBuildFile; fileRef = 7B98D7CA25FB64EC00C5A389 /* SentryWatchdogTerminationTrackingIntegration.h */; }; 7B98D7CF25FB650F00C5A389 /* SentryWatchdogTerminationTrackingIntegration.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B98D7CE25FB650F00C5A389 /* SentryWatchdogTerminationTrackingIntegration.m */; }; @@ -572,6 +572,7 @@ 7BF6505F292B77EC00BBA5A8 /* SentryMetricKitIntegrationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF6505E292B77EC00BBA5A8 /* SentryMetricKitIntegrationTests.swift */; }; 7BF65062292B8F1C00BBA5A8 /* SentryMXCallStackTree.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF65061292B8F1C00BBA5A8 /* SentryMXCallStackTree.swift */; }; 7BF65064292B905A00BBA5A8 /* SentryMXCallStackTreeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF65063292B905A00BBA5A8 /* SentryMXCallStackTreeTests.swift */; }; + 7BF69E072987D1FE002EBCA4 /* SentryCrashDoctorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF69E062987D1FE002EBCA4 /* SentryCrashDoctorTests.swift */; }; 7BF9EF722722A84800B5BBEF /* SentryClassRegistrator.h in Headers */ = {isa = PBXBuildFile; fileRef = 7BF9EF712722A84800B5BBEF /* SentryClassRegistrator.h */; }; 7BF9EF742722A85B00B5BBEF /* SentryClassRegistrator.m in Sources */ = {isa = PBXBuildFile; fileRef = 7BF9EF732722A85B00B5BBEF /* SentryClassRegistrator.m */; }; 7BF9EF762722B34700B5BBEF /* SentrySubClassFinder.h in Headers */ = {isa = PBXBuildFile; fileRef = 7BF9EF752722B34700B5BBEF /* SentrySubClassFinder.h */; }; @@ -1240,7 +1241,7 @@ 7B9657242683104C00C66E25 /* NSData+Sentry.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSData+Sentry.m"; sourceTree = ""; }; 7B965727268321CD00C66E25 /* SentryCrashScopeObserverTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryCrashScopeObserverTests.swift; sourceTree = ""; }; 7B9660B12783500E0014A767 /* ThreadSanitizer.sup */ = {isa = PBXFileReference; lastKnownFileType = text; path = ThreadSanitizer.sup; sourceTree = ""; }; - 7B984A9E28E572AF001F4BEE /* CrashReportWriter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CrashReportWriter.swift; sourceTree = ""; }; + 7B984A9E28E572AF001F4BEE /* CrashReport.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CrashReport.swift; sourceTree = ""; }; 7B98D7BB25FB607300C5A389 /* SentryWatchdogTerminationTracker.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentryWatchdogTerminationTracker.h; path = include/SentryWatchdogTerminationTracker.h; sourceTree = ""; }; 7B98D7CA25FB64EC00C5A389 /* SentryWatchdogTerminationTrackingIntegration.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentryWatchdogTerminationTrackingIntegration.h; path = include/SentryWatchdogTerminationTrackingIntegration.h; sourceTree = ""; }; 7B98D7CE25FB650F00C5A389 /* SentryWatchdogTerminationTrackingIntegration.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryWatchdogTerminationTrackingIntegration.m; sourceTree = ""; }; @@ -1400,6 +1401,7 @@ 7BF6505E292B77EC00BBA5A8 /* SentryMetricKitIntegrationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryMetricKitIntegrationTests.swift; sourceTree = ""; }; 7BF65061292B8F1C00BBA5A8 /* SentryMXCallStackTree.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryMXCallStackTree.swift; sourceTree = ""; }; 7BF65063292B905A00BBA5A8 /* SentryMXCallStackTreeTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryMXCallStackTreeTests.swift; sourceTree = ""; }; + 7BF69E062987D1FE002EBCA4 /* SentryCrashDoctorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryCrashDoctorTests.swift; sourceTree = ""; }; 7BF9EF712722A84800B5BBEF /* SentryClassRegistrator.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SentryClassRegistrator.h; sourceTree = ""; }; 7BF9EF732722A85B00B5BBEF /* SentryClassRegistrator.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryClassRegistrator.m; sourceTree = ""; }; 7BF9EF752722B34700B5BBEF /* SentrySubClassFinder.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SentrySubClassFinder.h; sourceTree = ""; }; @@ -2402,7 +2404,8 @@ 7BED3574266F7BC600EAA70D /* TestSentryCrashWrapper.h */, 7BED3575266F7BFF00EAA70D /* TestSentryCrashWrapper.m */, 0ADC33EF28D9BE690078D980 /* TestSentryUIDeviceWrapper.swift */, - 7B984A9E28E572AF001F4BEE /* CrashReportWriter.swift */, + 7B984A9E28E572AF001F4BEE /* CrashReport.swift */, + 7BF69E062987D1FE002EBCA4 /* SentryCrashDoctorTests.swift */, ); path = SentryCrash; sourceTree = ""; @@ -4001,7 +4004,7 @@ D88817DD26D72BA500BF2251 /* SentryTraceStateTests.swift in Sources */, 8E25C97525F8511A00DC215B /* TestRandom.swift in Sources */, 7B26BBFB24C0A66D00A79CCC /* SentrySdkInfoNilTests.m in Sources */, - 7B984A9F28E572AF001F4BEE /* CrashReportWriter.swift in Sources */, + 7B984A9F28E572AF001F4BEE /* CrashReport.swift in Sources */, 7BAF3DD7243DD4A1008A5414 /* TestConstants.swift in Sources */, 035E73CC27D575B3005EEB11 /* SentrySamplingProfilerTests.mm in Sources */, 7BED3576266F7BFF00EAA70D /* TestSentryCrashWrapper.m in Sources */, @@ -4103,6 +4106,7 @@ 7BAF3DD2243DD05C008A5414 /* SentryTransportInitializerTests.swift in Sources */, 7B68D93625FF5F1A0082D139 /* SentryAppState+Equality.m in Sources */, 7B5CAF7E27F5AD3500ED0DB6 /* TestNSURLRequestBuilder.m in Sources */, + 7BF69E072987D1FE002EBCA4 /* SentryCrashDoctorTests.swift in Sources */, 7B4F22DC294089530067EA17 /* FormatHexAddress.swift in Sources */, 8EAC7FF8265C8910005B44E5 /* SentryTracerTests.swift in Sources */, 0A1B497328E597DD00D7BFA3 /* TestLogOutput.swift in Sources */, diff --git a/Sources/SentryCrash/Recording/SentryCrashDoctor.m b/Sources/SentryCrash/Recording/SentryCrashDoctor.m index adbbf299594..e9a1ea785ab 100644 --- a/Sources/SentryCrash/Recording/SentryCrashDoctor.m +++ b/Sources/SentryCrash/Recording/SentryCrashDoctor.m @@ -458,8 +458,17 @@ - (NSString *)diagnoseCrash:(NSDictionary *)report if (address == 0) { return @"Attempted to dereference null pointer."; } - return [NSString - stringWithFormat:@"Attempted to dereference garbage pointer %p.", (void *)address]; + + NSString *codeName = errorReport[@SentryCrashField_Mach][@SentryCrashField_CodeName]; + if (codeName != nil) { + // Inspired by + // https://developer.apple.com/documentation/xcode/investigating-memory-access-crashes + return [NSString stringWithFormat:@"%@ at %p.", codeName, (void *)address]; + } else { + return + [NSString stringWithFormat:@"Attempted to dereference garbage pointer at %p.", + (void *)address]; + } } return nil; diff --git a/Sources/SentryCrash/Recording/Tools/SentryCrashMach.c b/Sources/SentryCrash/Recording/Tools/SentryCrashMach.c index f46f85688a6..afef898b176 100644 --- a/Sources/SentryCrash/Recording/Tools/SentryCrashMach.c +++ b/Sources/SentryCrash/Recording/Tools/SentryCrashMach.c @@ -27,6 +27,10 @@ #include #include +#if defined(__arm__) || defined(__arm64__) +# include +#endif /* defined (__arm__) || defined (__arm64__) */ + #define RETURN_NAME_FOR_ENUM(A) \ case A: \ return #A @@ -104,6 +108,19 @@ sentrycrashmach_kernelReturnCodeName(const int64_t returnCode) RETURN_NAME_FOR_ENUM(KERN_NOT_WAITING); RETURN_NAME_FOR_ENUM(KERN_OPERATION_TIMED_OUT); RETURN_NAME_FOR_ENUM(KERN_CODESIGN_ERROR); + +#if defined(__arm__) || defined(__arm64__) + /* + * Located at mach/arm/exception.h + * For EXC_BAD_ACCESS + * Note: do not conflict with kern_return_t values returned by vm_fault + */ + RETURN_NAME_FOR_ENUM(EXC_ARM_DA_ALIGN); + RETURN_NAME_FOR_ENUM(EXC_ARM_DA_DEBUG); + RETURN_NAME_FOR_ENUM(EXC_ARM_SP_ALIGN); + RETURN_NAME_FOR_ENUM(EXC_ARM_SWP); + RETURN_NAME_FOR_ENUM(EXC_ARM_PAC_FAIL); +#endif /* defined (__arm__) || defined (__arm64__) */ } return NULL; } diff --git a/Tests/Resources/crash-bad-access-no-subcode.json b/Tests/Resources/crash-bad-access-no-subcode.json new file mode 100644 index 00000000000..e627a970afd --- /dev/null +++ b/Tests/Resources/crash-bad-access-no-subcode.json @@ -0,0 +1,265 @@ +{ + "report": { + "version": "3.2.0", + "id": "42A64046-9255-4995-98C2-553FA204DF4D", + "process_name": "iOS-Swift", + "timestamp": 1675069636, + "type": "standard" + }, + "process": {}, + "system": { + "system_name": "iOS", + "system_version": "16.2", + "machine": "iPhone11,8", + "model": "N841AP", + "kernel_version": "Darwin Kernel Version 22.2.0: Tue Nov 1 21:21:17 PDT 2022; root:xnu-8792.60.51.122.1~1/RELEASE_ARM64_T8020", + "os_version": "20C5043e", + "jailbroken": false, + "boot_time": "2023-01-30T08:43:25Z", + "app_start_time": "2023-01-30T09:05:01Z", + "CFBundleExecutablePath": "/private/var/containers/Bundle/Application/53C684E3-9F0E-4FE3-8291-88677BAB718C/iOS-Swift.app/iOS-Swift", + "CFBundleExecutable": "iOS-Swift", + "CFBundleIdentifier": "io.sentry.sample.iOS-Swift", + "CFBundleName": "iOS-Swift", + "CFBundleVersion": "1", + "CFBundleShortVersionString": "7.31.5", + "app_uuid": "C488D0BE-E733-3031-AEF3-CC5182AB1E3B", + "cpu_arch": "arm64", + "cpu_type": 16777228, + "cpu_subtype": 2, + "binary_cpu_type": 16777228, + "binary_cpu_subtype": 0, + "process_name": "iOS-Swift", + "process_id": 495, + "parent_process_id": 1, + "device_app_hash": "9116712086e95f0c91b259ee97270e8f6a8a7768", + "build_type": "debug", + "total_storage": 63933894656, + "free_storage": 26521919488, + "memory": { + "size": 2976202752, + "usable": 2550726656, + "free": 66846720 + }, + "application_stats": { + "application_active": true, + "application_in_foreground": true, + "launches_since_last_crash": 1, + "sessions_since_last_crash": 2, + "active_time_since_last_crash": 120.664, + "background_time_since_last_crash": 12.2669, + "sessions_since_launch": 2, + "active_time_since_launch": 120.664, + "background_time_since_launch": 12.2669 + } + }, + "crash": { + "error": { + "mach": { + "exception": 1, + "exception_name": "EXC_BAD_ACCESS", + "code": 257, + "subcode": 5365848110 + }, + "signal": { + "signal": 10, + "name": "SIGBUS", + "code": 0, + "code_name": "BUS_NOOP" + }, + "address": 5365848110, + "type": "mach" + } + }, + "sentry_sdk_scope": { + "user": { + "email": "tony1@example.com", + "id": "1" + }, + "environment": "debug", + "tags": { + "language": "swift" + }, + "extra": { + "currentViewController": "" + }, + "breadcrumbs": [ + { + "category": "started", + "level": "info", + "message": "Breadcrumb Tracking", + "timestamp": "2023-01-30T09:05:01.740Z", + "type": "debug" + }, + { + "category": "device.orientation", + "data": { + "position": "portrait" + }, + "level": "info", + "timestamp": "2023-01-30T09:05:01.757Z", + "type": "navigation" + }, + { + "category": "ui.lifecycle", + "data": { + "beingPresented": "false", + "is_window_rootViewController": "true", + "screen": "UINavigationController", + "window": "; backgroundColor = ; layer = >", + "window_isKeyWindow": "true", + "window_windowLevel": "0.000000" + }, + "level": "info", + "timestamp": "2023-01-30T09:05:01.819Z", + "type": "navigation" + }, + { + "category": "ui.lifecycle", + "data": { + "beingPresented": "false", + "is_window_rootViewController": "false", + "parentViewController": "UINavigationController", + "screen": "ViewController", + "title": "Sentry Test App (Swift)", + "window": "; backgroundColor = ; layer = >", + "window_isKeyWindow": "true", + "window_windowLevel": "0.000000" + }, + "level": "info", + "timestamp": "2023-01-30T09:05:01.819Z", + "type": "navigation" + }, + { + "category": "app.lifecycle", + "data": { + "state": "foreground" + }, + "level": "info", + "timestamp": "2023-01-30T09:05:01.987Z", + "type": "navigation" + }, + { + "category": "device.event", + "data": { + "action": "BATTERY_STATE_CHANGE", + "level": 4, + "plugged": true + }, + "level": "info", + "timestamp": "2023-01-30T09:05:21.053Z", + "type": "system" + }, + { + "category": "device.event", + "data": { + "action": "BATTERY_STATE_CHANGE", + "level": 3, + "plugged": true + }, + "level": "info", + "timestamp": "2023-01-30T09:05:41.050Z", + "type": "system" + }, + { + "category": "device.event", + "data": { + "action": "BATTERY_STATE_CHANGE", + "level": 4, + "plugged": true + }, + "level": "info", + "timestamp": "2023-01-30T09:06:01.086Z", + "type": "system" + }, + { + "category": "device.event", + "data": { + "action": "BATTERY_STATE_CHANGE", + "level": 3, + "plugged": true + }, + "level": "info", + "timestamp": "2023-01-30T09:06:21.115Z", + "type": "system" + }, + { + "category": "app.lifecycle", + "data": { + "state": "background" + }, + "level": "info", + "timestamp": "2023-01-30T09:07:02.658Z", + "type": "navigation" + }, + { + "category": "device.orientation", + "data": { + "position": "portrait" + }, + "level": "info", + "timestamp": "2023-01-30T09:07:14.286Z", + "type": "navigation" + }, + { + "category": "app.lifecycle", + "data": { + "state": "foreground" + }, + "level": "info", + "timestamp": "2023-01-30T09:07:15.480Z", + "type": "navigation" + }, + { + "category": "touch", + "data": { + "title": "crash", + "view": ">" + }, + "level": "info", + "message": "crash:", + "timestamp": "2023-01-30T09:07:16.198Z", + "type": "user" + } + ] + }, + "user": { + "context": { + "app": { + "app_build": "1", + "app_id": "C488D0BE-E733-3031-AEF3-CC5182AB1E3B", + "app_identifier": "io.sentry.sample.iOS-Swift", + "app_name": "iOS-Swift", + "app_start_time": "2023-01-30T09:05:01Z", + "app_version": "7.31.5", + "build_type": "debug", + "device_app_hash": "9116712086e95f0c91b259ee97270e8f6a8a7768" + }, + "device": { + "arch": "arm64", + "boot_time": "2023-01-30T08:43:25Z", + "family": "iOS", + "free_memory": 38764544, + "free_storage": 26521919488, + "locale": "en_AT", + "memory_size": 2976202752, + "model": "iPhone11,8", + "model_id": "N841AP", + "screen_height_pixels": 896, + "screen_width_pixels": 414, + "simulator": false, + "storage_size": 63933894656, + "usable_memory": 2552430592 + }, + "os": { + "build": "20C5043e", + "kernel_version": "Darwin Kernel Version 22.2.0: Tue Nov 1 21:21:17 PDT 2022; root:xnu-8792.60.51.122.1~1/RELEASE_ARM64_T8020", + "name": "iOS", + "rooted": false, + "version": "16.2" + } + }, + "release": "io.sentry.sample.iOS-Swift@7.31.5+1" + }, + "debug": {} +} diff --git a/Tests/Resources/crash-bad-access.json b/Tests/Resources/crash-bad-access.json new file mode 100644 index 00000000000..eaae7b4cd81 --- /dev/null +++ b/Tests/Resources/crash-bad-access.json @@ -0,0 +1,266 @@ +{ + "report": { + "version": "3.2.0", + "id": "42A64046-9255-4995-98C2-553FA204DF4D", + "process_name": "iOS-Swift", + "timestamp": 1675069636, + "type": "standard" + }, + "process": {}, + "system": { + "system_name": "iOS", + "system_version": "16.2", + "machine": "iPhone11,8", + "model": "N841AP", + "kernel_version": "Darwin Kernel Version 22.2.0: Tue Nov 1 21:21:17 PDT 2022; root:xnu-8792.60.51.122.1~1/RELEASE_ARM64_T8020", + "os_version": "20C5043e", + "jailbroken": false, + "boot_time": "2023-01-30T08:43:25Z", + "app_start_time": "2023-01-30T09:05:01Z", + "CFBundleExecutablePath": "/private/var/containers/Bundle/Application/53C684E3-9F0E-4FE3-8291-88677BAB718C/iOS-Swift.app/iOS-Swift", + "CFBundleExecutable": "iOS-Swift", + "CFBundleIdentifier": "io.sentry.sample.iOS-Swift", + "CFBundleName": "iOS-Swift", + "CFBundleVersion": "1", + "CFBundleShortVersionString": "7.31.5", + "app_uuid": "C488D0BE-E733-3031-AEF3-CC5182AB1E3B", + "cpu_arch": "arm64", + "cpu_type": 16777228, + "cpu_subtype": 2, + "binary_cpu_type": 16777228, + "binary_cpu_subtype": 0, + "process_name": "iOS-Swift", + "process_id": 495, + "parent_process_id": 1, + "device_app_hash": "9116712086e95f0c91b259ee97270e8f6a8a7768", + "build_type": "debug", + "total_storage": 63933894656, + "free_storage": 26521919488, + "memory": { + "size": 2976202752, + "usable": 2550726656, + "free": 66846720 + }, + "application_stats": { + "application_active": true, + "application_in_foreground": true, + "launches_since_last_crash": 1, + "sessions_since_last_crash": 2, + "active_time_since_last_crash": 120.664, + "background_time_since_last_crash": 12.2669, + "sessions_since_launch": 2, + "active_time_since_launch": 120.664, + "background_time_since_launch": 12.2669 + } + }, + "crash": { + "error": { + "mach": { + "exception": 1, + "exception_name": "EXC_BAD_ACCESS", + "code": 257, + "code_name": "EXC_ARM_DA_ALIGN", + "subcode": 5365848110 + }, + "signal": { + "signal": 10, + "name": "SIGBUS", + "code": 0, + "code_name": "BUS_NOOP" + }, + "address": 5365848110, + "type": "mach" + } + }, + "sentry_sdk_scope": { + "user": { + "email": "tony1@example.com", + "id": "1" + }, + "environment": "debug", + "tags": { + "language": "swift" + }, + "extra": { + "currentViewController": "" + }, + "breadcrumbs": [ + { + "category": "started", + "level": "info", + "message": "Breadcrumb Tracking", + "timestamp": "2023-01-30T09:05:01.740Z", + "type": "debug" + }, + { + "category": "device.orientation", + "data": { + "position": "portrait" + }, + "level": "info", + "timestamp": "2023-01-30T09:05:01.757Z", + "type": "navigation" + }, + { + "category": "ui.lifecycle", + "data": { + "beingPresented": "false", + "is_window_rootViewController": "true", + "screen": "UINavigationController", + "window": "; backgroundColor = ; layer = >", + "window_isKeyWindow": "true", + "window_windowLevel": "0.000000" + }, + "level": "info", + "timestamp": "2023-01-30T09:05:01.819Z", + "type": "navigation" + }, + { + "category": "ui.lifecycle", + "data": { + "beingPresented": "false", + "is_window_rootViewController": "false", + "parentViewController": "UINavigationController", + "screen": "ViewController", + "title": "Sentry Test App (Swift)", + "window": "; backgroundColor = ; layer = >", + "window_isKeyWindow": "true", + "window_windowLevel": "0.000000" + }, + "level": "info", + "timestamp": "2023-01-30T09:05:01.819Z", + "type": "navigation" + }, + { + "category": "app.lifecycle", + "data": { + "state": "foreground" + }, + "level": "info", + "timestamp": "2023-01-30T09:05:01.987Z", + "type": "navigation" + }, + { + "category": "device.event", + "data": { + "action": "BATTERY_STATE_CHANGE", + "level": 4, + "plugged": true + }, + "level": "info", + "timestamp": "2023-01-30T09:05:21.053Z", + "type": "system" + }, + { + "category": "device.event", + "data": { + "action": "BATTERY_STATE_CHANGE", + "level": 3, + "plugged": true + }, + "level": "info", + "timestamp": "2023-01-30T09:05:41.050Z", + "type": "system" + }, + { + "category": "device.event", + "data": { + "action": "BATTERY_STATE_CHANGE", + "level": 4, + "plugged": true + }, + "level": "info", + "timestamp": "2023-01-30T09:06:01.086Z", + "type": "system" + }, + { + "category": "device.event", + "data": { + "action": "BATTERY_STATE_CHANGE", + "level": 3, + "plugged": true + }, + "level": "info", + "timestamp": "2023-01-30T09:06:21.115Z", + "type": "system" + }, + { + "category": "app.lifecycle", + "data": { + "state": "background" + }, + "level": "info", + "timestamp": "2023-01-30T09:07:02.658Z", + "type": "navigation" + }, + { + "category": "device.orientation", + "data": { + "position": "portrait" + }, + "level": "info", + "timestamp": "2023-01-30T09:07:14.286Z", + "type": "navigation" + }, + { + "category": "app.lifecycle", + "data": { + "state": "foreground" + }, + "level": "info", + "timestamp": "2023-01-30T09:07:15.480Z", + "type": "navigation" + }, + { + "category": "touch", + "data": { + "title": "crash", + "view": ">" + }, + "level": "info", + "message": "crash:", + "timestamp": "2023-01-30T09:07:16.198Z", + "type": "user" + } + ] + }, + "user": { + "context": { + "app": { + "app_build": "1", + "app_id": "C488D0BE-E733-3031-AEF3-CC5182AB1E3B", + "app_identifier": "io.sentry.sample.iOS-Swift", + "app_name": "iOS-Swift", + "app_start_time": "2023-01-30T09:05:01Z", + "app_version": "7.31.5", + "build_type": "debug", + "device_app_hash": "9116712086e95f0c91b259ee97270e8f6a8a7768" + }, + "device": { + "arch": "arm64", + "boot_time": "2023-01-30T08:43:25Z", + "family": "iOS", + "free_memory": 38764544, + "free_storage": 26521919488, + "locale": "en_AT", + "memory_size": 2976202752, + "model": "iPhone11,8", + "model_id": "N841AP", + "screen_height_pixels": 896, + "screen_width_pixels": 414, + "simulator": false, + "storage_size": 63933894656, + "usable_memory": 2552430592 + }, + "os": { + "build": "20C5043e", + "kernel_version": "Darwin Kernel Version 22.2.0: Tue Nov 1 21:21:17 PDT 2022; root:xnu-8792.60.51.122.1~1/RELEASE_ARM64_T8020", + "name": "iOS", + "rooted": false, + "version": "16.2" + } + }, + "release": "io.sentry.sample.iOS-Swift@7.31.5+1" + }, + "debug": {} +} diff --git a/Tests/SentryTests/SentryCrash/CrashReport.swift b/Tests/SentryTests/SentryCrash/CrashReport.swift new file mode 100644 index 00000000000..6c99c34eef7 --- /dev/null +++ b/Tests/SentryTests/SentryCrash/CrashReport.swift @@ -0,0 +1,22 @@ +import XCTest + +extension XCTestCase { + + private func jsonDataOfResource(resource: String) throws -> Data { + let jsonPath = Bundle(for: type(of: self)).path(forResource: resource, ofType: "json") + return try Data(contentsOf: URL(fileURLWithPath: jsonPath ?? "")) + } + + func givenStoredSentryCrashReport(resource: String) throws { + let jsonData = try jsonDataOfResource(resource: resource) + jsonData.withUnsafeBytes { ( bytes: UnsafeRawBufferPointer) -> Void in + let pointer = bytes.bindMemory(to: Int8.self) + sentrycrashcrs_addUserReport(pointer.baseAddress, Int32(jsonData.count)) + } + } + + func getCrashReport(resource: String) throws -> [String: Any] { + let jsonData = try jsonDataOfResource(resource: resource) + return try JSONSerialization.jsonObject(with: jsonData, options: []) as! [String: Any] + } +} diff --git a/Tests/SentryTests/SentryCrash/CrashReportWriter.swift b/Tests/SentryTests/SentryCrash/CrashReportWriter.swift deleted file mode 100644 index 1abf941c9a7..00000000000 --- a/Tests/SentryTests/SentryCrash/CrashReportWriter.swift +++ /dev/null @@ -1,12 +0,0 @@ -import XCTest - -extension XCTestCase { - func givenStoredSentryCrashReport(resource: String) throws { - let jsonPath = Bundle(for: type(of: self)).path(forResource: resource, ofType: "json") - let jsonData = try Data(contentsOf: URL(fileURLWithPath: jsonPath ?? "")) - jsonData.withUnsafeBytes { ( bytes: UnsafeRawBufferPointer) -> Void in - let pointer = bytes.bindMemory(to: Int8.self) - sentrycrashcrs_addUserReport(pointer.baseAddress, Int32(jsonData.count)) - } - } -} diff --git a/Tests/SentryTests/SentryCrash/SentryCrashDoctorTests.swift b/Tests/SentryTests/SentryCrash/SentryCrashDoctorTests.swift new file mode 100644 index 00000000000..97740ff230e --- /dev/null +++ b/Tests/SentryTests/SentryCrash/SentryCrashDoctorTests.swift @@ -0,0 +1,20 @@ +import XCTest + +final class SentryCrashDoctorTests: XCTestCase { + + func testBadAccess() throws { + let report = try getCrashReport(resource: "Resources/crash-bad-access") + + let diagnose = SentryCrashDoctor().diagnoseCrash(report) + + XCTAssertEqual("EXC_ARM_DA_ALIGN at 0x13fd4582e.", diagnose) + } + + func testBadAccess_NoSubcode() throws { + let report = try getCrashReport(resource: "Resources/crash-bad-access-no-subcode") + + let diagnose = SentryCrashDoctor().diagnoseCrash(report) + + XCTAssertEqual("Attempted to dereference garbage pointer at 0x13fd4582e.", diagnose) + } +} diff --git a/Tests/SentryTests/SentryTests-Bridging-Header.h b/Tests/SentryTests/SentryTests-Bridging-Header.h index 7c9d405e3ba..42ae5b16674 100644 --- a/Tests/SentryTests/SentryTests-Bridging-Header.h +++ b/Tests/SentryTests/SentryTests-Bridging-Header.h @@ -36,6 +36,7 @@ #import "SentryCrashDebug.h" #import "SentryCrashDefaultBinaryImageProvider.h" #import "SentryCrashDefaultMachineContextWrapper.h" +#import "SentryCrashDoctor.h" #import "SentryCrashInstallationReporter.h" #import "SentryCrashIntegration+TestInit.h" #import "SentryCrashIntegration.h"