From 3db3e35c43af949b9d27185b9c534adf0c38fdde Mon Sep 17 00:00:00 2001 From: Philipp Hofmann Date: Wed, 14 Feb 2024 17:55:07 +0100 Subject: [PATCH 01/25] fix: Remove non-allowed file APIs (#3627) Remove usage of NSFileSystemFreeSize and NSFileSystemSize because Apple forbids our usage; see https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_use_of_required_reason_api?language=objc. Fixes GH-3590 --- CHANGELOG.md | 3 + Sources/Sentry/SentryClient.m | 3 +- Sources/Sentry/SentryCrashIntegration.m | 2 - Sources/Sentry/SentryCrashWrapper.m | 5 - Sources/Sentry/SentryExtraContextProvider.m | 1 - Sources/Sentry/include/SentryCrashWrapper.h | 2 - .../Monitors/SentryCrashMonitorContext.h | 2 - .../Monitors/SentryCrashMonitor_System.h | 1 - .../Monitors/SentryCrashMonitor_System.m | 30 -- Sources/SentryCrash/Recording/SentryCrash.m | 2 - .../SentryCrash/Recording/SentryCrashReport.c | 4 - .../Recording/SentryCrashReportFields.h | 2 - .../crash-report-legacy-storage-info.json | 444 ++++++++++++++++++ .../crash-report-without-device-context.json | 428 +++++++++++++++++ .../SentryExtraContextProviderTests.swift | 2 - Tests/SentryTests/SentryClientTests.swift | 5 - ...SentryCrashInstallationReporterTests.swift | 38 ++ .../SentryCrash/TestSentryCrashWrapper.h | 2 - .../SentryCrash/TestSentryCrashWrapper.m | 6 - 19 files changed, 914 insertions(+), 68 deletions(-) create mode 100644 Tests/Resources/crash-report-legacy-storage-info.json create mode 100644 Tests/Resources/crash-report-without-device-context.json diff --git a/CHANGELOG.md b/CHANGELOG.md index 1e0733b0bc3..842aff2a95d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,9 @@ - Finish TTID span when transaction finishes (#3610) - Dont take screenshot and view hierarchy for app hanging (#3620) +- Remove `free_storage` and `storage_size` from the device context (#3627), because Apple forbids sending +information retrieved via `NSFileSystemFreeSize` and `NSFileSystemSize` off a device; see +[Apple docs](https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_use_of_required_reason_api?language=objc). ## 8.20.0 diff --git a/Sources/Sentry/SentryClient.m b/Sources/Sentry/SentryClient.m index 82e79df0475..a93836b2372 100644 --- a/Sources/Sentry/SentryClient.m +++ b/Sources/Sentry/SentryClient.m @@ -628,7 +628,7 @@ - (SentryEvent *_Nullable)prepareEvent:(SentryEvent *)event // applicable [self removeExtraDeviceContextFromEvent:event]; } else if (!isCrashEvent) { - // Store the current free memory, free storage, battery level and more mutable properties, + // Store the current free memory battery level and more mutable properties, // at the time of this event, but not for crashes as the current data isn't guaranteed to be // the same as when the app crashed. [self applyExtraDeviceContextToEvent:event]; @@ -842,7 +842,6 @@ - (void)removeExtraDeviceContextFromEvent:(SentryEvent *)event key:@"device" block:^(NSMutableDictionary *device) { [device removeObjectForKey:SentryDeviceContextFreeMemoryKey]; - [device removeObjectForKey:@"free_storage"]; [device removeObjectForKey:@"orientation"]; [device removeObjectForKey:@"charging"]; [device removeObjectForKey:@"battery_level"]; diff --git a/Sources/Sentry/SentryCrashIntegration.m b/Sources/Sentry/SentryCrashIntegration.m index 795e12b0cf6..81843ba704b 100644 --- a/Sources/Sentry/SentryCrashIntegration.m +++ b/Sources/Sentry/SentryCrashIntegration.m @@ -266,8 +266,6 @@ + (void)enrichScope:(SentryScope *)scope crashWrapper:(SentryCrashWrapper *)cras [deviceData setValue:systemInfo[@"freeMemorySize"] forKey:SentryDeviceContextFreeMemoryKey]; [deviceData setValue:systemInfo[@"usableMemorySize"] forKey:@"usable_memory"]; [deviceData setValue:systemInfo[@"memorySize"] forKey:@"memory_size"]; - [deviceData setValue:systemInfo[@"totalStorageSize"] forKey:@"storage_size"]; - [deviceData setValue:systemInfo[@"freeStorageSize"] forKey:@"free_storage"]; [deviceData setValue:systemInfo[@"bootTime"] forKey:@"boot_time"]; NSString *locale = [[NSLocale autoupdatingCurrentLocale] objectForKey:NSLocaleIdentifier]; diff --git a/Sources/Sentry/SentryCrashWrapper.m b/Sources/Sentry/SentryCrashWrapper.m index 8f9da00e555..bb0a7035aa7 100644 --- a/Sources/Sentry/SentryCrashWrapper.m +++ b/Sources/Sentry/SentryCrashWrapper.m @@ -66,11 +66,6 @@ - (bytes)freeMemorySize return sentrycrashcm_system_freememory_size(); } -- (bytes)freeStorageSize -{ - return sentrycrashcm_system_freestorage_size(); -} - - (bytes)appMemorySize { task_vm_info_data_t info; diff --git a/Sources/Sentry/SentryExtraContextProvider.m b/Sources/Sentry/SentryExtraContextProvider.m index 672f06cf5a4..daa576f2379 100644 --- a/Sources/Sentry/SentryExtraContextProvider.m +++ b/Sources/Sentry/SentryExtraContextProvider.m @@ -42,7 +42,6 @@ - (NSDictionary *)getExtraDeviceContext NSMutableDictionary *extraDeviceContext = [[NSMutableDictionary alloc] init]; extraDeviceContext[SentryDeviceContextFreeMemoryKey] = @(self.crashWrapper.freeMemorySize); - extraDeviceContext[@"free_storage"] = @(self.crashWrapper.freeStorageSize); extraDeviceContext[@"processor_count"] = @([self.processInfoWrapper processorCount]); #if TARGET_OS_IOS && SENTRY_HAS_UIKIT diff --git a/Sources/Sentry/include/SentryCrashWrapper.h b/Sources/Sentry/include/SentryCrashWrapper.h index 159b3cbcac8..f86783edfcc 100644 --- a/Sources/Sentry/include/SentryCrashWrapper.h +++ b/Sources/Sentry/include/SentryCrashWrapper.h @@ -33,8 +33,6 @@ SENTRY_NO_INIT - (bytes)appMemorySize; -- (bytes)freeStorageSize; - @end NS_ASSUME_NONNULL_END diff --git a/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitorContext.h b/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitorContext.h index 08eec503539..55afa1e8773 100644 --- a/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitorContext.h +++ b/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitorContext.h @@ -198,8 +198,6 @@ typedef struct SentryCrash_MonitorContext { int parentProcessID; const char *deviceAppHash; const char *buildType; - uint64_t totalStorageSize; - uint64_t freeStorageSize; uint64_t memorySize; uint64_t freeMemorySize; uint64_t usableMemorySize; diff --git a/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_System.h b/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_System.h index 8fbe326b0ef..51f4630d43a 100644 --- a/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_System.h +++ b/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_System.h @@ -42,7 +42,6 @@ SentryCrashMonitorAPI *sentrycrashcm_system_getAPI(void); bool sentrycrash_isSimulatorBuild(void); bytes sentrycrashcm_system_freememory_size(void); -bytes sentrycrashcm_system_freestorage_size(void); #ifdef __cplusplus } diff --git a/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_System.m b/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_System.m index 7920ae04183..2e5be74a67c 100644 --- a/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_System.m +++ b/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_System.m @@ -75,8 +75,6 @@ int parentProcessID; const char *deviceAppHash; const char *buildType; - bytes totalStorageSize; - bytes freeStorageSize; bytes memorySize; } SystemData; @@ -494,30 +492,6 @@ return "unknown"; } -static bytes -getTotalStorageSize(void) -{ - NSNumber *storageSize = [[[NSFileManager defaultManager] - attributesOfFileSystemForPath:NSHomeDirectory() - error:nil] objectForKey:NSFileSystemSize]; - return storageSize.unsignedLongLongValue; -} - -static bytes -getFreeStorageSize(void) -{ - NSNumber *storageSize = [[[NSFileManager defaultManager] - attributesOfFileSystemForPath:NSHomeDirectory() - error:nil] objectForKey:NSFileSystemFreeSize]; - return storageSize.unsignedLongLongValue; -} - -bytes -sentrycrashcm_system_freestorage_size(void) -{ - return getFreeStorageSize(); -} - // ============================================================================ #pragma mark - API - // ============================================================================ @@ -598,8 +572,6 @@ g_systemData.parentProcessID = getppid(); g_systemData.deviceAppHash = getDeviceAndAppHash(); g_systemData.buildType = getBuildType(); - g_systemData.totalStorageSize = getTotalStorageSize(); - g_systemData.freeStorageSize = getFreeStorageSize(); g_systemData.memorySize = sentrycrashsysctl_uint64ForName("hw.memsize"); } } @@ -652,8 +624,6 @@ COPY_REFERENCE(parentProcessID); COPY_REFERENCE(deviceAppHash); COPY_REFERENCE(buildType); - COPY_REFERENCE(totalStorageSize); - COPY_REFERENCE(freeStorageSize); COPY_REFERENCE(memorySize); eventContext->System.freeMemorySize = freeMemorySize(); eventContext->System.usableMemorySize = usableMemorySize(); diff --git a/Sources/SentryCrash/Recording/SentryCrash.m b/Sources/SentryCrash/Recording/SentryCrash.m index 41605770dfd..129b2842433 100644 --- a/Sources/SentryCrash/Recording/SentryCrash.m +++ b/Sources/SentryCrash/Recording/SentryCrash.m @@ -210,8 +210,6 @@ - (NSDictionary *)systemInfo COPY_PRIMITIVE(parentProcessID); COPY_STRING(deviceAppHash); COPY_STRING(buildType); - COPY_PRIMITIVE(totalStorageSize); - COPY_PRIMITIVE(freeStorageSize); COPY_PRIMITIVE(memorySize); COPY_PRIMITIVE(freeMemorySize); COPY_PRIMITIVE(usableMemorySize); diff --git a/Sources/SentryCrash/Recording/SentryCrashReport.c b/Sources/SentryCrash/Recording/SentryCrashReport.c index f193275f10c..fa0ce25f8ca 100644 --- a/Sources/SentryCrash/Recording/SentryCrashReport.c +++ b/Sources/SentryCrash/Recording/SentryCrashReport.c @@ -1585,10 +1585,6 @@ writeSystemInfo(const SentryCrashReportWriter *const writer, const char *const k writer, SentryCrashField_DeviceAppHash, monitorContext->System.deviceAppHash); writer->addStringElement( writer, SentryCrashField_BuildType, monitorContext->System.buildType); - writer->addIntegerElement(writer, SentryCrashField_Total_Storage, - (int64_t)monitorContext->System.totalStorageSize); - writer->addIntegerElement( - writer, SentryCrashField_Free_Storage, (int64_t)monitorContext->System.freeStorageSize); writeMemoryInfo(writer, SentryCrashField_Memory, monitorContext); writeAppStats(writer, SentryCrashField_AppStats, monitorContext); diff --git a/Sources/SentryCrash/Recording/SentryCrashReportFields.h b/Sources/SentryCrash/Recording/SentryCrashReportFields.h index 8736d2b6ea0..ced530f5c32 100644 --- a/Sources/SentryCrash/Recording/SentryCrashReportFields.h +++ b/Sources/SentryCrash/Recording/SentryCrashReportFields.h @@ -205,8 +205,6 @@ #define SentryCrashField_ProcessID "process_id" #define SentryCrashField_ProcessName "process_name" #define SentryCrashField_Size "size" -#define SentryCrashField_Total_Storage "total_storage" -#define SentryCrashField_Free_Storage "free_storage" #define SentryCrashField_SystemName "system_name" #define SentryCrashField_SystemVersion "system_version" #define SentryCrashField_BuildType "build_type" diff --git a/Tests/Resources/crash-report-legacy-storage-info.json b/Tests/Resources/crash-report-legacy-storage-info.json new file mode 100644 index 00000000000..a7a57071c6b --- /dev/null +++ b/Tests/Resources/crash-report-legacy-storage-info.json @@ -0,0 +1,444 @@ +{ + "report": { + "version": "3.2.0", + "id": "ABE4FB7A-581C-41DF-B676-52210C1590B9", + "process_name": "iOS-Swift", + "timestamp": 1707826257, + "type": "standard" + }, + "binary_images": [ + { + "image_addr": 4363304960, + "image_vmaddr": 4294967296, + "image_size": 425984, + "name": "/Users/philipp.hofmann/Library/Developer/CoreSimulator/Devices/0E1EFAC8-A7EC-4B5B-88D6-68A3CD1E73AA/data/Containers/Bundle/Application/6194E858-F114-438A-90A0-FC6EF24128BE/iOS-Swift.app/iOS-Swift", + "uuid": "98CB99D4-0577-3119-B6E0-E00C6F6D59CC", + "cpu_type": 16777228, + "cpu_subtype": 0, + "major_version": 0, + "minor_version": 0, + "revision_version": 0 + } + ], + "process": {}, + "system": { + "system_name": "iOS", + "system_version": "17.0.1", + "machine": "iPhone15,4", + "model": "simulator", + "kernel_version": "Darwin Kernel Version 23.3.0: Wed Dec 20 21:31:00 PST 2023; root:xnu-10002.81.5~7/RELEASE_ARM64_T6020", + "os_version": "23D56", + "jailbroken": false, + "boot_time": "2024-02-12T15:55:31Z", + "app_start_time": "2024-02-13T12:10:54Z", + "CFBundleExecutablePath": "/Users/philipp.hofmann/Library/Developer/CoreSimulator/Devices/0E1EFAC8-A7EC-4B5B-88D6-68A3CD1E73AA/data/Containers/Bundle/Application/6194E858-F114-438A-90A0-FC6EF24128BE/iOS-Swift.app/iOS-Swift", + "CFBundleExecutable": "iOS-Swift", + "CFBundleIdentifier": "io.sentry.sample.iOS-Swift", + "CFBundleName": "iOS-Swift", + "CFBundleVersion": "1", + "CFBundleShortVersionString": "8.20.0", + "app_uuid": "98CB99D4-0577-3119-B6E0-E00C6F6D59CC", + "cpu_arch": "arm64", + "cpu_type": 16777228, + "cpu_subtype": 2, + "binary_cpu_type": 16777228, + "binary_cpu_subtype": 0, + "process_name": "iOS-Swift", + "process_id": 17814, + "parent_process_id": 17092, + "device_app_hash": "4bb87ace435d51a45c8f98df9a86c87c5facd1fc", + "build_type": "simulator", + "total_storage": 994662584320, + "free_storage": 278914420736, + "memory": { + "size": 68719476736, + "usable": 57179553792, + "free": 256245760 + }, + "application_stats": { + "application_active": true, + "application_in_foreground": true, + "launches_since_last_crash": 8, + "sessions_since_last_crash": 8, + "active_time_since_last_crash": 0, + "background_time_since_last_crash": 0, + "sessions_since_launch": 1, + "active_time_since_launch": 0, + "background_time_since_launch": 0 + } + }, + "crash": { + "error": { + "mach": { + "exception": 1, + "exception_name": "EXC_BAD_ACCESS", + "code": 1, + "code_name": "KERN_INVALID_ADDRESS", + "subcode": 0 + }, + "signal": { + "signal": 11, + "name": "SIGSEGV", + "code": 0, + "code_name": "SEGV_NOOP" + }, + "address": 0, + "type": "mach" + }, + "threads": [ + { + "backtrace": { + "contents": [ + { + "object_name": "Sentry", + "object_addr": 4383588352, + "symbol_name": "", + "symbol_addr": 4384278748, + "instruction_addr": 4384278768 + }, + { + "object_name": "iOS-Swift", + "object_addr": 4363304960, + "symbol_name": "$s9iOS_Swift20ErrorsViewControllerC5crashyySo8UIButtonCF", + "symbol_addr": 4363557164, + "instruction_addr": 4363557216 + }, + { + "object_name": "iOS-Swift", + "object_addr": 4363304960, + "symbol_name": "", + "symbol_addr": 4363557228, + "instruction_addr": 4363557280 + }, + { + "object_name": "UIKitCore", + "object_addr": 6516912128, + "symbol_name": "-[UIApplication sendAction:to:from:forEvent:]", + "symbol_addr": 6529220144, + "instruction_addr": 6529220240 + }, + { + "object_name": "Sentry", + "object_addr": 4383588352, + "symbol_name": "", + "symbol_addr": 4384082644, + "instruction_addr": 4384082844 + }, + { + "object_name": "UIKitCore", + "object_addr": 6516912128, + "symbol_name": "-[UIControl sendAction:to:forEvent:]", + "symbol_addr": 6522034536, + "instruction_addr": 6522034644 + }, + { + "object_name": "UIKitCore", + "object_addr": 6516912128, + "symbol_name": "-[UIControl _sendActionsForEvents:withEvent:]", + "symbol_addr": 6522035212, + "instruction_addr": 6522035480 + }, + { + "object_name": "UIKitCore", + "object_addr": 6516912128, + "symbol_name": "-[UIButton _sendActionsForEvents:withEvent:]", + "symbol_addr": 6522021856, + "instruction_addr": 6522021976 + }, + { + "object_name": "UIKitCore", + "object_addr": 6516912128, + "symbol_name": "-[UIControl touchesEnded:withEvent:]", + "symbol_addr": 6522030284, + "instruction_addr": 6522030676 + }, + { + "object_name": "UIKitCore", + "object_addr": 6516912128, + "symbol_name": "-[UIWindow _sendTouchesForEvent:]", + "symbol_addr": 6529429928, + "instruction_addr": 6529430828 + }, + { + "object_name": "UIKitCore", + "object_addr": 6516912128, + "symbol_name": "-[UIWindow sendEvent:]", + "symbol_addr": 6529433072, + "instruction_addr": 6529436176 + }, + { + "object_name": "UIKitCore", + "object_addr": 6516912128, + "symbol_name": "-[UIApplication sendEvent:]", + "symbol_addr": 6529303628, + "instruction_addr": 6529304204 + }, + { + "object_name": "UIKit", + "object_addr": 7481049088, + "symbol_name": "-[UIApplicationAccessibility sendEvent:]", + "symbol_addr": 7481228444, + "instruction_addr": 7481228536 + }, + { + "object_name": "UIKitCore", + "object_addr": 6516912128, + "symbol_name": "__dispatchPreprocessedEventFromEventQueue", + "symbol_addr": 6529825128, + "instruction_addr": 6529826836 + }, + { + "object_name": "UIKitCore", + "object_addr": 6516912128, + "symbol_name": "__processEventQueue", + "symbol_addr": 6529833268, + "instruction_addr": 6529838788 + }, + { + "object_name": "UIKitCore", + "object_addr": 6516912128, + "symbol_name": "__eventFetcherSourceCallback", + "symbol_addr": 6529810108, + "instruction_addr": 6529810264 + }, + { + "object_name": "CoreFoundation", + "object_addr": 6445993984, + "symbol_name": "__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__", + "symbol_addr": 6446573188, + "instruction_addr": 6446573212 + }, + { + "object_name": "CoreFoundation", + "object_addr": 6445993984, + "symbol_name": "__CFRunLoopDoSource0", + "symbol_addr": 6446572856, + "instruction_addr": 6446573028 + }, + { + "object_name": "CoreFoundation", + "object_addr": 6445993984, + "symbol_name": "__CFRunLoopDoSources0", + "symbol_addr": 6446570604, + "instruction_addr": 6446570836 + }, + { + "object_name": "CoreFoundation", + "object_addr": 6445993984, + "symbol_name": "__CFRunLoopRun", + "symbol_addr": 6446547260, + "instruction_addr": 6446548028 + }, + { + "object_name": "CoreFoundation", + "object_addr": 6445993984, + "symbol_name": "CFRunLoopRunSpecific", + "symbol_addr": 6446545644, + "instruction_addr": 6446546216 + }, + { + "object_name": "GraphicsServices", + "object_addr": 6685499392, + "symbol_name": "GSEventRunModal", + "symbol_addr": 6685514528, + "instruction_addr": 6685514688 + }, + { + "object_name": "UIKitCore", + "object_addr": 6516912128, + "symbol_name": "-[UIApplication _run]", + "symbol_addr": 6529199224, + "instruction_addr": 6529200092 + }, + { + "object_name": "UIKitCore", + "object_addr": 6516912128, + "symbol_name": "UIApplicationMain", + "symbol_addr": 6529215448, + "instruction_addr": 6529215572 + }, + { + "object_name": "iOS-Swift", + "object_addr": 4363304960, + "symbol_name": "main", + "symbol_addr": 4363441632, + "instruction_addr": 4363441696 + }, + { + "instruction_addr": 4365768024 + }, + { + "instruction_addr": 4367130848 + } + ], + "skipped": 0 + }, + "registers": { + "basic": { + "x0": 4385128440, + "x1": 4384844146, + "x2": 4404141392, + "x3": 105553176740880, + "x4": 4404141392, + "x5": 105553176740880, + "x6": 10, + "x7": 1, + "x8": 0, + "x9": 854268, + "x10": 105553162603560, + "x11": 2, + "x12": 105553162603552, + "x13": 0, + "x14": 0, + "x15": 18446744073709551615, + "x16": 4385128482, + "x17": 4384278748, + "x18": 0, + "x19": 105553176740880, + "x20": 4368627504, + "x21": 4404141392, + "x22": 4363709787, + "x23": 105553116414048, + "x24": 8321801184, + "x25": 105553129294320, + "x26": 4363709787, + "x27": 4368627504, + "x28": 1, + "fp": 6103563328, + "lr": 4363557216, + "sp": 6103563280, + "pc": 4384278768, + "cpsr": 1073745920 + }, + "exception": { + "exception": 0, + "esr": 2449473606, + "far": 0 + } + }, + "index": 0, + "crashed": true, + "current_thread": false, + "stack": { + "grow_direction": "-", + "dump_start": 6103563200, + "dump_end": 6103563440, + "stack_pointer": 6103563280, + "overflow": false, + "contents": "C91B74DD3352DBD4FB3247DC75CB5EEEF8BF5F050100000072695B050100000050DD81060100000010C49A030060000050DD81060100000010C49A03006000000A00000000000000010000000000000000B0190401000000000000000000000072695B0501000000F8BF5F050100000030F763040100000050DD81060100000070FCCC6B01000000A09916040100000030F763040100000050DD81060100000030F763040100000010C49A0300600000A0FCCC6B0100000090FE2B850100000010C49A03006000005BED18040100000050DD81060100000030F763040100000030FDCC6B010000009CCB4F0501000000" + }, + "notable_addresses": { + "x0": { + "address": 4385128440, + "type": "objc_class", + "class": "SentrySDK" + }, + "x1": { + "address": 4384844146, + "type": "string", + "value": "crash" + }, + "x22": { + "address": 4363709787, + "type": "string", + "value": "crash:" + }, + "x26": { + "address": 4363709787, + "type": "string", + "value": "crash:" + }, + "stack@0x16bccfbc8": { + "address": 17176389735904916219, + "type": "objc_object", + "class": "NSDate", + "value": -9.53269e+182 + }, + "stack@0x16bccfbd0": { + "address": 4385128440, + "type": "objc_class", + "class": "SentrySDK" + }, + "stack@0x16bccfbd8": { + "address": 4384844146, + "type": "string", + "value": "crash" + }, + "stack@0x16bccfc20": { + "address": 4384844146, + "type": "string", + "value": "crash" + }, + "stack@0x16bccfc28": { + "address": 4385128440, + "type": "objc_class", + "class": "SentrySDK" + }, + "stack@0x16bccfc88": { + "address": 4363709787, + "type": "string", + "value": "crash:" + } + } + } + ] + }, + "sentry_sdk_scope": { + "breadcrumbs": [ + { + "category": "started", + "level": "info", + "message": "Breadcrumb Tracking", + "timestamp": "2024-02-13T12:10:54.920Z", + "type": "debug" + } + ] + }, + "user": { + "context": { + "app": { + "app_build": "1", + "app_id": "98CB99D4-0577-3119-B6E0-E00C6F6D59CC", + "app_identifier": "io.sentry.sample.iOS-Swift", + "app_name": "iOS-Swift", + "app_start_time": "2024-02-13T12:10:54Z", + "app_version": "8.20.0", + "build_type": "simulator", + "device_app_hash": "4bb87ace435d51a45c8f98df9a86c87c5facd1fc" + }, + "device": { + "arch": "arm64", + "boot_time": "2024-02-12T15:55:31Z", + "family": "iOS", + "free_memory": 365182976, + "free_storage": 278914420736, + "locale": "en_US", + "memory_size": 68719476736, + "model": "iPhone15,4", + "model_id": "simulator", + "screen_height_pixels": 852, + "screen_width_pixels": 393, + "simulator": true, + "storage_size": 994662584320, + "usable_memory": 57178783744 + }, + "os": { + "build": "23D56", + "kernel_version": "Darwin Kernel Version 23.3.0: Wed Dec 20 21:31:00 PST 2023; root:xnu-10002.81.5~7/RELEASE_ARM64_T6020", + "name": "iOS", + "rooted": false, + "version": "17.0.1" + } + }, + "environment": "debug", + "release": "io.sentry.sample.iOS-Swift@8.20.0+1", + "tags": { + "language": "swift" + }, + "user": { + "email": "tony@example.com", + "id": "1" + } + }, + "debug": {} +} diff --git a/Tests/Resources/crash-report-without-device-context.json b/Tests/Resources/crash-report-without-device-context.json new file mode 100644 index 00000000000..70d750619db --- /dev/null +++ b/Tests/Resources/crash-report-without-device-context.json @@ -0,0 +1,428 @@ +{ + "report": { + "version": "3.2.0", + "id": "ABE4FB7A-581C-41DF-B676-52210C1590B9", + "process_name": "iOS-Swift", + "timestamp": 1707826257, + "type": "standard" + }, + "binary_images": [ + { + "image_addr": 4363304960, + "image_vmaddr": 4294967296, + "image_size": 425984, + "name": "/Users/philipp.hofmann/Library/Developer/CoreSimulator/Devices/0E1EFAC8-A7EC-4B5B-88D6-68A3CD1E73AA/data/Containers/Bundle/Application/6194E858-F114-438A-90A0-FC6EF24128BE/iOS-Swift.app/iOS-Swift", + "uuid": "98CB99D4-0577-3119-B6E0-E00C6F6D59CC", + "cpu_type": 16777228, + "cpu_subtype": 0, + "major_version": 0, + "minor_version": 0, + "revision_version": 0 + } + ], + "process": {}, + "system": { + "system_name": "iOS", + "system_version": "17.0.1", + "machine": "iPhone15,4", + "model": "simulator", + "kernel_version": "Darwin Kernel Version 23.3.0: Wed Dec 20 21:31:00 PST 2023; root:xnu-10002.81.5~7/RELEASE_ARM64_T6020", + "os_version": "23D56", + "jailbroken": false, + "boot_time": "2024-02-12T15:55:31Z", + "app_start_time": "2024-02-13T12:10:54Z", + "CFBundleExecutablePath": "/Users/philipp.hofmann/Library/Developer/CoreSimulator/Devices/0E1EFAC8-A7EC-4B5B-88D6-68A3CD1E73AA/data/Containers/Bundle/Application/6194E858-F114-438A-90A0-FC6EF24128BE/iOS-Swift.app/iOS-Swift", + "CFBundleExecutable": "iOS-Swift", + "CFBundleIdentifier": "io.sentry.sample.iOS-Swift", + "CFBundleName": "iOS-Swift", + "CFBundleVersion": "1", + "CFBundleShortVersionString": "8.20.0", + "app_uuid": "98CB99D4-0577-3119-B6E0-E00C6F6D59CC", + "cpu_arch": "arm64", + "cpu_type": 16777228, + "cpu_subtype": 2, + "binary_cpu_type": 16777228, + "binary_cpu_subtype": 0, + "process_name": "iOS-Swift", + "process_id": 17814, + "parent_process_id": 17092, + "device_app_hash": "4bb87ace435d51a45c8f98df9a86c87c5facd1fc", + "build_type": "simulator", + "total_storage": 994662584320, + "free_storage": 278914420736, + "memory": { + "size": 68719476736, + "usable": 57179553792, + "free": 256245760 + }, + "application_stats": { + "application_active": true, + "application_in_foreground": true, + "launches_since_last_crash": 8, + "sessions_since_last_crash": 8, + "active_time_since_last_crash": 0, + "background_time_since_last_crash": 0, + "sessions_since_launch": 1, + "active_time_since_launch": 0, + "background_time_since_launch": 0 + } + }, + "crash": { + "error": { + "mach": { + "exception": 1, + "exception_name": "EXC_BAD_ACCESS", + "code": 1, + "code_name": "KERN_INVALID_ADDRESS", + "subcode": 0 + }, + "signal": { + "signal": 11, + "name": "SIGSEGV", + "code": 0, + "code_name": "SEGV_NOOP" + }, + "address": 0, + "type": "mach" + }, + "threads": [ + { + "backtrace": { + "contents": [ + { + "object_name": "Sentry", + "object_addr": 4383588352, + "symbol_name": "", + "symbol_addr": 4384278748, + "instruction_addr": 4384278768 + }, + { + "object_name": "iOS-Swift", + "object_addr": 4363304960, + "symbol_name": "$s9iOS_Swift20ErrorsViewControllerC5crashyySo8UIButtonCF", + "symbol_addr": 4363557164, + "instruction_addr": 4363557216 + }, + { + "object_name": "iOS-Swift", + "object_addr": 4363304960, + "symbol_name": "", + "symbol_addr": 4363557228, + "instruction_addr": 4363557280 + }, + { + "object_name": "UIKitCore", + "object_addr": 6516912128, + "symbol_name": "-[UIApplication sendAction:to:from:forEvent:]", + "symbol_addr": 6529220144, + "instruction_addr": 6529220240 + }, + { + "object_name": "Sentry", + "object_addr": 4383588352, + "symbol_name": "", + "symbol_addr": 4384082644, + "instruction_addr": 4384082844 + }, + { + "object_name": "UIKitCore", + "object_addr": 6516912128, + "symbol_name": "-[UIControl sendAction:to:forEvent:]", + "symbol_addr": 6522034536, + "instruction_addr": 6522034644 + }, + { + "object_name": "UIKitCore", + "object_addr": 6516912128, + "symbol_name": "-[UIControl _sendActionsForEvents:withEvent:]", + "symbol_addr": 6522035212, + "instruction_addr": 6522035480 + }, + { + "object_name": "UIKitCore", + "object_addr": 6516912128, + "symbol_name": "-[UIButton _sendActionsForEvents:withEvent:]", + "symbol_addr": 6522021856, + "instruction_addr": 6522021976 + }, + { + "object_name": "UIKitCore", + "object_addr": 6516912128, + "symbol_name": "-[UIControl touchesEnded:withEvent:]", + "symbol_addr": 6522030284, + "instruction_addr": 6522030676 + }, + { + "object_name": "UIKitCore", + "object_addr": 6516912128, + "symbol_name": "-[UIWindow _sendTouchesForEvent:]", + "symbol_addr": 6529429928, + "instruction_addr": 6529430828 + }, + { + "object_name": "UIKitCore", + "object_addr": 6516912128, + "symbol_name": "-[UIWindow sendEvent:]", + "symbol_addr": 6529433072, + "instruction_addr": 6529436176 + }, + { + "object_name": "UIKitCore", + "object_addr": 6516912128, + "symbol_name": "-[UIApplication sendEvent:]", + "symbol_addr": 6529303628, + "instruction_addr": 6529304204 + }, + { + "object_name": "UIKit", + "object_addr": 7481049088, + "symbol_name": "-[UIApplicationAccessibility sendEvent:]", + "symbol_addr": 7481228444, + "instruction_addr": 7481228536 + }, + { + "object_name": "UIKitCore", + "object_addr": 6516912128, + "symbol_name": "__dispatchPreprocessedEventFromEventQueue", + "symbol_addr": 6529825128, + "instruction_addr": 6529826836 + }, + { + "object_name": "UIKitCore", + "object_addr": 6516912128, + "symbol_name": "__processEventQueue", + "symbol_addr": 6529833268, + "instruction_addr": 6529838788 + }, + { + "object_name": "UIKitCore", + "object_addr": 6516912128, + "symbol_name": "__eventFetcherSourceCallback", + "symbol_addr": 6529810108, + "instruction_addr": 6529810264 + }, + { + "object_name": "CoreFoundation", + "object_addr": 6445993984, + "symbol_name": "__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__", + "symbol_addr": 6446573188, + "instruction_addr": 6446573212 + }, + { + "object_name": "CoreFoundation", + "object_addr": 6445993984, + "symbol_name": "__CFRunLoopDoSource0", + "symbol_addr": 6446572856, + "instruction_addr": 6446573028 + }, + { + "object_name": "CoreFoundation", + "object_addr": 6445993984, + "symbol_name": "__CFRunLoopDoSources0", + "symbol_addr": 6446570604, + "instruction_addr": 6446570836 + }, + { + "object_name": "CoreFoundation", + "object_addr": 6445993984, + "symbol_name": "__CFRunLoopRun", + "symbol_addr": 6446547260, + "instruction_addr": 6446548028 + }, + { + "object_name": "CoreFoundation", + "object_addr": 6445993984, + "symbol_name": "CFRunLoopRunSpecific", + "symbol_addr": 6446545644, + "instruction_addr": 6446546216 + }, + { + "object_name": "GraphicsServices", + "object_addr": 6685499392, + "symbol_name": "GSEventRunModal", + "symbol_addr": 6685514528, + "instruction_addr": 6685514688 + }, + { + "object_name": "UIKitCore", + "object_addr": 6516912128, + "symbol_name": "-[UIApplication _run]", + "symbol_addr": 6529199224, + "instruction_addr": 6529200092 + }, + { + "object_name": "UIKitCore", + "object_addr": 6516912128, + "symbol_name": "UIApplicationMain", + "symbol_addr": 6529215448, + "instruction_addr": 6529215572 + }, + { + "object_name": "iOS-Swift", + "object_addr": 4363304960, + "symbol_name": "main", + "symbol_addr": 4363441632, + "instruction_addr": 4363441696 + }, + { + "instruction_addr": 4365768024 + }, + { + "instruction_addr": 4367130848 + } + ], + "skipped": 0 + }, + "registers": { + "basic": { + "x0": 4385128440, + "x1": 4384844146, + "x2": 4404141392, + "x3": 105553176740880, + "x4": 4404141392, + "x5": 105553176740880, + "x6": 10, + "x7": 1, + "x8": 0, + "x9": 854268, + "x10": 105553162603560, + "x11": 2, + "x12": 105553162603552, + "x13": 0, + "x14": 0, + "x15": 18446744073709551615, + "x16": 4385128482, + "x17": 4384278748, + "x18": 0, + "x19": 105553176740880, + "x20": 4368627504, + "x21": 4404141392, + "x22": 4363709787, + "x23": 105553116414048, + "x24": 8321801184, + "x25": 105553129294320, + "x26": 4363709787, + "x27": 4368627504, + "x28": 1, + "fp": 6103563328, + "lr": 4363557216, + "sp": 6103563280, + "pc": 4384278768, + "cpsr": 1073745920 + }, + "exception": { + "exception": 0, + "esr": 2449473606, + "far": 0 + } + }, + "index": 0, + "crashed": true, + "current_thread": false, + "stack": { + "grow_direction": "-", + "dump_start": 6103563200, + "dump_end": 6103563440, + "stack_pointer": 6103563280, + "overflow": false, + "contents": "C91B74DD3352DBD4FB3247DC75CB5EEEF8BF5F050100000072695B050100000050DD81060100000010C49A030060000050DD81060100000010C49A03006000000A00000000000000010000000000000000B0190401000000000000000000000072695B0501000000F8BF5F050100000030F763040100000050DD81060100000070FCCC6B01000000A09916040100000030F763040100000050DD81060100000030F763040100000010C49A0300600000A0FCCC6B0100000090FE2B850100000010C49A03006000005BED18040100000050DD81060100000030F763040100000030FDCC6B010000009CCB4F0501000000" + }, + "notable_addresses": { + "x0": { + "address": 4385128440, + "type": "objc_class", + "class": "SentrySDK" + }, + "x1": { + "address": 4384844146, + "type": "string", + "value": "crash" + }, + "x22": { + "address": 4363709787, + "type": "string", + "value": "crash:" + }, + "x26": { + "address": 4363709787, + "type": "string", + "value": "crash:" + }, + "stack@0x16bccfbc8": { + "address": 17176389735904916219, + "type": "objc_object", + "class": "NSDate", + "value": -9.53269e+182 + }, + "stack@0x16bccfbd0": { + "address": 4385128440, + "type": "objc_class", + "class": "SentrySDK" + }, + "stack@0x16bccfbd8": { + "address": 4384844146, + "type": "string", + "value": "crash" + }, + "stack@0x16bccfc20": { + "address": 4384844146, + "type": "string", + "value": "crash" + }, + "stack@0x16bccfc28": { + "address": 4385128440, + "type": "objc_class", + "class": "SentrySDK" + }, + "stack@0x16bccfc88": { + "address": 4363709787, + "type": "string", + "value": "crash:" + } + } + } + ] + }, + "sentry_sdk_scope": { + "breadcrumbs": [ + { + "category": "started", + "level": "info", + "message": "Breadcrumb Tracking", + "timestamp": "2024-02-13T12:10:54.920Z", + "type": "debug" + } + ] + }, + "user": { + "context": { + "app": { + "app_build": "1", + "app_id": "98CB99D4-0577-3119-B6E0-E00C6F6D59CC", + "app_identifier": "io.sentry.sample.iOS-Swift", + "app_name": "iOS-Swift", + "app_start_time": "2024-02-13T12:10:54Z", + "app_version": "8.20.0", + "build_type": "simulator", + "device_app_hash": "4bb87ace435d51a45c8f98df9a86c87c5facd1fc" + }, + "os": { + "build": "23D56", + "kernel_version": "Darwin Kernel Version 23.3.0: Wed Dec 20 21:31:00 PST 2023; root:xnu-10002.81.5~7/RELEASE_ARM64_T6020", + "name": "iOS", + "rooted": false, + "version": "17.0.1" + } + }, + "environment": "debug", + "release": "io.sentry.sample.iOS-Swift@8.20.0+1", + "tags": { + "language": "swift" + }, + "user": { + "email": "tony@example.com", + "id": "1" + } + }, + "debug": {} +} diff --git a/Tests/SentryTests/Helper/SentryExtraContextProviderTests.swift b/Tests/SentryTests/Helper/SentryExtraContextProviderTests.swift index d27109dc3d7..3f7aaddb092 100644 --- a/Tests/SentryTests/Helper/SentryExtraContextProviderTests.swift +++ b/Tests/SentryTests/Helper/SentryExtraContextProviderTests.swift @@ -36,7 +36,6 @@ final class SentryExtraContextProviderTests: XCTestCase { let sut = fixture.getSut() fixture.crashWrapper.internalFreeMemorySize = 123_456 fixture.crashWrapper.internalAppMemorySize = 234_567 - fixture.crashWrapper.internalFreeStorageSize = 345_678 let actualContext = sut.getExtraContext() let device = actualContext["device"] as? [String: Any] @@ -44,7 +43,6 @@ final class SentryExtraContextProviderTests: XCTestCase { XCTAssertEqual(device?["free_memory"] as? UInt64, fixture.crashWrapper.internalFreeMemorySize) XCTAssertEqual(app?["app_memory"] as? UInt64, fixture.crashWrapper.internalAppMemorySize) - XCTAssertEqual(device?["free_storage"] as? UInt64, fixture.crashWrapper.internalFreeStorageSize) } func testExtraDeviceInfo() { diff --git a/Tests/SentryTests/SentryClientTests.swift b/Tests/SentryTests/SentryClientTests.swift index b650280d35f..fcc7afb8e17 100644 --- a/Tests/SentryTests/SentryClientTests.swift +++ b/Tests/SentryTests/SentryClientTests.swift @@ -64,7 +64,6 @@ class SentryClientTest: XCTestCase { crashWrapper.internalFreeMemorySize = 123_456 crashWrapper.internalAppMemorySize = 234_567 - crashWrapper.internalFreeStorageSize = 345_678 #if os(iOS) || targetEnvironment(macCatalyst) SentryDependencyContainer.sharedInstance().uiDeviceWrapper = deviceWrapper @@ -729,7 +728,6 @@ class SentryClientTest: XCTestCase { try assertLastSentEventWithAttachment { event in XCTAssertEqual(oomEvent.eventId, event.eventId) XCTAssertNil(event.context?["device"]?["free_memory"]) - XCTAssertNil(event.context?["device"]?["free_storage"]) XCTAssertNil(event.context?["device"]?["orientation"]) XCTAssertNil(event.context?["device"]?["charging"]) XCTAssertNil(event.context?["device"]?["battery_level"]) @@ -804,9 +802,6 @@ class SentryClientTest: XCTestCase { let eventAppMemory = actual.context?["app"]?["app_memory"] as? Int XCTAssertEqual(eventAppMemory, 234_567) - let eventFreeStorage = actual.context?["device"]?["free_storage"] as? Int - XCTAssertEqual(eventFreeStorage, 345_678) - let cpuCoreCount = actual.context?["device"]?["processor_count"] as? UInt XCTAssertEqual(fixture.processWrapper.processorCount, cpuCoreCount) } diff --git a/Tests/SentryTests/SentryCrash/SentryCrashInstallationReporterTests.swift b/Tests/SentryTests/SentryCrash/SentryCrashInstallationReporterTests.swift index adf6ebef499..3493d135ec5 100644 --- a/Tests/SentryTests/SentryCrash/SentryCrashInstallationReporterTests.swift +++ b/Tests/SentryTests/SentryCrash/SentryCrashInstallationReporterTests.swift @@ -28,6 +28,44 @@ class SentryCrashInstallationReporterTests: XCTestCase { expect(sentrycrash_getReportCount()) == 0 } + /** + * Validates that handling a crash report with the removed fields total_storage and free_storage works. + */ + func testShouldCaptureCrashReportWithLegacyStorageInfo() throws { + givenSutWithStartedSDK() + + try givenStoredSentryCrashReport(resource: "Resources/crash-report-legacy-storage-info") + + sut.sendAllReports { filteredReports, _, _ in + expect(filteredReports?.count) == 1 + } + + expect(self.testClient.captureCrashEventInvocations.count) == 1 + expect(sentrycrash_getReportCount()) == 0 + + let event = self.testClient.captureCrashEventInvocations.last?.event + expect(event?.context?["device"]?["free_storage"] as? Int) == 278_914_420_736 + // total_storage got converted to storage_size + expect(event?.context?["device"]?["storage_size"] as? Int) == 994_662_584_320 + } + + func testShouldCaptureCrashReportWithoutDeviceContext() throws { + givenSutWithStartedSDK() + + try givenStoredSentryCrashReport(resource: "Resources/crash-report-without-device-context") + + sut.sendAllReports { filteredReports, _, _ in + expect(filteredReports?.count) == 1 + } + + expect(self.testClient.captureCrashEventInvocations.count) == 1 + expect(sentrycrash_getReportCount()) == 0 + + let event = self.testClient.captureCrashEventInvocations.last?.event + expect(event?.context?["device"]) == nil + expect(event?.context?["app"]?["app_name"] as? String) == "iOS-Swift" + } + func testFaultyReportIsNotSentAndDeleted() throws { givenSutWithStartedSDK() diff --git a/Tests/SentryTests/SentryCrash/TestSentryCrashWrapper.h b/Tests/SentryTests/SentryCrash/TestSentryCrashWrapper.h index 7d61ab46c24..6599019fc75 100644 --- a/Tests/SentryTests/SentryCrash/TestSentryCrashWrapper.h +++ b/Tests/SentryTests/SentryCrash/TestSentryCrashWrapper.h @@ -31,8 +31,6 @@ SENTRY_NO_INIT @property (nonatomic, assign) uint64_t internalAppMemorySize; -@property (nonatomic, assign) uint64_t internalFreeStorageSize; - @property (nonatomic) BOOL binaryCacheStarted; @property (nonatomic) BOOL binaryCacheStopped; diff --git a/Tests/SentryTests/SentryCrash/TestSentryCrashWrapper.m b/Tests/SentryTests/SentryCrash/TestSentryCrashWrapper.m index b4882f9a5cf..3c0b6f875d7 100644 --- a/Tests/SentryTests/SentryCrash/TestSentryCrashWrapper.m +++ b/Tests/SentryTests/SentryCrash/TestSentryCrashWrapper.m @@ -17,7 +17,6 @@ + (instancetype)sharedInstance instance.uninstallAsyncHooksCalled = NO; instance.internalFreeMemorySize = 0; instance.internalAppMemorySize = 0; - instance.internalFreeStorageSize = 0; return instance; } @@ -88,9 +87,4 @@ - (bytes)appMemorySize return self.internalAppMemorySize; } -- (bytes)freeStorageSize -{ - return self.internalFreeStorageSize; -} - @end From 0a12181c582c75899c1209660f87ec3bb2a70717 Mon Sep 17 00:00:00 2001 From: Andrew McKnight Date: Thu, 15 Feb 2024 16:31:41 +0800 Subject: [PATCH 02/25] fix(profiling): slice samples serially, not concurrently (#3632) --- Sources/Sentry/SentryProfileTimeseries.mm | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/Sources/Sentry/SentryProfileTimeseries.mm b/Sources/Sentry/SentryProfileTimeseries.mm index 0a9ec459e15..faa3c11bc53 100644 --- a/Sources/Sentry/SentryProfileTimeseries.mm +++ b/Sources/Sentry/SentryProfileTimeseries.mm @@ -46,13 +46,11 @@ return nil; } - const auto firstIndex = - [samples indexOfObjectWithOptions:NSEnumerationConcurrent - passingTest:^BOOL(SentrySample *_Nonnull sample, NSUInteger idx, - BOOL *_Nonnull stop) { - *stop = sample.absoluteTimestamp >= startSystemTime; - return *stop; - }]; + const auto firstIndex = [samples indexOfObjectPassingTest:^BOOL( + SentrySample *_Nonnull sample, NSUInteger idx, BOOL *_Nonnull stop) { + *stop = sample.absoluteTimestamp >= startSystemTime; + return *stop; + }]; if (firstIndex == NSNotFound) { logSlicingFailureWithArray(samples, startSystemTime, endSystemTime, /*start*/ YES); @@ -62,7 +60,7 @@ } const auto lastIndex = - [samples indexOfObjectWithOptions:NSEnumerationConcurrent | NSEnumerationReverse + [samples indexOfObjectWithOptions:NSEnumerationReverse passingTest:^BOOL(SentrySample *_Nonnull sample, NSUInteger idx, BOOL *_Nonnull stop) { *stop = sample.absoluteTimestamp <= endSystemTime; From a9608cdc294b93c24b6f626ce0279e7330ec2f53 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 15 Feb 2024 11:34:50 +0100 Subject: [PATCH 03/25] build(deps): bump cocoapods from 1.15.0 to 1.15.2 (#3628) Bumps [cocoapods](https://github.com/CocoaPods/CocoaPods) from 1.15.0 to 1.15.2. - [Release notes](https://github.com/CocoaPods/CocoaPods/releases) - [Changelog](https://github.com/CocoaPods/CocoaPods/blob/master/CHANGELOG.md) - [Commits](https://github.com/CocoaPods/CocoaPods/compare/1.15.0...1.15.2) --- updated-dependencies: - dependency-name: cocoapods dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Philipp Hofmann --- Gemfile.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 4ed725fcd8a..ef1bcddb331 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -41,10 +41,10 @@ GEM bigdecimal (3.1.6) claide (1.1.0) clamp (1.3.2) - cocoapods (1.15.0) + cocoapods (1.15.2) addressable (~> 2.8) claide (>= 1.0.2, < 2.0) - cocoapods-core (= 1.15.0) + cocoapods-core (= 1.15.2) cocoapods-deintegrate (>= 1.0.3, < 2.0) cocoapods-downloader (>= 2.1, < 3.0) cocoapods-plugins (>= 1.0.0, < 2.0) @@ -59,7 +59,7 @@ GEM nap (~> 1.0) ruby-macho (>= 2.3.0, < 3.0) xcodeproj (>= 1.23.0, < 2.0) - cocoapods-core (1.15.0) + cocoapods-core (1.15.2) activesupport (>= 5.0, < 8) addressable (~> 2.8) algoliasearch (~> 1.0) @@ -225,7 +225,7 @@ GEM mini_magick (4.12.0) mini_mime (1.1.5) mini_portile2 (2.8.5) - minitest (5.21.2) + minitest (5.22.2) molinillo (0.8.0) multi_json (1.15.0) multipart-post (2.3.0) From 83887aff6461a3c4738c6852d55faaef69cd1d98 Mon Sep 17 00:00:00 2001 From: Philipp Hofmann Date: Thu, 15 Feb 2024 14:29:26 +0100 Subject: [PATCH 04/25] ref: Add multiple transports to TransportAdapter (#3641) Add the possibility to add multiple transports in the TransportAdapter, which is internal. This is a preparation for adding support for Spotlight. --- SentryTestUtils/TestClient.swift | 4 +- Sources/Sentry/SentryClient.m | 6 +-- Sources/Sentry/SentryTransportAdapter.m | 19 ++++++--- Sources/Sentry/SentryTransportFactory.m | 21 +++++----- .../Sentry/include/SentryTransportAdapter.h | 3 +- .../Sentry/include/SentryTransportFactory.h | 4 +- .../SentryCrashIntegrationTests.swift | 2 +- .../SentryTransportAdapterTests.swift | 39 +++++++++++-------- .../SentryTransportFactoryTests.swift | 5 ++- .../SentryTransportInitializerTests.swift | 9 +++-- Tests/SentryTests/SentryClientTests.swift | 2 +- Tests/SentryTests/SentrySDKTests.swift | 4 +- 12 files changed, 69 insertions(+), 49 deletions(-) diff --git a/SentryTestUtils/TestClient.swift b/SentryTestUtils/TestClient.swift index 7d5e9119727..b30faa95ced 100644 --- a/SentryTestUtils/TestClient.swift +++ b/SentryTestUtils/TestClient.swift @@ -2,11 +2,11 @@ import Foundation public class TestClient: SentryClient { public override init?(options: Options) { - super.init(options: options, fileManager: try! TestFileManager(options: options), deleteOldEnvelopeItems: false, transportAdapter: TestTransportAdapter(transport: TestTransport(), options: options)) + super.init(options: options, fileManager: try! TestFileManager(options: options), deleteOldEnvelopeItems: false, transportAdapter: TestTransportAdapter(transports: [TestTransport()], options: options)) } public override init?(options: Options, fileManager: SentryFileManager, deleteOldEnvelopeItems: Bool) { - super.init(options: options, fileManager: fileManager, deleteOldEnvelopeItems: deleteOldEnvelopeItems, transportAdapter: TestTransportAdapter(transport: TestTransport(), options: options)) + super.init(options: options, fileManager: fileManager, deleteOldEnvelopeItems: deleteOldEnvelopeItems, transportAdapter: TestTransportAdapter(transports: [TestTransport()], options: options)) } public override init(options: Options, fileManager: SentryFileManager, deleteOldEnvelopeItems: Bool, transportAdapter: SentryTransportAdapter) { diff --git a/Sources/Sentry/SentryClient.m b/Sources/Sentry/SentryClient.m index a93836b2372..d7435185011 100644 --- a/Sources/Sentry/SentryClient.m +++ b/Sources/Sentry/SentryClient.m @@ -98,11 +98,11 @@ - (instancetype)initWithOptions:(SentryOptions *)options fileManager:(SentryFileManager *)fileManager deleteOldEnvelopeItems:(BOOL)deleteOldEnvelopeItems { - id transport = [SentryTransportFactory initTransport:options - sentryFileManager:fileManager]; + NSArray> *transports = [SentryTransportFactory initTransports:options + sentryFileManager:fileManager]; SentryTransportAdapter *transportAdapter = - [[SentryTransportAdapter alloc] initWithTransport:transport options:options]; + [[SentryTransportAdapter alloc] initWithTransports:transports options:options]; return [self initWithOptions:options fileManager:fileManager diff --git a/Sources/Sentry/SentryTransportAdapter.m b/Sources/Sentry/SentryTransportAdapter.m index 829886da2a1..06c14609ee9 100644 --- a/Sources/Sentry/SentryTransportAdapter.m +++ b/Sources/Sentry/SentryTransportAdapter.m @@ -10,17 +10,18 @@ @interface SentryTransportAdapter () -@property (nonatomic, strong) id transport; +@property (nonatomic, strong) NSArray> *transports; @property (nonatomic, strong) SentryOptions *options; @end @implementation SentryTransportAdapter -- (instancetype)initWithTransport:(id)transport options:(SentryOptions *)options +- (instancetype)initWithTransports:(NSArray> *)transports + options:(SentryOptions *)options { if (self = [super init]) { - self.transport = transport; + self.transports = transports; self.options = options; } @@ -89,17 +90,23 @@ - (void)sendUserFeedback:(SentryUserFeedback *)userFeedback - (void)sendEnvelope:(SentryEnvelope *)envelope { - [self.transport sendEnvelope:envelope]; + for (id transport in self.transports) { + [transport sendEnvelope:envelope]; + } } - (void)recordLostEvent:(SentryDataCategory)category reason:(SentryDiscardReason)reason { - [self.transport recordLostEvent:category reason:reason]; + for (id transport in self.transports) { + [transport recordLostEvent:category reason:reason]; + } } - (void)flush:(NSTimeInterval)timeout { - [self.transport flush:timeout]; + for (id transport in self.transports) { + [transport flush:timeout]; + } } - (NSMutableArray *)buildEnvelopeItems:(SentryEvent *)event diff --git a/Sources/Sentry/SentryTransportFactory.m b/Sources/Sentry/SentryTransportFactory.m index caf47bdde30..c119346f2e7 100644 --- a/Sources/Sentry/SentryTransportFactory.m +++ b/Sources/Sentry/SentryTransportFactory.m @@ -23,8 +23,8 @@ @implementation SentryTransportFactory -+ (id)initTransport:(SentryOptions *)options - sentryFileManager:(SentryFileManager *)sentryFileManager ++ (NSArray> *)initTransports:(SentryOptions *)options + sentryFileManager:(SentryFileManager *)sentryFileManager { NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration ephemeralSessionConfiguration]; @@ -51,13 +51,16 @@ @implementation SentryTransportFactory [[SentryDispatchQueueWrapper alloc] initWithName:"sentry-http-transport" attributes:attributes]; - return [[SentryHttpTransport alloc] initWithOptions:options - fileManager:sentryFileManager - requestManager:requestManager - requestBuilder:[[SentryNSURLRequestBuilder alloc] init] - rateLimits:rateLimits - envelopeRateLimit:envelopeRateLimit - dispatchQueueWrapper:dispatchQueueWrapper]; + SentryHttpTransport *httpTransport = + [[SentryHttpTransport alloc] initWithOptions:options + fileManager:sentryFileManager + requestManager:requestManager + requestBuilder:[[SentryNSURLRequestBuilder alloc] init] + rateLimits:rateLimits + envelopeRateLimit:envelopeRateLimit + dispatchQueueWrapper:dispatchQueueWrapper]; + + return @[ httpTransport ]; } @end diff --git a/Sources/Sentry/include/SentryTransportAdapter.h b/Sources/Sentry/include/SentryTransportAdapter.h index 276e3e3adfe..d0a00f28062 100644 --- a/Sources/Sentry/include/SentryTransportAdapter.h +++ b/Sources/Sentry/include/SentryTransportAdapter.h @@ -16,7 +16,8 @@ NS_ASSUME_NONNULL_BEGIN @interface SentryTransportAdapter : NSObject SENTRY_NO_INIT -- (instancetype)initWithTransport:(id)transport options:(SentryOptions *)options; +- (instancetype)initWithTransports:(NSArray> *)transports + options:(SentryOptions *)options; - (void)sendEvent:(SentryEvent *)event session:(SentrySession *)session diff --git a/Sources/Sentry/include/SentryTransportFactory.h b/Sources/Sentry/include/SentryTransportFactory.h index 3170a2f0644..8f9c0213b0a 100644 --- a/Sources/Sentry/include/SentryTransportFactory.h +++ b/Sources/Sentry/include/SentryTransportFactory.h @@ -9,8 +9,8 @@ NS_ASSUME_NONNULL_BEGIN NS_SWIFT_NAME(TransportInitializer) @interface SentryTransportFactory : NSObject -+ (id)initTransport:(SentryOptions *)options - sentryFileManager:(SentryFileManager *)sentryFileManager; ++ (NSArray> *)initTransports:(SentryOptions *)options + sentryFileManager:(SentryFileManager *)sentryFileManager; @end diff --git a/Tests/SentryTests/Integrations/SentryCrash/SentryCrashIntegrationTests.swift b/Tests/SentryTests/Integrations/SentryCrash/SentryCrashIntegrationTests.swift index 762972338bf..6c1bc61ffbd 100644 --- a/Tests/SentryTests/Integrations/SentryCrash/SentryCrashIntegrationTests.swift +++ b/Tests/SentryTests/Integrations/SentryCrash/SentryCrashIntegrationTests.swift @@ -248,7 +248,7 @@ class SentryCrashIntegrationTests: NotificationCenterTestCase { let transport = TestTransport() let client = SentryClient(options: fixture.options, fileManager: try TestFileManager(options: fixture.options), deleteOldEnvelopeItems: false) - Dynamic(client).transportAdapter = TestTransportAdapter(transport: transport, options: fixture.options) + Dynamic(client).transportAdapter = TestTransportAdapter(transports: [transport], options: fixture.options) hub.bindClient(client) delayNonBlocking(timeout: 0.01) diff --git a/Tests/SentryTests/Networking/SentryTransportAdapterTests.swift b/Tests/SentryTests/Networking/SentryTransportAdapterTests.swift index c2df58430e2..a270a838fc9 100644 --- a/Tests/SentryTests/Networking/SentryTransportAdapterTests.swift +++ b/Tests/SentryTests/Networking/SentryTransportAdapterTests.swift @@ -1,3 +1,4 @@ +import Nimble import Sentry import SentryTestUtils import XCTest @@ -6,13 +7,14 @@ class SentryTransportAdapterTests: XCTestCase { private class Fixture { - let transport = TestTransport() + let transport1 = TestTransport() + let transport2 = TestTransport() let options = Options() let faultyAttachment = Attachment(path: "") let attachment = Attachment(data: Data(), filename: "test.txt") var sut: SentryTransportAdapter { - return SentryTransportAdapter(transport: transport, options: options) + return SentryTransportAdapter(transports: [transport1, transport2], options: options) } } @@ -44,10 +46,10 @@ class SentryTransportAdapterTests: XCTestCase { SentryEnvelopeItem(session: session) ]) - assertEnvelope(expected: expectedEnvelope) + try assertEnvelope(expected: expectedEnvelope) } - func testSendFaultyAttachment_FaultyAttachmentGetsDropped() { + func testSendFaultyAttachment_FaultyAttachmentGetsDropped() throws { let event = TestData.event sut.send(event: event, traceContext: nil, attachments: [fixture.faultyAttachment, fixture.attachment]) @@ -56,26 +58,28 @@ class SentryTransportAdapterTests: XCTestCase { SentryEnvelopeItem(attachment: fixture.attachment, maxAttachmentSize: fixture.options.maxAttachmentSize)! ]) - assertEnvelope(expected: expectedEnvelope) + try assertEnvelope(expected: expectedEnvelope) } - func testSendUserFeedback_SendsUserFeedbackEnvelope() { + func testSendUserFeedback_SendsUserFeedbackEnvelope() throws { let userFeedback = TestData.userFeedback sut.send(userFeedback: userFeedback) let expectedEnvelope = SentryEnvelope(userFeedback: userFeedback) - assertEnvelope(expected: expectedEnvelope) + try assertEnvelope(expected: expectedEnvelope) } - private func assertEnvelope(expected: SentryEnvelope) { - XCTAssertEqual(1, fixture.transport.sentEnvelopes.count) - let actual = fixture.transport.sentEnvelopes.first! - XCTAssertNotNil(actual) + private func assertEnvelope(expected: SentryEnvelope) throws { + expect(self.fixture.transport1.sentEnvelopes.count) == 1 + expect(self.fixture.transport2.sentEnvelopes.count) == 1 - XCTAssertEqual(expected.header.eventId, actual.header.eventId) - XCTAssertEqual(expected.header.sdkInfo, actual.header.sdkInfo) - XCTAssertEqual(expected.items.count, actual.items.count) + let actual = fixture.transport1.sentEnvelopes.first! + expect(actual) != nil + + expect(expected.header.eventId) == actual.header.eventId + expect(expected.header.sdkInfo) == actual.header.sdkInfo + expect(expected.items.count) == actual.items.count expected.items.forEach { expectedItem in let expectedHeader = expectedItem.header @@ -84,15 +88,16 @@ class SentryTransportAdapterTests: XCTestCase { expectedHeader.contentType == expectedItem.header.contentType } - XCTAssertTrue(containsHeader, "Envelope doesn't contain item with type:\(expectedHeader.type).") + expect(containsHeader).to(beTrue(), description: "Envelope doesn't contain item with type:\(expectedHeader.type).") let containsData = actual.items.contains { actualItem in actualItem.data == expectedItem.data } - XCTAssertTrue(containsData, "Envelope data with type:\(expectedHeader.type) doesn't match.") + expect(containsData).to(beTrue(), description: "Envelope data with type:\(expectedHeader.type) doesn't match.") } - XCTAssertEqual(try SentrySerialization.data(with: expected), try SentrySerialization.data(with: actual)) + let actualSerialized = try SentrySerialization.data(with: actual) + expect(try SentrySerialization.data(with: expected)) == actualSerialized } } diff --git a/Tests/SentryTests/Networking/SentryTransportFactoryTests.swift b/Tests/SentryTests/Networking/SentryTransportFactoryTests.swift index 09c55f77d5f..1216c744037 100644 --- a/Tests/SentryTests/Networking/SentryTransportFactoryTests.swift +++ b/Tests/SentryTests/Networking/SentryTransportFactoryTests.swift @@ -19,8 +19,9 @@ class SentryTransportFactoryTests: XCTestCase { options.urlSessionDelegate = urlSessionDelegateSpy let fileManager = try! SentryFileManager(options: options, dispatchQueueWrapper: TestSentryDispatchQueueWrapper()) - let transport = TransportInitializer.initTransport(options, sentryFileManager: fileManager) - let requestManager = Dynamic(transport).requestManager.asObject as! SentryQueueableRequestManager + let transports = TransportInitializer.initTransports(options, sentryFileManager: fileManager) + let httpTransport = transports.first + let requestManager = Dynamic(httpTransport).requestManager.asObject as! SentryQueueableRequestManager let imgUrl = URL(string: "https://github.com")! let request = URLRequest(url: imgUrl) diff --git a/Tests/SentryTests/Networking/SentryTransportInitializerTests.swift b/Tests/SentryTests/Networking/SentryTransportInitializerTests.swift index a2b2755b341..53acba9eb40 100644 --- a/Tests/SentryTests/Networking/SentryTransportInitializerTests.swift +++ b/Tests/SentryTests/Networking/SentryTransportInitializerTests.swift @@ -1,3 +1,4 @@ +import Nimble @testable import Sentry import SentryTestUtils import XCTest @@ -17,9 +18,11 @@ class SentryTransportInitializerTests: XCTestCase { func testDefault() throws { let options = try Options(dict: ["dsn": SentryTransportInitializerTests.dsnAsString]) + + let result = TransportInitializer.initTransports(options, sentryFileManager: fileManager) + expect(result.count) == 1 - let result = TransportInitializer.initTransport(options, sentryFileManager: fileManager) - - XCTAssertTrue(result.isKind(of: SentryHttpTransport.self)) + let firstTransport = result.first + expect(firstTransport?.isKind(of: SentryHttpTransport.self)) == true } } diff --git a/Tests/SentryTests/SentryClientTests.swift b/Tests/SentryTests/SentryClientTests.swift index fcc7afb8e17..8cccc5efde7 100644 --- a/Tests/SentryTests/SentryClientTests.swift +++ b/Tests/SentryTests/SentryClientTests.swift @@ -60,7 +60,7 @@ class SentryClientTest: XCTestCase { transaction = Transaction(trace: trace, children: []) transport = TestTransport() - transportAdapter = TestTransportAdapter(transport: transport, options: options) + transportAdapter = TestTransportAdapter(transports: [transport], options: options) crashWrapper.internalFreeMemorySize = 123_456 crashWrapper.internalAppMemorySize = 234_567 diff --git a/Tests/SentryTests/SentrySDKTests.swift b/Tests/SentryTests/SentrySDKTests.swift index ed7fb639975..ef58f48a969 100644 --- a/Tests/SentryTests/SentrySDKTests.swift +++ b/Tests/SentryTests/SentrySDKTests.swift @@ -668,7 +668,7 @@ class SentrySDKTests: XCTestCase { let transport = TestTransport() let client = SentryClient(options: fixture.options, fileManager: try TestFileManager(options: fixture.options), deleteOldEnvelopeItems: false) - Dynamic(client).transportAdapter = TestTransportAdapter(transport: transport, options: fixture.options) + Dynamic(client).transportAdapter = TestTransportAdapter(transports: [transport], options: fixture.options) SentrySDK.currentHub().bindClient(client) SentrySDK.close() @@ -683,7 +683,7 @@ class SentrySDKTests: XCTestCase { let transport = TestTransport() let client = SentryClient(options: fixture.options, fileManager: try TestFileManager(options: fixture.options), deleteOldEnvelopeItems: false) - Dynamic(client).transportAdapter = TestTransportAdapter(transport: transport, options: fixture.options) + Dynamic(client).transportAdapter = TestTransportAdapter(transports: [transport], options: fixture.options) SentrySDK.currentHub().bindClient(client) let flushTimeout = 10.0 From 6e1452db34c644362c1157f4ffbeb2ef162054db Mon Sep 17 00:00:00 2001 From: Andrew McKnight Date: Fri, 16 Feb 2024 20:26:48 +0800 Subject: [PATCH 05/25] test: reset file manager state in clearTestState() (#3643) --- SentryTestUtils/ClearTestState.swift | 1 + SentryTestUtils/SentryTestUtils-ObjC-BridgingHeader.h | 2 +- Sources/Sentry/SentryFileManager.m | 5 +++++ Tests/SentryTests/Helper/SentryFileManager+TestProperties.h | 2 ++ 4 files changed, 9 insertions(+), 1 deletion(-) diff --git a/SentryTestUtils/ClearTestState.swift b/SentryTestUtils/ClearTestState.swift index c1c5ecffaca..b2570dd9c9a 100644 --- a/SentryTestUtils/ClearTestState.swift +++ b/SentryTestUtils/ClearTestState.swift @@ -31,6 +31,7 @@ class TestCleanup: NSObject { SentryAppStartTracker.load() SentryUIViewControllerPerformanceTracker.shared.enableWaitForFullDisplay = false SentryDependencyContainer.sharedInstance().swizzleWrapper.removeAllCallbacks() + SentryDependencyContainer.sharedInstance().fileManager.clearDiskState() #endif // os(iOS) || os(tvOS) || targetEnvironment(macCatalyst) diff --git a/SentryTestUtils/SentryTestUtils-ObjC-BridgingHeader.h b/SentryTestUtils/SentryTestUtils-ObjC-BridgingHeader.h index 81b52766f33..60914206b5d 100644 --- a/SentryTestUtils/SentryTestUtils-ObjC-BridgingHeader.h +++ b/SentryTestUtils/SentryTestUtils-ObjC-BridgingHeader.h @@ -31,7 +31,7 @@ #import "SentryDispatchQueueWrapper.h" #import "SentryDispatchSourceWrapper.h" #import "SentryEnvelope.h" -#import "SentryFileManager.h" +#import "SentryFileManager+TestProperties.h" #import "SentryGlobalEventProcessor.h" #import "SentryLog.h" #import "SentryNSProcessInfoWrapper.h" diff --git a/Sources/Sentry/SentryFileManager.m b/Sources/Sentry/SentryFileManager.m index 30e9993aff0..f89a46621b1 100644 --- a/Sources/Sentry/SentryFileManager.m +++ b/Sources/Sentry/SentryFileManager.m @@ -710,6 +710,11 @@ - (BOOL)createDirectoryIfNotExists:(NSString *)path error:(NSError **)error return YES; } +- (void)clearDiskState +{ + [self removeFileAtPath:self.basePath]; +} + @end NS_ASSUME_NONNULL_END diff --git a/Tests/SentryTests/Helper/SentryFileManager+TestProperties.h b/Tests/SentryTests/Helper/SentryFileManager+TestProperties.h index e85d818f134..093e846e821 100644 --- a/Tests/SentryTests/Helper/SentryFileManager+TestProperties.h +++ b/Tests/SentryTests/Helper/SentryFileManager+TestProperties.h @@ -9,6 +9,8 @@ SentryFileManager () @property (nonatomic, copy) NSString *envelopesPath; @property (nonatomic, copy) NSString *timezoneOffsetFilePath; +- (void)clearDiskState; + @end NS_ASSUME_NONNULL_END From f8833c443d047f0c8dac5710e52b4c0624fc52ce Mon Sep 17 00:00:00 2001 From: Andrew McKnight Date: Fri, 16 Feb 2024 21:10:26 +0800 Subject: [PATCH 06/25] feat(app launch profiling): add app launch profiling (#3529) --- CHANGELOG.md | 5 + .../xcshareddata/xcschemes/iOS-Swift.xcscheme | 22 +- .../xcschemes/iOS-SwiftUITests.xcscheme | 2 +- Samples/iOS-Swift/iOS-Swift/AppDelegate.swift | 17 +- .../iOS-Swift/Base.lproj/Main.storyboard | 62 +++- .../Profiling/ProfilingViewController.swift | 106 ++++-- .../TransactionsViewController.swift | 37 +- .../iOS-SwiftUITests/BaseUITest.swift | 32 +- .../iOS-SwiftUITests/ProfilingUITests.swift | 266 ++++++++++++-- .../iOS-SwiftUI.xcodeproj/project.pbxproj | 122 +++++++ Sentry.xcodeproj/project.pbxproj | 52 +-- .../SentryTestUtils-ObjC-BridgingHeader.h | 2 +- .../Sentry/Profiling/SentryLaunchProfiling.m | 169 +++++++++ .../Sentry/Profiling/SentryProfilerState.mm | 11 +- Sources/Sentry/Public/SentryOptions.h | 22 +- .../Sentry/Public/SentryTransactionContext.h | 9 + Sources/Sentry/SentryFileManager.m | 153 ++++++-- Sources/Sentry/SentryHub.m | 28 +- Sources/Sentry/SentryLog.m | 7 +- Sources/Sentry/SentryOptions.m | 50 +-- Sources/Sentry/SentryProfileTimeseries.mm | 2 + Sources/Sentry/SentryProfiler.mm | 88 ++++- Sources/Sentry/SentryProfilesSampler.m | 93 ----- Sources/Sentry/SentrySDK.m | 19 +- Sources/Sentry/SentrySamplerDecision.m | 15 + Sources/Sentry/SentrySampling.m | 117 ++++++ Sources/Sentry/SentryTracer.m | 45 ++- Sources/Sentry/SentryTracesSampler.m | 84 ----- Sources/Sentry/include/SentryFileManager.h | 39 ++ .../Sentry/include/SentryInternalDefines.h | 8 +- .../Sentry/include/SentryLaunchProfiling.h | 33 ++ .../Sentry/include/SentryOptions+Private.h | 12 +- .../Sentry/include/SentryProfilesSampler.h | 55 --- .../Sentry/include/SentrySamplerDecision.h | 17 + Sources/Sentry/include/SentrySampling.h | 24 ++ Sources/Sentry/include/SentryTraceOrigins.h | 1 + Sources/Sentry/include/SentryTracer.h | 13 +- .../include/SentryTracerConfiguration.h | 6 +- Sources/Sentry/include/SentryTracesSampler.h | 46 --- .../SentryAppLaunchProfilingTests.m | 151 ++++++++ .../SentryProfilerSwiftTests.swift | 58 ++- .../SentryProfilerTests.mm | 2 +- ...tProperties.h => SentryFileManager+Test.h} | 3 + .../Helper/SentryFileManagerTests.swift | 332 ++++++++++++------ Tests/SentryTests/SentryHubTests.swift | 19 +- .../SentryTests/SentryLaunchProfiling+Tests.h | 27 ++ Tests/SentryTests/SentryOptionsTest.m | 27 +- Tests/SentryTests/SentrySDK+Tests.h | 8 +- .../SentryTests/SentryTests-Bridging-Header.h | 3 +- .../Transaction/SentryTracerObjCTests.m | 1 - develop-docs/README.md | 16 + 51 files changed, 1883 insertions(+), 655 deletions(-) create mode 100644 Sources/Sentry/Profiling/SentryLaunchProfiling.m delete mode 100644 Sources/Sentry/SentryProfilesSampler.m create mode 100644 Sources/Sentry/SentrySamplerDecision.m create mode 100644 Sources/Sentry/SentrySampling.m delete mode 100644 Sources/Sentry/SentryTracesSampler.m create mode 100644 Sources/Sentry/include/SentryLaunchProfiling.h delete mode 100644 Sources/Sentry/include/SentryProfilesSampler.h create mode 100644 Sources/Sentry/include/SentrySamplerDecision.h create mode 100644 Sources/Sentry/include/SentrySampling.h delete mode 100644 Sources/Sentry/include/SentryTracesSampler.h create mode 100644 Tests/SentryProfilerTests/SentryAppLaunchProfilingTests.m rename Tests/SentryTests/Helper/{SentryFileManager+TestProperties.h => SentryFileManager+Test.h} (72%) create mode 100644 Tests/SentryTests/SentryLaunchProfiling+Tests.h diff --git a/CHANGELOG.md b/CHANGELOG.md index 842aff2a95d..09733f266e0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +### Features + +- Automatically profile app launches (#3529) + ### Improvements - Cache installationID async to avoid file IO on the main thread when starting the SDK (#3601) @@ -10,6 +14,7 @@ ### Fixes - Finish TTID span when transaction finishes (#3610) +- Don't take screenshot and view hierarchy for app hanging (#3620) - Dont take screenshot and view hierarchy for app hanging (#3620) - Remove `free_storage` and `storage_size` from the device context (#3627), because Apple forbids sending information retrieved via `NSFileSystemFreeSize` and `NSFileSystemSize` off a device; see diff --git a/Samples/iOS-Swift/iOS-Swift.xcodeproj/xcshareddata/xcschemes/iOS-Swift.xcscheme b/Samples/iOS-Swift/iOS-Swift.xcodeproj/xcshareddata/xcschemes/iOS-Swift.xcscheme index fa07f21b626..dc3a836c25c 100644 --- a/Samples/iOS-Swift/iOS-Swift.xcodeproj/xcshareddata/xcschemes/iOS-Swift.xcscheme +++ b/Samples/iOS-Swift/iOS-Swift.xcodeproj/xcshareddata/xcschemes/iOS-Swift.xcscheme @@ -23,7 +23,7 @@ @@ -73,6 +73,26 @@ argument = "--disable-file-io-tracing" isEnabled = "NO"> + + + + + + + + + + diff --git a/Samples/iOS-Swift/iOS-Swift.xcodeproj/xcshareddata/xcschemes/iOS-SwiftUITests.xcscheme b/Samples/iOS-Swift/iOS-Swift.xcodeproj/xcshareddata/xcschemes/iOS-SwiftUITests.xcscheme index 55e1974867d..37a4ca1e81a 100644 --- a/Samples/iOS-Swift/iOS-Swift.xcodeproj/xcshareddata/xcschemes/iOS-SwiftUITests.xcscheme +++ b/Samples/iOS-Swift/iOS-Swift.xcodeproj/xcshareddata/xcschemes/iOS-SwiftUITests.xcscheme @@ -25,7 +25,7 @@ Bool { - print("[iOS-Swift] launch arguments: \(ProcessInfo.processInfo.arguments)") - print("[iOS-Swift] environment: \(ProcessInfo.processInfo.environment)") + print("[iOS-Swift] [debug] launch arguments: \(ProcessInfo.processInfo.arguments)") + print("[iOS-Swift] [debug] environment: \(ProcessInfo.processInfo.environment)") maybeWipeData() AppDelegate.startSentry() @@ -161,9 +165,10 @@ class AppDelegate: UIResponder, UIApplicationDelegate { } private extension AppDelegate { + // previously tried putting this in an AppDelegate.load override in ObjC, but it wouldn't run until after a launch profiler would have an opportunity to run, since SentryProfiler.load would always run first due to being dynamically linked in a framework module. it is sufficient to do it before calling SentrySDK.startWithOptions to clear state for testProfiledAppLaunches because we don't make any assertions on a launch profile the first launch of the app in that test func maybeWipeData() { if ProcessInfo.processInfo.arguments.contains("--io.sentry.wipe-data") { - print("[iOS-Swift] removing app data") + print("[iOS-Swift] [debug] removing app data") let appSupport = NSSearchPathForDirectoriesInDomains(.applicationSupportDirectory, .userDomainMask, true).first! let cache = NSSearchPathForDirectoriesInDomains(.cachesDirectory, .userDomainMask, true).first! for path in [appSupport, cache] { diff --git a/Samples/iOS-Swift/iOS-Swift/Base.lproj/Main.storyboard b/Samples/iOS-Swift/iOS-Swift/Base.lproj/Main.storyboard index 094218d85bd..67696810cb6 100644 --- a/Samples/iOS-Swift/iOS-Swift/Base.lproj/Main.storyboard +++ b/Samples/iOS-Swift/iOS-Swift/Base.lproj/Main.storyboard @@ -1,9 +1,9 @@ - + - + @@ -172,7 +172,7 @@ - + @@ -223,8 +223,57 @@ + + + + + + + + + + + + + + + - +