diff --git a/.buildkite/pipeline.full.yml b/.buildkite/pipeline.full.yml index a9346e089..b05758801 100644 --- a/.buildkite/pipeline.full.yml +++ b/.buildkite/pipeline.full.yml @@ -23,7 +23,7 @@ steps: - "--app=/app/build/iOSTestApp.ipa" - "--farm=bs" - "--device=IOS_14" - - "--appium-version=1.17.0" + - "--appium-version=1.21.0" - "--fail-fast" - "--exclude=features/[h-z].*.feature$" - "--order=random" @@ -50,7 +50,7 @@ steps: - "--app=/app/build/iOSTestApp.ipa" - "--farm=bs" - "--device=IOS_14" - - "--appium-version=1.17.0" + - "--appium-version=1.21.0" - "--fail-fast" - "--exclude=features/[a-g].*.feature$" - "--order=random" diff --git a/.jazzy.yaml b/.jazzy.yaml index 51c473cd9..0e626089e 100644 --- a/.jazzy.yaml +++ b/.jazzy.yaml @@ -2,11 +2,11 @@ author_url: "https://www.bugsnag.com" author: "Bugsnag Inc" clean: false # avoid deleting docs/.git framework_root: "Bugsnag" -github_file_prefix: "https://github.com/bugsnag/bugsnag-cocoa/tree/v6.16.3/Bugsnag" +github_file_prefix: "https://github.com/bugsnag/bugsnag-cocoa/tree/v6.16.4/Bugsnag" github_url: "https://github.com/bugsnag/bugsnag-cocoa" hide_documentation_coverage: true module: "Bugsnag" -module_version: "6.16.3" +module_version: "6.16.4" objc: true output: "docs" readme: "README.md" diff --git a/Bugsnag.podspec.json b/Bugsnag.podspec.json index 78b7de1ca..c4e2abc18 100644 --- a/Bugsnag.podspec.json +++ b/Bugsnag.podspec.json @@ -1,6 +1,6 @@ { "name": "Bugsnag", - "version": "6.16.3", + "version": "6.16.4", "summary": "The Bugsnag crash reporting framework for Apple platforms.", "homepage": "https://bugsnag.com", "license": "MIT", @@ -9,7 +9,7 @@ }, "source": { "git": "https://github.com/bugsnag/bugsnag-cocoa.git", - "tag": "v6.16.3" + "tag": "v6.16.4" }, "frameworks": [ "Foundation", diff --git a/Bugsnag.xcodeproj/project.pbxproj b/Bugsnag.xcodeproj/project.pbxproj index e441b5a6e..6295c2c3d 100644 --- a/Bugsnag.xcodeproj/project.pbxproj +++ b/Bugsnag.xcodeproj/project.pbxproj @@ -314,13 +314,6 @@ 008968CF2486DA9600DC48C2 /* BugsnagNotifier.h in Headers */ = {isa = PBXBuildFile; fileRef = 008968622486DA9500DC48C2 /* BugsnagNotifier.h */; }; 008968D02486DA9600DC48C2 /* BugsnagNotifier.h in Headers */ = {isa = PBXBuildFile; fileRef = 008968622486DA9500DC48C2 /* BugsnagNotifier.h */; }; 008968D12486DA9600DC48C2 /* BugsnagNotifier.h in Headers */ = {isa = PBXBuildFile; fileRef = 008968622486DA9500DC48C2 /* BugsnagNotifier.h */; }; - 008968DE2486DAA700DC48C2 /* BugsnagPluginClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 008968D92486DAA700DC48C2 /* BugsnagPluginClient.h */; }; - 008968DF2486DAA700DC48C2 /* BugsnagPluginClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 008968D92486DAA700DC48C2 /* BugsnagPluginClient.h */; }; - 008968E02486DAA700DC48C2 /* BugsnagPluginClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 008968D92486DAA700DC48C2 /* BugsnagPluginClient.h */; }; - 008968E12486DAA700DC48C2 /* BugsnagPluginClient.m in Sources */ = {isa = PBXBuildFile; fileRef = 008968DA2486DAA700DC48C2 /* BugsnagPluginClient.m */; }; - 008968E22486DAA700DC48C2 /* BugsnagPluginClient.m in Sources */ = {isa = PBXBuildFile; fileRef = 008968DA2486DAA700DC48C2 /* BugsnagPluginClient.m */; }; - 008968E32486DAA700DC48C2 /* BugsnagPluginClient.m in Sources */ = {isa = PBXBuildFile; fileRef = 008968DA2486DAA700DC48C2 /* BugsnagPluginClient.m */; }; - 008968E42486DAA700DC48C2 /* BugsnagPluginClient.m in Sources */ = {isa = PBXBuildFile; fileRef = 008968DA2486DAA700DC48C2 /* BugsnagPluginClient.m */; }; 008968E92486DAB800DC48C2 /* BugsnagSessionFileStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 008968E52486DAB800DC48C2 /* BugsnagSessionFileStore.m */; }; 008968EA2486DAB800DC48C2 /* BugsnagSessionFileStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 008968E52486DAB800DC48C2 /* BugsnagSessionFileStore.m */; }; 008968EB2486DAB800DC48C2 /* BugsnagSessionFileStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 008968E52486DAB800DC48C2 /* BugsnagSessionFileStore.m */; }; @@ -485,9 +478,6 @@ 008969F92486DAD100DC48C2 /* BSG_KSCrashReportVersion.h in Headers */ = {isa = PBXBuildFile; fileRef = 008969372486DAD000DC48C2 /* BSG_KSCrashReportVersion.h */; }; 008969FA2486DAD100DC48C2 /* BSG_KSCrashReportVersion.h in Headers */ = {isa = PBXBuildFile; fileRef = 008969372486DAD000DC48C2 /* BSG_KSCrashReportVersion.h */; }; 008969FB2486DAD100DC48C2 /* BSG_KSCrashReportVersion.h in Headers */ = {isa = PBXBuildFile; fileRef = 008969372486DAD000DC48C2 /* BSG_KSCrashReportVersion.h */; }; - 008969FC2486DAD100DC48C2 /* BSG_KSCrashAdvanced.h in Headers */ = {isa = PBXBuildFile; fileRef = 008969382486DAD000DC48C2 /* BSG_KSCrashAdvanced.h */; }; - 008969FD2486DAD100DC48C2 /* BSG_KSCrashAdvanced.h in Headers */ = {isa = PBXBuildFile; fileRef = 008969382486DAD000DC48C2 /* BSG_KSCrashAdvanced.h */; }; - 008969FE2486DAD100DC48C2 /* BSG_KSCrashAdvanced.h in Headers */ = {isa = PBXBuildFile; fileRef = 008969382486DAD000DC48C2 /* BSG_KSCrashAdvanced.h */; }; 00896A022486DAD100DC48C2 /* BSG_KSCrashSentry_NSException.m in Sources */ = {isa = PBXBuildFile; fileRef = 0089693B2486DAD000DC48C2 /* BSG_KSCrashSentry_NSException.m */; }; 00896A032486DAD100DC48C2 /* BSG_KSCrashSentry_NSException.m in Sources */ = {isa = PBXBuildFile; fileRef = 0089693B2486DAD000DC48C2 /* BSG_KSCrashSentry_NSException.m */; }; 00896A042486DAD100DC48C2 /* BSG_KSCrashSentry_NSException.m in Sources */ = {isa = PBXBuildFile; fileRef = 0089693B2486DAD000DC48C2 /* BSG_KSCrashSentry_NSException.m */; }; @@ -552,13 +542,13 @@ 00AD1F242486A17900A27979 /* Bugsnag.m in Sources */ = {isa = PBXBuildFile; fileRef = 00AD1EFE2486A17800A27979 /* Bugsnag.m */; }; 00AD1F252486A17900A27979 /* Bugsnag.m in Sources */ = {isa = PBXBuildFile; fileRef = 00AD1EFE2486A17800A27979 /* Bugsnag.m */; }; 00AD1F262486A17900A27979 /* Bugsnag.m in Sources */ = {isa = PBXBuildFile; fileRef = 00AD1EFE2486A17800A27979 /* Bugsnag.m */; }; - 00AD1F272486A17900A27979 /* BugsnagCrashSentry.m in Sources */ = {isa = PBXBuildFile; fileRef = 00AD1EFF2486A17900A27979 /* BugsnagCrashSentry.m */; }; - 00AD1F282486A17900A27979 /* BugsnagCrashSentry.m in Sources */ = {isa = PBXBuildFile; fileRef = 00AD1EFF2486A17900A27979 /* BugsnagCrashSentry.m */; }; - 00AD1F292486A17900A27979 /* BugsnagCrashSentry.m in Sources */ = {isa = PBXBuildFile; fileRef = 00AD1EFF2486A17900A27979 /* BugsnagCrashSentry.m */; }; - 00AD1F2A2486A17900A27979 /* BugsnagCrashSentry.m in Sources */ = {isa = PBXBuildFile; fileRef = 00AD1EFF2486A17900A27979 /* BugsnagCrashSentry.m */; }; - 00AD1F2B2486A17900A27979 /* BugsnagCrashSentry.h in Headers */ = {isa = PBXBuildFile; fileRef = 00AD1F002486A17900A27979 /* BugsnagCrashSentry.h */; }; - 00AD1F2C2486A17900A27979 /* BugsnagCrashSentry.h in Headers */ = {isa = PBXBuildFile; fileRef = 00AD1F002486A17900A27979 /* BugsnagCrashSentry.h */; }; - 00AD1F2D2486A17900A27979 /* BugsnagCrashSentry.h in Headers */ = {isa = PBXBuildFile; fileRef = 00AD1F002486A17900A27979 /* BugsnagCrashSentry.h */; }; + 00AD1F272486A17900A27979 /* BSGCrashSentry.m in Sources */ = {isa = PBXBuildFile; fileRef = 00AD1EFF2486A17900A27979 /* BSGCrashSentry.m */; }; + 00AD1F282486A17900A27979 /* BSGCrashSentry.m in Sources */ = {isa = PBXBuildFile; fileRef = 00AD1EFF2486A17900A27979 /* BSGCrashSentry.m */; }; + 00AD1F292486A17900A27979 /* BSGCrashSentry.m in Sources */ = {isa = PBXBuildFile; fileRef = 00AD1EFF2486A17900A27979 /* BSGCrashSentry.m */; }; + 00AD1F2A2486A17900A27979 /* BSGCrashSentry.m in Sources */ = {isa = PBXBuildFile; fileRef = 00AD1EFF2486A17900A27979 /* BSGCrashSentry.m */; }; + 00AD1F2B2486A17900A27979 /* BSGCrashSentry.h in Headers */ = {isa = PBXBuildFile; fileRef = 00AD1F002486A17900A27979 /* BSGCrashSentry.h */; }; + 00AD1F2C2486A17900A27979 /* BSGCrashSentry.h in Headers */ = {isa = PBXBuildFile; fileRef = 00AD1F002486A17900A27979 /* BSGCrashSentry.h */; }; + 00AD1F2D2486A17900A27979 /* BSGCrashSentry.h in Headers */ = {isa = PBXBuildFile; fileRef = 00AD1F002486A17900A27979 /* BSGCrashSentry.h */; }; 00AD1F2E2486A17900A27979 /* BugsnagSessionTracker.m in Sources */ = {isa = PBXBuildFile; fileRef = 00AD1F012486A17900A27979 /* BugsnagSessionTracker.m */; }; 00AD1F2F2486A17900A27979 /* BugsnagSessionTracker.m in Sources */ = {isa = PBXBuildFile; fileRef = 00AD1F012486A17900A27979 /* BugsnagSessionTracker.m */; }; 00AD1F302486A17900A27979 /* BugsnagSessionTracker.m in Sources */ = {isa = PBXBuildFile; fileRef = 00AD1F012486A17900A27979 /* BugsnagSessionTracker.m */; }; @@ -944,7 +934,6 @@ E746295824890D3000F92D67 /* BugsnagHandledState.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 0089684E2486DA9400DC48C2 /* BugsnagHandledState.h */; }; E746295924890D3000F92D67 /* BugsnagNotifier.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 008968622486DA9500DC48C2 /* BugsnagNotifier.h */; }; E746295E24890D3000F92D67 /* BugsnagStacktrace.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 0089684F2486DA9400DC48C2 /* BugsnagStacktrace.h */; }; - E746296324890D3000F92D67 /* BugsnagPluginClient.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 008968D92486DAA700DC48C2 /* BugsnagPluginClient.h */; }; E746296424890D3000F92D67 /* BugsnagFileStore.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 008968E62486DAB800DC48C2 /* BugsnagFileStore.h */; }; E746296524890D3000F92D67 /* BugsnagSessionFileStore.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 008968E82486DAB800DC48C2 /* BugsnagSessionFileStore.h */; }; E746296624890D3000F92D67 /* BSGOnErrorSentBlock.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 008968FD2486DAD000DC48C2 /* BSGOnErrorSentBlock.h */; }; @@ -975,7 +964,6 @@ E746298324890D3200F92D67 /* BSG_KSCrashReportFields.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 008969342486DAD000DC48C2 /* BSG_KSCrashReportFields.h */; }; E746298424890D3200F92D67 /* BSG_KSCrashState.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 008969352486DAD000DC48C2 /* BSG_KSCrashState.h */; }; E746298524890D3200F92D67 /* BSG_KSCrashReportVersion.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 008969372486DAD000DC48C2 /* BSG_KSCrashReportVersion.h */; }; - E746298624890D3200F92D67 /* BSG_KSCrashAdvanced.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 008969382486DAD000DC48C2 /* BSG_KSCrashAdvanced.h */; }; E746298824890D3200F92D67 /* BSG_KSCrashSentry_MachException.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 0089693C2486DAD000DC48C2 /* BSG_KSCrashSentry_MachException.h */; }; E746298924890D3200F92D67 /* BSG_KSCrashSentry_Private.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 0089693D2486DAD000DC48C2 /* BSG_KSCrashSentry_Private.h */; }; E746298A24890D3200F92D67 /* BSG_KSCrashSentry.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 0089693F2486DAD000DC48C2 /* BSG_KSCrashSentry.h */; }; @@ -984,7 +972,7 @@ E746298E24890D3200F92D67 /* BSG_KSCrashSentry_Signal.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 008969472486DAD000DC48C2 /* BSG_KSCrashSentry_Signal.h */; }; E746298F24890D3200F92D67 /* BSG_KSCrashType.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 008969482486DAD000DC48C2 /* BSG_KSCrashType.h */; }; E746299024890D3200F92D67 /* BSG_KSCrashIdentifier.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 0089694A2486DAD000DC48C2 /* BSG_KSCrashIdentifier.h */; }; - E746299524890D3200F92D67 /* BugsnagCrashSentry.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 00AD1F002486A17900A27979 /* BugsnagCrashSentry.h */; }; + E746299524890D3200F92D67 /* BSGCrashSentry.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 00AD1F002486A17900A27979 /* BSGCrashSentry.h */; }; E746299624890D3200F92D67 /* BugsnagSessionTracker.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 00AD1EF82486A17700A27979 /* BugsnagSessionTracker.h */; }; /* End PBXBuildFile section */ @@ -1066,7 +1054,6 @@ E746295824890D3000F92D67 /* BugsnagHandledState.h in CopyFiles */, E746295924890D3000F92D67 /* BugsnagNotifier.h in CopyFiles */, E746295E24890D3000F92D67 /* BugsnagStacktrace.h in CopyFiles */, - E746296324890D3000F92D67 /* BugsnagPluginClient.h in CopyFiles */, E746296424890D3000F92D67 /* BugsnagFileStore.h in CopyFiles */, E746296524890D3000F92D67 /* BugsnagSessionFileStore.h in CopyFiles */, E746296624890D3000F92D67 /* BSGOnErrorSentBlock.h in CopyFiles */, @@ -1097,7 +1084,6 @@ E746298324890D3200F92D67 /* BSG_KSCrashReportFields.h in CopyFiles */, E746298424890D3200F92D67 /* BSG_KSCrashState.h in CopyFiles */, E746298524890D3200F92D67 /* BSG_KSCrashReportVersion.h in CopyFiles */, - E746298624890D3200F92D67 /* BSG_KSCrashAdvanced.h in CopyFiles */, E746298824890D3200F92D67 /* BSG_KSCrashSentry_MachException.h in CopyFiles */, E746298924890D3200F92D67 /* BSG_KSCrashSentry_Private.h in CopyFiles */, E746298A24890D3200F92D67 /* BSG_KSCrashSentry.h in CopyFiles */, @@ -1106,7 +1092,7 @@ E746298E24890D3200F92D67 /* BSG_KSCrashSentry_Signal.h in CopyFiles */, E746298F24890D3200F92D67 /* BSG_KSCrashType.h in CopyFiles */, E746299024890D3200F92D67 /* BSG_KSCrashIdentifier.h in CopyFiles */, - E746299524890D3200F92D67 /* BugsnagCrashSentry.h in CopyFiles */, + E746299524890D3200F92D67 /* BSGCrashSentry.h in CopyFiles */, E746299624890D3200F92D67 /* BugsnagSessionTracker.h in CopyFiles */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1223,8 +1209,6 @@ 008968602486DA9500DC48C2 /* BugsnagApp.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BugsnagApp.m; sourceTree = ""; }; 008968612486DA9500DC48C2 /* BugsnagThread.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BugsnagThread.m; sourceTree = ""; }; 008968622486DA9500DC48C2 /* BugsnagNotifier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BugsnagNotifier.h; sourceTree = ""; }; - 008968D92486DAA700DC48C2 /* BugsnagPluginClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BugsnagPluginClient.h; sourceTree = ""; }; - 008968DA2486DAA700DC48C2 /* BugsnagPluginClient.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BugsnagPluginClient.m; sourceTree = ""; }; 008968E52486DAB800DC48C2 /* BugsnagSessionFileStore.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BugsnagSessionFileStore.m; sourceTree = ""; }; 008968E62486DAB800DC48C2 /* BugsnagFileStore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BugsnagFileStore.h; sourceTree = ""; }; 008968E72486DAB800DC48C2 /* BugsnagFileStore.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BugsnagFileStore.m; sourceTree = ""; }; @@ -1280,7 +1264,6 @@ 008969352486DAD000DC48C2 /* BSG_KSCrashState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BSG_KSCrashState.h; sourceTree = ""; }; 008969362486DAD000DC48C2 /* BSG_KSCrash.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BSG_KSCrash.m; sourceTree = ""; }; 008969372486DAD000DC48C2 /* BSG_KSCrashReportVersion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BSG_KSCrashReportVersion.h; sourceTree = ""; }; - 008969382486DAD000DC48C2 /* BSG_KSCrashAdvanced.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BSG_KSCrashAdvanced.h; sourceTree = ""; }; 0089693B2486DAD000DC48C2 /* BSG_KSCrashSentry_NSException.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BSG_KSCrashSentry_NSException.m; sourceTree = ""; }; 0089693C2486DAD000DC48C2 /* BSG_KSCrashSentry_MachException.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BSG_KSCrashSentry_MachException.h; sourceTree = ""; }; 0089693D2486DAD000DC48C2 /* BSG_KSCrashSentry_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BSG_KSCrashSentry_Private.h; sourceTree = ""; }; @@ -1309,8 +1292,8 @@ 00AD1CE424869C6C00A27979 /* libBugsnagStatic.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libBugsnagStatic.a; sourceTree = BUILT_PRODUCTS_DIR; }; 00AD1EF82486A17700A27979 /* BugsnagSessionTracker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BugsnagSessionTracker.h; sourceTree = ""; }; 00AD1EFE2486A17800A27979 /* Bugsnag.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Bugsnag.m; sourceTree = ""; }; - 00AD1EFF2486A17900A27979 /* BugsnagCrashSentry.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BugsnagCrashSentry.m; sourceTree = ""; }; - 00AD1F002486A17900A27979 /* BugsnagCrashSentry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BugsnagCrashSentry.h; sourceTree = ""; }; + 00AD1EFF2486A17900A27979 /* BSGCrashSentry.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BSGCrashSentry.m; sourceTree = ""; }; + 00AD1F002486A17900A27979 /* BSGCrashSentry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BSGCrashSentry.h; sourceTree = ""; }; 00AD1F012486A17900A27979 /* BugsnagSessionTracker.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BugsnagSessionTracker.m; sourceTree = ""; }; 00E636B2248702A1006CBF1A /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; 00E636B3248702A1006CBF1A /* LICENSE.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = LICENSE.txt; sourceTree = ""; }; @@ -1613,7 +1596,6 @@ CBD50F6025DA72EC00DF0314 /* BSG_Jailbreak.h */, 0089692D2486DAD000DC48C2 /* BSG_KSCrash.h */, 008969362486DAD000DC48C2 /* BSG_KSCrash.m */, - 008969382486DAD000DC48C2 /* BSG_KSCrashAdvanced.h */, 0089694B2486DAD000DC48C2 /* BSG_KSCrashC.c */, 0089692E2486DAD000DC48C2 /* BSG_KSCrashC.h */, 0089692A2486DAD000DC48C2 /* BSG_KSCrashContext.h */, @@ -1734,10 +1716,10 @@ 00AD1C7424869B0E00A27979 /* Bugsnag */ = { isa = PBXGroup; children = ( + 00AD1F002486A17900A27979 /* BSGCrashSentry.h */, + 00AD1EFF2486A17900A27979 /* BSGCrashSentry.m */, 00AD1EFE2486A17800A27979 /* Bugsnag.m */, 01937CF9257A7B4C00F2DE31 /* Bugsnag+Private.h */, - 00AD1F002486A17900A27979 /* BugsnagCrashSentry.h */, - 00AD1EFF2486A17900A27979 /* BugsnagCrashSentry.m */, 01099392273D123800128BBE /* BugsnagFeatureFlag.m */, 01CCAEE925D414D60057268D /* BugsnagLastRunInfo.m */, 01CCAEFF25D4151C0057268D /* BugsnagLastRunInfo+Private.h */, @@ -1754,7 +1736,6 @@ 008968F72486DAD000DC48C2 /* KSCrash */, 00AD1CF624869EEA00A27979 /* Metadata */, 00AD1CF724869EF100A27979 /* Payload */, - 00AD1CF824869EF800A27979 /* Plugins */, 00AD1CF924869F0100A27979 /* Storage */, ); path = Bugsnag; @@ -1969,15 +1950,6 @@ path = Payload; sourceTree = ""; }; - 00AD1CF824869EF800A27979 /* Plugins */ = { - isa = PBXGroup; - children = ( - 008968D92486DAA700DC48C2 /* BugsnagPluginClient.h */, - 008968DA2486DAA700DC48C2 /* BugsnagPluginClient.m */, - ); - path = Plugins; - sourceTree = ""; - }; 00AD1CF924869F0100A27979 /* Storage */ = { isa = PBXGroup; children = ( @@ -2115,11 +2087,9 @@ 01A2C546271EB9B400A27B23 /* BSG_Symbolicate.h in Headers */, 008969BD2486DAD100DC48C2 /* BSG_KSMachHeaders.h in Headers */, 0126F7BB25DD512B008483C2 /* BSGEventUploadKSCrashReportOperation.h in Headers */, - 008968DE2486DAA700DC48C2 /* BugsnagPluginClient.h in Headers */, 008969EA2486DAD100DC48C2 /* BSG_KSCrashReport.h in Headers */, 008969F02486DAD100DC48C2 /* BSG_KSCrashReportFields.h in Headers */, 00896A2F2486DAD100DC48C2 /* BSG_KSCrashIdentifier.h in Headers */, - 008969FC2486DAD100DC48C2 /* BSG_KSCrashAdvanced.h in Headers */, 01B79DA9267CC4A000C8CC5E /* BSGUtils.h in Headers */, 008967B82486D9D800DC48C2 /* BugsnagBreadcrumbs.h in Headers */, 008969DE2486DAD100DC48C2 /* BSG_KSCrashC.h in Headers */, @@ -2140,7 +2110,7 @@ 0089681B2486DA5600DC48C2 /* BSGSerialization.h in Headers */, 00896A262486DAD100DC48C2 /* BSG_KSCrashSentry_Signal.h in Headers */, 008968182486DA5600DC48C2 /* BugsnagCollections.h in Headers */, - 00AD1F2B2486A17900A27979 /* BugsnagCrashSentry.h in Headers */, + 00AD1F2B2486A17900A27979 /* BSGCrashSentry.h in Headers */, 00896A1D2486DAD100DC48C2 /* BSG_KSCrashSentry_NSException.h in Headers */, 0089695A2486DAD000DC48C2 /* BSG_KSBacktrace.h in Headers */, 0089688B2486DA9600DC48C2 /* BugsnagStacktrace.h in Headers */, @@ -2221,11 +2191,9 @@ 01A2C547271EB9B400A27B23 /* BSG_Symbolicate.h in Headers */, 008969BE2486DAD100DC48C2 /* BSG_KSMachHeaders.h in Headers */, 0126F7BC25DD512B008483C2 /* BSGEventUploadKSCrashReportOperation.h in Headers */, - 008968DF2486DAA700DC48C2 /* BugsnagPluginClient.h in Headers */, 008969EB2486DAD100DC48C2 /* BSG_KSCrashReport.h in Headers */, 008969F12486DAD100DC48C2 /* BSG_KSCrashReportFields.h in Headers */, 00896A302486DAD100DC48C2 /* BSG_KSCrashIdentifier.h in Headers */, - 008969FD2486DAD100DC48C2 /* BSG_KSCrashAdvanced.h in Headers */, 01B79DAA267CC4A000C8CC5E /* BSGUtils.h in Headers */, 008967B92486D9D800DC48C2 /* BugsnagBreadcrumbs.h in Headers */, 008969DF2486DAD100DC48C2 /* BSG_KSCrashC.h in Headers */, @@ -2246,7 +2214,7 @@ 0089681C2486DA5600DC48C2 /* BSGSerialization.h in Headers */, 00896A272486DAD100DC48C2 /* BSG_KSCrashSentry_Signal.h in Headers */, 008968192486DA5600DC48C2 /* BugsnagCollections.h in Headers */, - 00AD1F2C2486A17900A27979 /* BugsnagCrashSentry.h in Headers */, + 00AD1F2C2486A17900A27979 /* BSGCrashSentry.h in Headers */, 00896A1E2486DAD100DC48C2 /* BSG_KSCrashSentry_NSException.h in Headers */, 0089695B2486DAD000DC48C2 /* BSG_KSBacktrace.h in Headers */, 0089688C2486DA9600DC48C2 /* BugsnagStacktrace.h in Headers */, @@ -2327,11 +2295,9 @@ 01A2C548271EB9B400A27B23 /* BSG_Symbolicate.h in Headers */, 008969BF2486DAD100DC48C2 /* BSG_KSMachHeaders.h in Headers */, 0126F7BD25DD512B008483C2 /* BSGEventUploadKSCrashReportOperation.h in Headers */, - 008968E02486DAA700DC48C2 /* BugsnagPluginClient.h in Headers */, 008969EC2486DAD100DC48C2 /* BSG_KSCrashReport.h in Headers */, 008969F22486DAD100DC48C2 /* BSG_KSCrashReportFields.h in Headers */, 00896A312486DAD100DC48C2 /* BSG_KSCrashIdentifier.h in Headers */, - 008969FE2486DAD100DC48C2 /* BSG_KSCrashAdvanced.h in Headers */, 01B79DAB267CC4A000C8CC5E /* BSGUtils.h in Headers */, 008967BA2486D9D800DC48C2 /* BugsnagBreadcrumbs.h in Headers */, 008969E02486DAD100DC48C2 /* BSG_KSCrashC.h in Headers */, @@ -2352,7 +2318,7 @@ 0089681D2486DA5600DC48C2 /* BSGSerialization.h in Headers */, 00896A282486DAD100DC48C2 /* BSG_KSCrashSentry_Signal.h in Headers */, 0089681A2486DA5600DC48C2 /* BugsnagCollections.h in Headers */, - 00AD1F2D2486A17900A27979 /* BugsnagCrashSentry.h in Headers */, + 00AD1F2D2486A17900A27979 /* BSGCrashSentry.h in Headers */, 00896A1F2486DAD100DC48C2 /* BSG_KSCrashSentry_NSException.h in Headers */, 0089695C2486DAD000DC48C2 /* BSG_KSBacktrace.h in Headers */, 0089688D2486DA9600DC48C2 /* BugsnagStacktrace.h in Headers */, @@ -2693,7 +2659,6 @@ 00896A322486DAD100DC48C2 /* BSG_KSCrashC.c in Sources */, 0109939F273D13D800128BBE /* BSGFeatureFlagStore.m in Sources */, 008969902486DAD100DC48C2 /* BSG_RFC3339DateTool.m in Sources */, - 008968E12486DAA700DC48C2 /* BugsnagPluginClient.m in Sources */, CB33CD012703438400C76656 /* BSG_KSCrashNames.c in Sources */, 008968842486DA9600DC48C2 /* BugsnagNotifier.m in Sources */, CBCF77A625010648004AF22A /* BSGJSONSerialization.m in Sources */, @@ -2765,7 +2730,7 @@ 008967DA2486DA2D00DC48C2 /* BugsnagConfiguration.m in Sources */, 008969A52486DAD100DC48C2 /* BSG_KSBacktrace.c in Sources */, 00896A202486DAD100DC48C2 /* BSG_KSCrashSentry.c in Sources */, - 00AD1F272486A17900A27979 /* BugsnagCrashSentry.m in Sources */, + 00AD1F272486A17900A27979 /* BSGCrashSentry.m in Sources */, 008968B22486DA9600DC48C2 /* BugsnagDeviceWithState.m in Sources */, 0089682F2486DA5600DC48C2 /* BugsnagCollections.m in Sources */, 0089698D2486DAD100DC48C2 /* BSG_KSMach.c in Sources */, @@ -2870,7 +2835,6 @@ 008969852486DAD100DC48C2 /* BSG_KSMachHeaders.c in Sources */, 00896A332486DAD100DC48C2 /* BSG_KSCrashC.c in Sources */, 008969912486DAD100DC48C2 /* BSG_RFC3339DateTool.m in Sources */, - 008968E22486DAA700DC48C2 /* BugsnagPluginClient.m in Sources */, 008968852486DA9600DC48C2 /* BugsnagNotifier.m in Sources */, 008968922486DA9600DC48C2 /* BugsnagError.m in Sources */, CBCF77A725010648004AF22A /* BSGJSONSerialization.m in Sources */, @@ -2940,7 +2904,7 @@ 008967DB2486DA2D00DC48C2 /* BugsnagConfiguration.m in Sources */, 008969A62486DAD100DC48C2 /* BSG_KSBacktrace.c in Sources */, 00896A212486DAD100DC48C2 /* BSG_KSCrashSentry.c in Sources */, - 00AD1F282486A17900A27979 /* BugsnagCrashSentry.m in Sources */, + 00AD1F282486A17900A27979 /* BSGCrashSentry.m in Sources */, 008968B32486DA9600DC48C2 /* BugsnagDeviceWithState.m in Sources */, 008968302486DA5600DC48C2 /* BugsnagCollections.m in Sources */, 0089698E2486DAD100DC48C2 /* BSG_KSMach.c in Sources */, @@ -3042,7 +3006,6 @@ 00896A342486DAD100DC48C2 /* BSG_KSCrashC.c in Sources */, 010993A1273D13D800128BBE /* BSGFeatureFlagStore.m in Sources */, 008969922486DAD100DC48C2 /* BSG_RFC3339DateTool.m in Sources */, - 008968E32486DAA700DC48C2 /* BugsnagPluginClient.m in Sources */, CB33CD032703438400C76656 /* BSG_KSCrashNames.c in Sources */, 008968862486DA9600DC48C2 /* BugsnagNotifier.m in Sources */, 008968932486DA9600DC48C2 /* BugsnagError.m in Sources */, @@ -3114,7 +3077,7 @@ 008967DC2486DA2D00DC48C2 /* BugsnagConfiguration.m in Sources */, 008969A72486DAD100DC48C2 /* BSG_KSBacktrace.c in Sources */, 00896A222486DAD100DC48C2 /* BSG_KSCrashSentry.c in Sources */, - 00AD1F292486A17900A27979 /* BugsnagCrashSentry.m in Sources */, + 00AD1F292486A17900A27979 /* BSGCrashSentry.m in Sources */, 008968B42486DA9600DC48C2 /* BugsnagDeviceWithState.m in Sources */, 008968312486DA5600DC48C2 /* BugsnagCollections.m in Sources */, 0089698F2486DAD100DC48C2 /* BSG_KSMach.c in Sources */, @@ -3259,13 +3222,12 @@ 008968982486DA9600DC48C2 /* BugsnagHandledState.m in Sources */, 008968B52486DA9600DC48C2 /* BugsnagDeviceWithState.m in Sources */, CBAB4DDB2510D2460092CBAA /* BugsnagKVStoreObjC.m in Sources */, - 00AD1F2A2486A17900A27979 /* BugsnagCrashSentry.m in Sources */, + 00AD1F2A2486A17900A27979 /* BSGCrashSentry.m in Sources */, 008968052486DA4500DC48C2 /* BSGConnectivity.m in Sources */, 0126F7A125DD510E008483C2 /* BSGEventUploadObjectOperation.m in Sources */, 01099399273D123800128BBE /* BugsnagFeatureFlag.m in Sources */, 0089689C2486DA9600DC48C2 /* BugsnagStackframe.m in Sources */, 008967DD2486DA2D00DC48C2 /* BugsnagConfiguration.m in Sources */, - 008968E42486DAA700DC48C2 /* BugsnagPluginClient.m in Sources */, 01840B7525DC26E200F95648 /* BSGEventUploader.m in Sources */, 01CB95C5278F0C830077744A /* BSG_KSFile.c in Sources */, 008968BC2486DA9600DC48C2 /* BugsnagStacktrace.m in Sources */, diff --git a/Bugsnag/BSGCrashSentry.h b/Bugsnag/BSGCrashSentry.h new file mode 100644 index 000000000..dfd8cb5b7 --- /dev/null +++ b/Bugsnag/BSGCrashSentry.h @@ -0,0 +1,23 @@ +// +// BSGCrashSentry.h +// Bugsnag +// +// Created by Jamie Lynch on 11/08/2017. +// +// + +#import + +#import "BSG_KSCrashReportWriter.h" +#import "BSG_KSCrashType.h" + +@class BugsnagConfiguration; +@class BugsnagErrorTypes; + +NS_ASSUME_NONNULL_BEGIN + +void BSGCrashSentryInstall(BugsnagConfiguration *, BSG_KSReportWriteCallback); + +BSG_KSCrashType BSG_KSCrashTypeFromBugsnagErrorTypes(BugsnagErrorTypes *); + +NS_ASSUME_NONNULL_END diff --git a/Bugsnag/BugsnagCrashSentry.m b/Bugsnag/BSGCrashSentry.m similarity index 60% rename from Bugsnag/BugsnagCrashSentry.m rename to Bugsnag/BSGCrashSentry.m index 4b75fccc7..532837845 100644 --- a/Bugsnag/BugsnagCrashSentry.m +++ b/Bugsnag/BSGCrashSentry.m @@ -1,40 +1,36 @@ // -// BugsnagCrashSentry.m -// Pods +// BSGCrashSentry.m +// Bugsnag // // Created by Jamie Lynch on 11/08/2017. // // - -#import "BugsnagCrashSentry.h" +#import "BSGCrashSentry.h" #import "BSGFileLocations.h" -#import "BSG_KSCrashAdvanced.h" +#import "BSG_KSCrash.h" +#import "BSG_KSCrashC.h" #import "BSG_KSMach.h" #import "BugsnagConfiguration.h" #import "BugsnagErrorTypes.h" #import "BugsnagLogger.h" -@implementation BugsnagCrashSentry - -- (void)install:(BugsnagConfiguration *)config onCrash:(BSGReportCallback)onCrash -{ +void BSGCrashSentryInstall(BugsnagConfiguration *config, BSG_KSReportWriteCallback onCrash) { BSG_KSCrash *ksCrash = [BSG_KSCrash sharedInstance]; - ksCrash.introspectMemory = NO; - ksCrash.onCrash = onCrash; - ksCrash.maxStoredReports = (int)config.maxPersistedEvents; + + bsg_kscrash_setCrashNotifyCallback(onCrash); // overridden elsewhere for handled errors, so we can assume that this only // applies to unhandled errors - ksCrash.threadTracingEnabled = config.sendThreads != BSGThreadSendPolicyNever; + bsg_kscrash_setThreadTracingEnabled(config.sendThreads != BSGThreadSendPolicyNever); BSG_KSCrashType crashTypes = 0; if (config.autoDetectErrors) { if (bsg_ksmachisBeingTraced()) { bsg_log_info(@"Unhandled errors will not be reported because a debugger is attached"); } else { - crashTypes = [self mapKSToBSGCrashTypes:config.enabledErrorTypes]; + crashTypes = BSG_KSCrashTypeFromBugsnagErrorTypes(config.enabledErrorTypes); } } @@ -53,12 +49,9 @@ - (void)install:(BugsnagConfiguration *)config onCrash:(BSGReportCallback)onCras * @param errorTypes The enabled error types * @returns A BSG_KSCrashType equivalent (with the above caveats) to the input */ -- (BSG_KSCrashType)mapKSToBSGCrashTypes:(BugsnagErrorTypes *)errorTypes -{ - return (BSG_KSCrashType) ((errorTypes.unhandledExceptions ? BSG_KSCrashTypeNSException : 0) - | (errorTypes.cppExceptions ? BSG_KSCrashTypeCPPException : 0) - | (errorTypes.signals ? BSG_KSCrashTypeSignal : 0) - | (errorTypes.machExceptions ? BSG_KSCrashTypeMachException : 0)); +BSG_KSCrashType BSG_KSCrashTypeFromBugsnagErrorTypes(BugsnagErrorTypes *errorTypes) { + return ((errorTypes.unhandledExceptions ? BSG_KSCrashTypeNSException : 0) | + (errorTypes.cppExceptions ? BSG_KSCrashTypeCPPException : 0) | + (errorTypes.signals ? BSG_KSCrashTypeSignal : 0) | + (errorTypes.machExceptions ? BSG_KSCrashTypeMachException : 0) ); } - -@end diff --git a/Bugsnag/BugsnagCrashSentry.h b/Bugsnag/BugsnagCrashSentry.h deleted file mode 100644 index 2365dc6d5..000000000 --- a/Bugsnag/BugsnagCrashSentry.h +++ /dev/null @@ -1,23 +0,0 @@ -// -// BugsnagCrashSentry.h -// Pods -// -// Created by Jamie Lynch on 11/08/2017. -// -// - -#import - -#import "BSG_KSCrashReportWriter.h" -#import "BSG_KSCrashType.h" - -@class BugsnagConfiguration; -@class BugsnagErrorTypes; - -@interface BugsnagCrashSentry : NSObject - -- (void)install:(BugsnagConfiguration *)config onCrash:(BSGReportCallback)onCrash; - -- (BSG_KSCrashType)mapKSToBSGCrashTypes:(BugsnagErrorTypes *)errorTypes; - -@end diff --git a/Bugsnag/BugsnagSystemState.h b/Bugsnag/BugsnagSystemState.h index bf8385f6a..693c48cca 100644 --- a/Bugsnag/BugsnagSystemState.h +++ b/Bugsnag/BugsnagSystemState.h @@ -16,7 +16,6 @@ #define SYSTEMSTATE_KEY_DEVICE @"device" #define SYSTEMSTATE_APP_WAS_TERMINATED @"wasTerminated" -#define SYSTEMSTATE_APP_IS_ACTIVE @"isActive" #define SYSTEMSTATE_APP_IS_IN_FOREGROUND @"inForeground" #define SYSTEMSTATE_APP_IS_LAUNCHING BSGKeyIsLaunching #define SYSTEMSTATE_APP_VERSION @"version" diff --git a/Bugsnag/BugsnagSystemState.m b/Bugsnag/BugsnagSystemState.m index 3347cb6fc..47d59b966 100644 --- a/Bugsnag/BugsnagSystemState.m +++ b/Bugsnag/BugsnagSystemState.m @@ -19,6 +19,7 @@ #import "BSGFileLocations.h" #import "BSGJSONSerialization.h" #import "BSGUtils.h" +#import "BSG_KSCrashState.h" #import "BSG_KSMach.h" #import "BSG_KSSystemInfo.h" #import "BSG_RFC3339DateTool.h" @@ -57,7 +58,6 @@ // KV-store versions of these are authoritative for (NSString *key in @[SYSTEMSTATE_APP_DEBUGGER_IS_ACTIVE, - SYSTEMSTATE_APP_IS_ACTIVE, SYSTEMSTATE_APP_IS_IN_FOREGROUND, SYSTEMSTATE_APP_IS_LAUNCHING, SYSTEMSTATE_APP_WAS_TERMINATED]) { @@ -85,18 +85,19 @@ id blankIfNil(id value) { bool isBeingDebugged = bsg_ksmachisBeingTraced(); bool isInForeground = true; - bool isActive = true; #if TARGET_OS_OSX // MacOS "active" serves the same purpose as "foreground" in iOS isInForeground = [NSAPPLICATION sharedApplication].active; #else - UIApplicationState appState = [BSG_KSSystemInfo currentAppState]; - isInForeground = [BSG_KSSystemInfo isInForeground:appState]; - isActive = appState == UIApplicationStateActive; + const BSG_KSCrash_State *crashState = bsg_kscrashstate_currentState(); + NSCParameterAssert(crashState != nil); + if (crashState) { + isInForeground = crashState->applicationIsInForeground; + } #endif [kvstore deleteKey:SYSTEMSTATE_APP_WAS_TERMINATED]; - [kvstore setBoolean:isActive forKey:SYSTEMSTATE_APP_IS_ACTIVE]; + [kvstore deleteKey:@"isActive"]; // Deprecated key [kvstore setBoolean:isInForeground forKey:SYSTEMSTATE_APP_IS_IN_FOREGROUND]; [kvstore setBoolean:true forKey:SYSTEMSTATE_APP_IS_LAUNCHING]; [kvstore setBoolean:isBeingDebugged forKey:SYSTEMSTATE_APP_DEBUGGER_IS_ACTIVE]; @@ -110,7 +111,6 @@ id blankIfNil(id value) { app[BSGKeyMachoUUID] = systemInfo[@BSG_KSSystemField_AppUUID]; app[@"binaryArch"] = systemInfo[@BSG_KSSystemField_BinaryArch]; app[@"inForeground"] = @(isInForeground); - app[@"isActive"] = @(isActive); #if TARGET_OS_TV app[BSGKeyType] = @"tvOS"; #elif TARGET_OS_IOS @@ -225,14 +225,8 @@ - (instancetype)initWithConfiguration:(BugsnagConfiguration *)config { [center addObserverForName:UIApplicationDidBecomeActiveNotification object:nil queue:nil usingBlock:^(__attribute__((unused)) NSNotification * _Nonnull note) { __strong __typeof__(self) strongSelf = weakSelf; - [strongSelf.kvStore setBoolean:YES forKey:SYSTEMSTATE_APP_IS_ACTIVE]; - [strongSelf setValue:@YES forAppKey:SYSTEMSTATE_APP_IS_ACTIVE]; - }]; - [center addObserverForName:UIApplicationWillResignActiveNotification object:nil queue:nil - usingBlock:^(__attribute__((unused)) NSNotification * _Nonnull note) { - __strong __typeof__(self) strongSelf = weakSelf; - [strongSelf.kvStore setBoolean:NO forKey:SYSTEMSTATE_APP_IS_ACTIVE]; - [strongSelf setValue:@NO forAppKey:SYSTEMSTATE_APP_IS_ACTIVE]; + [strongSelf.kvStore setBoolean:YES forKey:SYSTEMSTATE_APP_IS_IN_FOREGROUND]; + [strongSelf setValue:@YES forAppKey:SYSTEMSTATE_APP_IS_IN_FOREGROUND]; }]; #endif [center addObserver:self selector:@selector(sessionUpdateNotification:) name:BSGSessionUpdateNotification object:nil]; @@ -353,9 +347,8 @@ - (BOOL)lastLaunchTerminatedUnexpectedly { return NO; // The debugger may have killed the app } - // If the app was inactive or in the background, we cannot determine whether the termination was unexpected - if (![previousAppState[SYSTEMSTATE_APP_IS_ACTIVE] boolValue] || - ![previousAppState[SYSTEMSTATE_APP_IS_IN_FOREGROUND] boolValue]) { + // If the app was in the background, we cannot determine whether the termination was unexpected + if (![previousAppState[SYSTEMSTATE_APP_IS_IN_FOREGROUND] boolValue]) { return NO; } diff --git a/Bugsnag/Client/BugsnagClient+Private.h b/Bugsnag/Client/BugsnagClient+Private.h index 84c384709..bad553134 100644 --- a/Bugsnag/Client/BugsnagClient+Private.h +++ b/Bugsnag/Client/BugsnagClient+Private.h @@ -15,11 +15,9 @@ @class BugsnagAppWithState; @class BugsnagBreadcrumbs; @class BugsnagConfiguration; -@class BugsnagCrashSentry; @class BugsnagDeviceWithState; @class BugsnagMetadata; @class BugsnagNotifier; -@class BugsnagPluginClient; @class BugsnagSessionTracker; @class BugsnagSystemState; @@ -45,10 +43,6 @@ typedef void (^ BSGClientObserver)(BSGClientObserverEvent event, _Nullable id va @property (nullable, nonatomic) BugsnagEvent *appHangEvent; -/// Alters whether error detection should be enabled or not after Bugsnag has been initialized. -/// Intended for internal use only by Unity. -@property (nonatomic) BOOL autoNotify; - @property (nullable, retain, nonatomic) BugsnagBreadcrumbs *breadcrumbs; @property (nullable, nonatomic) NSString *codeBundleId; @@ -59,8 +53,6 @@ typedef void (^ BSGClientObserver)(BSGClientObserverEvent event, _Nullable id va @property (retain, nonatomic) BugsnagConfiguration *configuration; -@property (strong, nonatomic) BugsnagCrashSentry *crashSentry; - /// The App hang or OOM event that caused the last launch to crash. @property (nullable, nonatomic) BugsnagEvent *eventFromLastLaunch; @@ -80,8 +72,6 @@ typedef void (^ BSGClientObserver)(BSGClientObserverEvent event, _Nullable id va @property (readonly, nonatomic) BugsnagNotifier *notifier; // Used in BugsnagReactNative -@property (strong, nonatomic) BugsnagPluginClient *pluginClient; - @property (strong, nonatomic) BugsnagSessionTracker *sessionTracker; // Used in BugsnagReactNative @property (nonatomic) BOOL started; diff --git a/Bugsnag/Client/BugsnagClient.m b/Bugsnag/Client/BugsnagClient.m index 1fbe4a4bc..778c90be0 100644 --- a/Bugsnag/Client/BugsnagClient.m +++ b/Bugsnag/Client/BugsnagClient.m @@ -28,6 +28,7 @@ #import "BSGAppHangDetector.h" #import "BSGConnectivity.h" +#import "BSGCrashSentry.h" #import "BSGEventUploader.h" #import "BSGFileLocations.h" #import "BSGInternalErrorReporter.h" @@ -51,7 +52,6 @@ #import "BugsnagBreadcrumbs.h" #import "BugsnagCollections.h" #import "BugsnagConfiguration+Private.h" -#import "BugsnagCrashSentry.h" #import "BugsnagDeviceWithState+Private.h" #import "BugsnagError+Private.h" #import "BugsnagErrorTypes.h" @@ -62,7 +62,7 @@ #import "BugsnagLogger.h" #import "BugsnagMetadata+Private.h" #import "BugsnagNotifier.h" -#import "BugsnagPluginClient.h" +#import "BugsnagPlugin.h" #import "BugsnagSession+Private.h" #import "BugsnagSessionTracker.h" #import "BugsnagStackframe+Private.h" @@ -113,7 +113,7 @@ * * @param writer report writer which will receive updated metadata */ -void BSSerializeDataCrashHandler(const BSG_KSCrashReportWriter *writer, __attribute__((unused)) int type) { +void BSSerializeDataCrashHandler(const BSG_KSCrashReportWriter *writer) { BOOL isCrash = YES; if (hasRecordedSessions) { // a session is available // persist session info @@ -219,7 +219,6 @@ - (instancetype)initWithConfiguration:(BugsnagConfiguration *)configuration { }]; _notifier = _configuration.notifier ?: [[BugsnagNotifier alloc] init]; - self.systemState = [[BugsnagSystemState alloc] initWithConfiguration:_configuration]; BSGFileLocations *fileLocations = [BSGFileLocations current]; @@ -238,7 +237,7 @@ - (instancetype)initWithConfiguration:(BugsnagConfiguration *)configuration { self.stateEventBlocks = [NSMutableArray new]; self.extraRuntimeInfo = [NSMutableDictionary new]; - self.crashSentry = [BugsnagCrashSentry new]; + _eventUploader = [[BSGEventUploader alloc] initWithConfiguration:_configuration notifier:_notifier]; bsg_g_bugsnag_data.onCrash = (void (*)(const BSG_KSCrashReportWriter *))self.configuration.onCrashHandler; @@ -273,9 +272,6 @@ - (instancetype)initWithConfiguration:(BugsnagConfiguration *)configuration { [self.metadata setStorageBuffer:&bsg_g_bugsnag_data.metadataJSON file:_metadataFile]; [self.state setStorageBuffer:&bsg_g_bugsnag_data.stateJSON file:_stateMetadataFile]; - self.pluginClient = [[BugsnagPluginClient alloc] initWithPlugins:self.configuration.plugins - client:self]; - BSGInternalErrorReporter.sharedInstance = [[BSGInternalErrorReporter alloc] initWithDataSource:self]; } return self; @@ -283,7 +279,8 @@ - (instancetype)initWithConfiguration:(BugsnagConfiguration *)configuration { - (void)start { [self.configuration validate]; - [self.crashSentry install:self.configuration onCrash:&BSSerializeDataCrashHandler]; + BSGCrashSentryInstall(self.configuration, BSSerializeDataCrashHandler); + self.systemState = [[BugsnagSystemState alloc] initWithConfiguration:self.configuration]; [self computeDidCrashLastLaunch]; [self.breadcrumbs removeAllBreadcrumbs]; [self setupConnectivityListener]; @@ -355,13 +352,23 @@ - (void)start { self.started = YES; + id reactNativePlugin = [NSClassFromString(@"BugsnagReactNativePlugin") new]; + if (reactNativePlugin) { + [self.configuration.plugins addObject:reactNativePlugin]; + } + for (id plugin in self.configuration.plugins) { + @try { + [plugin load:self]; + } @catch (NSException *exception) { + bsg_log_err(@"Plugin %@ threw exception in -load: %@", plugin, exception); + } + } + [self.sessionTracker startWithNotificationCenter:center isInForeground:bsg_kscrashstate_currentState()->applicationIsInForeground]; // Record a "Bugsnag Loaded" message [self addAutoBreadcrumbOfType:BSGBreadcrumbTypeState withMessage:@"Bugsnag loaded" andMetadata:nil]; - [self.pluginClient loadPlugins]; - if (self.configuration.launchDurationMillis > 0) { self.appLaunchTimer = [NSTimer scheduledTimerWithTimeInterval:(double)self.configuration.launchDurationMillis / 1000.0 target:self selector:@selector(appLaunchTimerFired:) @@ -1150,40 +1157,6 @@ - (void)setObserver:(BSGClientObserver)observer { } } -// ============================================================================= -// MARK: - autoNotify -// ============================================================================= - -- (BOOL)autoNotify { - return self.configuration.autoDetectErrors; -} - -/// Alters whether error detection should be enabled or not after Bugsnag has been initialized. -/// Intended for internal use only by Unity. -- (void)setAutoNotify:(BOOL)autoNotify { - BOOL changed = self.configuration.autoDetectErrors != autoNotify; - self.configuration.autoDetectErrors = autoNotify; - - if (changed) { - [self updateCrashDetectionSettings]; - } -} - -/// Updates the crash detection settings after Bugsnag has been initialized. -/// App Hang detection is not updated as it will always be disabled for Unity. -- (void)updateCrashDetectionSettings { - if (self.configuration.autoDetectErrors) { - // alter the enabled KSCrash types - BugsnagErrorTypes *errorTypes = self.configuration.enabledErrorTypes; - BSG_KSCrashType crashTypes = [self.crashSentry mapKSToBSGCrashTypes:errorTypes]; - bsg_kscrash_setHandlingCrashTypes(crashTypes); - } else { - // Only enable support for notify()-based reports - bsg_kscrash_setHandlingCrashTypes(BSG_KSCrashTypeNone); - } - // OOMs are controlled by config.autoDetectErrors so don't require any further action -} - // MARK: - App Hangs - (void)startAppHangDetector { diff --git a/Bugsnag/Helpers/BSGAppHangDetector.m b/Bugsnag/Helpers/BSGAppHangDetector.m index beec79ea0..a9a4eba32 100644 --- a/Bugsnag/Helpers/BSGAppHangDetector.m +++ b/Bugsnag/Helpers/BSGAppHangDetector.m @@ -22,7 +22,6 @@ @interface BSGAppHangDetector () @property (weak, nonatomic) id delegate; -@property (nonatomic) BOOL runLoopIsRunning; @property (nonatomic) BOOL recordAllThreads; @property (nonatomic) CFRunLoopObserverRef observer; @property (atomic) dispatch_time_t processingDeadline; @@ -82,7 +81,6 @@ - (void)startWithDelegate:(id)delegate { // Each iteration indicates a separate unit of work so the hang detection should be reset accordingly. dispatch_semaphore_signal(self.processingFinished); } - self.runLoopIsRunning = YES; self.processingDeadline = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(threshold * NSEC_PER_SEC)); dispatch_semaphore_signal(self.processingStarted); isProcessing = YES; @@ -148,9 +146,7 @@ - (void)detectAppHangs { } #endif - // Ignore background state if the runloop has not yet ticked so that hangs in `didFinishLaunching` in UIScene-based - // apps are detected. UIScene-based apps always start in UIApplicationStateBackground, unlike those without scenes. - if (shouldReportAppHang && !bsg_kscrashstate_currentState()->applicationIsInForeground && self.runLoopIsRunning) { + if (shouldReportAppHang && !bsg_kscrashstate_currentState()->applicationIsInForeground) { bsg_log_debug(@"Ignoring app hang because app is in the background"); shouldReportAppHang = NO; } diff --git a/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrash.h b/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrash.h index a8a458c44..e73c6da8b 100644 --- a/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrash.h +++ b/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrash.h @@ -26,7 +26,6 @@ #import -#import "BSG_KSCrashReportWriter.h" #import "BSG_KSCrashType.h" /** @@ -36,15 +35,6 @@ */ @interface BSG_KSCrash : NSObject -/** If YES, introspect memory contents during a crash. - * Any Objective-C objects or C strings near the stack pointer or referenced by - * cpu registers or exceptions will be recorded in the crash report, along with - * their contents. - * - * Default: YES - */ -@property(nonatomic, readwrite, assign) bool introspectMemory; - /** Get the singleton instance of the crash reporter. */ + (BSG_KSCrash *)sharedInstance; @@ -57,26 +47,4 @@ */ - (BSG_KSCrashType)install:(BSG_KSCrashType)crashTypes directory:(NSString *)directory; -/** - * Collects information about the application's foreground state (duration in foreground/background) - */ -- (NSDictionary *)captureAppStats; - -/** If YES, reports will be sent even if a debugger is attached - * - * Default: NO - */ -@property(nonatomic, readwrite, assign) BOOL reportWhenDebuggerIsAttached; - -/** -* The methodology used for tracing threads. - */ -@property(nonatomic, readwrite, assign) BOOL threadTracingEnabled; - @end - -//! Project version number for BSG_KSCrashFramework. -FOUNDATION_EXPORT const double BSG_KSCrashFrameworkVersionNumber; - -//! Project version string for BSG_KSCrashFramework. -FOUNDATION_EXPORT const unsigned char BSG_KSCrashFrameworkVersionString[]; diff --git a/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrash.m b/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrash.m index 808e91140..9dba395a6 100644 --- a/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrash.m +++ b/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrash.m @@ -24,22 +24,10 @@ // THE SOFTWARE. // -#import -#import "BSG_KSCrashAdvanced.h" +#import "BSG_KSCrash.h" #import "BSG_KSCrashC.h" -#import "BSG_KSJSONCodecObjC.h" -#import "NSError+BSG_SimpleConstructor.h" - -//#define BSG_KSLogger_LocalLevel TRACE -#import "BSG_KSLogger.h" -#import "BugsnagThread+Private.h" -#import "BSGJSONSerialization.h" -#import "BSGSerialization.h" -#import "Bugsnag.h" -#import "BugsnagCollections.h" #import "BSG_KSCrashIdentifier.h" -#import "BSG_KSCrashReportFields.h" #if TARGET_OS_IOS || TARGET_OS_TV #import "BSGUIKit.h" @@ -54,41 +42,8 @@ #define BSG_kCrashStateFilenameSuffix "-CrashState.json" -// ============================================================================ -#pragma mark - Globals - -// ============================================================================ - -@interface BSG_KSCrash () - -@property(nonatomic, readwrite, retain) NSString *nextCrashID; - -// Mirrored from BSG_KSCrashAdvanced.h to provide ivars -@property(nonatomic, readwrite, retain) NSString *logFilePath; -@property(nonatomic, readwrite, assign) BSGReportCallback onCrash; -@property(nonatomic, readwrite, assign) bool printTraceToStdout; -@property(nonatomic, readwrite, assign) int maxStoredReports; - -@end - @implementation BSG_KSCrash -// ============================================================================ -#pragma mark - Properties - -// ============================================================================ - -@synthesize printTraceToStdout = _printTraceToStdout; -@synthesize onCrash = _onCrash; -@synthesize logFilePath = _logFilePath; -@synthesize nextCrashID = _nextCrashID; -@synthesize introspectMemory = _introspectMemory; -@synthesize maxStoredReports = _maxStoredReports; -@synthesize reportWhenDebuggerIsAttached = _reportWhenDebuggerIsAttached; -@synthesize threadTracingEnabled = _threadTracingEnabled; - -// ============================================================================ -#pragma mark - Lifecycle - -// ============================================================================ - + (BSG_KSCrash *)sharedInstance { static id sharedInstance; static dispatch_once_t onceToken; @@ -99,49 +54,11 @@ + (BSG_KSCrash *)sharedInstance { return sharedInstance; } -- (instancetype)init { - if ((self = [super init])) { - self.nextCrashID = [NSUUID UUID].UUIDString; - self.introspectMemory = YES; - self.maxStoredReports = 5; - self.reportWhenDebuggerIsAttached = NO; - } - return self; -} - -// ============================================================================ -#pragma mark - API - -// ============================================================================ - -- (void)setPrintTraceToStdout:(bool)printTraceToStdout { - _printTraceToStdout = printTraceToStdout; - bsg_kscrash_setPrintTraceToStdout(printTraceToStdout); -} - -- (void)setOnCrash:(BSGReportCallback)onCrash { - _onCrash = onCrash; - bsg_kscrash_setCrashNotifyCallback(onCrash); -} - -- (void)setIntrospectMemory:(bool)introspectMemory { - _introspectMemory = introspectMemory; - bsg_kscrash_setIntrospectMemory(introspectMemory); -} - -- (void)setReportWhenDebuggerIsAttached:(BOOL)reportWhenDebuggerIsAttached { - _reportWhenDebuggerIsAttached = reportWhenDebuggerIsAttached; - bsg_kscrash_setReportWhenDebuggerIsAttached(reportWhenDebuggerIsAttached); -} - -- (void)setThreadTracingEnabled:(BOOL)threadTracingEnabled { - _threadTracingEnabled = threadTracingEnabled; - bsg_kscrash_setThreadTracingEnabled(threadTracingEnabled); -} - - (BSG_KSCrashType)install:(BSG_KSCrashType)crashTypes directory:(NSString *)directory { bsg_kscrash_generate_report_initialize(directory.fileSystemRepresentation); - char *crashReportPath = bsg_kscrash_generate_report_path(self.nextCrashID.UTF8String, false); - char *recrashReportPath = bsg_kscrash_generate_report_path(self.nextCrashID.UTF8String, true); + NSString *nextCrashID = [NSUUID UUID].UUIDString; + char *crashReportPath = bsg_kscrash_generate_report_path(nextCrashID.UTF8String, false); + char *recrashReportPath = bsg_kscrash_generate_report_path(nextCrashID.UTF8String, true); NSString *stateFilePrefix = [[NSBundle mainBundle] infoDictionary][@"CFBundleName"] /* Not all processes have an Info.plist */ ?: NSProcessInfo.processInfo.processName; NSString *stateFilePath = [directory stringByAppendingPathComponent: @@ -151,7 +68,7 @@ - (BSG_KSCrashType)install:(BSG_KSCrashType)crashTypes directory:(NSString *)dir BSG_KSCrashType installedCrashTypes = bsg_kscrash_install( crashReportPath, recrashReportPath, - [stateFilePath UTF8String], [self.nextCrashID UTF8String]); + [stateFilePath UTF8String], [nextCrashID UTF8String]); free(crashReportPath); free(recrashReportPath); @@ -174,10 +91,6 @@ - (BSG_KSCrashType)install:(BSG_KSCrashType)crashTypes directory:(NSString *)dir selector:@selector(applicationWillEnterForeground) name:UIApplicationWillEnterForegroundNotification object:nil]; - [nCenter addObserver:self - selector:@selector(applicationWillTerminate) - name:UIApplicationWillTerminateNotification - object:nil]; #elif TARGET_OS_OSX // MacOS "active" serves the same purpose as "foreground" in iOS [nCenter addObserver:self @@ -188,55 +101,11 @@ - (BSG_KSCrashType)install:(BSG_KSCrashType)crashTypes directory:(NSString *)dir selector:@selector(applicationWillEnterForeground) name:NSApplicationDidBecomeActiveNotification object:nil]; - [nCenter addObserver:self - selector:@selector(applicationWillTerminate) - name:NSApplicationWillTerminateNotification - object:nil]; #endif return installedCrashTypes; } -- (NSDictionary *)captureAppStats { - BSG_KSCrash_State state = crashContext()->state; - bsg_kscrashstate_updateDurationStats(&state); - NSMutableDictionary *dict = [NSMutableDictionary new]; - dict[@BSG_KSCrashField_ActiveTimeSinceLaunch] = @(state.foregroundDurationSinceLaunch); - dict[@BSG_KSCrashField_BGTimeSinceLaunch] = @(state.backgroundDurationSinceLaunch); - dict[@BSG_KSCrashField_AppInFG] = @(state.applicationIsInForeground); - return dict; -} - -// ============================================================================ -#pragma mark - Advanced API - -// ============================================================================ - -#define BSG_SYNTHESIZE_CRASH_STATE_PROPERTY(TYPE, NAME) \ - -(TYPE)NAME { \ - return bsg_kscrashstate_currentState()->NAME; \ - } - -BSG_SYNTHESIZE_CRASH_STATE_PROPERTY(NSTimeInterval, - foregroundDurationSinceLastCrash) -BSG_SYNTHESIZE_CRASH_STATE_PROPERTY(NSTimeInterval, - backgroundDurationSinceLastCrash) -BSG_SYNTHESIZE_CRASH_STATE_PROPERTY(int, launchesSinceLastCrash) -BSG_SYNTHESIZE_CRASH_STATE_PROPERTY(int, sessionsSinceLastCrash) -BSG_SYNTHESIZE_CRASH_STATE_PROPERTY(NSTimeInterval, foregroundDurationSinceLaunch) -BSG_SYNTHESIZE_CRASH_STATE_PROPERTY(NSTimeInterval, - backgroundDurationSinceLaunch) -BSG_SYNTHESIZE_CRASH_STATE_PROPERTY(int, sessionsSinceLaunch) -BSG_SYNTHESIZE_CRASH_STATE_PROPERTY(BOOL, crashedLastLaunch) - -- (BOOL)redirectConsoleLogsToFile:(NSString *)fullPath - overwrite:(BOOL)overwrite { - if (bsg_kslog_setLogFilename([fullPath UTF8String], overwrite)) { - self.logFilePath = fullPath; - return YES; - } - return NO; -} - // ============================================================================ #pragma mark - Callbacks - // ============================================================================ @@ -257,14 +126,10 @@ - (void)applicationWillEnterForeground { bsg_kscrashstate_notifyAppInForeground(true); } -- (void)applicationWillTerminate { - bsg_kscrashstate_notifyAppTerminate(); -} - @end //! Project version number for BSG_KSCrashFramework. -const double BSG_KSCrashFrameworkVersionNumber = 1.813; +//const double BSG_KSCrashFrameworkVersionNumber = 1.813; //! Project version string for BSG_KSCrashFramework. -const unsigned char BSG_KSCrashFrameworkVersionString[] = "1.8.13"; +//const unsigned char BSG_KSCrashFrameworkVersionString[] = "1.8.13"; diff --git a/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrashAdvanced.h b/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrashAdvanced.h deleted file mode 100644 index bfe2fef96..000000000 --- a/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrashAdvanced.h +++ /dev/null @@ -1,107 +0,0 @@ -// -// BSG_KSCrashAdvanced.h -// -// Created by Karl Stenerud on 2012-05-06. -// -// Copyright (c) 2012 Karl Stenerud. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall remain in place -// in this source code. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// - -#import "BSG_KSCrash.h" - -/** - * Advanced interface to the BSG_KSCrash system. - */ -@interface BSG_KSCrash (Advanced) - -#pragma mark - Information - - -/** Total active time elapsed since the last crash. */ -@property(nonatomic, readonly, assign) - NSTimeInterval foregroundDurationSinceLastCrash; - -/** Total time backgrounded elapsed since the last crash. */ -@property(nonatomic, readonly, assign) - NSTimeInterval backgroundDurationSinceLastCrash; - -/** Number of app launches since the last crash. */ -@property(nonatomic, readonly, assign) int launchesSinceLastCrash; - -/** Number of sessions (launch, resume from suspend) since last crash. */ -@property(nonatomic, readonly, assign) int sessionsSinceLastCrash; - -/** Total active time elapsed since launch. */ -@property(nonatomic, readonly, assign) NSTimeInterval foregroundDurationSinceLaunch; - -/** Total time backgrounded elapsed since launch. */ -@property(nonatomic, readonly, assign) - NSTimeInterval backgroundDurationSinceLaunch; - -/** Number of sessions (launch, resume from suspend) since app launch. */ -@property(nonatomic, readonly, assign) int sessionsSinceLaunch; - -/** If true, the application crashed on the previous launch. */ -@property(nonatomic, readonly, assign) BOOL crashedLastLaunch; - -/** Max number of reports to store on disk before throwing older reports out. - * (default 5) */ -@property(nonatomic, readwrite, assign) int maxStoredReports; - -#pragma mark - Configuration - - -/** C Function to call during a crash report to give the callee an opportunity - * to add to the report. NULL = ignore. - * - * WARNING: Only call async-safe functions from this function! DO NOT call - * Objective-C methods!!! - * - * Note: If you use an installation, it will automatically set this property. - * Do not modify it in such a case. - */ -@property(nonatomic, readwrite, assign) BSGReportCallback onCrash; - -/** Path where the log of BSG_KSCrash's activities will be written. - * If nil, log entries will be printed to the console. - * - * This property cannot be set directly. Use one of the "redirectConsoleLogs" - * methods instead. - * - * Default: nil - */ -@property(nonatomic, readonly, retain) NSString *logFilePath; - -/** If YES, print a stack trace to stdout when a crash occurs. - * - * Default: NO - */ -@property(nonatomic, readwrite, assign) bool printTraceToStdout; - -/** Redirect the log of BSG_KSCrash's activities from the console to the - * specified log file. - * - * @param fullPath The path to the logfile (nil = log to console instead). - * @param overwrite If true, overwrite the file (ignored if fullPath is nil). - * - * @return true if the operation was successful. - */ -- (BOOL)redirectConsoleLogsToFile:(NSString *)fullPath - overwrite:(BOOL)overwrite; - -@end diff --git a/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrashC.c b/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrashC.c index 935cf4812..7d1a3b8c2 100644 --- a/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrashC.c +++ b/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrashC.c @@ -154,9 +154,6 @@ void bsg_kscrash_reinstall(const char *const crashReportFilePath, if (!bsg_kscrashstate_init(bsg_g_stateFilePath, &context->state)) { BSG_KSLOG_ERROR("Failed to initialize persistent crash state"); } - uint64_t timeNow = mach_absolute_time(); - context->state.appLaunchTime = timeNow; - context->state.lastUpdateDurationsTime = timeNow; } BSG_KSCrashType bsg_kscrash_setHandlingCrashTypes(BSG_KSCrashType crashTypes) { @@ -183,7 +180,7 @@ void bsg_kscrash_setIntrospectMemory(bool introspectMemory) { } void bsg_kscrash_setCrashNotifyCallback( - const BSGReportCallback onCrashNotify) { + const BSG_KSReportWriteCallback onCrashNotify) { BSG_KSLOG_TRACE("Set onCrashNotify to %p", onCrashNotify); crashContext()->config.onCrashNotify = onCrashNotify; } diff --git a/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrashC.h b/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrashC.h index 7bcc10479..9789fd220 100644 --- a/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrashC.h +++ b/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrashC.h @@ -119,7 +119,7 @@ void bsg_kscrash_setIntrospectMemory(bool introspectMemory); * Default: NULL */ void bsg_kscrash_setCrashNotifyCallback( - const BSGReportCallback onCrashNotify); + const BSG_KSReportWriteCallback onCrashNotify); /** If YES, user reported exceptions even if a debugger is attached * diff --git a/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrashContext.h b/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrashContext.h index 40e12ede9..905bc4a07 100644 --- a/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrashContext.h +++ b/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrashContext.h @@ -72,7 +72,7 @@ typedef struct { /** Callback allowing the application the opportunity to add extra data to * the report file. Application MUST NOT call async-unsafe methods! */ - BSGReportCallback onCrashNotify; + BSG_KSReportWriteCallback onCrashNotify; /** * File path to write the crash report diff --git a/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrashIdentifier.m b/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrashIdentifier.m index 4c13195d6..b71c00d25 100644 --- a/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrashIdentifier.m +++ b/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrashIdentifier.m @@ -1,6 +1,6 @@ #import "BSG_KSCrashIdentifier.h" -#import "BSG_KSCrashAdvanced.h" +#import "BSG_KSCrash.h" #import diff --git a/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrashReport.c b/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrashReport.c index 092e3f56e..ba129ad4d 100644 --- a/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrashReport.c +++ b/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrashReport.c @@ -1347,20 +1347,6 @@ void bsg_kscrw_i_writeAppStats(const BSG_KSCrashReportWriter *const writer, { writer->addBooleanElement(writer, BSG_KSCrashField_AppInFG, state->applicationIsInForeground); - - writer->addIntegerElement(writer, BSG_KSCrashField_LaunchesSinceCrash, - state->launchesSinceLastCrash); - writer->addIntegerElement(writer, BSG_KSCrashField_SessionsSinceCrash, - state->sessionsSinceLastCrash); - writer->addFloatingPointElement(writer, - BSG_KSCrashField_ActiveTimeSinceCrash, - state->foregroundDurationSinceLastCrash); - writer->addFloatingPointElement( - writer, BSG_KSCrashField_BGTimeSinceCrash, - state->backgroundDurationSinceLastCrash); - - writer->addIntegerElement(writer, BSG_KSCrashField_SessionsSinceLaunch, - state->sessionsSinceLaunch); writer->addFloatingPointElement(writer, BSG_KSCrashField_ActiveTimeSinceLaunch, state->foregroundDurationSinceLaunch); @@ -1479,12 +1465,6 @@ void bsg_kscrw_i_updateStackOverflowStatus( } } -void bsg_kscrw_i_callUserCrashHandler(BSG_KSCrash_Context *const crashContext, - BSG_KSCrashReportWriter *writer) { - BSG_KSCrashType type = crashContext->crash.crashType; - crashContext->config.onCrashNotify(writer, (int)type); -} - // ============================================================================ #pragma mark - Main API - // ============================================================================ @@ -1589,7 +1569,7 @@ void bsg_kscrashreport_writeStandardReport( // Write handled exception report info writer->beginObject(writer, BSG_KSCrashField_UserAtCrash); - { bsg_kscrw_i_callUserCrashHandler(crashContext, writer); } + crashContext->config.onCrashNotify(writer); writer->endContainer(writer); } } diff --git a/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrashReportFields.h b/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrashReportFields.h index 33fe865ee..ebe9eebf0 100644 --- a/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrashReportFields.h +++ b/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrashReportFields.h @@ -145,14 +145,9 @@ #pragma mark - App Stats - -#define BSG_KSCrashField_ActiveTimeSinceCrash "active_time_since_last_crash" #define BSG_KSCrashField_ActiveTimeSinceLaunch "active_time_since_launch" #define BSG_KSCrashField_AppInFG "application_in_foreground" -#define BSG_KSCrashField_BGTimeSinceCrash "background_time_since_last_crash" #define BSG_KSCrashField_BGTimeSinceLaunch "background_time_since_launch" -#define BSG_KSCrashField_LaunchesSinceCrash "launches_since_last_crash" -#define BSG_KSCrashField_SessionsSinceCrash "sessions_since_last_crash" -#define BSG_KSCrashField_SessionsSinceLaunch "sessions_since_launch" #pragma mark - Report - diff --git a/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrashState.h b/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrashState.h index 54676e3b3..c7c6652c3 100644 --- a/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrashState.h +++ b/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrashState.h @@ -37,33 +37,17 @@ extern "C" { #include #include -#include "BSG_KSCrashType.h" typedef struct { // Saved data - /** Total time elapsed in the foreground since the last crash. */ - double foregroundDurationSinceLastCrash; - - /** Total time backgrounded elapsed since the last crash. */ - double backgroundDurationSinceLastCrash; - - /** Number of app launches since the last crash. */ - int launchesSinceLastCrash; - - /** Number of sessions (launch, resume from suspend) since last crash. */ - int sessionsSinceLastCrash; - /** Total time elapsed in the foreground since launch. */ double foregroundDurationSinceLaunch; /** Total time backgrounded elapsed since launch. */ double backgroundDurationSinceLaunch; - /** Number of sessions (launch, resume from suspend) since app launch. */ - int sessionsSinceLaunch; - /** If true, the application crashed on the previous launch. */ bool crashedLastLaunch; @@ -101,10 +85,6 @@ bool bsg_kscrashstate_init(const char *stateFilePath, BSG_KSCrash_State *state); */ void bsg_kscrashstate_notifyAppInForeground(bool isInForeground); -/** Notify the crash reporter that the application is terminating. - */ -void bsg_kscrashstate_notifyAppTerminate(void); - /** Notify the crash reporter that the application has crashed. */ void bsg_kscrashstate_notifyAppCrash(void); diff --git a/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrashState.m b/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrashState.m index 1a223b3f3..ad85d8cff 100644 --- a/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrashState.m +++ b/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrashState.m @@ -24,25 +24,32 @@ // THE SOFTWARE. // -#include "BSG_KSCrashState.h" +#import "BSG_KSCrashState.h" -#include "BSG_KSFile.h" -#include "BSG_KSJSONCodec.h" -#include "BSG_KSJSONCodecObjC.h" -#include "BSG_KSMach.h" -#include "BSG_KSSystemInfo.h" - -//#define BSG_KSLogger_LocalLevel TRACE -#include "BSG_KSLogger.h" +#import "BSGJSONSerialization.h" +#import "BSG_KSFile.h" +#import "BSG_KSJSONCodec.h" +#import "BSG_KSLogger.h" +#import "BSG_KSMach.h" +#import "BSG_KSSystemInfo.h" #if TARGET_OS_IOS || TARGET_OS_TV #import "BSGUIKit.h" #endif -#include -#include -#include -#include -#include + +#if TARGET_OS_IOS +#import +#import +#import +#endif + +#import +#import +#import +#import +#import + +static bool bsg_kscrashstate_i_isInForeground(void); // ============================================================================ #pragma mark - Constants - @@ -52,11 +59,6 @@ #define BSG_kKeyFormatVersion "version" #define BSG_kKeyCrashedLastLaunch "crashedLastLaunch" -#define BSG_kKeyActiveDurationSinceLastCrash "foregroundDurationSinceLastCrash" -#define BSG_kKeyBackgroundDurationSinceLastCrash \ - "backgroundDurationSinceLastCrash" -#define BSG_kKeyLaunchesSinceLastCrash "launchesSinceLastCrash" -#define BSG_kKeySessionsSinceLastCrash "sessionsSinceLastCrash" // ============================================================================ #pragma mark - Globals - @@ -68,90 +70,13 @@ /** Current state. */ static BSG_KSCrash_State *bsg_g_state; -// Avoiding static functions due to linker issues. - // ============================================================================ #pragma mark - JSON Encoding - // ============================================================================ -int bsg_kscrashstate_i_onBooleanElement(const char *const name, - const bool value, - void *const userData) { - BSG_KSCrash_State *state = userData; - - if (strcmp(name, BSG_kKeyCrashedLastLaunch) == 0) { - state->crashedLastLaunch = value; - } - - return BSG_KSJSON_OK; -} - -int bsg_kscrashstate_i_onFloatingPointElement(const char *const name, - const double value, - void *const userData) { - BSG_KSCrash_State *state = userData; - - if (strcmp(name, BSG_kKeyActiveDurationSinceLastCrash) == 0) { - state->foregroundDurationSinceLastCrash = value; - } - if (strcmp(name, BSG_kKeyBackgroundDurationSinceLastCrash) == 0) { - state->backgroundDurationSinceLastCrash = value; - } - - return BSG_KSJSON_OK; -} - -int bsg_kscrashstate_i_onIntegerElement(const char *const name, - const long long value, - void *const userData) { - BSG_KSCrash_State *state = userData; - - if (strcmp(name, BSG_kKeyFormatVersion) == 0) { - if (value != BSG_kFormatVersion) { - bsg_log_err(@"Expected version 1 but got %lld", value); - return BSG_KSJSON_ERROR_INVALID_DATA; - } - } else if (strcmp(name, BSG_kKeyLaunchesSinceLastCrash) == 0) { - state->launchesSinceLastCrash = (int)value; - } else if (strcmp(name, BSG_kKeySessionsSinceLastCrash) == 0) { - state->sessionsSinceLastCrash = (int)value; - } - - // FP value might have been written as a whole number. - return bsg_kscrashstate_i_onFloatingPointElement(name, (double)value, userData); -} - -int bsg_kscrashstate_i_onNullElement(__unused const char *const name, - __unused void *const userData) { - return BSG_KSJSON_OK; -} - -int bsg_kscrashstate_i_onStringElement(__unused const char *const name, - __unused const char *const value, - __unused void *const userData) { - return BSG_KSJSON_OK; -} - -int bsg_kscrashstate_i_onBeginObject(__unused const char *const name, - __unused void *const userData) { - return BSG_KSJSON_OK; -} - -int bsg_kscrashstate_i_onBeginArray(__unused const char *const name, - __unused void *const userData) { - return BSG_KSJSON_OK; -} - -int bsg_kscrashstate_i_onEndContainer(__unused void *const userData) { - return BSG_KSJSON_OK; -} - -int bsg_kscrashstate_i_onEndData(__unused void *const userData) { - return BSG_KSJSON_OK; -} - /** Callback for adding JSON data. */ +static int bsg_kscrashstate_i_addJSONData(const char *const data, const size_t length, void *const userData) { bool success = BSG_KSFileWrite(userData, data, length); @@ -172,41 +97,27 @@ int bsg_kscrashstate_i_addJSONData(const char *const data, const size_t length, */ bool bsg_kscrashstate_i_loadState(BSG_KSCrash_State *const context, const char *const path) { - if (path == NULL) { - return false; - } - NSString *file = [NSFileManager.defaultManager stringWithFileSystemRepresentation:path length:strlen(path)]; + NSString *file = path ? @(path) : nil; if (!file) { bsg_log_err(@"Invalid path: %s", path); return false; } - NSError *error = nil; - NSData *data = [NSData dataWithContentsOfFile:file options:0 error:&error]; - if (error != nil) { - if (!(error.domain == NSCocoaErrorDomain && error.code == NSFileReadNoSuchFileError)) { + NSError *error; + NSDictionary *dict = [BSGJSONSerialization + JSONObjectWithContentsOfFile:file + options:0 error:&error]; + if (![dict isKindOfClass:[NSDictionary class]]) { + if (!(error.domain == NSCocoaErrorDomain && + error.code == NSFileReadNoSuchFileError)) { bsg_log_err(@"%s: Could not load file: %@", path, error); } return false; } - id objectContext = [BSG_KSJSONCodec decode:data error:&error]; - if (error != nil) { - bsg_log_err(@"%s: Could not load file: %@", path, error); + if (![dict[@ BSG_kKeyFormatVersion] isEqual:@ BSG_kFormatVersion]) { + bsg_log_err(@"Version mismatch"); return false; } - - context->foregroundDurationSinceLastCrash = [objectContext[@"foregroundDurationSinceLastCrash"] doubleValue]; - context->foregroundDurationSinceLaunch = [objectContext[@"foregroundDurationSinceLaunch"] doubleValue]; - context->appLaunchTime = [objectContext[@"appLaunchTime"] unsignedLongLongValue]; - context->lastUpdateDurationsTime = [objectContext[@"appStateTransitionTime"] unsignedLongLongValue]; - context->launchesSinceLastCrash = [objectContext[@"launchesSinceLastCrash"] intValue]; - context->sessionsSinceLastCrash = [objectContext[@"sessionsSinceLastCrash"] intValue]; - context->sessionsSinceLaunch = [objectContext[@"sessionsSinceLaunch"] intValue]; - context->crashedLastLaunch = [objectContext[@"crashedLastLaunch"] boolValue]; - context->crashedThisLaunch = [objectContext[@"crashedThisLaunch"] boolValue]; - context->applicationIsInForeground = [objectContext[@"applicationIsInForeground"] boolValue]; - context->backgroundDurationSinceLaunch = [objectContext[@"backgroundDurationSinceLaunch"] doubleValue]; - context->backgroundDurationSinceLastCrash = [objectContext[@"backgroundDurationSinceLastCrash"] doubleValue]; - + context->crashedLastLaunch = [dict[@ BSG_kKeyCrashedLastLaunch] boolValue]; return true; } @@ -249,26 +160,6 @@ bool bsg_kscrashstate_i_saveState(const BSG_KSCrash_State *const state, state->crashedThisLaunch)) != BSG_KSJSON_OK) { goto done; } - if ((result = bsg_ksjsonaddFloatingPointElement( - &JSONContext, BSG_kKeyActiveDurationSinceLastCrash, - state->foregroundDurationSinceLastCrash)) != BSG_KSJSON_OK) { - goto done; - } - if ((result = bsg_ksjsonaddFloatingPointElement( - &JSONContext, BSG_kKeyBackgroundDurationSinceLastCrash, - state->backgroundDurationSinceLastCrash)) != BSG_KSJSON_OK) { - goto done; - } - if ((result = bsg_ksjsonaddIntegerElement( - &JSONContext, BSG_kKeyLaunchesSinceLastCrash, - state->launchesSinceLastCrash)) != BSG_KSJSON_OK) { - goto done; - } - if ((result = bsg_ksjsonaddIntegerElement( - &JSONContext, BSG_kKeySessionsSinceLastCrash, - state->sessionsSinceLastCrash)) != BSG_KSJSON_OK) { - goto done; - } result = bsg_ksjsonendEncode(&JSONContext); done: @@ -291,32 +182,78 @@ bool bsg_kscrashstate_init(const char *const stateFilePath, bsg_g_stateFilePath = stateFilePath; bsg_g_state = state; + uint64_t timeNow = mach_absolute_time(); + memset(state, 0, sizeof(*state)); bsg_kscrashstate_i_loadState(state, stateFilePath); + state->appLaunchTime = timeNow; + state->lastUpdateDurationsTime = timeNow; + + // On iOS/tvOS, the app may have launched in the background due to a fetch + // event or notification (or prewarming on iOS 15+) + state->applicationIsInForeground = bsg_kscrashstate_i_isInForeground(); + + return bsg_kscrashstate_i_saveState(state, stateFilePath); +} - state->sessionsSinceLaunch = 1; - state->foregroundDurationSinceLaunch = 0; - state->backgroundDurationSinceLaunch = 0; - if (state->crashedLastLaunch) { - state->foregroundDurationSinceLastCrash = 0; - state->backgroundDurationSinceLastCrash = 0; - state->launchesSinceLastCrash = 0; - state->sessionsSinceLastCrash = 0; +static bool bsg_kscrashstate_i_isInForeground(void) { +#if TARGET_OS_IOS + // + // Work around unreliability of -[UIApplication applicationState] which + // always returns UIApplicationStateBackground during the launch of UIScene + // based apps (until the first scene has been created.) + // + task_category_policy_data_t policy; + mach_msg_type_number_t count = TASK_CATEGORY_POLICY_COUNT; + boolean_t get_default = FALSE; + // task_policy_get() is prohibited on tvOS and watchOS + kern_return_t kr = task_policy_get(mach_task_self(), TASK_CATEGORY_POLICY, + (void *)&policy, &count, &get_default); + if (kr == KERN_SUCCESS) { + // TASK_FOREGROUND_APPLICATION -> normal foreground launch + // TASK_NONUI_APPLICATION -> background launch + // TASK_DARWINBG_APPLICATION -> iOS 15 prewarming launch + // TASK_UNSPECIFIED -> iOS 9 Simulator + if (!get_default && policy.role == TASK_FOREGROUND_APPLICATION) { + return true; + } + } else { + bsg_log_err(@"task_policy_get failed: %s", mach_error_string(kr)); } - state->crashedThisLaunch = false; +#endif - // Simulate first transition to foreground - state->launchesSinceLastCrash++; - state->sessionsSinceLastCrash++; #if TARGET_OS_IOS || TARGET_OS_TV - // On iOS/tvOS, the app may have launched in the background due to a fetch - // event or notification - UIApplicationState appState = [BSG_KSSystemInfo currentAppState]; - state->applicationIsInForeground = [BSG_KSSystemInfo isInForeground:appState]; + // +sharedApplication is unavailable to app extensions + if ([BSG_KSSystemInfo isRunningInAppExtension]) { + // Returning "foreground" seems wrong but matches what + // +[BSG_KSSystemInfo currentAppState] used to return + return true; + } + + // Using performSelector: to avoid a compile-time check that + // +sharedApplication is not called from app extensions + UIApplication *application = [UIAPPLICATION performSelector: + @selector(sharedApplication)]; + + // There will be no UIApplication if UIApplicationMain() has not yet been + // called - e.g. from a SwiftUI app's init() function or UIKit app's main() + if (!application) { + return false; + } + + __block UIApplicationState applicationState; + if ([[NSThread currentThread] isMainThread]) { + applicationState = [application applicationState]; + } else { + // -[UIApplication applicationState] is a main thread-only API + dispatch_sync(dispatch_get_main_queue(), ^{ + applicationState = [application applicationState]; + }); + } + + return applicationState != UIApplicationStateBackground; #else - state->applicationIsInForeground = true; + return true; #endif - - return bsg_kscrashstate_i_saveState(state, stateFilePath); } void bsg_kscrashstate_notifyAppInForeground(const bool isInForeground) { @@ -332,27 +269,13 @@ void bsg_kscrashstate_notifyAppInForeground(const bool isInForeground) { timeNow, state->lastUpdateDurationsTime); if (isInForeground) { state->backgroundDurationSinceLaunch += duration; - state->backgroundDurationSinceLastCrash += duration; - state->sessionsSinceLastCrash++; - state->sessionsSinceLaunch++; } else { state->foregroundDurationSinceLaunch += duration; - state->foregroundDurationSinceLastCrash += duration; bsg_kscrashstate_i_saveState(state, stateFilePath); } state->lastUpdateDurationsTime = timeNow; } -void bsg_kscrashstate_notifyAppTerminate(void) { - BSG_KSCrash_State *const state = bsg_g_state; - const char *const stateFilePath = bsg_g_stateFilePath; - - const double duration = bsg_ksmachtimeDifferenceInSeconds( - mach_absolute_time(), state->lastUpdateDurationsTime); - state->backgroundDurationSinceLastCrash += duration; - bsg_kscrashstate_i_saveState(state, stateFilePath); -} - void bsg_kscrashstate_notifyAppCrash(void) { BSG_KSCrash_State *const state = bsg_g_state; const char *const stateFilePath = bsg_g_stateFilePath; @@ -367,10 +290,8 @@ void bsg_kscrashstate_updateDurationStats(BSG_KSCrash_State *const state) { timeNow, state->lastUpdateDurationsTime ?: state->appLaunchTime); if (state->applicationIsInForeground) { state->foregroundDurationSinceLaunch += duration; - state->foregroundDurationSinceLastCrash += duration; } else { state->backgroundDurationSinceLaunch += duration; - state->backgroundDurationSinceLastCrash += duration; } state->lastUpdateDurationsTime = timeNow; } diff --git a/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSSystemInfo.h b/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSSystemInfo.h index 327774633..bf7b6c228 100644 --- a/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSSystemInfo.h +++ b/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSSystemInfo.h @@ -89,14 +89,4 @@ */ + (NSString *)deviceAndAppHash; -#if TARGET_OS_IOS || TARGET_OS_TV -+ (UIApplicationState)currentAppState; - -/** - * YES if the app is currently shown in the foreground - */ -+ (BOOL)isInForeground:(UIApplicationState)state; - -#endif - @end diff --git a/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSSystemInfo.m b/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSSystemInfo.m index 1cac07437..57572d4d2 100644 --- a/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSSystemInfo.m +++ b/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSSystemInfo.m @@ -24,19 +24,22 @@ // THE SOFTWARE. // -#import "BSGKeys.h" #import "BSG_KSSystemInfo.h" -#import "BSG_KSSystemInfoC.h" -#import "BSG_KSMachHeaders.h" + +#import "BSGKeys.h" +#import "BSG_Jailbreak.h" +#import "BSG_KSCrash.h" +#import "BSG_KSCrashC.h" +#import "BSG_KSCrashReportFields.h" #import "BSG_KSFileUtils.h" #import "BSG_KSJSONCodecObjC.h" +#import "BSG_KSLogger.h" +#import "BSG_KSMach.h" #import "BSG_KSMach.h" +#import "BSG_KSMachHeaders.h" #import "BSG_KSSysCtl.h" +#import "BSG_KSSystemInfoC.h" #import "BugsnagCollections.h" -#import "BSG_KSLogger.h" -#import "BSG_KSCrashReportFields.h" -#import "BSG_KSMach.h" -#import "BSG_KSCrash.h" #import #import @@ -44,7 +47,6 @@ #if TARGET_OS_IOS || TARGET_OS_TV #import "BSGUIKit.h" #endif -#import "BSG_Jailbreak.h" static inline bool is_jailbroken() { @@ -444,7 +446,12 @@ + (NSDictionary *)systemInfo { } } - NSDictionary *statsInfo = [[BSG_KSCrash sharedInstance] captureAppStats]; + BSG_KSCrash_State state = crashContext()->state; + bsg_kscrashstate_updateDurationStats(&state); + NSMutableDictionary *statsInfo = [NSMutableDictionary dictionary]; + statsInfo[@ BSG_KSCrashField_ActiveTimeSinceLaunch] = @(state.foregroundDurationSinceLaunch); + statsInfo[@ BSG_KSCrashField_BGTimeSinceLaunch] = @(state.backgroundDurationSinceLaunch); + statsInfo[@ BSG_KSCrashField_AppInFG] = @(state.applicationIsInForeground); sysInfo[@BSG_KSCrashField_AppStats] = statsInfo; return sysInfo; } @@ -464,60 +471,6 @@ + (BOOL)isRunningInAppExtension { return NSBundle.mainBundle.infoDictionary[@"NSExtension"][@"NSExtensionPointIdentifier"] != nil; } -#if TARGET_OS_IOS || TARGET_OS_TV - -+ (UIApplicationState)currentAppState { - // Only checked outside of app extensions since sharedApplication is - // unavailable to extension UIKit APIs - if ([self isRunningInAppExtension]) { - return UIApplicationStateActive; - } - - UIApplication * (^ getSharedApplication)(void) = ^() { - // Calling this API indirectly to avoid a compile-time check that - // [UIApplication sharedApplication] is not called from app extensions - // (which is handled above) - return [UIAPPLICATION performSelector:@selector(sharedApplication)]; - }; - - __block UIApplication *application = nil; - if ([[NSThread currentThread] isMainThread]) { - application = getSharedApplication(); - } else { - // [UIApplication sharedApplication] is a main thread-only API - dispatch_sync(dispatch_get_main_queue(), ^{ - application = getSharedApplication(); - }); - } - - // There will be no UIApplication if UIApplicationMain() has not yet been - // called. This happens if started from a SwiftUI app's init() function or - // UIKit app's main() function. Returning UIApplicationStateActive (0) would - // be higly misleading, so we must check for this condition. - if (!application) { - return UIApplicationStateBackground; - } - - return application.applicationState; -} - -+ (BOOL)isInForeground:(UIApplicationState)state { - // The app is in the foreground if the current state is "active" or - // "inactive". From the UIApplicationState docs: - // > UIApplicationStateActive - // > The app is running in the foreground and currently receiving events. - // > UIApplicationStateInactive - // > The app is running in the foreground but is not receiving events. - // > This might happen as a result of an interruption or because the app - // > is transitioning to or from the background. - // > UIApplicationStateBackground - // > The app is running in the background. - return state == UIApplicationStateInactive - || state == UIApplicationStateActive; -} - -#endif - @end char *bsg_kssysteminfo_toJSON(void) { diff --git a/Bugsnag/KSCrash/Source/KSCrash/Recording/Sentry/BSG_KSCrashSentry_CPPException.mm b/Bugsnag/KSCrash/Source/KSCrash/Recording/Sentry/BSG_KSCrashSentry_CPPException.mm index a63d01757..fbaacf74e 100644 --- a/Bugsnag/KSCrash/Source/KSCrash/Recording/Sentry/BSG_KSCrashSentry_CPPException.mm +++ b/Bugsnag/KSCrash/Source/KSCrash/Recording/Sentry/BSG_KSCrashSentry_CPPException.mm @@ -108,17 +108,24 @@ static void CPPExceptionTerminate(void) { bool isNSException = false; char descriptionBuff[DESCRIPTION_BUFFER_LENGTH]; const char *name = NULL; - const char *description = NULL; + const char *crashReason = NULL; BSG_KSLOG_DEBUG("Get exception type name."); std::type_info *tinfo = __cxxabiv1::__cxa_current_exception_type(); if (tinfo != NULL) { name = tinfo->name(); + } else { + name = "std::terminate"; + crashReason = "throw may have been called without an exception"; + if (!bsg_g_stackTraceCount) { + BSG_KSLOG_DEBUG("No exception backtrace"); + bsg_g_stackTraceCount = + backtrace((void **)bsg_g_stackTrace, + sizeof(bsg_g_stackTrace) / sizeof(*bsg_g_stackTrace)); + } + goto after_rethrow; // Using goto to avoid indenting code below } - description = descriptionBuff; - descriptionBuff[0] = 0; - BSG_KSLOG_DEBUG("Discovering what kind of exception was thrown."); bsg_g_captureNextStackTrace = false; try { @@ -135,13 +142,16 @@ static void CPPExceptionTerminate(void) { } } catch (std::exception &exc) { strlcpy(descriptionBuff, exc.what(), sizeof(descriptionBuff)); + crashReason = descriptionBuff; } catch (std::exception *exc) { strlcpy(descriptionBuff, exc->what(), sizeof(descriptionBuff)); + crashReason = descriptionBuff; } #define CATCH_VALUE(TYPE, PRINTFTYPE) \ catch (TYPE value) { \ snprintf(descriptionBuff, sizeof(descriptionBuff), "%" #PRINTFTYPE, \ value); \ + crashReason = descriptionBuff; \ } CATCH_VALUE(char, d) CATCH_VALUE(short, d) @@ -158,8 +168,9 @@ static void CPPExceptionTerminate(void) { CATCH_VALUE(long double, Lf) CATCH_VALUE(char *, s) catch (...) { - description = NULL; } + +after_rethrow: bsg_g_captureNextStackTrace = (bsg_g_installed != 0); if (!isNSException && @@ -174,7 +185,7 @@ static void CPPExceptionTerminate(void) { bsg_g_stackTrace + 1; // Don't record __cxa_throw stack entry bsg_g_context->stackTraceLength = bsg_g_stackTraceCount - 1; bsg_g_context->CPPException.name = name; - bsg_g_context->crashReason = description; + bsg_g_context->crashReason = crashReason; BSG_KSLOG_DEBUG("Calling main crash handler."); bsg_g_context->onCrash(crashContext()); diff --git a/Bugsnag/Payload/BugsnagNotifier.m b/Bugsnag/Payload/BugsnagNotifier.m index 355357fb8..8e286e81c 100644 --- a/Bugsnag/Payload/BugsnagNotifier.m +++ b/Bugsnag/Payload/BugsnagNotifier.m @@ -21,7 +21,7 @@ - (instancetype)init { #else _name = @"Bugsnag Objective-C"; #endif - _version = @"6.16.3"; + _version = @"6.16.4"; _url = @"https://github.com/bugsnag/bugsnag-cocoa"; _dependencies = @[]; } diff --git a/Bugsnag/Plugins/BugsnagPluginClient.h b/Bugsnag/Plugins/BugsnagPluginClient.h deleted file mode 100644 index 0936bf6f4..000000000 --- a/Bugsnag/Plugins/BugsnagPluginClient.h +++ /dev/null @@ -1,23 +0,0 @@ -// -// BugsnagPluginClient.h -// Bugsnag -// -// Created by Jamie Lynch on 12/03/2020. -// Copyright © 2020 Bugsnag. All rights reserved. -// - -#import - -#import - -NS_ASSUME_NONNULL_BEGIN - -@interface BugsnagPluginClient : NSObject - -- (instancetype _Nonnull)initWithPlugins:(NSMutableSet> *_Nonnull)plugins - client:(BugsnagClient *)client; -- (void)loadPlugins; - -@end - -NS_ASSUME_NONNULL_END diff --git a/Bugsnag/Plugins/BugsnagPluginClient.m b/Bugsnag/Plugins/BugsnagPluginClient.m deleted file mode 100644 index 008d52213..000000000 --- a/Bugsnag/Plugins/BugsnagPluginClient.m +++ /dev/null @@ -1,59 +0,0 @@ -// -// BugsnagPluginClient.m -// Bugsnag -// -// Created by Jamie Lynch on 12/03/2020. -// Copyright © 2020 Bugsnag. All rights reserved. -// - -#import "Bugsnag.h" -#import "BugsnagPluginClient.h" -#import "BugsnagPlugin.h" -#import "BugsnagLogger.h" - -static NSString *const kPluginReactNative = @"BugsnagReactNativePlugin"; - -@interface BugsnagPluginClient () -@property (nonatomic) NSSet> *plugins; -@property (nonatomic) BugsnagClient *client; -@end - -@implementation BugsnagPluginClient - -- (instancetype _Nonnull)initWithPlugins:(NSMutableSet> *_Nonnull)plugins - client:(BugsnagClient *)client { - if ((self = [super init])) { - NSMutableSet *instantiatedPlugins = [plugins mutableCopy]; - id rnPlugin = [self instantiateBugsnagPlugin:kPluginReactNative]; - - if (rnPlugin) { - [instantiatedPlugins addObject:rnPlugin]; - } - _plugins = [NSSet setWithSet:instantiatedPlugins]; - _client = client; - } - return self; -} - -/** - * Automagically instantiate plugins which Bugsnag uses via class name (e.g. BugsnagReactNativePlugin) - */ -- (instancetype)instantiateBugsnagPlugin:(NSString *)clzName { - Class clz = NSClassFromString(clzName); - if (clz) { - return [clz new]; - } - return nil; -} - -- (void)loadPlugins { - for (id plugin in self.plugins) { - @try { - [plugin load:self.client]; - } @catch (NSException *exception) { - bsg_log_err(@"Failed to load plugin %@, continuing with initialisation.", plugin); - } - } -} - -@end diff --git a/Bugsnag/include/Bugsnag/BSG_KSCrashReportWriter.h b/Bugsnag/include/Bugsnag/BSG_KSCrashReportWriter.h index 08b26e1ca..f4f563c82 100644 --- a/Bugsnag/include/Bugsnag/BSG_KSCrashReportWriter.h +++ b/Bugsnag/include/Bugsnag/BSG_KSCrashReportWriter.h @@ -231,9 +231,6 @@ typedef struct BSG_KSCrashReportWriter { typedef void (*BSG_KSReportWriteCallback)( const BSG_KSCrashReportWriter *writer); -typedef void (*BSGReportCallback)( - const BSG_KSCrashReportWriter *writer, int type); - #ifdef __cplusplus } #endif diff --git a/BugsnagNetworkRequestPlugin.podspec.json b/BugsnagNetworkRequestPlugin.podspec.json index 0d2172f8c..62e3110e0 100644 --- a/BugsnagNetworkRequestPlugin.podspec.json +++ b/BugsnagNetworkRequestPlugin.podspec.json @@ -1,16 +1,16 @@ { "name": "BugsnagNetworkRequestPlugin", - "version": "6.16.3", + "version": "6.16.4", "summary": "Network request monitoring support for Bugsnag.", "homepage": "https://bugsnag.com", "license": "MIT", "authors": { "Bugsnag": "notifiers@bugsnag.com" }, - "readme": "https://raw.githubusercontent.com/bugsnag/bugsnag-cocoa/v6.16.3/BugsnagNetworkRequestPlugin/README.md", + "readme": "https://raw.githubusercontent.com/bugsnag/bugsnag-cocoa/v6.16.4/BugsnagNetworkRequestPlugin/README.md", "source": { "git": "https://github.com/bugsnag/bugsnag-cocoa.git", - "tag": "v6.16.3" + "tag": "v6.16.4" }, "dependencies": { "Bugsnag": "~> 6.13" diff --git a/CHANGELOG.md b/CHANGELOG.md index ee6d86826..37b4081b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,16 @@ Changelog ========= +## 6.16.4 (2022-03-02) + +### Bug fixes + +* Fix crash in `CPPExceptionTerminate()` if `throw` was called without an exception. + [#1312](https://github.com/bugsnag/bugsnag-cocoa/pull/1312) + +* Fix accuracy of `app.inForeground` and prevent reporting of hangs during background launches. + [#1307](https://github.com/bugsnag/bugsnag-cocoa/pull/1307) + ## 6.16.3 (2022-02-23) ### Bug fixes diff --git a/Framework/Info.plist b/Framework/Info.plist index 0303c92f0..53d1a8787 100644 --- a/Framework/Info.plist +++ b/Framework/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 6.16.3 + 6.16.4 CFBundleVersion 1 diff --git a/Gemfile.lock b/Gemfile.lock index ab22ef883..83f01bbfb 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -147,7 +147,7 @@ GEM mime-types (3.4.1) mime-types-data (~> 3.2015) mime-types-data (3.2022.0105) - mini_portile2 (2.7.1) + mini_portile2 (2.8.0) minitest (5.15.0) molinillo (0.8.0) multi_test (0.1.2) @@ -155,8 +155,8 @@ GEM nanaimo (0.3.0) nap (1.1.0) netrc (0.11.0) - nokogiri (1.13.0) - mini_portile2 (~> 2.7.0) + nokogiri (1.13.3) + mini_portile2 (~> 2.8.0) racc (~> 1.4) open4 (1.3.4) optimist (3.0.1) diff --git a/Tests/BugsnagTests/BSGOutOfMemoryTests.m b/Tests/BugsnagTests/BSGOutOfMemoryTests.m index 60abe3910..a7d4dbbb3 100644 --- a/Tests/BugsnagTests/BSGOutOfMemoryTests.m +++ b/Tests/BugsnagTests/BSGOutOfMemoryTests.m @@ -1,14 +1,14 @@ #import -#import "BugsnagSystemState.h" + +#import "BSGFileLocations.h" +#import "BSG_KSCrashState.h" #import "BSG_KSSystemInfo.h" -#import "BugsnagConfiguration.h" #import "Bugsnag.h" #import "BugsnagClient+Private.h" -#import "BugsnagTestConstants.h" +#import "BugsnagConfiguration.h" #import "BugsnagKVStoreObjC.h" -#import "BSGFileLocations.h" - -#import +#import "BugsnagSystemState.h" +#import "BugsnagTestConstants.h" @interface BSGOutOfMemoryTests : XCTestCase @end @@ -20,7 +20,9 @@ - (BugsnagClient *)newClient { // config.autoDetectErrors = NO; config.releaseStage = @"MagicalTestingTime"; - return [[BugsnagClient alloc] initWithConfiguration:config]; + BugsnagClient *client = [[BugsnagClient alloc] initWithConfiguration:config]; + [client start]; + return client; } /** @@ -33,6 +35,7 @@ - (void)testOOMFieldsSetCorrectly { client.codeBundleId = @"codeBundleIdHere"; // The update happens on a bg thread, so let it run. [NSThread sleepForTimeInterval:0.01f]; + NSDictionary *state = systemState.currentLaunchState; XCTAssertNotNil([state objectForKey:@"app"]); XCTAssertNotNil([state objectForKey:@"device"]); @@ -68,16 +71,6 @@ -(void)testBadJSONData { } - (void)testLastLaunchTerminatedUnexpectedly { - Method isRunningInAppExtension = class_getClassMethod([BSG_KSSystemInfo class], @selector(isRunningInAppExtension)); - IMP originalImp = method_setImplementation(isRunningInAppExtension, imp_implementationWithBlock(^{ - // Xcode's unit test runner has no CFBundlePackageType, which causes +isRunningInAppExtension to return YES and disables - // unexpected termination / OOM detection. - return NO; - })); - [self addTeardownBlock:^{ - method_setImplementation(isRunningInAppExtension, originalImp); - }]; - BugsnagKVStore *kvStore = [BugsnagKVStore new]; BugsnagSystemState *(^ systemState)() = ^{ return [[BugsnagSystemState alloc] initWithConfiguration:[[BugsnagConfiguration alloc] initWithApiKey:DUMMY_APIKEY_32CHAR_1]]; @@ -87,108 +80,50 @@ - (void)testLastLaunchTerminatedUnexpectedly { [kvStore setBoolean:true forKey:SYSTEMSTATE_APP_DEBUGGER_IS_ACTIVE]; [kvStore setBoolean:true forKey:SYSTEMSTATE_APP_WAS_TERMINATED]; - [kvStore setBoolean:true forKey:SYSTEMSTATE_APP_IS_ACTIVE]; [kvStore setBoolean:true forKey:SYSTEMSTATE_APP_IS_IN_FOREGROUND]; XCTAssertFalse(systemState().lastLaunchTerminatedUnexpectedly); [kvStore setBoolean:true forKey:SYSTEMSTATE_APP_DEBUGGER_IS_ACTIVE]; [kvStore setBoolean:true forKey:SYSTEMSTATE_APP_WAS_TERMINATED]; - [kvStore setBoolean:true forKey:SYSTEMSTATE_APP_IS_ACTIVE]; - [kvStore setBoolean:false forKey:SYSTEMSTATE_APP_IS_IN_FOREGROUND]; - XCTAssertFalse(systemState().lastLaunchTerminatedUnexpectedly); - - [kvStore setBoolean:true forKey:SYSTEMSTATE_APP_DEBUGGER_IS_ACTIVE]; - [kvStore setBoolean:true forKey:SYSTEMSTATE_APP_WAS_TERMINATED]; - [kvStore setBoolean:false forKey:SYSTEMSTATE_APP_IS_ACTIVE]; - [kvStore setBoolean:true forKey:SYSTEMSTATE_APP_IS_IN_FOREGROUND]; - XCTAssertFalse(systemState().lastLaunchTerminatedUnexpectedly); - - [kvStore setBoolean:true forKey:SYSTEMSTATE_APP_DEBUGGER_IS_ACTIVE]; - [kvStore setBoolean:true forKey:SYSTEMSTATE_APP_WAS_TERMINATED]; - [kvStore setBoolean:false forKey:SYSTEMSTATE_APP_IS_ACTIVE]; [kvStore setBoolean:false forKey:SYSTEMSTATE_APP_IS_IN_FOREGROUND]; XCTAssertFalse(systemState().lastLaunchTerminatedUnexpectedly); [kvStore setBoolean:true forKey:SYSTEMSTATE_APP_DEBUGGER_IS_ACTIVE]; [kvStore setBoolean:false forKey:SYSTEMSTATE_APP_WAS_TERMINATED]; - [kvStore setBoolean:true forKey:SYSTEMSTATE_APP_IS_ACTIVE]; [kvStore setBoolean:true forKey:SYSTEMSTATE_APP_IS_IN_FOREGROUND]; XCTAssertFalse(systemState().lastLaunchTerminatedUnexpectedly); [kvStore setBoolean:true forKey:SYSTEMSTATE_APP_DEBUGGER_IS_ACTIVE]; [kvStore setBoolean:false forKey:SYSTEMSTATE_APP_WAS_TERMINATED]; - [kvStore setBoolean:true forKey:SYSTEMSTATE_APP_IS_ACTIVE]; [kvStore setBoolean:false forKey:SYSTEMSTATE_APP_IS_IN_FOREGROUND]; XCTAssertFalse(systemState().lastLaunchTerminatedUnexpectedly); - [kvStore setBoolean:true forKey:SYSTEMSTATE_APP_DEBUGGER_IS_ACTIVE]; - [kvStore setBoolean:false forKey:SYSTEMSTATE_APP_WAS_TERMINATED]; - [kvStore setBoolean:false forKey:SYSTEMSTATE_APP_IS_ACTIVE]; - [kvStore setBoolean:true forKey:SYSTEMSTATE_APP_IS_IN_FOREGROUND]; - XCTAssertFalse(systemState().lastLaunchTerminatedUnexpectedly); - - [kvStore setBoolean:true forKey:SYSTEMSTATE_APP_DEBUGGER_IS_ACTIVE]; - [kvStore setBoolean:false forKey:SYSTEMSTATE_APP_WAS_TERMINATED]; - [kvStore setBoolean:false forKey:SYSTEMSTATE_APP_IS_ACTIVE]; - [kvStore setBoolean:false forKey:SYSTEMSTATE_APP_IS_IN_FOREGROUND]; - XCTAssertFalse(systemState().lastLaunchTerminatedUnexpectedly); - // Debugger inactive [kvStore setBoolean:false forKey:SYSTEMSTATE_APP_DEBUGGER_IS_ACTIVE]; [kvStore setBoolean:true forKey:SYSTEMSTATE_APP_WAS_TERMINATED]; - [kvStore setBoolean:true forKey:SYSTEMSTATE_APP_IS_ACTIVE]; [kvStore setBoolean:true forKey:SYSTEMSTATE_APP_IS_IN_FOREGROUND]; XCTAssertFalse(systemState().lastLaunchTerminatedUnexpectedly); [kvStore setBoolean:false forKey:SYSTEMSTATE_APP_DEBUGGER_IS_ACTIVE]; [kvStore setBoolean:true forKey:SYSTEMSTATE_APP_WAS_TERMINATED]; - [kvStore setBoolean:true forKey:SYSTEMSTATE_APP_IS_ACTIVE]; - [kvStore setBoolean:false forKey:SYSTEMSTATE_APP_IS_IN_FOREGROUND]; - XCTAssertFalse(systemState().lastLaunchTerminatedUnexpectedly); - - [kvStore setBoolean:false forKey:SYSTEMSTATE_APP_DEBUGGER_IS_ACTIVE]; - [kvStore setBoolean:true forKey:SYSTEMSTATE_APP_WAS_TERMINATED]; - [kvStore setBoolean:false forKey:SYSTEMSTATE_APP_IS_ACTIVE]; - [kvStore setBoolean:true forKey:SYSTEMSTATE_APP_IS_IN_FOREGROUND]; - XCTAssertFalse(systemState().lastLaunchTerminatedUnexpectedly); - - [kvStore setBoolean:false forKey:SYSTEMSTATE_APP_DEBUGGER_IS_ACTIVE]; - [kvStore setBoolean:true forKey:SYSTEMSTATE_APP_WAS_TERMINATED]; - [kvStore setBoolean:false forKey:SYSTEMSTATE_APP_IS_ACTIVE]; [kvStore setBoolean:false forKey:SYSTEMSTATE_APP_IS_IN_FOREGROUND]; XCTAssertFalse(systemState().lastLaunchTerminatedUnexpectedly); [kvStore setBoolean:false forKey:SYSTEMSTATE_APP_DEBUGGER_IS_ACTIVE]; [kvStore setBoolean:false forKey:SYSTEMSTATE_APP_WAS_TERMINATED]; - [kvStore setBoolean:true forKey:SYSTEMSTATE_APP_IS_ACTIVE]; [kvStore setBoolean:true forKey:SYSTEMSTATE_APP_IS_IN_FOREGROUND]; XCTAssertTrue(systemState().lastLaunchTerminatedUnexpectedly); [kvStore setBoolean:false forKey:SYSTEMSTATE_APP_DEBUGGER_IS_ACTIVE]; [kvStore setBoolean:false forKey:SYSTEMSTATE_APP_WAS_TERMINATED]; - [kvStore setBoolean:true forKey:SYSTEMSTATE_APP_IS_ACTIVE]; - [kvStore setBoolean:false forKey:SYSTEMSTATE_APP_IS_IN_FOREGROUND]; - XCTAssertFalse(systemState().lastLaunchTerminatedUnexpectedly); - - [kvStore setBoolean:false forKey:SYSTEMSTATE_APP_DEBUGGER_IS_ACTIVE]; - [kvStore setBoolean:false forKey:SYSTEMSTATE_APP_WAS_TERMINATED]; - [kvStore setBoolean:false forKey:SYSTEMSTATE_APP_IS_ACTIVE]; - [kvStore setBoolean:true forKey:SYSTEMSTATE_APP_IS_IN_FOREGROUND]; - XCTAssertFalse(systemState().lastLaunchTerminatedUnexpectedly); - - [kvStore setBoolean:false forKey:SYSTEMSTATE_APP_DEBUGGER_IS_ACTIVE]; - [kvStore setBoolean:false forKey:SYSTEMSTATE_APP_WAS_TERMINATED]; - [kvStore setBoolean:false forKey:SYSTEMSTATE_APP_IS_ACTIVE]; [kvStore setBoolean:false forKey:SYSTEMSTATE_APP_IS_IN_FOREGROUND]; XCTAssertFalse(systemState().lastLaunchTerminatedUnexpectedly); // Delete keys so they don't interfere with other tests. [kvStore deleteKey:SYSTEMSTATE_APP_DEBUGGER_IS_ACTIVE]; [kvStore deleteKey:SYSTEMSTATE_APP_WAS_TERMINATED]; - [kvStore deleteKey:SYSTEMSTATE_APP_IS_ACTIVE]; [kvStore deleteKey:SYSTEMSTATE_APP_IS_IN_FOREGROUND]; } @end - diff --git a/Tests/BugsnagTests/BugsnagClientMirrorTest.m b/Tests/BugsnagTests/BugsnagClientMirrorTest.m index 1de4b82c7..1f4cdbd27 100644 --- a/Tests/BugsnagTests/BugsnagClientMirrorTest.m +++ b/Tests/BugsnagTests/BugsnagClientMirrorTest.m @@ -42,8 +42,6 @@ - (void)setUp { @"appendNSErrorInfo:block:event: B40@0:8@16@?24@32", @"appendNSErrorInfo:block:event: c40@0:8@16@?24@32", @"applicationWillTerminate: v24@0:8@16", - @"autoNotify B16@0:8", - @"autoNotify c16@0:8", @"automaticBreadcrumbControlEvents @16@0:8", @"automaticBreadcrumbMenuItemEvents @16@0:8", @"automaticBreadcrumbStateEvents @16@0:8", @@ -61,7 +59,6 @@ - (void)setUp { @"configMetadataFile @16@0:8", @"configMetadataFromLastLaunch @16@0:8", @"context @16@0:8", - @"crashSentry @16@0:8", @"createNSErrorWrapper: @24@0:8@16", @"dealloc v16@0:8", @"deserializeJson: @24@0:8*16", @@ -107,13 +104,10 @@ - (void)setUp { @"setAppHangDetector: v24@0:8@16", @"setAppHangEvent: v24@0:8@16", @"setAppLaunchTimer: v24@0:8@16", - @"setAutoNotify: v20@0:8B16", - @"setAutoNotify: v20@0:8c16", @"setBreadcrumbs: v24@0:8@16", @"setCodeBundleId: v24@0:8@16", @"setConfigMetadataFromLastLaunch: v24@0:8@16", @"setConfiguration: v24@0:8@16", - @"setCrashSentry: v24@0:8@16", @"setEventFromLastLaunch: v24@0:8@16", @"setEventUploader: v24@0:8@16", @"setExtraRuntimeInfo: v24@0:8@16", @@ -150,7 +144,6 @@ - (void)setUp { @"thermalStateDidChange: v24@0:8@16", @"unsubscribeFromNotifications: v24@0:8@16", @"updateAutomaticBreadcrumbDetectionSettings v16@0:8", - @"updateCrashDetectionSettings v16@0:8", @"workspaceBreadcrumbStateEvents @16@0:8", ]]; diff --git a/Tests/BugsnagTests/BugsnagConfigurationTests.m b/Tests/BugsnagTests/BugsnagConfigurationTests.m index 738d3b178..59ee4d14f 100644 --- a/Tests/BugsnagTests/BugsnagConfigurationTests.m +++ b/Tests/BugsnagTests/BugsnagConfigurationTests.m @@ -7,7 +7,7 @@ #import "BSG_KSCrashType.h" #import "BugsnagClient+Private.h" #import "BugsnagConfiguration+Private.h" -#import "BugsnagCrashSentry.h" +#import "BSGCrashSentry.h" #import "BugsnagEndpointConfiguration.h" #import "BugsnagErrorTypes.h" #import "BugsnagNotifier.h" @@ -771,32 +771,29 @@ -(void)testBSGErrorTypes { * Test the mapping between BSGErrorTypes and KSCrashTypes */ -(void)testCrashTypeMapping { - BugsnagConfiguration *config = [[BugsnagConfiguration alloc] initWithApiKey:DUMMY_APIKEY_32CHAR_1]; - BugsnagCrashSentry *sentry = [BugsnagCrashSentry new]; - BSG_KSCrashType crashTypes = BSG_KSCrashTypeNSException - | BSG_KSCrashTypeMachException - | BSG_KSCrashTypeSignal - | BSG_KSCrashTypeCPPException; - - XCTAssertEqual(crashTypes, [sentry mapKSToBSGCrashTypes:[config enabledErrorTypes]]); + XCTAssertEqual(BSG_KSCrashTypeFromBugsnagErrorTypes([BugsnagErrorTypes new]), + BSG_KSCrashTypeNSException | + BSG_KSCrashTypeMachException | + BSG_KSCrashTypeSignal | + BSG_KSCrashTypeCPPException); // Check partial sets BugsnagErrorTypes *errorTypes = [BugsnagErrorTypes new]; errorTypes.ooms = false; errorTypes.signals = false; errorTypes.machExceptions = false; - crashTypes = BSG_KSCrashTypeNSException | BSG_KSCrashTypeCPPException; - XCTAssertEqual((NSUInteger)crashTypes, [sentry mapKSToBSGCrashTypes:errorTypes]); + XCTAssertEqual(BSG_KSCrashTypeFromBugsnagErrorTypes(errorTypes), + BSG_KSCrashTypeNSException | BSG_KSCrashTypeCPPException); errorTypes.signals = true; errorTypes.cppExceptions = false; - crashTypes = BSG_KSCrashTypeNSException | BSG_KSCrashTypeSignal; - XCTAssertEqual((NSUInteger)crashTypes, [sentry mapKSToBSGCrashTypes:errorTypes]); + XCTAssertEqual(BSG_KSCrashTypeFromBugsnagErrorTypes(errorTypes), + BSG_KSCrashTypeNSException | BSG_KSCrashTypeSignal); errorTypes.cppExceptions = true; errorTypes.unhandledExceptions = false; - crashTypes = BSG_KSCrashTypeCPPException | BSG_KSCrashTypeSignal; - XCTAssertEqual((NSUInteger)crashTypes, [sentry mapKSToBSGCrashTypes:errorTypes]); + XCTAssertEqual(BSG_KSCrashTypeFromBugsnagErrorTypes(errorTypes), + BSG_KSCrashTypeCPPException | BSG_KSCrashTypeSignal); } /** diff --git a/Tests/BugsnagTests/Info.plist b/Tests/BugsnagTests/Info.plist index a7b277872..4d47098c4 100644 --- a/Tests/BugsnagTests/Info.plist +++ b/Tests/BugsnagTests/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType $(PRODUCT_BUNDLE_PACKAGE_TYPE) CFBundleShortVersionString - 6.16.3 + 6.16.4 CFBundleVersion 1 diff --git a/Tests/BugsnagTests/TestSupport.m b/Tests/BugsnagTests/TestSupport.m index 1f21d525e..4c9a15032 100644 --- a/Tests/BugsnagTests/TestSupport.m +++ b/Tests/BugsnagTests/TestSupport.m @@ -8,6 +8,8 @@ #import "TestSupport.h" +#import "BSG_KSCrashC.h" +#import "BSG_KSCrashState.h" #import "BSGFileLocations.h" #import "BSGUtils.h" #import "Bugsnag+Private.h" @@ -24,7 +26,14 @@ + (void) purgePersistentData { [NSException raise:NSInternalInconsistencyException format:@"Could not delete %@", dir]; } }); + [Bugsnag purge]; + + // bsg_kscrash_install() will refuse to install itself twice, so reinit kscrashstate to avoid leaking state between tests + NSString *path = [BSGFileLocations current].state; + NSString *dir = [path stringByDeletingLastPathComponent]; + [NSFileManager.defaultManager createDirectoryAtPath:dir withIntermediateDirectories:YES attributes:nil error:nil]; + bsg_kscrashstate_init(path.fileSystemRepresentation, &crashContext()->state); } @end diff --git a/Tests/KSCrashTests/KSCrashState_Tests.m b/Tests/KSCrashTests/KSCrashState_Tests.m index e659edbff..e1d0c3a70 100755 --- a/Tests/KSCrashTests/KSCrashState_Tests.m +++ b/Tests/KSCrashTests/KSCrashState_Tests.m @@ -62,15 +62,10 @@ - (void) testInitRelaunch XCTAssertTrue(context.applicationIsInForeground, @""); - XCTAssertEqual(context.foregroundDurationSinceLastCrash, 0.0, @""); - XCTAssertEqual(context.backgroundDurationSinceLastCrash, 0.0, @""); - XCTAssertEqual(context.launchesSinceLastCrash, 1, @""); - XCTAssertEqual(context.sessionsSinceLastCrash, 1, @""); - XCTAssertEqual(context.appLaunchTime, 0, @""); + XCTAssertNotEqual(context.appLaunchTime, 0); XCTAssertEqual(context.foregroundDurationSinceLaunch, 0.0, @""); XCTAssertEqual(context.backgroundDurationSinceLaunch, 0.0, @""); - XCTAssertEqual(context.sessionsSinceLaunch, 1, @""); XCTAssertFalse(context.crashedThisLaunch, @""); XCTAssertFalse(context.crashedLastLaunch, @""); @@ -81,15 +76,10 @@ - (void) testInitRelaunch XCTAssertTrue(context.applicationIsInForeground, @""); - XCTAssertEqual(context.foregroundDurationSinceLastCrash, 0.0, @""); - XCTAssertEqual(context.backgroundDurationSinceLastCrash, 0.0, @""); - XCTAssertEqual(context.launchesSinceLastCrash, 2, @""); - XCTAssertEqual(context.sessionsSinceLastCrash, 2, @""); - XCTAssertEqual(context.appLaunchTime, 0, @""); + XCTAssertNotEqual(context.appLaunchTime, 0); XCTAssertEqual(context.foregroundDurationSinceLaunch, 0.0, @""); XCTAssertEqual(context.backgroundDurationSinceLaunch, 0.0, @""); - XCTAssertEqual(context.sessionsSinceLaunch, 1, @""); XCTAssertFalse(context.crashedThisLaunch, @""); XCTAssertFalse(context.crashedLastLaunch, @""); @@ -112,21 +102,10 @@ - (void) testInitCrash checkpoint0.applicationIsInForeground, @""); XCTAssertTrue(checkpointC.appLaunchTime == checkpoint0.appLaunchTime, @""); - XCTAssertGreaterThan(checkpointC.foregroundDurationSinceLastCrash, - checkpoint0.foregroundDurationSinceLastCrash); - XCTAssertTrue(checkpointC.backgroundDurationSinceLastCrash == - checkpoint0.backgroundDurationSinceLastCrash, @""); - XCTAssertTrue(checkpointC.launchesSinceLastCrash == - checkpoint0.launchesSinceLastCrash, @""); - XCTAssertTrue(checkpointC.sessionsSinceLastCrash == - checkpoint0.sessionsSinceLastCrash, @""); - XCTAssertGreaterThan(checkpointC.foregroundDurationSinceLaunch, checkpoint0.foregroundDurationSinceLaunch); XCTAssertTrue(checkpointC.backgroundDurationSinceLaunch == checkpoint0.backgroundDurationSinceLaunch, @""); - XCTAssertTrue(checkpointC.sessionsSinceLaunch == - checkpoint0.sessionsSinceLaunch, @""); XCTAssertTrue(checkpointC.crashedThisLaunch, @""); XCTAssertFalse(checkpointC.crashedLastLaunch, @""); @@ -137,14 +116,8 @@ - (void) testInitCrash XCTAssertTrue(context.applicationIsInForeground, @""); - XCTAssertEqual(context.foregroundDurationSinceLastCrash, 0.0, @""); - XCTAssertEqual(context.backgroundDurationSinceLastCrash, 0.0, @""); - XCTAssertEqual(context.launchesSinceLastCrash, 1, @""); - XCTAssertEqual(context.sessionsSinceLastCrash, 1, @""); - XCTAssertEqual(context.foregroundDurationSinceLaunch, 0.0, @""); XCTAssertEqual(context.backgroundDurationSinceLaunch, 0.0, @""); - XCTAssertEqual(context.sessionsSinceLaunch, 1, @""); XCTAssertFalse(context.crashedThisLaunch, @""); XCTAssertTrue(context.crashedLastLaunch, @""); @@ -180,17 +153,10 @@ - (void)testRelaunch BSG_KSCrash_State checkpointR = context; XCTAssertTrue(checkpointR.applicationIsInForeground, @""); - XCTAssertEqual(checkpointR.appLaunchTime, 0, @""); - - // We don't save after going inactive, so this will still be 0. - XCTAssertEqual(checkpointR.foregroundDurationSinceLastCrash, 0.0, @""); - XCTAssertEqual(checkpointR.backgroundDurationSinceLastCrash, 0.0, @""); - XCTAssertEqual(checkpointR.launchesSinceLastCrash, 2, @""); - XCTAssertEqual(checkpointR.sessionsSinceLastCrash, 2, @""); + XCTAssertNotEqual(context.appLaunchTime, 0); XCTAssertEqual(checkpointR.foregroundDurationSinceLaunch, 0.0, @""); XCTAssertEqual(checkpointR.backgroundDurationSinceLaunch, 0.0, @""); - XCTAssertEqual(checkpointR.sessionsSinceLaunch, 1, @""); XCTAssertFalse(checkpointR.crashedThisLaunch, @""); XCTAssertFalse(checkpointR.crashedLastLaunch, @""); @@ -215,21 +181,10 @@ - (void)testBGRelaunch XCTAssertFalse(checkpoint1.applicationIsInForeground, @""); XCTAssertTrue(checkpoint0.appLaunchTime == checkpoint1.appLaunchTime, @""); - XCTAssertGreaterThan(checkpoint1.foregroundDurationSinceLastCrash, - checkpoint0.foregroundDurationSinceLastCrash); - XCTAssertTrue(checkpoint1.backgroundDurationSinceLastCrash == - checkpoint0.backgroundDurationSinceLastCrash, @""); - XCTAssertTrue(checkpoint1.launchesSinceLastCrash == - checkpoint0.launchesSinceLastCrash, @""); - XCTAssertTrue(checkpoint1.sessionsSinceLastCrash == - checkpoint0.sessionsSinceLastCrash, @""); - XCTAssertGreaterThan(checkpoint1.foregroundDurationSinceLaunch, checkpoint0.foregroundDurationSinceLaunch); XCTAssertTrue(checkpoint1.backgroundDurationSinceLaunch == checkpoint0.backgroundDurationSinceLaunch, @""); - XCTAssertTrue(checkpoint1.sessionsSinceLaunch == - checkpoint0.sessionsSinceLaunch, @""); XCTAssertFalse(checkpoint1.crashedThisLaunch, @""); XCTAssertFalse(checkpoint1.crashedLastLaunch, @""); @@ -242,14 +197,8 @@ - (void)testBGRelaunch XCTAssertTrue(checkpointR.applicationIsInForeground, @""); - XCTAssertTrue(checkpointR.foregroundDurationSinceLastCrash > 0, @""); - XCTAssertEqual(checkpointR.backgroundDurationSinceLastCrash, 0.0, @""); - XCTAssertEqual(checkpointR.launchesSinceLastCrash, 2, @""); - XCTAssertEqual(checkpointR.sessionsSinceLastCrash, 2, @""); - XCTAssertEqual(checkpointR.foregroundDurationSinceLaunch, 0.0, @""); XCTAssertEqual(checkpointR.backgroundDurationSinceLaunch, 0.0, @""); - XCTAssertEqual(checkpointR.sessionsSinceLaunch, 1, @""); XCTAssertFalse(checkpointR.crashedThisLaunch, @""); XCTAssertFalse(checkpointR.crashedLastLaunch, @""); @@ -267,25 +216,17 @@ - (void)testBGTerminate bsg_kscrashstate_notifyAppInForeground(false); BSG_KSCrash_State checkpoint0 = context; usleep(1); - bsg_kscrashstate_notifyAppTerminate(); - usleep(1); memset(&context, 0, sizeof(context)); bsg_kscrashstate_init([stateFile cStringUsingEncoding:NSUTF8StringEncoding], &context); BSG_KSCrash_State checkpointR = context; XCTAssertTrue(checkpointR.applicationIsInForeground, @""); - XCTAssertEqual(checkpointR.appLaunchTime, 0, @""); - - XCTAssertTrue(checkpointR.backgroundDurationSinceLastCrash > - checkpoint0.backgroundDurationSinceLastCrash, @""); - XCTAssertEqual(checkpointR.launchesSinceLastCrash, 2, @""); - XCTAssertEqual(checkpointR.sessionsSinceLastCrash, 2, @""); + XCTAssertNotEqual(context.appLaunchTime, 0); XCTAssertEqual(checkpointR.foregroundDurationSinceLaunch, 0.0, @""); XCTAssertEqual(checkpointR.backgroundDurationSinceLaunch, 0.0, @""); - XCTAssertEqual(checkpointR.sessionsSinceLaunch, 1, @""); XCTAssertFalse(checkpointR.crashedThisLaunch, @""); XCTAssertFalse(checkpointR.crashedLastLaunch, @""); @@ -311,21 +252,10 @@ - (void)testBGCrash checkpoint0.applicationIsInForeground, @""); XCTAssertTrue(checkpointC.appLaunchTime == checkpoint0.appLaunchTime, @""); - XCTAssertTrue(checkpointC.foregroundDurationSinceLastCrash == - checkpoint0.foregroundDurationSinceLastCrash, @""); - XCTAssertTrue(checkpointC.backgroundDurationSinceLastCrash > - checkpoint0.backgroundDurationSinceLastCrash, @""); - XCTAssertTrue(checkpointC.launchesSinceLastCrash == - checkpoint0.launchesSinceLastCrash, @""); - XCTAssertTrue(checkpointC.sessionsSinceLastCrash == - checkpoint0.sessionsSinceLastCrash, @""); - XCTAssertTrue(checkpointC.foregroundDurationSinceLaunch == checkpoint0.foregroundDurationSinceLaunch, @""); XCTAssertTrue(checkpointC.backgroundDurationSinceLaunch > checkpoint0.backgroundDurationSinceLaunch, @""); - XCTAssertTrue(checkpointC.sessionsSinceLaunch == - checkpoint0.sessionsSinceLaunch, @""); XCTAssertTrue(checkpointC.crashedThisLaunch, @""); XCTAssertFalse(checkpointC.crashedLastLaunch, @""); @@ -336,32 +266,13 @@ - (void)testBGCrash XCTAssertTrue(context.applicationIsInForeground, @""); - XCTAssertEqual(context.foregroundDurationSinceLastCrash, 0.0, @""); - XCTAssertEqual(context.backgroundDurationSinceLastCrash, 0.0, @""); - XCTAssertEqual(context.launchesSinceLastCrash, 1, @""); - XCTAssertEqual(context.sessionsSinceLastCrash, 1, @""); - XCTAssertEqual(context.foregroundDurationSinceLaunch, 0.0, @""); XCTAssertEqual(context.backgroundDurationSinceLaunch, 0.0, @""); - XCTAssertEqual(context.sessionsSinceLaunch, 1, @""); XCTAssertFalse(context.crashedThisLaunch, @""); XCTAssertTrue(context.crashedLastLaunch, @""); } -- (void) testAppLaunchTime -{ - BSG_KSCrash_State context = {0}; - NSString* stateFile = [self.tempPath stringByAppendingPathComponent:@"state.json"]; - NSData *data = [NSJSONSerialization dataWithJSONObject:@{@"appLaunchTime": @34234235534534 } options:0 error:nil]; - [data writeToFile:stateFile atomically:YES]; - - bsg_kscrashstate_init([stateFile cStringUsingEncoding:NSUTF8StringEncoding], - &context); - usleep(1); - XCTAssertEqual(34234235534534, context.appLaunchTime); -} - - (void)testBGFGRelaunch { BSG_KSCrash_State context = {0}; @@ -383,21 +294,10 @@ - (void)testBGFGRelaunch XCTAssertTrue(checkpoint1.applicationIsInForeground, @""); XCTAssertTrue(checkpoint1.appLaunchTime == checkpoint0.appLaunchTime, @""); - XCTAssertTrue(checkpoint1.foregroundDurationSinceLastCrash == - checkpoint0.foregroundDurationSinceLastCrash, @""); - XCTAssertTrue(checkpoint1.backgroundDurationSinceLastCrash > - checkpoint0.backgroundDurationSinceLastCrash, @""); - XCTAssertTrue(checkpoint1.launchesSinceLastCrash == - checkpoint0.launchesSinceLastCrash, @""); - XCTAssertTrue(checkpoint1.sessionsSinceLastCrash == - checkpoint0.sessionsSinceLastCrash + 1, @""); - XCTAssertTrue(checkpoint1.foregroundDurationSinceLaunch == checkpoint0.foregroundDurationSinceLaunch, @""); XCTAssertTrue(checkpoint1.backgroundDurationSinceLaunch > checkpoint0.backgroundDurationSinceLaunch, @""); - XCTAssertTrue(checkpoint1.sessionsSinceLaunch == - checkpoint0.sessionsSinceLaunch + 1, @""); XCTAssertFalse(checkpoint1.crashedThisLaunch, @""); XCTAssertFalse(checkpoint1.crashedLastLaunch, @""); @@ -410,15 +310,8 @@ - (void)testBGFGRelaunch XCTAssertTrue(checkpointR.applicationIsInForeground, @""); - XCTAssertTrue(checkpointR.foregroundDurationSinceLastCrash > 0, @""); - // We don't save after going to FG, so this will still be 0. - XCTAssertEqual(checkpointR.backgroundDurationSinceLastCrash, 0.0, @""); - XCTAssertEqual(checkpointR.launchesSinceLastCrash, 2, @""); - XCTAssertEqual(checkpointR.sessionsSinceLastCrash, 2, @""); - XCTAssertEqual(checkpointR.foregroundDurationSinceLaunch, 0.0, @""); XCTAssertEqual(checkpointR.backgroundDurationSinceLaunch, 0.0, @""); - XCTAssertEqual(checkpointR.sessionsSinceLaunch, 1, @""); XCTAssertFalse(checkpointR.crashedThisLaunch, @""); XCTAssertFalse(checkpointR.crashedLastLaunch, @""); @@ -445,21 +338,10 @@ - (void)testBGFGCrash checkpoint0.applicationIsInForeground, @""); XCTAssertTrue(checkpointC.appLaunchTime == checkpoint0.appLaunchTime, @""); - XCTAssertGreaterThan(checkpointC.foregroundDurationSinceLastCrash, - checkpoint0.foregroundDurationSinceLastCrash); - XCTAssertTrue(checkpointC.backgroundDurationSinceLastCrash == - checkpoint0.backgroundDurationSinceLastCrash, @""); - XCTAssertTrue(checkpointC.launchesSinceLastCrash == - checkpoint0.launchesSinceLastCrash, @""); - XCTAssertTrue(checkpointC.sessionsSinceLastCrash == - checkpoint0.sessionsSinceLastCrash, @""); - XCTAssertGreaterThan(checkpointC.foregroundDurationSinceLaunch, checkpoint0.foregroundDurationSinceLaunch); XCTAssertTrue(checkpointC.backgroundDurationSinceLaunch == checkpoint0.backgroundDurationSinceLaunch, @""); - XCTAssertTrue(checkpointC.sessionsSinceLaunch == - checkpoint0.sessionsSinceLaunch, @""); XCTAssertTrue(checkpointC.crashedThisLaunch, @""); XCTAssertFalse(checkpointC.crashedLastLaunch, @""); @@ -470,14 +352,8 @@ - (void)testBGFGCrash XCTAssertTrue(context.applicationIsInForeground, @""); - XCTAssertEqual(context.foregroundDurationSinceLastCrash, 0.0, @""); - XCTAssertEqual(context.backgroundDurationSinceLastCrash, 0.0, @""); - XCTAssertEqual(context.launchesSinceLastCrash, 1, @""); - XCTAssertEqual(context.sessionsSinceLastCrash, 1, @""); - XCTAssertEqual(context.foregroundDurationSinceLaunch, 0.0, @""); XCTAssertEqual(context.backgroundDurationSinceLaunch, 0.0, @""); - XCTAssertEqual(context.sessionsSinceLaunch, 1, @""); XCTAssertFalse(context.crashedThisLaunch, @""); XCTAssertTrue(context.crashedLastLaunch, @""); diff --git a/Tests/KSCrashTests/KSSystemInfo_Tests.m b/Tests/KSCrashTests/KSSystemInfo_Tests.m index 79d1105dd..b23570d6d 100755 --- a/Tests/KSCrashTests/KSSystemInfo_Tests.m +++ b/Tests/KSCrashTests/KSSystemInfo_Tests.m @@ -29,10 +29,6 @@ #import "BSG_KSSystemInfo.h" #import "BSG_KSSystemInfoC.h" -#if TARGET_OS_TV -#import "UIApplicationStub.h" -#endif - @interface KSSystemInfo_Tests : XCTestCase @end @@ -61,26 +57,4 @@ - (void) testCopyProcessName } } -#if TARGET_OS_TV || TARGET_OS_IOS -- (void)testCurrentAppState { -#if TARGET_OS_TV - [self setUpUIApplicationStub]; -#endif - XCTAssertEqual(UIApplicationStateActive, [BSG_KSSystemInfo currentAppState]); -} - -- (void)testInactiveIsInForeground { - XCTAssertTrue([BSG_KSSystemInfo isInForeground:UIApplicationStateInactive]); -} - -- (void)testActiveIsInForeground { - XCTAssertTrue([BSG_KSSystemInfo isInForeground:UIApplicationStateActive]); - -} - -- (void)testBackgroundIsNotInForeground { - XCTAssertFalse([BSG_KSSystemInfo isInForeground:UIApplicationStateBackground]); -} -#endif - @end diff --git a/Tests/TestHost-iOS/Info.plist b/Tests/TestHost-iOS/Info.plist index 65239c5d4..e7f2ea457 100644 --- a/Tests/TestHost-iOS/Info.plist +++ b/Tests/TestHost-iOS/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType $(PRODUCT_BUNDLE_PACKAGE_TYPE) CFBundleShortVersionString - 6.16.3 + 6.16.4 CFBundleVersion 1 LSRequiresIPhoneOS diff --git a/VERSION b/VERSION index 7030011d5..f3472f93a 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -6.16.3 +6.16.4 diff --git a/features/auto_notify.feature b/features/auto_notify.feature deleted file mode 100644 index e184c686f..000000000 --- a/features/auto_notify.feature +++ /dev/null @@ -1,43 +0,0 @@ -Feature: autoNotify flag allows disabling error detection after Bugsnag is initialized - - Background: - Given I clear all persistent data - - Scenario: Uncaught NSException not reported when autoNotify is false - When I run "AutoNotifyFalseHandledScenario" - And I wait to receive an error - Then the error is valid for the error reporting API - And the error payload field "events" is an array with 1 elements - And the event "unhandled" is false - And I discard the oldest error - And I relaunch the app - When I run "AutoNotifyFalseNSExceptionScenario" and relaunch the crashed app - And I configure Bugsnag for "AutoNotifyFalseHandledScenario" - Then I should receive no requests - - Scenario: Signal not reported when autoNotify is false - When I run "AutoNotifyFalseHandledScenario" - And I wait to receive an error - Then the error is valid for the error reporting API - And the error payload field "events" is an array with 1 elements - And the event "unhandled" is false - And I discard the oldest error - And I relaunch the app - When I run "AutoNotifyFalseAbortScenario" and relaunch the crashed app - And I configure Bugsnag for "AutoNotifyFalseHandledScenario" - Then I should receive no requests - - Scenario: Uncaught NSException reported when autoDetectErrors set to false then true - When I run "AutoDetectFalseHandledScenario" - And I wait to receive an error - Then the error is valid for the error reporting API - And the error payload field "events" is an array with 1 elements - And the event "unhandled" is false - And I discard the oldest error - And I relaunch the app - When I run "AutoNotifyReenabledScenario" and relaunch the crashed app - And I configure Bugsnag for "AutoNotifyReenabledScenario" - And I wait to receive an error - Then the error is valid for the error reporting API - And the error payload field "events" is an array with 1 elements - And the event "unhandled" is true diff --git a/features/fixtures/ios/iOSTestApp.xcodeproj/project.pbxproj b/features/fixtures/ios/iOSTestApp.xcodeproj/project.pbxproj index a0746e367..30963441a 100644 --- a/features/fixtures/ios/iOSTestApp.xcodeproj/project.pbxproj +++ b/features/fixtures/ios/iOSTestApp.xcodeproj/project.pbxproj @@ -37,6 +37,8 @@ 01F1474425F282E600C2DC65 /* AppHangScenarios.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01F1474325F282E600C2DC65 /* AppHangScenarios.swift */; }; 01FA9EC426D63BB20059FF4A /* AppHangInTerminationScenario.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01FA9EC326D63BB20059FF4A /* AppHangInTerminationScenario.swift */; }; 6526A0D4248A83350002E2C9 /* LoadConfigFromFileAutoScenario.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6526A0D3248A83350002E2C9 /* LoadConfigFromFileAutoScenario.swift */; }; + 8A096DF627C7E56C00DB6ECC /* CxxUnexpectedScenario.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8A096DF527C7E56C00DB6ECC /* CxxUnexpectedScenario.mm */; }; + 8A096DFC27C7E77600DB6ECC /* CxxBareThrowScenario.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8A096DFB27C7E77600DB6ECC /* CxxBareThrowScenario.mm */; }; 8A14F0F62282D4AE00337B05 /* (null) in Sources */ = {isa = PBXBuildFile; }; 8A32DB8222424E3000EDD92F /* NSExceptionShiftScenario.m in Sources */ = {isa = PBXBuildFile; fileRef = 8A32DB8122424E3000EDD92F /* NSExceptionShiftScenario.m */; }; 8A38C5D124094D7B00BC4463 /* DiscardedBreadcrumbTypeScenario.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8A38C5D024094D7B00BC4463 /* DiscardedBreadcrumbTypeScenario.swift */; }; @@ -121,10 +123,6 @@ E7B79CD6247FD7750039FB88 /* AutoContextNSErrorScenario.swift in Sources */ = {isa = PBXBuildFile; fileRef = E7B79CD5247FD7750039FB88 /* AutoContextNSErrorScenario.swift */; }; E7B79CD8247FD7810039FB88 /* AutoContextNSExceptionScenario.swift in Sources */ = {isa = PBXBuildFile; fileRef = E7B79CD7247FD7810039FB88 /* AutoContextNSExceptionScenario.swift */; }; E7B79CDA24800A5D0039FB88 /* MetadataMergeScenario.swift in Sources */ = {isa = PBXBuildFile; fileRef = E7B79CD924800A5D0039FB88 /* MetadataMergeScenario.swift */; }; - E7FDB6C2264D5AB900BCF881 /* AutoNotifyFalseHandledScenario.swift in Sources */ = {isa = PBXBuildFile; fileRef = E7FDB6C1264D5AB900BCF881 /* AutoNotifyFalseHandledScenario.swift */; }; - E7FDB6C4264D5ACA00BCF881 /* AutoNotifyFalseNSExceptionScenario.swift in Sources */ = {isa = PBXBuildFile; fileRef = E7FDB6C3264D5ACA00BCF881 /* AutoNotifyFalseNSExceptionScenario.swift */; }; - E7FDB6C6264D5AD800BCF881 /* AutoNotifyFalseAbortScenario.swift in Sources */ = {isa = PBXBuildFile; fileRef = E7FDB6C5264D5AD800BCF881 /* AutoNotifyFalseAbortScenario.swift */; }; - E7FDB6C8264D607F00BCF881 /* AutoNotifyReenabledScenario.swift in Sources */ = {isa = PBXBuildFile; fileRef = E7FDB6C7264D607F00BCF881 /* AutoNotifyReenabledScenario.swift */; }; F429502603396F8671B333B3 /* HandledExceptionScenario.swift in Sources */ = {isa = PBXBuildFile; fileRef = F429526319377A8848136413 /* HandledExceptionScenario.swift */; }; F4295109FCAB93708FDAFE12 /* DisabledSessionTrackingScenario.m in Sources */ = {isa = PBXBuildFile; fileRef = F429563584D9BC3A5B86BECF /* DisabledSessionTrackingScenario.m */; }; F42951A9FD696D9047149DA8 /* UndefinedInstructionScenario.m in Sources */ = {isa = PBXBuildFile; fileRef = F429538D19421F28D8EB0446 /* UndefinedInstructionScenario.m */; }; @@ -201,6 +199,8 @@ 01F1474325F282E600C2DC65 /* AppHangScenarios.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppHangScenarios.swift; sourceTree = ""; }; 01FA9EC326D63BB20059FF4A /* AppHangInTerminationScenario.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppHangInTerminationScenario.swift; sourceTree = ""; }; 6526A0D3248A83350002E2C9 /* LoadConfigFromFileAutoScenario.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoadConfigFromFileAutoScenario.swift; sourceTree = ""; }; + 8A096DF527C7E56C00DB6ECC /* CxxUnexpectedScenario.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = CxxUnexpectedScenario.mm; sourceTree = ""; }; + 8A096DFB27C7E77600DB6ECC /* CxxBareThrowScenario.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = CxxBareThrowScenario.mm; sourceTree = ""; }; 8A32DB8022424E3000EDD92F /* NSExceptionShiftScenario.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NSExceptionShiftScenario.h; sourceTree = ""; }; 8A32DB8122424E3000EDD92F /* NSExceptionShiftScenario.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NSExceptionShiftScenario.m; sourceTree = ""; }; 8A38C5D024094D7B00BC4463 /* DiscardedBreadcrumbTypeScenario.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DiscardedBreadcrumbTypeScenario.swift; sourceTree = ""; }; @@ -316,10 +316,6 @@ E7B79CD7247FD7810039FB88 /* AutoContextNSExceptionScenario.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutoContextNSExceptionScenario.swift; sourceTree = ""; }; E7B79CD924800A5D0039FB88 /* MetadataMergeScenario.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MetadataMergeScenario.swift; sourceTree = ""; }; E7F6087B244F0A3A00F1532A /* BugsnagHooks.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BugsnagHooks.h; sourceTree = ""; }; - E7FDB6C1264D5AB900BCF881 /* AutoNotifyFalseHandledScenario.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutoNotifyFalseHandledScenario.swift; sourceTree = ""; }; - E7FDB6C3264D5ACA00BCF881 /* AutoNotifyFalseNSExceptionScenario.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutoNotifyFalseNSExceptionScenario.swift; sourceTree = ""; }; - E7FDB6C5264D5AD800BCF881 /* AutoNotifyFalseAbortScenario.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutoNotifyFalseAbortScenario.swift; sourceTree = ""; }; - E7FDB6C7264D607F00BCF881 /* AutoNotifyReenabledScenario.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutoNotifyReenabledScenario.swift; sourceTree = ""; }; F42950588CE34967588DF438 /* ObjCExceptionScenario.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ObjCExceptionScenario.h; sourceTree = ""; }; F42950D49A5F24FF7155EEE1 /* NonExistentMethodScenario.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NonExistentMethodScenario.h; sourceTree = ""; }; F429511ED32FC9FB46649CAE /* ObjCMsgSendScenario.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ObjCMsgSendScenario.m; sourceTree = ""; }; @@ -570,17 +566,6 @@ name = Context; sourceTree = ""; }; - E7FDB6C0264D5A8800BCF881 /* AutoNotify */ = { - isa = PBXGroup; - children = ( - E7FDB6C1264D5AB900BCF881 /* AutoNotifyFalseHandledScenario.swift */, - E7FDB6C3264D5ACA00BCF881 /* AutoNotifyFalseNSExceptionScenario.swift */, - E7FDB6C5264D5AD800BCF881 /* AutoNotifyFalseAbortScenario.swift */, - E7FDB6C7264D607F00BCF881 /* AutoNotifyReenabledScenario.swift */, - ); - name = AutoNotify; - sourceTree = ""; - }; F42953DE2BB41023C0B07F41 /* scenarios */ = { isa = PBXGroup; children = ( @@ -588,7 +573,6 @@ E7A324E4247E9C96008B0052 /* Breadcrumb Callbacks */, E75040AC2478213D005D33BD /* Metadata Redaction */, E750409C24780158005D33BD /* AutoDetectErrors */, - E7FDB6C0264D5A8800BCF881 /* AutoNotify */, E7B79CCE247FD6520039FB88 /* Context */, F49695A9244545EC00105DA9 /* Crashprobe */, F49695B0244547CB00105DA9 /* Cross notifier notify */, @@ -603,6 +587,8 @@ 01AF6A52258A112F00FFC803 /* BareboneTestScenarios.swift */, 01DCB82A27985D2C0048640A /* ConcurrentCrashesScenario.mm */, 01DE903726CE99B800455213 /* CriticalThermalStateScenario.swift */, + 8A096DFB27C7E77600DB6ECC /* CxxBareThrowScenario.mm */, + 8A096DF527C7E56C00DB6ECC /* CxxUnexpectedScenario.mm */, 0163BFA62583B3CF008DC28B /* DiscardClassesScenarios.swift */, 01847DD526453D4E00ADA4C7 /* InvalidCrashReportScenario.m */, 017B4133276B8D9B0054C91D /* OnSendErrorPersistenceScenario.m */, @@ -915,8 +901,8 @@ E700EE65247D6C08008CFFB6 /* OnSendCallbackRemovalScenario.m in Sources */, 8A38C5D124094D7B00BC4463 /* DiscardedBreadcrumbTypeScenario.swift in Sources */, 8AEEBBD020FC9E1D00C60763 /* AutoSessionMixedEventsScenario.m in Sources */, - E7FDB6C8264D607F00BCF881 /* AutoNotifyReenabledScenario.swift in Sources */, E753F24624927409001FB671 /* NotifyCallbackCrashScenario.swift in Sources */, + 8A096DFC27C7E77600DB6ECC /* CxxBareThrowScenario.mm in Sources */, AA6ACD1C2773E0B3006464C4 /* UserFromConfigScenario.swift in Sources */, 8AF8FCAC22BD1E5400A967CA /* UnhandledInternalNotifyScenario.swift in Sources */, 6526A0D4248A83350002E2C9 /* LoadConfigFromFileAutoScenario.swift in Sources */, @@ -933,7 +919,6 @@ CBE1C9242574F532004B8B5B /* OnErrorOverwriteUnhandledFalseScenario.swift in Sources */, A1117E5B2536036400014FDA /* OOMSessionScenario.swift in Sources */, 8AF8FCAE22BD23BA00A967CA /* HandledInternalNotifyScenario.swift in Sources */, - E7FDB6C4264D5ACA00BCF881 /* AutoNotifyFalseNSExceptionScenario.swift in Sources */, CBE1C9252574F532004B8B5B /* OnErrorOverwriteUnhandledTrueScenario.swift in Sources */, 8A42FD35225DEE04007AE561 /* SessionOOMScenario.m in Sources */, AA6ACD202773E3F0006464C4 /* UserInfoScenario.swift in Sources */, @@ -945,7 +930,6 @@ 01E5EAD225B713990066EA8A /* OOMScenario.m in Sources */, 8A530CCC22FDDBF000F0C108 /* ManyConcurrentNotifyScenario.m in Sources */, F42958881D3F34A76CADE4EC /* SwiftCrashScenario.swift in Sources */, - E7FDB6C6264D5AD800BCF881 /* AutoNotifyFalseAbortScenario.swift in Sources */, E7A324EA247E9DA5008B0052 /* BreadcrumbCallbackOverrideScenario.swift in Sources */, F42955DB6D08642528917FAB /* CxxExceptionScenario.mm in Sources */, 017B4134276B8D9B0054C91D /* OnSendErrorPersistenceScenario.m in Sources */, @@ -969,6 +953,7 @@ F429538D8941382EC2C857CE /* AsyncSafeThreadScenario.m in Sources */, F42955869D33EE0E510B9651 /* ReadGarbagePointerScenario.m in Sources */, 01FA9EC426D63BB20059FF4A /* AppHangInTerminationScenario.swift in Sources */, + 8A096DF627C7E56C00DB6ECC /* CxxUnexpectedScenario.mm in Sources */, 8AEFC73420F8D1BB00A78779 /* ManualSessionWithUserScenario.m in Sources */, E753F25424937A83001FB671 /* ThreadScenarios.m in Sources */, F4295B56219D228FAA99BC14 /* ObjCExceptionScenario.m in Sources */, @@ -1010,7 +995,6 @@ E700EE6F247D79F6008CFFB6 /* SIGTRAPScenario.m in Sources */, F4295A0B0DA0AF3B5502D29C /* PrivilegedInstructionScenario.m in Sources */, F42958BE5DDACDBF653CA926 /* ManualSessionScenario.m in Sources */, - E7FDB6C2264D5AB900BCF881 /* AutoNotifyFalseHandledScenario.swift in Sources */, E7A324E8247E9D9A008B0052 /* BreadcrumbCallbackOrderScenario.swift in Sources */, F42951BF19D7F35A03273CFB /* AutoSessionScenario.m in Sources */, E700EE4A247D1164008CFFB6 /* UserSessionOverrideScenario.swift in Sources */, diff --git a/features/fixtures/macos/macOSTestApp.xcodeproj/project.pbxproj b/features/fixtures/macos/macOSTestApp.xcodeproj/project.pbxproj index 32bf57045..6b7f1ee48 100644 --- a/features/fixtures/macos/macOSTestApp.xcodeproj/project.pbxproj +++ b/features/fixtures/macos/macOSTestApp.xcodeproj/project.pbxproj @@ -136,13 +136,11 @@ 01F47D32254B1B3100B184AD /* ResumeSessionOOMScenario.m in Sources */ = {isa = PBXBuildFile; fileRef = 01F47CC1254B1B3000B184AD /* ResumeSessionOOMScenario.m */; }; 01F7365A278D90440000113C /* NetworkBreadcrumbsScenario.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01F73659278D90440000113C /* NetworkBreadcrumbsScenario.swift */; }; 01FA9EC626D64FFF0059FF4A /* AppHangInTerminationScenario.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01FA9EC526D64FFF0059FF4A /* AppHangInTerminationScenario.swift */; }; + 8A096DF827C7E63A00DB6ECC /* CxxUnexpectedScenario.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8A096DF727C7E63A00DB6ECC /* CxxUnexpectedScenario.mm */; }; + 8A096DFA27C7E6D800DB6ECC /* CxxBareThrowScenario.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8A096DF927C7E6D800DB6ECC /* CxxBareThrowScenario.mm */; }; AA6ACD1A2773E098006464C4 /* UserFromConfigScenario.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA6ACD192773E098006464C4 /* UserFromConfigScenario.swift */; }; AA6ACD1E2773E39C006464C4 /* UserInfoScenario.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA6ACD1D2773E39C006464C4 /* UserInfoScenario.swift */; }; CBB7878E2578FB3F0071BDE4 /* MarkUnhandledHandledScenario.m in Sources */ = {isa = PBXBuildFile; fileRef = CBB7878C2578FB3F0071BDE4 /* MarkUnhandledHandledScenario.m */; }; - E780377D264D703500430C11 /* AutoNotifyReenabledScenario.swift in Sources */ = {isa = PBXBuildFile; fileRef = E7803779264D703500430C11 /* AutoNotifyReenabledScenario.swift */; }; - E780377E264D703500430C11 /* AutoNotifyFalseHandledScenario.swift in Sources */ = {isa = PBXBuildFile; fileRef = E780377A264D703500430C11 /* AutoNotifyFalseHandledScenario.swift */; }; - E780377F264D703500430C11 /* AutoNotifyFalseNSExceptionScenario.swift in Sources */ = {isa = PBXBuildFile; fileRef = E780377B264D703500430C11 /* AutoNotifyFalseNSExceptionScenario.swift */; }; - E7803780264D703500430C11 /* AutoNotifyFalseAbortScenario.swift in Sources */ = {isa = PBXBuildFile; fileRef = E780377C264D703500430C11 /* AutoNotifyFalseAbortScenario.swift */; }; FECF3DC11A84CDC5FD442710 /* Pods_macOSTestApp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C65BFC9838298CFA8A35072 /* Pods_macOSTestApp.framework */; }; /* End PBXBuildFile section */ @@ -348,15 +346,13 @@ 01FA9EC526D64FFF0059FF4A /* AppHangInTerminationScenario.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppHangInTerminationScenario.swift; sourceTree = ""; }; 2C49722B331FF4B0DC477462 /* Pods-macOSTestApp.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-macOSTestApp.release.xcconfig"; path = "Target Support Files/Pods-macOSTestApp/Pods-macOSTestApp.release.xcconfig"; sourceTree = ""; }; 5C65BFC9838298CFA8A35072 /* Pods_macOSTestApp.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_macOSTestApp.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 8A096DF727C7E63A00DB6ECC /* CxxUnexpectedScenario.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = CxxUnexpectedScenario.mm; sourceTree = ""; }; + 8A096DF927C7E6D800DB6ECC /* CxxBareThrowScenario.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = CxxBareThrowScenario.mm; sourceTree = ""; }; AA6ACD192773E098006464C4 /* UserFromConfigScenario.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserFromConfigScenario.swift; sourceTree = ""; }; AA6ACD1D2773E39C006464C4 /* UserInfoScenario.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserInfoScenario.swift; sourceTree = ""; }; CBB7878C2578FB3F0071BDE4 /* MarkUnhandledHandledScenario.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MarkUnhandledHandledScenario.m; sourceTree = ""; }; CBB7878D2578FB3F0071BDE4 /* MarkUnhandledHandledScenario.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MarkUnhandledHandledScenario.h; sourceTree = ""; }; E32FA33AF8114150BBC3AEF4 /* Pods-macOSTestApp.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-macOSTestApp.debug.xcconfig"; path = "Target Support Files/Pods-macOSTestApp/Pods-macOSTestApp.debug.xcconfig"; sourceTree = ""; }; - E7803779264D703500430C11 /* AutoNotifyReenabledScenario.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AutoNotifyReenabledScenario.swift; sourceTree = ""; }; - E780377A264D703500430C11 /* AutoNotifyFalseHandledScenario.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AutoNotifyFalseHandledScenario.swift; sourceTree = ""; }; - E780377B264D703500430C11 /* AutoNotifyFalseNSExceptionScenario.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AutoNotifyFalseNSExceptionScenario.swift; sourceTree = ""; }; - E780377C264D703500430C11 /* AutoNotifyFalseAbortScenario.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AutoNotifyFalseAbortScenario.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -393,10 +389,6 @@ 01F47C68254B1B2E00B184AD /* AutoDetectFalseAbortScenario.swift */, 01F47C44254B1B2D00B184AD /* AutoDetectFalseHandledScenario.swift */, 01F47C59254B1B2E00B184AD /* AutoDetectFalseNSExceptionScenario.swift */, - E780377C264D703500430C11 /* AutoNotifyFalseAbortScenario.swift */, - E780377A264D703500430C11 /* AutoNotifyFalseHandledScenario.swift */, - E780377B264D703500430C11 /* AutoNotifyFalseNSExceptionScenario.swift */, - E7803779264D703500430C11 /* AutoNotifyReenabledScenario.swift */, 01F47CBC254B1B3000B184AD /* AutoSessionCustomVersionScenario.h */, 01F47C8B254B1B2F00B184AD /* AutoSessionCustomVersionScenario.m */, 01F47C9A254B1B2F00B184AD /* AutoSessionHandledEventsScenario.h */, @@ -423,8 +415,10 @@ 01DE903926CEAD1200455213 /* CriticalThermalStateScenario.swift */, 01F47C77254B1B2E00B184AD /* CustomPluginNotifierDescriptionScenario.h */, 01F47C85254B1B2F00B184AD /* CustomPluginNotifierDescriptionScenario.m */, + 8A096DF927C7E6D800DB6ECC /* CxxBareThrowScenario.mm */, 01F47C26254B1B2C00B184AD /* CxxExceptionScenario.h */, 01F47C8F254B1B2F00B184AD /* CxxExceptionScenario.mm */, + 8A096DF727C7E63A00DB6ECC /* CxxUnexpectedScenario.mm */, 01F47C43254B1B2D00B184AD /* DisabledSessionTrackingScenario.h */, 01F47C88254B1B2F00B184AD /* DisabledSessionTrackingScenario.m */, 0163BF9A2583AF2A008DC28B /* DiscardClassesScenarios.swift */, @@ -753,7 +747,6 @@ 01F47CCF254B1B3100B184AD /* ObjCExceptionScenario.m in Sources */, 01ECBCF425A7522000FC0678 /* OnErrorOverwriteUnhandledFalseScenario.swift in Sources */, 011B7A4C26CD52080071C3EB /* ThermalStateBreadcrumbScenario.swift in Sources */, - E780377F264D703500430C11 /* AutoNotifyFalseNSExceptionScenario.swift in Sources */, 01AF6A50258A00DE00FFC803 /* BareboneTestScenarios.swift in Sources */, 01F47CED254B1B3100B184AD /* ResumedSessionScenario.swift in Sources */, 01F47CE8254B1B3100B184AD /* AppAndDeviceAttributesScenario.swift in Sources */, @@ -803,6 +796,7 @@ 015AE23A276B88300044B1AE /* OnSendErrorPersistenceScenario.m in Sources */, 01F47D17254B1B3100B184AD /* ReleaseStageSessionScenario.swift in Sources */, 01F47CD2254B1B3100B184AD /* Scenario.m in Sources */, + 8A096DFA27C7E6D800DB6ECC /* CxxBareThrowScenario.mm in Sources */, 017FBFB8254B09C300809042 /* MainWindowController.m in Sources */, 01F47CF0254B1B3100B184AD /* OnSendOverwriteScenario.swift in Sources */, 01F47D1B254B1B3100B184AD /* SIGSEGVScenario.m in Sources */, @@ -816,6 +810,7 @@ 01F47D30254B1B3100B184AD /* AutoContextNSExceptionScenario.swift in Sources */, 01F47CE1254B1B3100B184AD /* ManualSessionWithUserScenario.m in Sources */, 01FA9EC626D64FFF0059FF4A /* AppHangInTerminationScenario.swift in Sources */, + 8A096DF827C7E63A00DB6ECC /* CxxUnexpectedScenario.mm in Sources */, 01F47D01254B1B3100B184AD /* SessionCallbackOrderScenario.swift in Sources */, 01AF6A84258BB38A00FFC803 /* DispatchCrashScenario.swift in Sources */, 01F47D0A254B1B3100B184AD /* CxxExceptionScenario.mm in Sources */, @@ -834,10 +829,8 @@ 01F47CDB254B1B3100B184AD /* UnhandledMachExceptionScenario.m in Sources */, 01F47D12254B1B3100B184AD /* OnSendCallbackRemovalScenario.m in Sources */, 01F47D24254B1B3100B184AD /* UserSessionOverrideScenario.swift in Sources */, - E780377E264D703500430C11 /* AutoNotifyFalseHandledScenario.swift in Sources */, 01F47CD8254B1B3100B184AD /* ManualContextConfigurationScenario.swift in Sources */, 01F47CFA254B1B3100B184AD /* BreadcrumbCallbackOrderScenario.swift in Sources */, - E780377D264D703500430C11 /* AutoNotifyReenabledScenario.swift in Sources */, 01F47CF3254B1B3100B184AD /* AutoCaptureRunScenario.m in Sources */, 01F47CF8254B1B3100B184AD /* ModifyBreadcrumbInNotifyScenario.swift in Sources */, 01F47D14254B1B3100B184AD /* OOMEnabledErrorTypesScenario.swift in Sources */, @@ -853,7 +846,6 @@ 01F47D20254B1B3100B184AD /* ObjCMsgSendScenario.m in Sources */, 01F47CD4254B1B3100B184AD /* AsyncSafeThreadScenario.m in Sources */, 01ECBCF525A7522000FC0678 /* OnErrorOverwriteUnhandledTrueScenario.swift in Sources */, - E7803780264D703500430C11 /* AutoNotifyFalseAbortScenario.swift in Sources */, 01DCB82D279868160048640A /* ConcurrentCrashesScenario.mm in Sources */, 0123189C275921590007EFD7 /* RecrashScenarios.mm in Sources */, 01F47CDE254B1B3100B184AD /* ReleasedObjectScenario.m in Sources */, diff --git a/features/fixtures/shared/scenarios/AutoNotifyFalseAbortScenario.swift b/features/fixtures/shared/scenarios/AutoNotifyFalseAbortScenario.swift deleted file mode 100644 index e525c6b3c..000000000 --- a/features/fixtures/shared/scenarios/AutoNotifyFalseAbortScenario.swift +++ /dev/null @@ -1,23 +0,0 @@ -// -// AutoNotifyFalseAbortScenario.swift -// iOSTestApp -// -// Created by Jamie Lynch on 13/05/2021. -// Copyright © 2021 Bugsnag. All rights reserved. -// - -/** -* Raises a SIGABRT with autoNotify set to false, which should be ignored by Bugsnag -*/ -internal class AutoNotifyFalseAbortScenario: Scenario { - - override func startBugsnag() { - self.config.autoTrackSessions = false - super.startBugsnag() - } - - override func run() { - Bugsnag.client.autoNotify = false - abort() - } -} diff --git a/features/fixtures/shared/scenarios/AutoNotifyFalseHandledScenario.swift b/features/fixtures/shared/scenarios/AutoNotifyFalseHandledScenario.swift deleted file mode 100644 index e6694500b..000000000 --- a/features/fixtures/shared/scenarios/AutoNotifyFalseHandledScenario.swift +++ /dev/null @@ -1,24 +0,0 @@ -// -// AutoNotifyFalseHandledScenario.swift -// iOSTestApp -// -// Created by Jamie Lynch on 13/05/2021. -// Copyright © 2021 Bugsnag. All rights reserved. -// - -/** - * Sends a handled error to Bugsnag with autoNotify set to false - */ -internal class AutoNotifyFalseHandledScenario: Scenario { - - override func startBugsnag() { - self.config.autoTrackSessions = false - super.startBugsnag() - } - - override func run() { - Bugsnag.client.autoNotify = false - let error = NSError(domain: "UserDefaultInfoScenario", code: 100, userInfo: nil) - Bugsnag.notifyError(error) - } -} diff --git a/features/fixtures/shared/scenarios/AutoNotifyFalseNSExceptionScenario.swift b/features/fixtures/shared/scenarios/AutoNotifyFalseNSExceptionScenario.swift deleted file mode 100644 index 2bde6ac3e..000000000 --- a/features/fixtures/shared/scenarios/AutoNotifyFalseNSExceptionScenario.swift +++ /dev/null @@ -1,23 +0,0 @@ -// -// AutoNotifyFalseNSExceptionScenario.swift -// iOSTestApp -// -// Created by Jamie Lynch on 13/05/2021. -// Copyright © 2021 Bugsnag. All rights reserved. -// - -/** - * Raises an unhandled NSException with autoNotify set to false, which should be ignored by Bugsnag - */ -internal class AutoNotifyFalseNSExceptionScenario: Scenario { - - override func startBugsnag() { - self.config.autoTrackSessions = false - super.startBugsnag() - } - - override func run() { - Bugsnag.client.autoNotify = false - NSException.init(name: NSExceptionName("SomeError"), reason: "Something went wrong", userInfo: nil).raise() - } -} diff --git a/features/fixtures/shared/scenarios/AutoNotifyReenabledScenario.swift b/features/fixtures/shared/scenarios/AutoNotifyReenabledScenario.swift deleted file mode 100644 index cfa3d6391..000000000 --- a/features/fixtures/shared/scenarios/AutoNotifyReenabledScenario.swift +++ /dev/null @@ -1,25 +0,0 @@ -// -// AutoNotifyReenabledScenario.swift -// iOSTestApp -// -// Created by Jamie Lynch on 13/05/2021. -// Copyright © 2021 Bugsnag. All rights reserved. -// - -/** - * Raises an unhandled NSException with autoNotify set to false then true, - * which should be reported by Bugsnag - */ -internal class AutoNotifyReenabledScenario: Scenario { - - override func startBugsnag() { - self.config.autoTrackSessions = false - super.startBugsnag() - } - - override func run() { - Bugsnag.client.autoNotify = false - Bugsnag.client.autoNotify = true - NSException.init(name: NSExceptionName("SomeError"), reason: "Something went wrong", userInfo: nil).raise() - } -} diff --git a/features/fixtures/shared/scenarios/BugsnagHooks.h b/features/fixtures/shared/scenarios/BugsnagHooks.h index a71e0d05c..ff8a9cb5d 100644 --- a/features/fixtures/shared/scenarios/BugsnagHooks.h +++ b/features/fixtures/shared/scenarios/BugsnagHooks.h @@ -18,10 +18,4 @@ NS_ASSUME_NONNULL_BEGIN @end -@interface BugsnagClient() - -@property (nonatomic) BOOL autoNotify; - -@end - NS_ASSUME_NONNULL_END diff --git a/features/fixtures/shared/scenarios/CxxBareThrowScenario.mm b/features/fixtures/shared/scenarios/CxxBareThrowScenario.mm new file mode 100644 index 000000000..ee6d0a021 --- /dev/null +++ b/features/fixtures/shared/scenarios/CxxBareThrowScenario.mm @@ -0,0 +1,25 @@ +// +// CxxBareThrowScenario.mm +// macOSTestApp +// +// Created by Delisa Fuller on 2/24/22. +// Copyright © 2022 Bugsnag Inc. All rights reserved. +// + +#import "Scenario.h" +#import + +@interface CxxBareThrowScenario : Scenario +@end + +@implementation CxxBareThrowScenario + +- (void)run { + try { + throw; + } catch (...) { + // hmm! + } +} + +@end diff --git a/features/fixtures/shared/scenarios/CxxUnexpectedScenario.mm b/features/fixtures/shared/scenarios/CxxUnexpectedScenario.mm new file mode 100644 index 000000000..716823f53 --- /dev/null +++ b/features/fixtures/shared/scenarios/CxxUnexpectedScenario.mm @@ -0,0 +1,21 @@ +// +// CxxUnexpectedScenario.mm +// iOSTestApp +// +// Created by Delisa Fuller on 2/24/22. +// Copyright © 2022 Bugsnag. All rights reserved. +// + +#import "Scenario.h" +#import + +@interface CxxUnexpectedScenario : Scenario +@end + +@implementation CxxUnexpectedScenario + +- (void)run { + std::unexpected(); +} + +@end diff --git a/features/unhandled_cpp_exception.feature b/features/unhandled_cpp_exception.feature index 7df0455c1..94b8d86f6 100644 --- a/features/unhandled_cpp_exception.feature +++ b/features/unhandled_cpp_exception.feature @@ -27,3 +27,21 @@ Feature: Thrown C++ exceptions are captured by Bugsnag And the event "unhandled" is false And the event "severityReason.unhandledOverridden" is true And the event "severityReason.type" equals "unhandledException" + + Scenario: Throwing without an exception + When I run "CxxBareThrowScenario" and relaunch the crashed app + And I configure Bugsnag for "CxxBareThrowScenario" + And I wait to receive an error + Then the error is valid for the error reporting API + And the exception "errorClass" equals "std::terminate" + And the exception "message" equals "throw may have been called without an exception" + And the "method" of stack frame 2 equals "-[CxxBareThrowScenario run]" + + Scenario: Causing an unexpected event + When I run "CxxUnexpectedScenario" and relaunch the crashed app + And I configure Bugsnag for "CxxUnexpectedScenario" + And I wait to receive an error + Then the error is valid for the error reporting API + And the exception "errorClass" equals "std::terminate" + And the exception "message" equals "throw may have been called without an exception" + And the "method" of stack frame 4 equals "-[CxxUnexpectedScenario run]"