From 12ef7a56fc7b2022165d713a7b74af3868487c04 Mon Sep 17 00:00:00 2001 From: Mert Buran Date: Thu, 12 Aug 2021 13:42:36 +0200 Subject: [PATCH] RUMM-1492 isSystemImage logic is fixed In device, user images can be in /Bundle/Application/ only. Otherwise, it is a system image. In simulator, system image can be in Xcode.app/Contents/Developer/Platforms only. Otherwise, it is a user image. --- .../CrashReport.swift | 19 ++++++- .../CrashReportTests.swift | 52 ++++++++++++++----- 2 files changed, 55 insertions(+), 16 deletions(-) diff --git a/Sources/DatadogCrashReporting/PLCrashReporterIntegration/CrashReport.swift b/Sources/DatadogCrashReporting/PLCrashReporterIntegration/CrashReport.swift index f5d84d35c6..c002447ac0 100644 --- a/Sources/DatadogCrashReporting/PLCrashReporterIntegration/CrashReport.swift +++ b/Sources/DatadogCrashReporting/PLCrashReporterIntegration/CrashReport.swift @@ -241,8 +241,12 @@ extension BinaryImageInfo { self.uuid = imageUUID self.imageName = URL(string: imagePath)?.lastPathComponent - // NOTE: RUMM-1492 refer to JIRA ticket or `CrashReportTests.swift` to see imagePath examples - self.isSystemImage = !imagePath.contains("/Bundle/Application/") || imagePath.contains("/Contents/Developer/Platforms/") + + #if targetEnvironment(simulator) + self.isSystemImage = Self.isPathSystemImageInSimulator(imagePath) + #else + self.isSystemImage = Self.isPathSystemImageInDevice(imagePath) + #endif if let codeType = imageInfo.codeType { self.codeType = CodeType(from: codeType) @@ -254,6 +258,17 @@ extension BinaryImageInfo { self.imageBaseAddress = imageInfo.imageBaseAddress self.imageSize = imageInfo.imageSize } + + static func isPathSystemImageInSimulator(_ path: String) -> Bool { + // in simulator, example system image path: ~/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/... + return path.contains("/Contents/Developer/Platforms/") + } + + static func isPathSystemImageInDevice(_ path: String) -> Bool { + // in device, example user image path: .../containers/Bundle/Application/0000/Example.app/Frameworks/... + let isUserImage = path.contains("/Bundle/Application/") + return !isUserImage + } } extension BinaryImageInfo.CodeType { diff --git a/Tests/DatadogCrashReportingTests/PLCrashReporterIntegration/CrashReportTests.swift b/Tests/DatadogCrashReportingTests/PLCrashReporterIntegration/CrashReportTests.swift index d7e0adff0f..0866c78ca5 100644 --- a/Tests/DatadogCrashReportingTests/PLCrashReporterIntegration/CrashReportTests.swift +++ b/Tests/DatadogCrashReportingTests/PLCrashReporterIntegration/CrashReportTests.swift @@ -205,6 +205,37 @@ class CrashReportTests: XCTestCase { XCTAssertEqual(threadInfo.stackFrames.count, mockStackFrames.count) } + private let systemImagePaths_device = [ + "/System/Library/PrivateFrameworks/UIKitCore.framework/UIKitCore", + "/usr/lib/system/libdyld.dylib" + ] + private let systemImagePaths_simulator = [ + "/Users/john.appleseed/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation" + ] + private let userImagePaths_device = [ + "/private/var/containers/Bundle/Application/0000/Example.app/Example", + "/private/var/containers/Bundle/Application/0000/Example.app/Frameworks/DatadogCrashReporting.framework/DatadogCrashReporting" + ] + private let userImagePaths_simulator = [ + "/Users/john.appleseed/Library/Developer/CoreSimulator/Devices/0000/data/Containers/Bundle/Application/0000/Example.app/Example", + "/Users/john.appleseed/Library/Developer/Xcode/DerivedData/Datadog-abcd/Build/Products/Release-iphonesimulator/DatadogCrashReporting.framework/DatadogCrashReporting" + ] + + func testItDetectsSystemImages() throws { + for systemImagePath in systemImagePaths_device { + XCTAssertTrue(BinaryImageInfo.isPathSystemImageInDevice(systemImagePath), "\(systemImagePath) is a system image") + } + for systemImagePath in systemImagePaths_simulator { + XCTAssertTrue(BinaryImageInfo.isPathSystemImageInSimulator(systemImagePath), "\(systemImagePath) is a system image") + } + for userImagePath in userImagePaths_device { + XCTAssertFalse(BinaryImageInfo.isPathSystemImageInDevice(userImagePath), "\(userImagePath) is an user image") + } + for userImagePath in userImagePaths_simulator { + XCTAssertFalse(BinaryImageInfo.isPathSystemImageInSimulator(userImagePath), "\(userImagePath) is an user image") + } + } + func testItReadsBinaryImageInfo() throws { func mock(with imagePath: URL) -> PLCrashReportMock.BinaryImageInfo { let mock = PLCrashReportMock.BinaryImageInfo() @@ -220,20 +251,13 @@ class CrashReportTests: XCTestCase { } // Given - let systemImagePathString = [ - "/System/Library/PrivateFrameworks/UIKitCore.framework/UIKitCore", - "/usr/lib/system/libdyld.dylib", - "/Users/john.appleseed/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation" - ].randomElement()! - let systemImagePath = URL(string: systemImagePathString)! - - let userImagePathString = [ - "/private/var/containers/Bundle/Application/0000/Example.app/Example", - "/private/var/containers/Bundle/Application/0000/Example.app/Frameworks/DatadogCrashReporting.framework/DatadogCrashReporting", - "/Users/john.appleseed/Library/Developer/CoreSimulator/Devices/0000/data/Containers/Bundle/Application/0000/Example.app/Example", - "/Users/john.appleseed/Library/Developer/Xcode/DerivedData/Datadog-abcd/Build/Products/Release-iphonesimulator/DatadogCrashReporting.framework/DatadogCrashReporting" - ].randomElement()! - let userImagePath = URL(string: userImagePathString)! + #if targetEnvironment(simulator) + let systemImagePath = URL(string: systemImagePaths_simulator.randomElement()!)! + let userImagePath = URL(string: userImagePaths_simulator.randomElement()!)! + #else + let systemImagePath = URL(string: systemImagePaths_device.randomElement()!)! + let userImagePath = URL(string: userImagePaths_device.randomElement()!)! + #endif let mockSystemImage = mock(with: systemImagePath) let mockUserImage = mock(with: userImagePath)