From e20c6606b4474e3e9f359d7028d9465f0b90be06 Mon Sep 17 00:00:00 2001 From: Andrew McKnight Date: Tue, 14 Mar 2023 16:20:54 -0800 Subject: [PATCH 01/25] meta: move some headers to include/ directory (#2788) --- Sentry.xcodeproj/project.pbxproj | 8 ++++---- .../{ => include}/SentryDefaultObjCRuntimeWrapper.h | 0 Sources/Sentry/{ => include}/SentryNoOpSpan.h | 0 Sources/Sentry/{ => include}/SentryProfilesSampler.h | 0 Sources/Sentry/{ => include}/SentrySubClassFinder.h | 0 5 files changed, 4 insertions(+), 4 deletions(-) rename Sources/Sentry/{ => include}/SentryDefaultObjCRuntimeWrapper.h (100%) rename Sources/Sentry/{ => include}/SentryNoOpSpan.h (100%) rename Sources/Sentry/{ => include}/SentryProfilesSampler.h (100%) rename Sources/Sentry/{ => include}/SentrySubClassFinder.h (100%) diff --git a/Sentry.xcodeproj/project.pbxproj b/Sentry.xcodeproj/project.pbxproj index fab663ca19..5b647b78c9 100644 --- a/Sentry.xcodeproj/project.pbxproj +++ b/Sentry.xcodeproj/project.pbxproj @@ -841,7 +841,7 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ - 0356A56E288B4612008BF593 /* SentryProfilesSampler.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentryProfilesSampler.h; path = Sources/Sentry/SentryProfilesSampler.h; sourceTree = SOURCE_ROOT; }; + 0356A56E288B4612008BF593 /* SentryProfilesSampler.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentryProfilesSampler.h; path = Sources/Sentry/include/SentryProfilesSampler.h; sourceTree = SOURCE_ROOT; }; 0356A56F288B4612008BF593 /* SentryProfilesSampler.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = SentryProfilesSampler.m; path = Sources/Sentry/SentryProfilesSampler.m; sourceTree = SOURCE_ROOT; }; 035E73C727D56757005EEB11 /* SentryBacktraceTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = SentryBacktraceTests.mm; sourceTree = ""; }; 035E73C927D57398005EEB11 /* SentryThreadHandleTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = SentryThreadHandleTests.mm; sourceTree = ""; }; @@ -1424,7 +1424,7 @@ 7BE3C78624472E9800A38442 /* TestRequestManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestRequestManager.swift; sourceTree = ""; }; 7BE8E8442593313500C4DA1F /* SentryAttachment+Equality.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SentryAttachment+Equality.h"; sourceTree = ""; }; 7BE8E8452593313500C4DA1F /* SentryAttachment+Equality.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "SentryAttachment+Equality.m"; sourceTree = ""; }; - 7BE912AA272162AF00E49E62 /* SentryNoOpSpan.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SentryNoOpSpan.h; sourceTree = ""; }; + 7BE912AA272162AF00E49E62 /* SentryNoOpSpan.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentryNoOpSpan.h; path = include/SentryNoOpSpan.h; sourceTree = ""; }; 7BE912AC272162D900E49E62 /* SentryNoOpSpan.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryNoOpSpan.m; sourceTree = ""; }; 7BE912AE272166DD00E49E62 /* SentryNoOpSpanTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryNoOpSpanTests.swift; sourceTree = ""; }; 7BE912B02721C76000E49E62 /* SentryPerformanceTrackingIntegrationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryPerformanceTrackingIntegrationTests.swift; sourceTree = ""; }; @@ -1445,10 +1445,10 @@ 7BF69E062987D1FE002EBCA4 /* SentryCrashDoctorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryCrashDoctorTests.swift; sourceTree = ""; }; 7BF9EF712722A84800B5BBEF /* SentryClassRegistrator.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SentryClassRegistrator.h; sourceTree = ""; }; 7BF9EF732722A85B00B5BBEF /* SentryClassRegistrator.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryClassRegistrator.m; sourceTree = ""; }; - 7BF9EF752722B34700B5BBEF /* SentrySubClassFinder.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SentrySubClassFinder.h; sourceTree = ""; }; + 7BF9EF752722B34700B5BBEF /* SentrySubClassFinder.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentrySubClassFinder.h; path = include/SentrySubClassFinder.h; sourceTree = ""; }; 7BF9EF772722B35D00B5BBEF /* SentrySubClassFinder.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentrySubClassFinder.m; sourceTree = ""; }; 7BF9EF792722B58900B5BBEF /* SentrySubClassFinderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentrySubClassFinderTests.swift; sourceTree = ""; }; - 7BF9EF7B2722B90E00B5BBEF /* SentryDefaultObjCRuntimeWrapper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SentryDefaultObjCRuntimeWrapper.h; sourceTree = ""; }; + 7BF9EF7B2722B90E00B5BBEF /* SentryDefaultObjCRuntimeWrapper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentryDefaultObjCRuntimeWrapper.h; path = include/SentryDefaultObjCRuntimeWrapper.h; sourceTree = ""; }; 7BF9EF7D2722B91F00B5BBEF /* SentryDefaultObjCRuntimeWrapper.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryDefaultObjCRuntimeWrapper.m; sourceTree = ""; }; 7BF9EF832722D07B00B5BBEF /* SentryObjCRuntimeWrapper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentryObjCRuntimeWrapper.h; path = include/SentryObjCRuntimeWrapper.h; sourceTree = ""; }; 7BF9EF852722D10600B5BBEF /* SentryTestObjCRuntimeWrapper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SentryTestObjCRuntimeWrapper.h; sourceTree = ""; }; diff --git a/Sources/Sentry/SentryDefaultObjCRuntimeWrapper.h b/Sources/Sentry/include/SentryDefaultObjCRuntimeWrapper.h similarity index 100% rename from Sources/Sentry/SentryDefaultObjCRuntimeWrapper.h rename to Sources/Sentry/include/SentryDefaultObjCRuntimeWrapper.h diff --git a/Sources/Sentry/SentryNoOpSpan.h b/Sources/Sentry/include/SentryNoOpSpan.h similarity index 100% rename from Sources/Sentry/SentryNoOpSpan.h rename to Sources/Sentry/include/SentryNoOpSpan.h diff --git a/Sources/Sentry/SentryProfilesSampler.h b/Sources/Sentry/include/SentryProfilesSampler.h similarity index 100% rename from Sources/Sentry/SentryProfilesSampler.h rename to Sources/Sentry/include/SentryProfilesSampler.h diff --git a/Sources/Sentry/SentrySubClassFinder.h b/Sources/Sentry/include/SentrySubClassFinder.h similarity index 100% rename from Sources/Sentry/SentrySubClassFinder.h rename to Sources/Sentry/include/SentrySubClassFinder.h From 49819af904d11b8cb5bf99f4153f455f4efa75db Mon Sep 17 00:00:00 2001 From: Karl Heinz Struggl Date: Wed, 15 Mar 2023 13:57:59 +0100 Subject: [PATCH 02/25] chore: Add note to 8.3.0 changelog and fix PR reference in 8.3.1 changelog (#2800) * Update CHANGELOG.md fix: Add note about Profiling crash to 8.3.0 changelog * Update CHANGELOG.md fix: Fix referenced PR in 8.3.1 changelog --- CHANGELOG.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fdfa4b5a1d..490ccb2b7f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,10 +6,13 @@ - Stop using UIScreen.main (#2762) - Profile timestamp alignment with transactions (#2771) and app start spans (#2772) -- Fix crash when compiling profiling data during transaction serialization (#2783) +- Fix crash when compiling profiling data during transaction serialization (#2786) ## 8.3.0 +### Important Note +This release can cause crashes when Profiling is enabled (#2779). Please update to `8.3.1`. + ### Fixes - Crash in AppHangs when no threads (#2725) From ad7cec6ed97b2a4ab413d80404806d580920e6fc Mon Sep 17 00:00:00 2001 From: Philipp Hofmann Date: Wed, 15 Mar 2023 16:42:05 +0100 Subject: [PATCH 03/25] test: Remove SentryTestObserver (#2796) We are not using the SentryTestObserver and therefore we can remove it. --- Sentry.xcodeproj/project.pbxproj | 6 -- .../TestUtils/SentryTestObserver.h | 13 --- .../TestUtils/SentryTestObserver.m | 100 ------------------ 3 files changed, 119 deletions(-) delete mode 100644 Tests/SentryTests/TestUtils/SentryTestObserver.h delete mode 100644 Tests/SentryTests/TestUtils/SentryTestObserver.m diff --git a/Sentry.xcodeproj/project.pbxproj b/Sentry.xcodeproj/project.pbxproj index 5b647b78c9..61d36d244b 100644 --- a/Sentry.xcodeproj/project.pbxproj +++ b/Sentry.xcodeproj/project.pbxproj @@ -554,7 +554,6 @@ 7BED3576266F7BFF00EAA70D /* TestSentryCrashWrapper.m in Sources */ = {isa = PBXBuildFile; fileRef = 7BED3575266F7BFF00EAA70D /* TestSentryCrashWrapper.m */; }; 7BEF4957270C4B9D00F8F30E /* SentryUIViewControllerSwizzlingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BEF4956270C4B9D00F8F30E /* SentryUIViewControllerSwizzlingTests.swift */; }; 7BEFB044270B0F630025F808 /* SentryTracerObjCTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 7BEFB043270B0F630025F808 /* SentryTracerObjCTests.m */; }; - 7BF1F6AE282A4FE2006BD6AB /* SentryTestObserver.m in Sources */ = {isa = PBXBuildFile; fileRef = 7BF1F6AD282A4FE2006BD6AB /* SentryTestObserver.m */; }; 7BF536D124BDF3E7004FA6A2 /* SentryEnvelopeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF536D024BDF3E7004FA6A2 /* SentryEnvelopeTests.swift */; }; 7BF536D424BEF255004FA6A2 /* SentryAssertions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF536D324BEF255004FA6A2 /* SentryAssertions.swift */; }; 7BF6505F292B77EC00BBA5A8 /* SentryMetricKitIntegrationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF6505E292B77EC00BBA5A8 /* SentryMetricKitIntegrationTests.swift */; }; @@ -1435,8 +1434,6 @@ 7BED3575266F7BFF00EAA70D /* TestSentryCrashWrapper.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TestSentryCrashWrapper.m; sourceTree = ""; }; 7BEF4956270C4B9D00F8F30E /* SentryUIViewControllerSwizzlingTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryUIViewControllerSwizzlingTests.swift; sourceTree = ""; }; 7BEFB043270B0F630025F808 /* SentryTracerObjCTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryTracerObjCTests.m; sourceTree = ""; }; - 7BF1F6AC282A4FC6006BD6AB /* SentryTestObserver.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SentryTestObserver.h; sourceTree = ""; }; - 7BF1F6AD282A4FE2006BD6AB /* SentryTestObserver.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryTestObserver.m; sourceTree = ""; }; 7BF536D024BDF3E7004FA6A2 /* SentryEnvelopeTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryEnvelopeTests.swift; sourceTree = ""; }; 7BF536D324BEF255004FA6A2 /* SentryAssertions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryAssertions.swift; sourceTree = ""; }; 7BF6505E292B77EC00BBA5A8 /* SentryMetricKitIntegrationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryMetricKitIntegrationTests.swift; sourceTree = ""; }; @@ -2956,8 +2953,6 @@ 7B6D98EC24C703F8005502FA /* Async.swift */, 7BF9EF712722A84800B5BBEF /* SentryClassRegistrator.h */, 7BF9EF732722A85B00B5BBEF /* SentryClassRegistrator.m */, - 7BF1F6AC282A4FC6006BD6AB /* SentryTestObserver.h */, - 7BF1F6AD282A4FE2006BD6AB /* SentryTestObserver.m */, 7B72D23928D074BC0014798A /* TestExtensions.swift */, 7BB7E7C629267A28004BF96B /* EmptyIntegration.swift */, 7B4F22DB294089530067EA17 /* FormatHexAddress.swift */, @@ -4071,7 +4066,6 @@ 7BE3C7752445C82300A38442 /* SentryCurrentDateTests.swift in Sources */, 7B3398672459C4AE00BD9C96 /* SentryEnvelopeRateLimitTests.swift in Sources */, 8EA9AF492665AC48002771B4 /* SentryPerformanceTrackerTests.swift in Sources */, - 7BF1F6AE282A4FE2006BD6AB /* SentryTestObserver.m in Sources */, 7B3B473E25D6CEA500D01640 /* SentryNSErrorTests.swift in Sources */, 632331F62404FFA8008D91D6 /* SentryScopeTests.m in Sources */, D808FB88281AB33C009A2A33 /* SentryUIEventTrackerTests.swift in Sources */, diff --git a/Tests/SentryTests/TestUtils/SentryTestObserver.h b/Tests/SentryTests/TestUtils/SentryTestObserver.h deleted file mode 100644 index 92f65751bc..0000000000 --- a/Tests/SentryTests/TestUtils/SentryTestObserver.h +++ /dev/null @@ -1,13 +0,0 @@ -#import -#import - -NS_ASSUME_NONNULL_BEGIN - -/** - * Report failing tests to Sentry. - */ -@interface SentryTestObserver : NSObject - -@end - -NS_ASSUME_NONNULL_END diff --git a/Tests/SentryTests/TestUtils/SentryTestObserver.m b/Tests/SentryTests/TestUtils/SentryTestObserver.m deleted file mode 100644 index 439cf61203..0000000000 --- a/Tests/SentryTests/TestUtils/SentryTestObserver.m +++ /dev/null @@ -1,100 +0,0 @@ -#import "SentryTestObserver.h" -#import "SentryBreadcrumb.h" -#import "SentryClient.h" -#import "SentryCrashIntegration.h" -#import "SentryCrashWrapper.h" -#import "SentryCurrentDate.h" -#import "SentryDefaultCurrentDateProvider.h" -#import "SentryHub.h" -#import "SentryLog+TestInit.h" -#import "SentryOptions.h" -#import "SentryScope.h" -#import "SentrySdk+Private.h" -#import "XCTest/XCTIssue.h" -#import "XCTest/XCTest.h" -#import "XCTest/XCTestCase.h" -#import - -NS_ASSUME_NONNULL_BEGIN - -@interface -SentryTestObserver () - -@property (nonatomic, strong) SentryOptions *options; -@property (nonatomic, strong) SentryScope *scope; - -@end - -@implementation SentryTestObserver - -+ (void)load -{ -#if defined(TESTCI) - [[XCTestObservationCenter sharedTestObservationCenter] - addTestObserver:[[SentryTestObserver alloc] init]]; -#endif -} - -- (instancetype)init -{ - if (self = [super init]) { - SentryOptions *options = [[SentryOptions alloc] init]; - options.dsn = @"https://6cc9bae94def43cab8444a99e0031c28@o447951.ingest.sentry.io/5428557"; - options.environment = @"unit-tests"; - options.debug = YES; - options.enableAutoSessionTracking = NO; - options.maxBreadcrumbs = 5000; - - // The SentryCrashIntegration enriches the scope. We need to install the integration - // once to get the scope data. - [SentrySDK startWithOptions:options]; - - self.scope = [[SentryScope alloc] init]; - [SentryCrashIntegration enrichScope:self.scope - crashWrapper:[SentryCrashWrapper sharedInstance]]; - - self.options = options; - } - return self; -} - -#pragma mark - XCTestObservation - -- (void)testCaseWillStart:(XCTestCase *)testCase -{ - SentryBreadcrumb *crumb = [[SentryBreadcrumb alloc] initWithLevel:kSentryLevelDebug - category:@"test.started"]; - [crumb setMessage:testCase.name]; - // The tests might have a different time set - [crumb setTimestamp:[NSDate new]]; - [self.scope addBreadcrumb:crumb]; -} - -- (void)testBundleDidFinish:(NSBundle *)testBundle -{ - [SentrySDK flush:5.0]; -} - -- (void)testCase:(XCTestCase *)testCase didRecordIssue:(XCTIssue *)issue -{ - // Tests set a fixed time. We want to use the current time for sending - // the test result to Sentry. - id currentDateProvider = [SentryCurrentDate getCurrentDateProvider]; - [SentryCurrentDate setCurrentDateProvider:[SentryDefaultCurrentDateProvider sharedInstance]]; - - // The tests might mess up the files or something else. Therefore, we create a fresh client and - // hub to make sure the sending works. - SentryClient *client = [[SentryClient alloc] initWithOptions:self.options]; - // We create our own hub here, because we don't know the state of the SentrySDK. - SentryHub *hub = [[SentryHub alloc] initWithClient:client andScope:self.scope]; - NSException *exception = [[NSException alloc] initWithName:testCase.name - reason:issue.description - userInfo:nil]; - [hub captureException:exception withScope:hub.scope]; - - [SentryCurrentDate setCurrentDateProvider:currentDateProvider]; -} - -@end - -NS_ASSUME_NONNULL_END From 06548c0f88eefd4a54851752c7d33f4270e34ba9 Mon Sep 17 00:00:00 2001 From: Philipp Hofmann Date: Wed, 15 Mar 2023 16:47:23 +0100 Subject: [PATCH 04/25] fix: Updating AppHang state on main thread (#2793) Move updating the app hang state to a background thread for anrStopped. Fixes GH-2791 --- CHANGELOG.md | 6 ++++++ .../iOS-Swift/iOS-Swift/ViewController.swift | 19 ++++++++++++++++--- .../TestSentryDispatchQueueWrapper.swift | 2 +- Sources/Sentry/SentryANRTracker.m | 8 +++++++- Sources/Sentry/include/SentryANRTracker.h | 3 +++ .../ANR/SentryANRTrackerTests.swift | 4 +++- 6 files changed, 36 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 490ccb2b7f..ac29ec5871 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## Unreleased + +### Fixes + +- Updating AppHang state on main thread (#2793) + ## 8.3.1 ### Fixes diff --git a/Samples/iOS-Swift/iOS-Swift/ViewController.swift b/Samples/iOS-Swift/iOS-Swift/ViewController.swift index a69aed30ab..c42c1ab443 100644 --- a/Samples/iOS-Swift/iOS-Swift/ViewController.swift +++ b/Samples/iOS-Swift/iOS-Swift/ViewController.swift @@ -251,18 +251,31 @@ class ViewController: UIViewController { @IBAction func anrFillingRunLoop(_ sender: Any) { let buttonTitle = self.anrFillingRunLoopButton.currentTitle var i = 0 + + func sleep(timeout: Double) { + let group = DispatchGroup() + group.enter() + let queue = DispatchQueue(label: "delay", qos: .background, attributes: []) + + queue.asyncAfter(deadline: .now() + timeout) { + group.leave() + } + + group.wait() + } dispatchQueue.async { - for _ in 0...100_000 { + for _ in 0...30 { i += Int.random(in: 0...10) i -= 1 DispatchQueue.main.async { - self.anrFillingRunLoopButton.setTitle("Work in Progress \(i)", for: .normal) + sleep(timeout: 0.1) + self.anrFillingRunLoopButton.setTitle("Title \(i)", for: .normal) } } - DispatchQueue.main.async { + DispatchQueue.main.sync { self.anrFillingRunLoopButton.setTitle(buttonTitle, for: .normal) } } diff --git a/SentryTestUtils/TestSentryDispatchQueueWrapper.swift b/SentryTestUtils/TestSentryDispatchQueueWrapper.swift index 107a120eed..ced28591b7 100644 --- a/SentryTestUtils/TestSentryDispatchQueueWrapper.swift +++ b/SentryTestUtils/TestSentryDispatchQueueWrapper.swift @@ -9,7 +9,7 @@ public class TestSentryDispatchQueueWrapper: SentryDispatchQueueWrapper { /// - SeeAlso: `delayDispatches`, which controls whether the block should execute immediately or with the requested delay. public var dispatchAfterExecutesBlock = false - var dispatchAsyncInvocations = Invocations<() -> Void>() + public var dispatchAsyncInvocations = Invocations<() -> Void>() public var dispatchAsyncExecutesBlock = true public override func dispatchAsync(_ block: @escaping () -> Void) { dispatchAsyncCalled += 1 diff --git a/Sources/Sentry/SentryANRTracker.m b/Sources/Sentry/SentryANRTracker.m index e293c45c34..cb08e8746e 100644 --- a/Sources/Sentry/SentryANRTracker.m +++ b/Sources/Sentry/SentryANRTracker.m @@ -89,7 +89,13 @@ - (void)detectANRs if (reported) { SENTRY_LOG_WARN(@"ANR stopped."); - [self ANRStopped]; + + // The ANR stopped, don't block the main thread with calling ANRStopped listeners. + // While the ANR code reports an ANR and collects the stack trace, the ANR might + // stop simultaneously. In that case, the ANRs stack trace would contain the + // following code running on the main thread. To avoid this, we offload work to a + // background thread. + [self.dispatchQueueWrapper dispatchAsyncWithBlock:^{ [self ANRStopped]; }]; } reported = NO; diff --git a/Sources/Sentry/include/SentryANRTracker.h b/Sources/Sentry/include/SentryANRTracker.h index 2f2779cad2..9bdd45659d 100644 --- a/Sources/Sentry/include/SentryANRTracker.h +++ b/Sources/Sentry/include/SentryANRTracker.h @@ -39,6 +39,9 @@ SENTRY_NO_INIT @end +/** + * The ``SentryANRTracker`` calls the methods from background threads. + */ @protocol SentryANRTrackerDelegate - (void)anrDetected; diff --git a/Tests/SentryTests/Integrations/ANR/SentryANRTrackerTests.swift b/Tests/SentryTests/Integrations/ANR/SentryANRTrackerTests.swift index 078984cfa5..844ac8c05b 100644 --- a/Tests/SentryTests/Integrations/ANR/SentryANRTrackerTests.swift +++ b/Tests/SentryTests/Integrations/ANR/SentryANRTrackerTests.swift @@ -90,8 +90,9 @@ class SentryANRTrackerTests: XCTestCase, SentryANRTrackerDelegate { func testMultipleANRs_MultipleReported() { anrDetectedExpectation.expectedFulfillmentCount = 3 + let expectedANRStoppedInvocations = 2 anrStoppedExpectation.isInverted = false - anrStoppedExpectation.expectedFulfillmentCount = 2 + anrStoppedExpectation.expectedFulfillmentCount = expectedANRStoppedInvocations fixture.dispatchQueue.blockBeforeMainBlock = { self.advanceTime(bySeconds: self.fixture.timeoutInterval) @@ -105,6 +106,7 @@ class SentryANRTrackerTests: XCTestCase, SentryANRTrackerDelegate { start() wait(for: [anrDetectedExpectation, anrStoppedExpectation], timeout: waitTimeout) + XCTAssertEqual(expectedANRStoppedInvocations, fixture.dispatchQueue.dispatchAsyncInvocations.count) } func testAppSuspended_NoANR() { From 230ba67c4f59d08a881b0fc0c791ed90b5de1419 Mon Sep 17 00:00:00 2001 From: Karl Heinz Struggl Date: Fri, 17 Mar 2023 13:17:29 +0100 Subject: [PATCH 05/25] Fix readme.md workflow shields badge for build status (#2810) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 171a70546b..749713dfcc 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ _Bad software is everywhere, and we're tired of it. Sentry is on a mission to help developers write better software faster, so we can get back to enjoying technology. If you want to join us [**Check out our open positions**](https://sentry.io/careers/)_ -[![Build](https://img.shields.io/github/workflow/status/getsentry/sentry-cocoa/Build%20%26%20Test)](https://github.com/getsentry/sentry-cocoa/actions?query=workflow%3A%22Build+%26+Test%22) +[![Build](https://img.shields.io/github/actions/workflow/status/getsentry/sentry-cocoa/build.yml?branch=main)](https://github.com/getsentry/sentry-cocoa/actions/workflows/build.yml?query=branch%3Amain) [![codebeat badge](https://codebeat.co/badges/07f0bc91-9102-4fd8-99a6-30b25dc98037)](https://codebeat.co/projects/github-com-getsentry-sentry-cocoa-master) [![codecov.io](https://codecov.io/gh/getsentry/sentry-cocoa/branch/master/graph/badge.svg)](https://codecov.io/gh/getsentry/sentry-cocoa) [![CocoaPods compadible](https://img.shields.io/cocoapods/v/Sentry.svg)](https://cocoapods.org/pods/Sentry) From 7bc3c0d8e54a5921c8c1a9510088c683dba2c1b2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 17 Mar 2023 14:04:18 +0100 Subject: [PATCH 06/25] build(deps): bump activesupport from 7.0.4.2 to 7.0.4.3 (#2802) Bumps [activesupport](https://github.com/rails/rails) from 7.0.4.2 to 7.0.4.3. - [Release notes](https://github.com/rails/rails/releases) - [Changelog](https://github.com/rails/rails/blob/v7.0.4.3/activesupport/CHANGELOG.md) - [Commits](https://github.com/rails/rails/compare/v7.0.4.2...v7.0.4.3) --- updated-dependencies: - dependency-name: activesupport dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Philipp Hofmann --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index d9daed1e82..df2e418690 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -3,7 +3,7 @@ GEM specs: CFPropertyList (3.0.6) rexml - activesupport (7.0.4.2) + activesupport (7.0.4.3) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 1.6, < 2) minitest (>= 5.1) From b4fb156607835a1d1e8e5d49dfc8d49f04daeced Mon Sep 17 00:00:00 2001 From: Philipp Hofmann Date: Mon, 20 Mar 2023 07:43:38 +0100 Subject: [PATCH 07/25] test: Remove not needed thread safe comment (#2808) --- .../Performance/Network/SentryNetworkTrackerTests.swift | 4 ---- Tests/SentryTests/Protocol/SentryUserTests.swift | 3 --- 2 files changed, 7 deletions(-) diff --git a/Tests/SentryTests/Integrations/Performance/Network/SentryNetworkTrackerTests.swift b/Tests/SentryTests/Integrations/Performance/Network/SentryNetworkTrackerTests.swift index 5230baaa55..8b24de0ada 100644 --- a/Tests/SentryTests/Integrations/Performance/Network/SentryNetworkTrackerTests.swift +++ b/Tests/SentryTests/Integrations/Performance/Network/SentryNetworkTrackerTests.swift @@ -473,8 +473,6 @@ class SentryNetworkTrackerTests: XCTestCase { assertOneSpanCreated(transaction) } - // Although we only run this test above the below specified versions, we expect the - // implementation to be thread safe func testResumeCalledMultipleTimesConcurrent_OneSpanCreated() { let task = createDataTask() let sut = fixture.getSut() @@ -498,8 +496,6 @@ class SentryNetworkTrackerTests: XCTestCase { assertOneSpanCreated(transaction) } - // Although we only run this test above the below specified versions, we expect the - // implementation to be thread safe func testChangeStateMultipleTimesConcurrent_OneSpanFinished() { let task = createDataTask() let sut = fixture.getSut() diff --git a/Tests/SentryTests/Protocol/SentryUserTests.swift b/Tests/SentryTests/Protocol/SentryUserTests.swift index ccc1afd857..8ada7693fe 100644 --- a/Tests/SentryTests/Protocol/SentryUserTests.swift +++ b/Tests/SentryTests/Protocol/SentryUserTests.swift @@ -88,9 +88,6 @@ class SentryUserTests: XCTestCase { XCTAssertEqual(TestData.user, copiedUser) } - // Although we only run this test above the below specified versions, we expect the - // implementation to be thread safe - // With this test we test if modifications from multiple threads don't lead to a crash. func testModifyingFromMultipleThreads() { let queue = DispatchQueue(label: "SentryScopeTests", qos: .userInteractive, attributes: [.concurrent, .initiallyInactive]) let group = DispatchGroup() From 20163bbb741f4984e55f1f971d68a9105dcaebc1 Mon Sep 17 00:00:00 2001 From: Philipp Hofmann Date: Mon, 20 Mar 2023 09:01:12 +0100 Subject: [PATCH 08/25] perf: Remove not needed locks in SentryUser (#2809) Remove added not needed locks with https://github.com/getsentry/sentry-cocoa/pull/888 in SentryUser. The copy, isEqual, serialize, and hash methods don't need to be thread safe. When modifying the user from multiple threads and calling any of these methods, the callee should use locks. --- CHANGELOG.md | 4 + Sources/Sentry/SentryUser.m | 142 ++++++++---------- .../Protocol/SentryUserTests.swift | 2 +- 3 files changed, 70 insertions(+), 78 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ac29ec5871..932e80ae74 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ - Updating AppHang state on main thread (#2793) +### Improvements + +- Remove not needed locks in SentryUser (#2809) + ## 8.3.1 ### Fixes diff --git a/Sources/Sentry/SentryUser.m b/Sources/Sentry/SentryUser.m index 4b80d9653e..f6fc00695b 100644 --- a/Sources/Sentry/SentryUser.m +++ b/Sources/Sentry/SentryUser.m @@ -23,15 +23,13 @@ - (id)copyWithZone:(nullable NSZone *)zone { SentryUser *copy = [[SentryUser allocWithZone:zone] init]; - @synchronized(self) { - if (copy != nil) { - copy.userId = self.userId; - copy.email = self.email; - copy.username = self.username; - copy.ipAddress = self.ipAddress; - copy.segment = self.segment; - copy.data = self.data.copy; - } + if (copy != nil) { + copy.userId = self.userId; + copy.email = self.email; + copy.username = self.username; + copy.ipAddress = self.ipAddress; + copy.segment = self.segment; + copy.data = self.data.copy; } return copy; @@ -41,93 +39,83 @@ - (id)copyWithZone:(nullable NSZone *)zone { NSMutableDictionary *serializedData = [[NSMutableDictionary alloc] init]; - @synchronized(self) { - [serializedData setValue:self.userId forKey:@"id"]; - [serializedData setValue:self.email forKey:@"email"]; - [serializedData setValue:self.username forKey:@"username"]; - [serializedData setValue:self.ipAddress forKey:@"ip_address"]; - [serializedData setValue:self.segment forKey:@"segment"]; - [serializedData setValue:[self.data sentry_sanitize] forKey:@"data"]; - } + [serializedData setValue:self.userId forKey:@"id"]; + [serializedData setValue:self.email forKey:@"email"]; + [serializedData setValue:self.username forKey:@"username"]; + [serializedData setValue:self.ipAddress forKey:@"ip_address"]; + [serializedData setValue:self.segment forKey:@"segment"]; + [serializedData setValue:[self.data sentry_sanitize] forKey:@"data"]; return serializedData; } - (BOOL)isEqual:(id _Nullable)other { - @synchronized(self) { - if (other == self) { - return YES; - } - if (!other || ![[other class] isEqual:[self class]]) { - return NO; - } - - return [self isEqualToUser:other]; + + if (other == self) { + return YES; } + if (!other || ![[other class] isEqual:[self class]]) { + return NO; + } + + return [self isEqualToUser:other]; } - (BOOL)isEqualToUser:(SentryUser *)user { - @synchronized(self) { - // We need to get some local copies of the properties, because they could be modified during - // the if statements - - if (self == user) { - return YES; - } - if (user == nil) { - return NO; - } - - NSString *otherUserId = user.userId; - if (self.userId != otherUserId && ![self.userId isEqualToString:otherUserId]) { - return NO; - } - - NSString *otherEmail = user.email; - if (self.email != otherEmail && ![self.email isEqualToString:otherEmail]) { - return NO; - } - - NSString *otherUsername = user.username; - if (self.username != otherUsername && ![self.username isEqualToString:otherUsername]) { - return NO; - } - - NSString *otherIpAdress = user.ipAddress; - if (self.ipAddress != otherIpAdress && ![self.ipAddress isEqualToString:otherIpAdress]) { - return NO; - } - - NSString *otherSegment = user.segment; - if (self.segment != otherSegment && ![self.segment isEqualToString:otherSegment]) { - return NO; - } - - NSDictionary *otherUserData = user.data; - if (self.data != otherUserData && ![self.data isEqualToDictionary:otherUserData]) { - return NO; - } - + if (self == user) { return YES; } + if (user == nil) { + return NO; + } + + NSString *otherUserId = user.userId; + if (self.userId != otherUserId && ![self.userId isEqualToString:otherUserId]) { + return NO; + } + + NSString *otherEmail = user.email; + if (self.email != otherEmail && ![self.email isEqualToString:otherEmail]) { + return NO; + } + + NSString *otherUsername = user.username; + if (self.username != otherUsername && ![self.username isEqualToString:otherUsername]) { + return NO; + } + + NSString *otherIpAdress = user.ipAddress; + if (self.ipAddress != otherIpAdress && ![self.ipAddress isEqualToString:otherIpAdress]) { + return NO; + } + + NSString *otherSegment = user.segment; + if (self.segment != otherSegment && ![self.segment isEqualToString:otherSegment]) { + return NO; + } + + NSDictionary *otherUserData = user.data; + if (self.data != otherUserData && ![self.data isEqualToDictionary:otherUserData]) { + return NO; + } + + return YES; } - (NSUInteger)hash { - @synchronized(self) { - NSUInteger hash = 17; + NSUInteger hash = 17; - hash = hash * 23 + [self.userId hash]; - hash = hash * 23 + [self.email hash]; - hash = hash * 23 + [self.username hash]; - hash = hash * 23 + [self.ipAddress hash]; - hash = hash * 23 + [self.segment hash]; - hash = hash * 23 + [self.data hash]; + hash = hash * 23 + [self.userId hash]; + hash = hash * 23 + [self.email hash]; + hash = hash * 23 + [self.username hash]; + hash = hash * 23 + [self.ipAddress hash]; + hash = hash * 23 + [self.segment hash]; + hash = hash * 23 + [self.data hash]; - return hash; - } + return hash; } @end diff --git a/Tests/SentryTests/Protocol/SentryUserTests.swift b/Tests/SentryTests/Protocol/SentryUserTests.swift index 8ada7693fe..54bd77c34f 100644 --- a/Tests/SentryTests/Protocol/SentryUserTests.swift +++ b/Tests/SentryTests/Protocol/SentryUserTests.swift @@ -89,7 +89,7 @@ class SentryUserTests: XCTestCase { } func testModifyingFromMultipleThreads() { - let queue = DispatchQueue(label: "SentryScopeTests", qos: .userInteractive, attributes: [.concurrent, .initiallyInactive]) + let queue = DispatchQueue(label: "SentryUserTests", qos: .userInteractive, attributes: [.concurrent, .initiallyInactive]) let group = DispatchGroup() let user = TestData.user.copy() as! User From 1e065bcccc0572b03c44fa943cd9e6080e42c820 Mon Sep 17 00:00:00 2001 From: Philipp Hofmann Date: Mon, 20 Mar 2023 10:55:04 +0100 Subject: [PATCH 09/25] ref: Remove unused zombie crash monitor (#2782) The zombie crash monitor is disabled by default and never enabled anywhere in the code. --- Sentry.xcodeproj/project.pbxproj | 8 - .../Recording/Monitors/SentryCrashMonitor.c | 5 - .../Monitors/SentryCrashMonitorType.c | 1 - .../Monitors/SentryCrashMonitorType.h | 12 +- .../Monitors/SentryCrashMonitor_Zombie.c | 247 ------------------ .../Monitors/SentryCrashMonitor_Zombie.h | 67 ----- Sources/SentryCrash/Recording/SentryCrash.h | 7 - Sources/SentryCrash/Recording/SentryCrash.m | 13 +- Sources/SentryCrash/Recording/SentryCrashC.c | 1 - .../SentryCrash/Recording/SentryCrashReport.c | 20 -- .../SentryCrashReportStore_Tests.m | 1 + 11 files changed, 5 insertions(+), 377 deletions(-) delete mode 100644 Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_Zombie.c delete mode 100644 Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_Zombie.h diff --git a/Sentry.xcodeproj/project.pbxproj b/Sentry.xcodeproj/project.pbxproj index 61d36d244b..d82952aa39 100644 --- a/Sentry.xcodeproj/project.pbxproj +++ b/Sentry.xcodeproj/project.pbxproj @@ -168,7 +168,6 @@ 63FE70DD20DA4C1000CDBAE8 /* SentryCrashMonitor_Signal.h in Headers */ = {isa = PBXBuildFile; fileRef = 63FE6FF420DA4C1000CDBAE8 /* SentryCrashMonitor_Signal.h */; }; 63FE70DF20DA4C1000CDBAE8 /* SentryCrashMonitorType.c in Sources */ = {isa = PBXBuildFile; fileRef = 63FE6FF520DA4C1000CDBAE8 /* SentryCrashMonitorType.c */; }; 63FE70E120DA4C1000CDBAE8 /* SentryCrashMonitor_CPPException.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 63FE6FF620DA4C1000CDBAE8 /* SentryCrashMonitor_CPPException.cpp */; }; - 63FE70E320DA4C1000CDBAE8 /* SentryCrashMonitor_Zombie.c in Sources */ = {isa = PBXBuildFile; fileRef = 63FE6FF720DA4C1000CDBAE8 /* SentryCrashMonitor_Zombie.c */; }; 63FE70E520DA4C1000CDBAE8 /* SentryCrashMonitor_CPPException.h in Headers */ = {isa = PBXBuildFile; fileRef = 63FE6FF820DA4C1000CDBAE8 /* SentryCrashMonitor_CPPException.h */; }; 63FE70E720DA4C1000CDBAE8 /* SentryCrashMonitor.c in Sources */ = {isa = PBXBuildFile; fileRef = 63FE6FF920DA4C1000CDBAE8 /* SentryCrashMonitor.c */; }; 63FE70EB20DA4C1000CDBAE8 /* SentryCrashMonitor_MachException.h in Headers */ = {isa = PBXBuildFile; fileRef = 63FE6FFB20DA4C1000CDBAE8 /* SentryCrashMonitor_MachException.h */; }; @@ -178,7 +177,6 @@ 63FE70F320DA4C1000CDBAE8 /* SentryCrashMonitor_Signal.c in Sources */ = {isa = PBXBuildFile; fileRef = 63FE6FFF20DA4C1000CDBAE8 /* SentryCrashMonitor_Signal.c */; }; 63FE70F520DA4C1000CDBAE8 /* SentryCrashMonitor_System.h in Headers */ = {isa = PBXBuildFile; fileRef = 63FE700020DA4C1000CDBAE8 /* SentryCrashMonitor_System.h */; }; 63FE70F920DA4C1000CDBAE8 /* SentryCrashMonitor.h in Headers */ = {isa = PBXBuildFile; fileRef = 63FE700220DA4C1000CDBAE8 /* SentryCrashMonitor.h */; }; - 63FE70FB20DA4C1000CDBAE8 /* SentryCrashMonitor_Zombie.h in Headers */ = {isa = PBXBuildFile; fileRef = 63FE700320DA4C1000CDBAE8 /* SentryCrashMonitor_Zombie.h */; }; 63FE70FD20DA4C1000CDBAE8 /* SentryCrashCachedData.c in Sources */ = {isa = PBXBuildFile; fileRef = 63FE700420DA4C1000CDBAE8 /* SentryCrashCachedData.c */; }; 63FE710120DA4C1000CDBAE8 /* SentryCrashDate.h in Headers */ = {isa = PBXBuildFile; fileRef = 63FE700720DA4C1000CDBAE8 /* SentryCrashDate.h */; }; 63FE710320DA4C1000CDBAE8 /* SentryCrashMachineContext_Apple.h in Headers */ = {isa = PBXBuildFile; fileRef = 63FE700820DA4C1000CDBAE8 /* SentryCrashMachineContext_Apple.h */; }; @@ -1015,7 +1013,6 @@ 63FE6FF420DA4C1000CDBAE8 /* SentryCrashMonitor_Signal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SentryCrashMonitor_Signal.h; sourceTree = ""; }; 63FE6FF520DA4C1000CDBAE8 /* SentryCrashMonitorType.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SentryCrashMonitorType.c; sourceTree = ""; }; 63FE6FF620DA4C1000CDBAE8 /* SentryCrashMonitor_CPPException.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SentryCrashMonitor_CPPException.cpp; sourceTree = ""; }; - 63FE6FF720DA4C1000CDBAE8 /* SentryCrashMonitor_Zombie.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SentryCrashMonitor_Zombie.c; sourceTree = ""; }; 63FE6FF820DA4C1000CDBAE8 /* SentryCrashMonitor_CPPException.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SentryCrashMonitor_CPPException.h; sourceTree = ""; }; 63FE6FF920DA4C1000CDBAE8 /* SentryCrashMonitor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SentryCrashMonitor.c; sourceTree = ""; }; 63FE6FFB20DA4C1000CDBAE8 /* SentryCrashMonitor_MachException.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SentryCrashMonitor_MachException.h; sourceTree = ""; }; @@ -1025,7 +1022,6 @@ 63FE6FFF20DA4C1000CDBAE8 /* SentryCrashMonitor_Signal.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SentryCrashMonitor_Signal.c; sourceTree = ""; }; 63FE700020DA4C1000CDBAE8 /* SentryCrashMonitor_System.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SentryCrashMonitor_System.h; sourceTree = ""; }; 63FE700220DA4C1000CDBAE8 /* SentryCrashMonitor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SentryCrashMonitor.h; sourceTree = ""; }; - 63FE700320DA4C1000CDBAE8 /* SentryCrashMonitor_Zombie.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SentryCrashMonitor_Zombie.h; sourceTree = ""; }; 63FE700420DA4C1000CDBAE8 /* SentryCrashCachedData.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SentryCrashCachedData.c; sourceTree = ""; }; 63FE700720DA4C1000CDBAE8 /* SentryCrashDate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SentryCrashDate.h; sourceTree = ""; }; 63FE700820DA4C1000CDBAE8 /* SentryCrashMachineContext_Apple.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SentryCrashMachineContext_Apple.h; sourceTree = ""; }; @@ -2324,8 +2320,6 @@ 63FE6FF420DA4C1000CDBAE8 /* SentryCrashMonitor_Signal.h */, 63FE700020DA4C1000CDBAE8 /* SentryCrashMonitor_System.h */, 63FE6FF320DA4C1000CDBAE8 /* SentryCrashMonitor_System.m */, - 63FE6FF720DA4C1000CDBAE8 /* SentryCrashMonitor_Zombie.c */, - 63FE700320DA4C1000CDBAE8 /* SentryCrashMonitor_Zombie.h */, 63FE6FF920DA4C1000CDBAE8 /* SentryCrashMonitor.c */, 63FE700220DA4C1000CDBAE8 /* SentryCrashMonitor.h */, 63FE6FEE20DA4C1000CDBAE8 /* SentryCrashMonitorContext.h */, @@ -3331,7 +3325,6 @@ D8ACE3CF2762187D00F5A213 /* SentryFileIOTrackingIntegration.h in Headers */, 7BECF42226145C5D00D9826E /* SentryMechanismMeta.h in Headers */, 63FE718920DA4C1100CDBAE8 /* SentryCrash.h in Headers */, - 63FE70FB20DA4C1000CDBAE8 /* SentryCrashMonitor_Zombie.h in Headers */, 63AA769A1EB9C1C200D153DE /* SentryLog.h in Headers */, 7B56D73124616CCD00B842DA /* SentryConcurrentRateLimitsDictionary.h in Headers */, 03F84D2A27DD416B008FE43F /* SentryProfilingLogging.hpp in Headers */, @@ -3972,7 +3965,6 @@ 63FE714120DA4C1100CDBAE8 /* SentryCrashDate.c in Sources */, 63FE70DB20DA4C1000CDBAE8 /* SentryCrashMonitor_System.m in Sources */, 7BA61CBB247BC5D800C130A8 /* SentryCrashDefaultBinaryImageProvider.m in Sources */, - 63FE70E320DA4C1000CDBAE8 /* SentryCrashMonitor_Zombie.c in Sources */, 63FE713120DA4C1100CDBAE8 /* SentryCrashDynamicLinker.c in Sources */, 8E25C95325F836D000DC215B /* SentryRandom.m in Sources */, 7BC85231245812EC005A70F0 /* SentryFileContents.m in Sources */, diff --git a/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor.c b/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor.c index f80c27b72b..28b8bc9477 100644 --- a/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor.c +++ b/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor.c @@ -35,7 +35,6 @@ #include "SentryCrashMonitor_NSException.h" #include "SentryCrashMonitor_Signal.h" #include "SentryCrashMonitor_System.h" -#include "SentryCrashMonitor_Zombie.h" #include "SentryCrashSystemCapabilities.h" #include "SentryCrashThread.h" @@ -71,10 +70,6 @@ static Monitor g_monitors[] = { .monitorType = SentryCrashMonitorTypeNSException, .getAPI = sentrycrashcm_nsexception_getAPI, }, - { - .monitorType = SentryCrashMonitorTypeZombie, - .getAPI = sentrycrashcm_zombie_getAPI, - }, #endif { .monitorType = SentryCrashMonitorTypeCPPException, diff --git a/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitorType.c b/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitorType.c index c8a9d8196b..86481cc3b1 100644 --- a/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitorType.c +++ b/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitorType.c @@ -40,7 +40,6 @@ static const struct { MONITORTYPE(SentryCrashMonitorTypeNSException), MONITORTYPE(SentryCrashMonitorTypeSystem), MONITORTYPE(SentryCrashMonitorTypeApplicationState), - MONITORTYPE(SentryCrashMonitorTypeZombie), }; static const int g_monitorTypesCount = sizeof(g_monitorTypes) / sizeof(*g_monitorTypes); diff --git a/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitorType.h b/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitorType.h index 3370d24de3..7a388a4209 100644 --- a/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitorType.h +++ b/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitorType.h @@ -56,15 +56,12 @@ typedef enum { /* Keeps track of and injects application state. */ SentryCrashMonitorTypeApplicationState = 0x80, - /* Keeps track of zombies, and injects the last zombie NSException. */ - SentryCrashMonitorTypeZombie = 0x100, } SentryCrashMonitorType; #define SentryCrashMonitorTypeAll \ (SentryCrashMonitorTypeMachException | SentryCrashMonitorTypeSignal \ | SentryCrashMonitorTypeCPPException | SentryCrashMonitorTypeNSException \ - | SentryCrashMonitorTypeSystem | SentryCrashMonitorTypeApplicationState \ - | SentryCrashMonitorTypeZombie) + | SentryCrashMonitorTypeSystem | SentryCrashMonitorTypeApplicationState) #define SentryCrashMonitorTypeDebuggerUnsafe \ (SentryCrashMonitorTypeMachException | SentryCrashMonitorTypeSignal \ @@ -73,8 +70,6 @@ typedef enum { #define SentryCrashMonitorTypeAsyncSafe \ (SentryCrashMonitorTypeMachException | SentryCrashMonitorTypeSignal) -#define SentryCrashMonitorTypeOptional (SentryCrashMonitorTypeZombie) - #define SentryCrashMonitorTypeAsyncUnsafe \ (SentryCrashMonitorTypeAll & (~SentryCrashMonitorTypeAsyncSafe)) @@ -87,9 +82,8 @@ typedef enum { */ #define SentryCrashMonitorTypeProductionSafe (SentryCrashMonitorTypeAll) -/** Production safe monitors, minus the optional ones. */ -#define SentryCrashMonitorTypeProductionSafeMinimal \ - (SentryCrashMonitorTypeProductionSafe & (~SentryCrashMonitorTypeOptional)) +/** Production safe monitors */ +#define SentryCrashMonitorTypeProductionSafeMinimal (SentryCrashMonitorTypeProductionSafe) /** Monitors that are required for proper operation. * These add essential information to the reports, but do not trigger reporting. diff --git a/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_Zombie.c b/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_Zombie.c deleted file mode 100644 index c2bdbcb6f0..0000000000 --- a/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_Zombie.c +++ /dev/null @@ -1,247 +0,0 @@ -// -// SentryCrashZombie.m -// -// Created by Karl Stenerud on 2012-09-15. -// -// 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. -// - -#include "SentryCrashMonitor_Zombie.h" -#include "SentryCrashLogger.h" -#include "SentryCrashMonitorContext.h" -#include "SentryCrashObjC.h" - -#include -#include - -#define CACHE_SIZE 0x8000 - -// Compiler hints for "if" statements -#define likely_if(x) if (__builtin_expect(x, 1)) -#define unlikely_if(x) if (__builtin_expect(x, 0)) - -typedef struct { - const void *object; - const char *className; -} Zombie; - -static volatile Zombie *g_zombieCache; -static unsigned g_zombieHashMask; - -static volatile bool g_isEnabled = false; - -static struct { - Class class; - const void *address; - char name[100]; - char reason[900]; -} g_lastDeallocedException; - -static inline unsigned -hashIndex(const void *object) -{ - uintptr_t objPtr = (uintptr_t)object; - objPtr >>= (sizeof(object) - 1); - return objPtr & g_zombieHashMask; -} - -static bool -copyStringIvar(const void *self, const char *ivarName, char *buffer, int bufferLength) -{ - Class class = object_getClass((id)self); - SentryCrashObjCIvar ivar = { 0 }; - likely_if(sentrycrashobjc_ivarNamed(class, ivarName, &ivar)) - { - void *pointer; - likely_if(sentrycrashobjc_ivarValue(self, ivar.index, &pointer)) - { - likely_if(sentrycrashobjc_isValidObject(pointer)) - { - likely_if(sentrycrashobjc_copyStringContents(pointer, buffer, bufferLength) > 0) - { - return true; - } - else - { - SentryCrashLOG_DEBUG("sentrycrashobjc_copyStringContents %s failed", ivarName); - } - } - else - { - SentryCrashLOG_DEBUG("sentrycrashobjc_isValidObject %s failed", ivarName); - } - } - else - { - SentryCrashLOG_DEBUG("sentrycrashobjc_ivarValue %s failed", ivarName); - } - } - else - { - SentryCrashLOG_DEBUG("sentrycrashobjc_ivarNamed %s failed", ivarName); - } - return false; -} - -static void -storeException(const void *exception) -{ - g_lastDeallocedException.address = exception; - copyStringIvar( - exception, "name", g_lastDeallocedException.name, sizeof(g_lastDeallocedException.name)); - copyStringIvar(exception, "reason", g_lastDeallocedException.reason, - sizeof(g_lastDeallocedException.reason)); -} - -static inline void -handleDealloc(const void *self) -{ - volatile Zombie *cache = g_zombieCache; - likely_if(cache != NULL) - { - Zombie *zombie = (Zombie *)cache + hashIndex(self); - zombie->object = self; - Class class = object_getClass((id)self); - zombie->className = class_getName(class); - for (; class != nil; class = class_getSuperclass(class)) { - unlikely_if(class == g_lastDeallocedException.class) { storeException(self); } - } - } -} - -#define CREATE_ZOMBIE_HANDLER_INSTALLER(CLASS) \ - static IMP g_originalDealloc_##CLASS; \ - static void handleDealloc_##CLASS(id self, SEL _cmd) \ - { \ - handleDealloc(self); \ - typedef void (*fn)(id, SEL); \ - fn f = (fn)g_originalDealloc_##CLASS; \ - f(self, _cmd); \ - } \ - static void installDealloc_##CLASS() \ - { \ - Method method \ - = class_getInstanceMethod(objc_getClass(#CLASS), sel_registerName("dealloc")); \ - g_originalDealloc_##CLASS = method_getImplementation(method); \ - method_setImplementation(method, (IMP)handleDealloc_##CLASS); \ - } -// TODO: Uninstall doesn't work. -// static void uninstallDealloc_ ## CLASS() \ -//{ \ -// method_setImplementation(class_getInstanceMethod(objc_getClass(#CLASS), -// sel_registerName("dealloc")), g_originalDealloc_ ## CLASS); \ -//} - -CREATE_ZOMBIE_HANDLER_INSTALLER(NSObject) -CREATE_ZOMBIE_HANDLER_INSTALLER(NSProxy) - -static void -install() -{ - unsigned cacheSize = CACHE_SIZE; - g_zombieHashMask = cacheSize - 1; - g_zombieCache = calloc(cacheSize, sizeof(*g_zombieCache)); - if (g_zombieCache == NULL) { - SentryCrashLOG_ERROR("Error: Could not allocate %u bytes of memory. " - "SentryCrashZombie NOT installed!", - cacheSize * sizeof(*g_zombieCache)); - return; - } - - g_lastDeallocedException.class = objc_getClass("NSException"); - g_lastDeallocedException.address = NULL; - g_lastDeallocedException.name[0] = 0; - g_lastDeallocedException.reason[0] = 0; - - installDealloc_NSObject(); - installDealloc_NSProxy(); -} - -// TODO: Uninstall doesn't work. -// static void uninstall(void) -//{ -// uninstallDealloc_NSObject(); -// uninstallDealloc_NSProxy(); -// -// void* ptr = (void*)g_zombieCache; -// g_zombieCache = NULL; -// dispatch_time_t tenSeconds = dispatch_time(DISPATCH_TIME_NOW, -// (int64_t)(10.0 * NSEC_PER_SEC)); dispatch_after(tenSeconds, -// dispatch_get_main_queue(), ^ -// { -// free(ptr); -// }); -//} - -const char * -sentrycrashzombie_className(const void *object) -{ - volatile Zombie *cache = g_zombieCache; - if (cache == NULL || object == NULL) { - return NULL; - } - - Zombie *zombie = (Zombie *)cache + hashIndex(object); - if (zombie->object == object) { - return zombie->className; - } - return NULL; -} - -static void -setEnabled(bool isEnabled) -{ - if (isEnabled != g_isEnabled) { - g_isEnabled = isEnabled; - if (isEnabled) { - install(); - } else { - // TODO: Uninstall doesn't work. - g_isEnabled = true; - // uninstall(); - } - } -} - -static bool -isEnabled() -{ - return g_isEnabled; -} - -static void -addContextualInfoToEvent(SentryCrash_MonitorContext *eventContext) -{ - if (g_isEnabled) { - eventContext->ZombieException.address = (uintptr_t)g_lastDeallocedException.address; - eventContext->ZombieException.name = g_lastDeallocedException.name; - eventContext->ZombieException.reason = g_lastDeallocedException.reason; - } -} - -SentryCrashMonitorAPI * -sentrycrashcm_zombie_getAPI() -{ - static SentryCrashMonitorAPI api = { .setEnabled = setEnabled, - .isEnabled = isEnabled, - .addContextualInfoToEvent = addContextualInfoToEvent }; - return &api; -} diff --git a/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_Zombie.h b/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_Zombie.h deleted file mode 100644 index dc3ec7c929..0000000000 --- a/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_Zombie.h +++ /dev/null @@ -1,67 +0,0 @@ -// -// SentryCrashMonitor_Zombie.h -// -// Created by Karl Stenerud on 2012-09-15. -// -// 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. -// - -/* Poor man's zombie tracking. - * - * Benefits: - * - Very low CPU overhead. - * - Low memory overhead. - * - * Limitations: - * - Not guaranteed to catch all zombies. - * - Can generate false positives or incorrect class names. - * - SentryCrashZombie itself must be compiled with ARC disabled. You can enable - * ARC in your app, but SentryCrashZombie must be compiled in a separate library - * if you do. - */ - -#ifndef HDR_SentryCrashZombie_h -#define HDR_SentryCrashZombie_h - -#ifdef __cplusplus -extern "C" { -#endif - -#include "SentryCrashMonitor.h" -#include - -/** Get the class of a deallocated object pointer, if it was tracked. - * - * @param object A pointer to a deallocated object. - * - * @return The object's class name, or NULL if it wasn't found. - */ -const char *sentrycrashzombie_className(const void *object); - -/** Access the Monitor API. - */ -SentryCrashMonitorAPI *sentrycrashcm_zombie_getAPI(void); - -#ifdef __cplusplus -} -#endif - -#endif // HDR_SentryCrashZombie_h diff --git a/Sources/SentryCrash/Recording/SentryCrash.h b/Sources/SentryCrash/Recording/SentryCrash.h index a78363d5a2..1ba6b77595 100644 --- a/Sources/SentryCrash/Recording/SentryCrash.h +++ b/Sources/SentryCrash/Recording/SentryCrash.h @@ -100,13 +100,6 @@ static NSString *const SENTRYCRASH_REPORT_ATTACHMENTS_ITEM = @"attachments"; */ @property (nonatomic, readwrite, assign) BOOL introspectMemory; -/** If YES, monitor all Objective-C/Swift deallocations and keep track of any - * accesses after deallocation. - * - * Default: NO - */ -@property (nonatomic, readwrite, assign) BOOL catchZombies; - /** List of Objective-C classes that should never be introspected. * Whenever a class in this list is encountered, only the class name will be * recorded. This can be useful for information security concerns. diff --git a/Sources/SentryCrash/Recording/SentryCrash.m b/Sources/SentryCrash/Recording/SentryCrash.m index bda3b8cc02..644b471951 100644 --- a/Sources/SentryCrash/Recording/SentryCrash.m +++ b/Sources/SentryCrash/Recording/SentryCrash.m @@ -105,7 +105,6 @@ @implementation SentryCrash @synthesize bundleName = _bundleName; @synthesize basePath = _basePath; @synthesize introspectMemory = _introspectMemory; -@synthesize catchZombies = _catchZombies; @synthesize doNotIntrospectClasses = _doNotIntrospectClasses; @synthesize demangleLanguages = _demangleLanguages; @synthesize maxReportCount = _maxReportCount; @@ -141,7 +140,6 @@ - (id)initWithBasePath:(NSString *)basePath } self.deleteBehaviorAfterSendAll = SentryCrashCDeleteAlways; self.introspectMemory = YES; - self.catchZombies = NO; self.maxReportCount = 5; self.monitoring = SentryCrashMonitorTypeProductionSafeMinimal; self.monitoringFromUninstalledToRestore = NO; @@ -196,12 +194,6 @@ - (void)setIntrospectMemory:(BOOL)introspectMemory sentrycrash_setIntrospectMemory(introspectMemory); } -- (void)setCatchZombies:(BOOL)catchZombies -{ - _catchZombies = catchZombies; - self.monitoring |= SentryCrashMonitorTypeZombie; -} - - (void)setDoNotIntrospectClasses:(NSArray *)doNotIntrospectClasses { _doNotIntrospectClasses = doNotIntrospectClasses; @@ -385,10 +377,7 @@ - (void)deleteReportWithID:(NSNumber *)reportID // ============================================================================ #define SYNTHESIZE_CRASH_STATE_PROPERTY(TYPE, NAME) \ - -(TYPE)NAME \ - { \ - return sentrycrashstate_currentState()->NAME; \ - } + -(TYPE)NAME { return sentrycrashstate_currentState()->NAME; } SYNTHESIZE_CRASH_STATE_PROPERTY(NSTimeInterval, activeDurationSinceLastCrash) SYNTHESIZE_CRASH_STATE_PROPERTY(NSTimeInterval, backgroundDurationSinceLastCrash) diff --git a/Sources/SentryCrash/Recording/SentryCrashC.c b/Sources/SentryCrash/Recording/SentryCrashC.c index 1ecd32fbfe..f2d073e534 100644 --- a/Sources/SentryCrash/Recording/SentryCrashC.c +++ b/Sources/SentryCrash/Recording/SentryCrashC.c @@ -31,7 +31,6 @@ #include "SentryCrashMonitorContext.h" #include "SentryCrashMonitor_AppState.h" #include "SentryCrashMonitor_System.h" -#include "SentryCrashMonitor_Zombie.h" #include "SentryCrashObjC.h" #include "SentryCrashReport.h" #include "SentryCrashReportFixer.h" diff --git a/Sources/SentryCrash/Recording/SentryCrashReport.c b/Sources/SentryCrash/Recording/SentryCrashReport.c index 58c56a6c0a..41c7379403 100644 --- a/Sources/SentryCrash/Recording/SentryCrashReport.c +++ b/Sources/SentryCrash/Recording/SentryCrashReport.c @@ -33,7 +33,6 @@ #include "SentryCrashJSONCodec.h" #include "SentryCrashMach.h" #include "SentryCrashMemory.h" -#include "SentryCrashMonitor_Zombie.h" #include "SentryCrashObjC.h" #include "SentryCrashReportFields.h" #include "SentryCrashReportVersion.h" @@ -605,19 +604,6 @@ isRestrictedClass(const char *name) return false; } -static void -writeZombieIfPresent( - const SentryCrashReportWriter *const writer, const char *const key, const uintptr_t address) -{ -#if SentryCrashCRASH_HAS_OBJC - const void *object = (const void *)address; - const char *zombieClassName = sentrycrashzombie_className(object); - if (zombieClassName != NULL) { - writer->addStringElement(writer, key, zombieClassName); - } -#endif -} - static bool writeObjCObject(const SentryCrashReportWriter *const writer, const uintptr_t address, int *limit) { @@ -700,7 +686,6 @@ writeMemoryContents(const SentryCrashReportWriter *const writer, const char *con writer->beginObject(writer, key); { writer->addUIntegerElement(writer, SentryCrashField_Address, address); - writeZombieIfPresent(writer, SentryCrashField_LastDeallocObject, address); if (!writeObjCObject(writer, address, limit)) { if (object == NULL) { writer->addStringElement( @@ -744,10 +729,6 @@ isNotableAddress(const uintptr_t address) const void *object = (const void *)address; #if SentryCrashCRASH_HAS_OBJC - if (sentrycrashzombie_className(object) != NULL) { - return true; - } - if (sentrycrashobjc_objectType(object) != SentryCrashObjCTypeUnknown) { return true; } @@ -1352,7 +1333,6 @@ writeError(const SentryCrashReportWriter *const writer, const char *const key, case SentryCrashMonitorTypeSystem: case SentryCrashMonitorTypeApplicationState: - case SentryCrashMonitorTypeZombie: SentryCrashLOG_ERROR( "Crash monitor type 0x%x shouldn't be able to cause events!", crash->crashType); break; diff --git a/Tests/SentryTests/SentryCrash/SentryCrashReportStore_Tests.m b/Tests/SentryTests/SentryCrash/SentryCrashReportStore_Tests.m index 961bb5ca16..8cb62e67fa 100644 --- a/Tests/SentryTests/SentryCrash/SentryCrashReportStore_Tests.m +++ b/Tests/SentryTests/SentryCrash/SentryCrashReportStore_Tests.m @@ -57,6 +57,7 @@ - (int64_t)getReportIDFromPath:(NSString *)path int64_t reportID = 0; sscanf(filename, scanFormat, &reportID); + return reportID; } From d80d4105bd9c6a1d2271115383875a7c62c7aa33 Mon Sep 17 00:00:00 2001 From: Dhiogo Brustolin Date: Mon, 20 Mar 2023 13:24:22 +0100 Subject: [PATCH 10/25] chore: Remove private references from public headers (#2743) We made SentrySession private but we did not remove references from public headers. Also changing a few forward declarations to #import to help with .NET hybrid SDK. --- Sentry.xcodeproj/project.pbxproj | 2 +- Sources/Sentry/Public/SentryClient.h | 6 ++---- Sources/Sentry/Public/SentryHub.h | 9 ++------- Sources/Sentry/SentryHub.m | 1 + Sources/Sentry/SentryTraceContext.m | 1 + .../HybridPublic/PrivateSentrySDKOnly.h | 4 ++-- .../include/HybridPublic/SentryEnvelope.h | 20 +++++++++++++++---- Sources/Sentry/include/SentryClient+Private.h | 5 ++++- Sources/Sentry/include/SentrySdkInfo.h | 7 ++++++- Sources/Sentry/include/SentryTraceContext.h | 13 ++++++++++-- develop-docs/README.md | 4 ++++ 11 files changed, 50 insertions(+), 22 deletions(-) diff --git a/Sentry.xcodeproj/project.pbxproj b/Sentry.xcodeproj/project.pbxproj index d82952aa39..53fe837d69 100644 --- a/Sentry.xcodeproj/project.pbxproj +++ b/Sentry.xcodeproj/project.pbxproj @@ -748,7 +748,7 @@ D885266427739D01001269FC /* SentryFileIOTrackingIntegrationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D885266327739D01001269FC /* SentryFileIOTrackingIntegrationTests.swift */; }; D8853C842833EABC00700D64 /* SentryANRTracker.h in Headers */ = {isa = PBXBuildFile; fileRef = 7BCFA71427D0BAB7008C662C /* SentryANRTracker.h */; }; D88817D826D7149100BF2251 /* SentryTraceContext.m in Sources */ = {isa = PBXBuildFile; fileRef = D88817D626D7149100BF2251 /* SentryTraceContext.m */; }; - D88817DA26D72AB800BF2251 /* SentryTraceContext.h in Headers */ = {isa = PBXBuildFile; fileRef = D88817D926D72AB800BF2251 /* SentryTraceContext.h */; }; + D88817DA26D72AB800BF2251 /* SentryTraceContext.h in Headers */ = {isa = PBXBuildFile; fileRef = D88817D926D72AB800BF2251 /* SentryTraceContext.h */; settings = {ATTRIBUTES = (Private, ); }; }; D88817DD26D72BA500BF2251 /* SentryTraceStateTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D88817DB26D72B7B00BF2251 /* SentryTraceStateTests.swift */; }; D8918B222849FA6D00701F9A /* SentrySDKIntegrationTestsBase.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8918B212849FA6D00701F9A /* SentrySDKIntegrationTestsBase.swift */; }; D8AB40DB2806EC1900E5E9F7 /* SentryScreenshotIntegration.h in Headers */ = {isa = PBXBuildFile; fileRef = D8AB40DA2806EC1900E5E9F7 /* SentryScreenshotIntegration.h */; }; diff --git a/Sources/Sentry/Public/SentryClient.h b/Sources/Sentry/Public/SentryClient.h index a7db0de3db..6584591a10 100644 --- a/Sources/Sentry/Public/SentryClient.h +++ b/Sources/Sentry/Public/SentryClient.h @@ -1,7 +1,7 @@ #import "SentryDefines.h" -@class SentryOptions, SentrySession, SentryEvent, SentryScope, SentryFileManager, SentryId, - SentryUserFeedback, SentryTransaction; +@class SentryOptions, SentryEvent, SentryScope, SentryFileManager, SentryId, SentryUserFeedback, + SentryTransaction; NS_ASSUME_NONNULL_BEGIN @@ -108,8 +108,6 @@ SENTRY_NO_INIT - (void)captureUserFeedback:(SentryUserFeedback *)userFeedback NS_SWIFT_NAME(capture(userFeedback:)); -- (void)captureSession:(SentrySession *)session NS_SWIFT_NAME(capture(session:)); - /** * Waits synchronously for the SDK to flush out all queued and cached items for up to the specified * timeout in seconds. If there is no internet connection, the function returns immediately. The SDK diff --git a/Sources/Sentry/Public/SentryHub.h b/Sources/Sentry/Public/SentryHub.h index 9a94d6cb84..02d4e2dd88 100644 --- a/Sources/Sentry/Public/SentryHub.h +++ b/Sources/Sentry/Public/SentryHub.h @@ -2,8 +2,8 @@ #import "SentryIntegrationProtocol.h" #import "SentrySpanProtocol.h" -@class SentryEvent, SentryClient, SentryScope, SentrySession, SentryUser, SentryBreadcrumb, - SentryId, SentryUserFeedback, SentryTransactionContext; +@class SentryEvent, SentryClient, SentryScope, SentryUser, SentryBreadcrumb, SentryId, + SentryUserFeedback, SentryTransactionContext; NS_ASSUME_NONNULL_BEGIN @interface SentryHub : NSObject @@ -12,11 +12,6 @@ SENTRY_NO_INIT - (instancetype)initWithClient:(SentryClient *_Nullable)client andScope:(SentryScope *_Nullable)scope; -/** - * Since there's no scope stack, single hub instance, we keep the session here. - */ -@property (nonatomic, readonly, strong) SentrySession *_Nullable session; - /** * Starts a new SentrySession. If there's a running SentrySession, it ends it before starting the * new one. You can use this method in combination with endSession to manually track SentrySessions. diff --git a/Sources/Sentry/SentryHub.m b/Sources/Sentry/SentryHub.m index 57383ba589..0abe5bdefd 100644 --- a/Sources/Sentry/SentryHub.m +++ b/Sources/Sentry/SentryHub.m @@ -28,6 +28,7 @@ SentryHub () @property (nullable, nonatomic, strong) SentryClient *client; +@property (nullable, nonatomic, strong) SentrySession *session; @property (nullable, nonatomic, strong) SentryScope *scope; @property (nonatomic, strong) SentryCrashWrapper *crashWrapper; @property (nonatomic, strong) SentryTracesSampler *tracesSampler; diff --git a/Sources/Sentry/SentryTraceContext.m b/Sources/Sentry/SentryTraceContext.m index c6a95b6eed..c6bf936085 100644 --- a/Sources/Sentry/SentryTraceContext.m +++ b/Sources/Sentry/SentryTraceContext.m @@ -1,6 +1,7 @@ #import "SentryTraceContext.h" #import "SentryBaggage.h" #import "SentryDsn.h" +#import "SentryId.h" #import "SentryLog.h" #import "SentryOptions+Private.h" #import "SentryScope+Private.h" diff --git a/Sources/Sentry/include/HybridPublic/PrivateSentrySDKOnly.h b/Sources/Sentry/include/HybridPublic/PrivateSentrySDKOnly.h index c09e5d000a..f788ce5981 100644 --- a/Sources/Sentry/include/HybridPublic/PrivateSentrySDKOnly.h +++ b/Sources/Sentry/include/HybridPublic/PrivateSentrySDKOnly.h @@ -1,10 +1,10 @@ #import "PrivatesHeader.h" #import "SentryAppStartMeasurement.h" +#import "SentryEnvelope.h" #import "SentryEnvelopeItemType.h" #import "SentryScreenFrames.h" -@class SentryEnvelope, SentryDebugMeta, SentryAppStartMeasurement, SentryScreenFrames, - SentryOptions; +@class SentryDebugMeta, SentryAppStartMeasurement, SentryScreenFrames, SentryOptions; NS_ASSUME_NONNULL_BEGIN diff --git a/Sources/Sentry/include/HybridPublic/SentryEnvelope.h b/Sources/Sentry/include/HybridPublic/SentryEnvelope.h index c304cf0b69..a7edf941dc 100644 --- a/Sources/Sentry/include/HybridPublic/SentryEnvelope.h +++ b/Sources/Sentry/include/HybridPublic/SentryEnvelope.h @@ -1,8 +1,20 @@ #import "PrivatesHeader.h" -#import "SentryEnvelopeItemHeader.h" - -@class SentryEvent, SentrySession, SentrySdkInfo, SentryId, SentryUserFeedback, SentryAttachment, - SentryTransaction, SentryTraceContext, SentryClientReport, SentryEnvelopeItemHeader; +#if __has_include() +# import +#else +# import "SentryEnvelopeItemHeader.h" +#endif + +#if COCOAPODS +@class SentrySdkInfo, SentryTraceContext; +#else +# import "SentrySdkInfo.h" +# import "SentryTraceContext.h" + +#endif + +@class SentryEvent, SentrySession, SentryId, SentryUserFeedback, SentryAttachment, + SentryTransaction, SentryClientReport, SentryEnvelopeItemHeader; NS_ASSUME_NONNULL_BEGIN diff --git a/Sources/Sentry/include/SentryClient+Private.h b/Sources/Sentry/include/SentryClient+Private.h index 30a891a0f3..a9bcd46981 100644 --- a/Sources/Sentry/include/SentryClient+Private.h +++ b/Sources/Sentry/include/SentryClient+Private.h @@ -2,7 +2,8 @@ #import "SentryDataCategory.h" #import "SentryDiscardReason.h" -@class SentryEnvelopeItem, SentryId, SentryAttachment, SentryThreadInspector, SentryEnvelope; +@class SentrySession, SentryEnvelopeItem, SentryId, SentryAttachment, SentryThreadInspector, + SentryEnvelope; NS_ASSUME_NONNULL_BEGIN @@ -41,6 +42,8 @@ SentryClient () additionalEnvelopeItems:(NSArray *)additionalEnvelopeItems NS_SWIFT_NAME(capture(event:scope:additionalEnvelopeItems:)); +- (void)captureSession:(SentrySession *)session NS_SWIFT_NAME(capture(session:)); + /** * Needed by hybrid SDKs as react-native to synchronously store an envelope to disk. */ diff --git a/Sources/Sentry/include/SentrySdkInfo.h b/Sources/Sentry/include/SentrySdkInfo.h index ef80f2cabc..d3799c1326 100644 --- a/Sources/Sentry/include/SentrySdkInfo.h +++ b/Sources/Sentry/include/SentrySdkInfo.h @@ -1,6 +1,11 @@ -#import "SentrySerializable.h" #import +#if __has_include() +# import +#else +# import "SentrySerializable.h" +#endif + NS_ASSUME_NONNULL_BEGIN /** diff --git a/Sources/Sentry/include/SentryTraceContext.h b/Sources/Sentry/include/SentryTraceContext.h index 0958e406ac..3fd1b49192 100644 --- a/Sources/Sentry/include/SentryTraceContext.h +++ b/Sources/Sentry/include/SentryTraceContext.h @@ -1,5 +1,14 @@ -#import "SentryId.h" -#import "SentrySerializable.h" +#if __has_include() +# import +#else +# import "SentrySerializable.h" +#endif + +#if __has_include() +# import +#else +# import "SentryId.h" +#endif NS_ASSUME_NONNULL_BEGIN diff --git a/develop-docs/README.md b/develop-docs/README.md index ad817bf73a..651278ff8c 100644 --- a/develop-docs/README.md +++ b/develop-docs/README.md @@ -196,3 +196,7 @@ Date: January 18th, 2023 Contributors: @brustolin and @philipphofmann We release experimental SentrySwiftUI cocoa package with the version 8.0.0 because all podspecs file in a repo need to have the same version. + +## Usage of `__has_include` + +Some private headers add a dependency of a public header, when those private headers are used in a sample project, or referenced from a hybrid SDK, it is treated as part of the project using it, therefore, if it points to a header that is not part of said project, a compilation error will occur. To solve this we make use of `__has_include` to try to point to the SDK version of the header, or to fallback to the direct reference when compiling the SDK. From 228a90914c969c2dab7cdfeeb0a9faaf575f1eed Mon Sep 17 00:00:00 2001 From: Philipp Hofmann Date: Mon, 20 Mar 2023 13:32:43 +0100 Subject: [PATCH 11/25] test: Add Error Description in iOS-Swift sample (#2813) Add custom error description when capturing swift errors. --- .../iOS-Swift/Tools/RandomErrors.swift | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/Samples/iOS-Swift/iOS-Swift/Tools/RandomErrors.swift b/Samples/iOS-Swift/iOS-Swift/Tools/RandomErrors.swift index 7321b615a8..80e9700091 100644 --- a/Samples/iOS-Swift/iOS-Swift/Tools/RandomErrors.swift +++ b/Samples/iOS-Swift/iOS-Swift/Tools/RandomErrors.swift @@ -6,6 +6,23 @@ enum SampleError: Error { case awesomeCentaur } +extension SampleError: CustomNSError { + var errorUserInfo: [String: Any] { + func getDebugDescription() -> String { + switch self { + case SampleError.bestDeveloper: + return "bestDeveloper" + case .happyCustomer: + return "happyCustomer" + case .awesomeCentaur: + return "awesomeCentaur" + } + } + + return [NSDebugDescriptionErrorKey: getDebugDescription()] + } +} + class RandomErrorGenerator { static func generate() throws { From cd3bfeb82d32f9fad68892fef6c0b59a69505d8b Mon Sep 17 00:00:00 2001 From: Dhiogo Brustolin Date: Mon, 20 Mar 2023 13:56:57 +0100 Subject: [PATCH 12/25] fix: App Hang report crashes with too many threads (#2811) Add a limit of 70 threads to report App hang. More than 100 is causing the SDK to crash, we add an extra safety margin. Co-authored-by: Dhiogo Ramos Brustolin Co-authored-by: Philipp Hofmann --- CHANGELOG.md | 1 + Sources/Sentry/SentryThreadInspector.m | 12 +++++++++- .../Tools/SentryCrashMachineContext.c | 14 ++++++++++++ .../Tools/SentryCrashMachineContext.h | 7 ++++++ .../SentryThreadInspectorTests.swift | 22 +++++++++++++++++++ 5 files changed, 55 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 932e80ae74..f92db8c709 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ### Fixes - Updating AppHang state on main thread (#2793) +- App Hang report crashes with too many threads (#2811) ### Improvements diff --git a/Sources/Sentry/SentryThreadInspector.m b/Sources/Sentry/SentryThreadInspector.m index 82f13ca8ca..e6829a2467 100644 --- a/Sources/Sentry/SentryThreadInspector.m +++ b/Sources/Sentry/SentryThreadInspector.m @@ -119,10 +119,20 @@ - (SentryStacktrace *)stacktraceForCurrentThreadAsyncUnsafe thread_act_array_t suspendedThreads = NULL; mach_msg_type_number_t numSuspendedThreads = 0; - sentrycrashmc_suspendEnvironment(&suspendedThreads, &numSuspendedThreads); + // SentryThreadInspector is crashing when there is too many threads. + // We add a limit of 70 threads because in test with up to 100 threads it seems fine. + // We are giving it an extra safety margin. + sentrycrashmc_suspendEnvironment_upToMaxSupportedThreads( + &suspendedThreads, &numSuspendedThreads, 70); // DANGER: Do not try to allocate memory in the heap or call Objective-C code in this // section Doing so when the threads are suspended may lead to deadlocks or crashes. + // If no threads was suspended we don't need to do anything. + // This may happen if there is more than max amount of threads (70). + if (numSuspendedThreads == 0) { + return threads; + } + SentryThreadInfo threadsInfos[numSuspendedThreads]; for (int i = 0; i < numSuspendedThreads; i++) { diff --git a/Sources/SentryCrash/Recording/Tools/SentryCrashMachineContext.c b/Sources/SentryCrash/Recording/Tools/SentryCrashMachineContext.c index fab1ff8c90..66bb6c1e06 100644 --- a/Sources/SentryCrash/Recording/Tools/SentryCrashMachineContext.c +++ b/Sources/SentryCrash/Recording/Tools/SentryCrashMachineContext.c @@ -146,6 +146,14 @@ sentrycrashmc_getContextForSignal( void sentrycrashmc_suspendEnvironment( thread_act_array_t *suspendedThreads, mach_msg_type_number_t *numSuspendedThreads) +{ + sentrycrashmc_suspendEnvironment_upToMaxSupportedThreads( + suspendedThreads, numSuspendedThreads, UINT32_MAX); +} + +void +sentrycrashmc_suspendEnvironment_upToMaxSupportedThreads(thread_act_array_t *suspendedThreads, + mach_msg_type_number_t *numSuspendedThreads, mach_msg_type_number_t maxSupportedThreads) { #if SentryCrashCRASH_HAS_THREADS_API SentryCrashLOG_DEBUG("Suspending environment."); @@ -158,6 +166,12 @@ sentrycrashmc_suspendEnvironment( return; } + if (*numSuspendedThreads > maxSupportedThreads) { + *numSuspendedThreads = 0; + SentryCrashLOG_DEBUG("Too many threads to suspend. Aborting operation."); + return; + } + for (mach_msg_type_number_t i = 0; i < *numSuspendedThreads; i++) { thread_t thread = (*suspendedThreads)[i]; if (thread != thisThread && !sentrycrashcm_isReservedThread(thread)) { diff --git a/Sources/SentryCrash/Recording/Tools/SentryCrashMachineContext.h b/Sources/SentryCrash/Recording/Tools/SentryCrashMachineContext.h index 798e6bfd3d..fb494eeff2 100644 --- a/Sources/SentryCrash/Recording/Tools/SentryCrashMachineContext.h +++ b/Sources/SentryCrash/Recording/Tools/SentryCrashMachineContext.h @@ -40,6 +40,13 @@ extern "C" { void sentrycrashmc_suspendEnvironment( thread_act_array_t *suspendedThreads, mach_msg_type_number_t *numSuspendedThreads); +/** + Suspend the runtime environment only if the amount of threads is not higher than + maxSupportedThreads. + */ +void sentrycrashmc_suspendEnvironment_upToMaxSupportedThreads(thread_act_array_t *suspendedThreads, + mach_msg_type_number_t *numSuspendedThreads, mach_msg_type_number_t maxSupportedThreads); + /** Resume the runtime environment. */ void sentrycrashmc_resumeEnvironment(thread_act_array_t threads, mach_msg_type_number_t numThreads); diff --git a/Tests/SentryTests/SentryCrash/SentryThreadInspectorTests.swift b/Tests/SentryTests/SentryCrash/SentryThreadInspectorTests.swift index bbc315bb40..c9f58cbd49 100644 --- a/Tests/SentryTests/SentryCrash/SentryThreadInspectorTests.swift +++ b/Tests/SentryTests/SentryCrash/SentryThreadInspectorTests.swift @@ -5,6 +5,7 @@ class SentryThreadInspectorTests: XCTestCase { private class Fixture { var testMachineContextWrapper = TestMachineContextWrapper() var stacktraceBuilder = TestSentryStacktraceBuilder(crashStackEntryMapper: SentryCrashStackEntryMapper(inAppLogic: SentryInAppLogic(inAppIncludes: [], inAppExcludes: []))) + var keepThreadAlive = true func getSut(testWithRealMachineContextWrapper: Bool = false) -> SentryThreadInspector { @@ -80,6 +81,27 @@ class SentryThreadInspectorTests: XCTestCase { wait(for: [expect], timeout: 10) } + func testGetCurrentThreadWithStackTrack_TooManyThreads() { + let expect = expectation(description: "Wait all Threads") + expect.expectedFulfillmentCount = 70 + + let sut = self.fixture.getSut(testWithRealMachineContextWrapper: true) + + for _ in 0.. Date: Mon, 20 Mar 2023 19:18:09 +0100 Subject: [PATCH 13/25] chore: Add a button to iOSSwift sample to start threads Added a button that will start 100 threads that will be alive for 10 seconds. I believe is enough time to click any other button to try a feature with that many threads running. --- .../iOS-Swift/iOS-Swift/Base.lproj/Main.storyboard | 14 +++++++++++--- Samples/iOS-Swift/iOS-Swift/ViewController.swift | 8 ++++++++ 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/Samples/iOS-Swift/iOS-Swift/Base.lproj/Main.storyboard b/Samples/iOS-Swift/iOS-Swift/Base.lproj/Main.storyboard index c5caddff8b..4598c342bd 100644 --- a/Samples/iOS-Swift/iOS-Swift/Base.lproj/Main.storyboard +++ b/Samples/iOS-Swift/iOS-Swift/Base.lproj/Main.storyboard @@ -136,7 +136,7 @@ - + + @@ -424,14 +432,14 @@ - + - + diff --git a/Samples/iOS-Swift/iOS-Swift/ViewController.swift b/Samples/iOS-Swift/iOS-Swift/ViewController.swift index c42c1ab443..cd7f6f2031 100644 --- a/Samples/iOS-Swift/iOS-Swift/ViewController.swift +++ b/Samples/iOS-Swift/iOS-Swift/ViewController.swift @@ -216,6 +216,14 @@ class ViewController: UIViewController { } } } + + @IBAction func start100Threads(_ sender: Any) { + for _ in 0..<100 { + Thread.detachNewThread { + Thread.sleep(forTimeInterval: 10) + } + } + } private func calcPi() -> Double { var denominator = 1.0 From 24b4df1f13612797fd9d9e1257e9e573092bdaf4 Mon Sep 17 00:00:00 2001 From: Andrew McKnight Date: Mon, 20 Mar 2023 17:08:33 -0800 Subject: [PATCH 14/25] output xcodebuild logs from carthage build and archive if failed (#2798) --- .github/workflows/build.yml | 8 ++++++++ Makefile | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 237d5e1aa8..c69a56eaa6 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -104,6 +104,14 @@ jobs: path: | ${{ github.workspace }}/*.zip + - name: Archive build log if failed + uses: actions/upload-artifact@v3 + if: ${{ failure() || cancelled() }} + with: + name: raw-build-output-build-xcframework + path: | + build-xcframework.log + validate-xcframework: name: Validate XCFramework Xcode ${{ matrix.xcode }} runs-on: macos-12 diff --git a/Makefile b/Makefile index ea43494c8f..def0d43e4c 100644 --- a/Makefile +++ b/Makefile @@ -57,7 +57,7 @@ analyze: # For more info check out: https://github.com/Carthage/Carthage/releases/tag/0.38.0 build-xcframework: @echo "--> Carthage: creating Sentry xcframework" - carthage build --use-xcframeworks --no-skip-current + carthage build --use-xcframeworks --no-skip-current --verbose > build-xcframework.log # use ditto here to avoid clobbering symlinks which exist in macOS frameworks ditto -c -k -X --rsrc --keepParent Carthage Sentry.xcframework.zip From 3fc79ea6ebcfd726e48bea1d98f89bc3a32d5cf2 Mon Sep 17 00:00:00 2001 From: getsentry-bot Date: Tue, 21 Mar 2023 13:24:24 +0000 Subject: [PATCH 15/25] release: 8.3.2 --- CHANGELOG.md | 2 +- Sentry.podspec | 4 ++-- SentryPrivate.podspec | 2 +- SentrySwiftUI.podspec | 4 ++-- Sources/Configuration/Sentry.xcconfig | 2 +- Sources/Configuration/SentryPrivate.xcconfig | 2 +- Sources/Sentry/SentryMeta.m | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f92db8c709..b049066a0a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## Unreleased +## 8.3.2 ### Fixes diff --git a/Sentry.podspec b/Sentry.podspec index 4a9643b0a9..37436e6f6d 100644 --- a/Sentry.podspec +++ b/Sentry.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "Sentry" - s.version = "8.3.1" + s.version = "8.3.2" s.summary = "Sentry client for cocoa" s.homepage = "https://github.com/getsentry/sentry-cocoa" s.license = "mit" @@ -27,7 +27,7 @@ Pod::Spec.new do |s| } s.default_subspecs = ['Core'] - s.dependency "SentryPrivate", "8.3.1" + s.dependency "SentryPrivate", "8.3.2" s.subspec 'Core' do |sp| sp.source_files = "Sources/Sentry/**/*.{h,hpp,m,mm,c,cpp}", diff --git a/SentryPrivate.podspec b/SentryPrivate.podspec index 3a469bca2c..bd5668d444 100644 --- a/SentryPrivate.podspec +++ b/SentryPrivate.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "SentryPrivate" - s.version = "8.3.1" + s.version = "8.3.2" s.summary = "Sentry Private Library." s.homepage = "https://github.com/getsentry/sentry-cocoa" s.license = "mit" diff --git a/SentrySwiftUI.podspec b/SentrySwiftUI.podspec index 46098e8df1..2320e16083 100644 --- a/SentrySwiftUI.podspec +++ b/SentrySwiftUI.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "SentrySwiftUI" - s.version = "8.3.1" + s.version = "8.3.2" s.summary = "Sentry client for SwiftUI" s.homepage = "https://github.com/getsentry/sentry-cocoa" s.license = "mit" @@ -19,5 +19,5 @@ Pod::Spec.new do |s| s.watchos.framework = 'WatchKit' s.source_files = "Sources/SentrySwiftUI/**/*.{swift,h,m}" - s.dependency 'Sentry', "8.3.1" + s.dependency 'Sentry', "8.3.2" end diff --git a/Sources/Configuration/Sentry.xcconfig b/Sources/Configuration/Sentry.xcconfig index 4630abf7db..7eb85ee32b 100644 --- a/Sources/Configuration/Sentry.xcconfig +++ b/Sources/Configuration/Sentry.xcconfig @@ -2,6 +2,6 @@ PRODUCT_NAME = Sentry INFOPLIST_FILE = Sources/Sentry/Info.plist PRODUCT_BUNDLE_IDENTIFIER = io.sentry.Sentry -CURRENT_PROJECT_VERSION = 8.3.1 +CURRENT_PROJECT_VERSION = 8.3.2 MODULEMAP_FILE = $(SRCROOT)/Sources/Sentry/Sentry.modulemap diff --git a/Sources/Configuration/SentryPrivate.xcconfig b/Sources/Configuration/SentryPrivate.xcconfig index 5948037db1..bcfb92ec30 100644 --- a/Sources/Configuration/SentryPrivate.xcconfig +++ b/Sources/Configuration/SentryPrivate.xcconfig @@ -1,3 +1,3 @@ PRODUCT_NAME = SentryPrivate MACH_O_TYPE = staticlib -CURRENT_PROJECT_VERSION = 8.3.1 +CURRENT_PROJECT_VERSION = 8.3.2 diff --git a/Sources/Sentry/SentryMeta.m b/Sources/Sentry/SentryMeta.m index 38285834ba..4574b4dbfa 100644 --- a/Sources/Sentry/SentryMeta.m +++ b/Sources/Sentry/SentryMeta.m @@ -5,7 +5,7 @@ @implementation SentryMeta // Don't remove the static keyword. If you do the compiler adds the constant name to the global // symbol table and it might clash with other constants. When keeping the static keyword the // compiler replaces all occurrences with the value. -static NSString *versionString = @"8.3.1"; +static NSString *versionString = @"8.3.2"; static NSString *sdkName = @"sentry.cocoa"; + (NSString *)versionString From cbf622587a012a1410857c9abfa452bf05a0ade4 Mon Sep 17 00:00:00 2001 From: Philipp Hofmann Date: Tue, 21 Mar 2023 16:37:00 +0100 Subject: [PATCH 16/25] test: Build TestFlight with Xcode 14.2 (#2816) A bug in Fastlane required us to pin to Fastlane to Xcode 14.0.1, which is fixed: https://github.com/fastlane/fastlane/issues/20910 Now we can build with Xcode 14.2. --- .github/workflows/testflight.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/testflight.yml b/.github/workflows/testflight.yml index 84f35af194..9dc39892dc 100644 --- a/.github/workflows/testflight.yml +++ b/.github/workflows/testflight.yml @@ -16,8 +16,7 @@ jobs: runs-on: macos-12 steps: - uses: actions/checkout@v3 - # Xcode 14.1 has a bug with fastlane see https://github.com/fastlane/fastlane/issues/20910 - - run: ./scripts/ci-select-xcode.sh 14.0.1 + - run: ./scripts/ci-select-xcode.sh 14.2 - run: bundle install # We upload a new version to TestFlight on every commit on main From ea73af67ef22bb8a3274150841491b42f801aecd Mon Sep 17 00:00:00 2001 From: Dhiogo Brustolin Date: Tue, 21 Mar 2023 20:46:43 +0100 Subject: [PATCH 17/25] feat: Add CPU Core count in device context (#2814) Added the amount of CPU cores in the device context. --- CHANGELOG.md | 4 ++++ Sources/Sentry/SentryClient.m | 4 ++++ Tests/SentryTests/SentryClientTests.swift | 12 ++++++++++-- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b049066a0a..09eefa60fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## 8.3.2 +### Features + +- Add CPU core count in device context (#2814) + ### Fixes - Updating AppHang state on main thread (#2793) diff --git a/Sources/Sentry/SentryClient.m b/Sources/Sentry/SentryClient.m index 03145d8467..c9c962a3d1 100644 --- a/Sources/Sentry/SentryClient.m +++ b/Sources/Sentry/SentryClient.m @@ -31,6 +31,7 @@ #import "SentryMessage.h" #import "SentryMeta.h" #import "SentryNSError.h" +#import "SentryNSProcessInfoWrapper.h" #import "SentryOptions+Private.h" #import "SentrySDK+Private.h" #import "SentryScope+Private.h" @@ -63,6 +64,7 @@ @property (nonatomic, strong) SentryUIDeviceWrapper *deviceWrapper; @property (nonatomic, strong) NSLocale *locale; @property (nonatomic, strong) NSTimeZone *timezone; +@property (nonatomic, strong) SentryNSProcessInfoWrapper *processInfoWrapper; @end @@ -171,6 +173,7 @@ - (instancetype)initWithOptions:(SentryOptions *)options self.timezone = timezone; self.attachmentProcessors = [[NSMutableArray alloc] init]; self.deviceWrapper = deviceWrapper; + self.processInfoWrapper = [[SentryNSProcessInfoWrapper alloc] init]; if (deleteOldEnvelopeItems) { [fileManager deleteOldEnvelopeItems]; @@ -794,6 +797,7 @@ - (void)applyExtraDeviceContextToEvent:(SentryEvent *)event block:^(NSMutableDictionary *device) { device[SentryDeviceContextFreeMemoryKey] = @(self.crashWrapper.freeMemorySize); device[@"free_storage"] = @(self.crashWrapper.freeStorageSize); + device[@"processor_count"] = @([self.processInfoWrapper processorCount]); #if TARGET_OS_IOS if (self.deviceWrapper.orientation != UIDeviceOrientationUnknown) { diff --git a/Tests/SentryTests/SentryClientTests.swift b/Tests/SentryTests/SentryClientTests.swift index bca1f80c62..4d91e2d19c 100644 --- a/Tests/SentryTests/SentryClientTests.swift +++ b/Tests/SentryTests/SentryClientTests.swift @@ -607,9 +607,14 @@ class SentryClientTest: XCTestCase { } } - func testCaptureEvent_AddCurrentMemoryAndStorage() { + func testCaptureEvent_AddCurrentMemoryStorageAndCPUCoreCount() { - fixture.getSut().capture(event: TestData.event) + let sut = fixture.getSut() + let testProcessWrapper = TestSentryNSProcessInfoWrapper() + testProcessWrapper.overrides.processorCount = 12 + Dynamic(sut).processInfoWrapper = testProcessWrapper + + sut.capture(event: TestData.event) assertLastSentEvent { actual in let eventFreeMemory = actual.context?["device"]?[SentryDeviceContextFreeMemoryKey] as? Int @@ -620,6 +625,9 @@ class SentryClientTest: XCTestCase { let eventFreeStorage = actual.context?["device"]?["free_storage"] as? Int XCTAssertEqual(eventFreeStorage, 345_678) + + let cpuCoreCount = actual.context?["device"]?["processor_count"] as? UInt + XCTAssertEqual(testProcessWrapper.processorCount, cpuCoreCount) } } From 66922caa6de29602cb803dadf1a5dcfcc2007ebd Mon Sep 17 00:00:00 2001 From: Dhiogo Brustolin Date: Wed, 22 Mar 2023 08:22:46 +0100 Subject: [PATCH 18/25] fix: View hierarchy not sent for crashes (#2781) View hierarchy was not being sent for crashes because of the lack of a filename. Co-authored-by: Andrew McKnight --- CHANGELOG.md | 7 +++++++ Sources/Sentry/SentryScreenshot.m | 4 ++-- .../Sentry/SentryViewHierarchyIntegration.m | 11 ++++++++-- Sources/Sentry/include/SentryScreenshot.h | 8 +++++++- Sources/Sentry/include/SentryViewHierarchy.h | 5 +++++ Sources/SentryCrash/Recording/SentryCrashC.h | 20 +++++++++++++++---- .../SentryViewHierarchyIntegrationTests.swift | 6 ++++++ .../ViewHierarchy/TestSentryViewHierarchy.h | 3 +++ .../TestSentryViewHierarchy.swift | 6 ++++++ 9 files changed, 61 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 09eefa60fb..f5b6867061 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## Unreleased + +### Fixes + +- View hierarchy not sent for crashes (#2781) + ## 8.3.2 ### Features @@ -8,6 +14,7 @@ ### Fixes + - Updating AppHang state on main thread (#2793) - App Hang report crashes with too many threads (#2811) diff --git a/Sources/Sentry/SentryScreenshot.m b/Sources/Sentry/SentryScreenshot.m index 9fe1ee45ab..d4b1cb21f0 100644 --- a/Sources/Sentry/SentryScreenshot.m +++ b/Sources/Sentry/SentryScreenshot.m @@ -20,7 +20,7 @@ @implementation SentryScreenshot return result; } -- (void)saveScreenShots:(NSString *)path +- (void)saveScreenShots:(NSString *)imagesDirectoryPath { // This function does not dispatch the screenshot to the main thread. // The caller should be aware of that. @@ -31,7 +31,7 @@ - (void)saveScreenShots:(NSString *)path NSString *name = idx == 0 ? @"screenshot.png" : [NSString stringWithFormat:@"screenshot-%li.png", (unsigned long)idx + 1]; - NSString *fileName = [path stringByAppendingPathComponent:name]; + NSString *fileName = [imagesDirectoryPath stringByAppendingPathComponent:name]; [obj writeToFile:fileName atomically:YES]; }]; } diff --git a/Sources/Sentry/SentryViewHierarchyIntegration.m b/Sources/Sentry/SentryViewHierarchyIntegration.m index dcef9bf6be..f159349a73 100644 --- a/Sources/Sentry/SentryViewHierarchyIntegration.m +++ b/Sources/Sentry/SentryViewHierarchyIntegration.m @@ -10,10 +10,17 @@ #if SENTRY_HAS_UIKIT +/** + * Function to call through to the ObjC method to save a view hierarchy, which can be passed around + * as a function pointer in the C crash reporting code. + * @param reportDirectoryPath The path to the directory containing crash reporting files, in which a + * new file will be created to store the view hierarchy description. + */ void -saveViewHierarchy(const char *path) +saveViewHierarchy(const char *reportDirectoryPath) { - NSString *reportPath = [NSString stringWithUTF8String:path]; + NSString *reportPath = [[NSString stringWithUTF8String:reportDirectoryPath] + stringByAppendingPathComponent:@"view-hierarchy.json"]; [SentryDependencyContainer.sharedInstance.viewHierarchy saveViewHierarchy:reportPath]; } diff --git a/Sources/Sentry/include/SentryScreenshot.h b/Sources/Sentry/include/SentryScreenshot.h index 32d4fdcd55..ccac8580cb 100644 --- a/Sources/Sentry/include/SentryScreenshot.h +++ b/Sources/Sentry/include/SentryScreenshot.h @@ -13,7 +13,13 @@ NS_ASSUME_NONNULL_BEGIN */ - (nullable NSArray *)appScreenshots; -- (void)saveScreenShots:(NSString *)path; +/** + * Save the current app screen shots in the given directory. + * If an app has more than one screen, one image for each screen will be saved. + * + * @param imagesDirectoryPath The path where the images should be saved. + */ +- (void)saveScreenShots:(NSString *)imagesDirectoryPath; - (NSArray *)takeScreenshots; @end diff --git a/Sources/Sentry/include/SentryViewHierarchy.h b/Sources/Sentry/include/SentryViewHierarchy.h index 81bc1246e9..5051d06805 100644 --- a/Sources/Sentry/include/SentryViewHierarchy.h +++ b/Sources/Sentry/include/SentryViewHierarchy.h @@ -8,6 +8,11 @@ NS_ASSUME_NONNULL_BEGIN - (nullable NSData *)fetchViewHierarchy; +/** + * Save the current app view hierarchy in the given file path. + * + * @param filePath The full path where the view hierarchy should be saved. + */ - (BOOL)saveViewHierarchy:(NSString *)filePath; @end diff --git a/Sources/SentryCrash/Recording/SentryCrashC.h b/Sources/SentryCrash/Recording/SentryCrashC.h index 660a4ff84a..eeba4f817e 100644 --- a/Sources/SentryCrash/Recording/SentryCrashC.h +++ b/Sources/SentryCrash/Recording/SentryCrashC.h @@ -111,20 +111,32 @@ void sentrycrash_setCrashNotifyCallback(const SentryCrashReportWriteCallback onC */ void sentrycrash_setMaxReportCount(int maxReportCount); +/** + * @typedef SaveAttachmentCallback + * + * This typedef defines a function pointer to a callback that will be called during crashes + * to request extra attachments to be saved. + * + * @param directoryPath The path to a directory where the view hierarchy should be saved. + */ +typedef void (*SaveAttachmentCallback)(const char *directoryPath); + /** * Set the callback to be called at the end of a crash to make the app save a screenshot; * - * @param callback function pointer that will be called with a give path. + * @param callback function pointer that will be called with a path to a directory where the screen + * shot should be saved. */ -void sentrycrash_setSaveScreenshots(void (*callback)(const char *)); +void sentrycrash_setSaveScreenshots(SaveAttachmentCallback callback); /** * Set the callback to be called at the end of a crash to make the app save the view hierarchy * descriptions; * - * @param callback function pointer that will be called with a give path. + * @param callback function pointer that will be called with a path to a directory where the view + * hierarchy should be saved. */ -void sentrycrash_setSaveViewHierarchy(void (*callback)(const char *)); +void sentrycrash_setSaveViewHierarchy(SaveAttachmentCallback callback); /** Report a custom, user defined exception. * This can be useful when dealing with scripting languages. diff --git a/Tests/SentryTests/Integrations/ViewHierarchy/SentryViewHierarchyIntegrationTests.swift b/Tests/SentryTests/Integrations/ViewHierarchy/SentryViewHierarchyIntegrationTests.swift index 8c3243b68b..e157894146 100644 --- a/Tests/SentryTests/Integrations/ViewHierarchy/SentryViewHierarchyIntegrationTests.swift +++ b/Tests/SentryTests/Integrations/ViewHierarchy/SentryViewHierarchyIntegrationTests.swift @@ -53,6 +53,12 @@ class SentryViewHierarchyIntegrationTests: XCTestCase { XCTAssertFalse(sentrycrash_hasSaveViewHierarchyCallback()) } + func test_integrationAddFileName() { + SentrySDK.start { $0.attachViewHierarchy = true } + saveViewHierarchy("/test/path") + XCTAssertEqual("/test/path/view-hierarchy.json", fixture.viewHierarchy.saveFilePathUsed) + } + func test_processAttachments() { let sut = fixture.getSut() let event = Event(error: NSError(domain: "", code: -1)) diff --git a/Tests/SentryTests/Integrations/ViewHierarchy/TestSentryViewHierarchy.h b/Tests/SentryTests/Integrations/ViewHierarchy/TestSentryViewHierarchy.h index 92ef21291e..9f5ded4a11 100644 --- a/Tests/SentryTests/Integrations/ViewHierarchy/TestSentryViewHierarchy.h +++ b/Tests/SentryTests/Integrations/ViewHierarchy/TestSentryViewHierarchy.h @@ -3,6 +3,9 @@ #import "SentryViewHierarchy.h" #if SENTRY_HAS_UIKIT + +void saveViewHierarchy(const char *path); + @interface SentryViewHierarchy (Test) - (int)viewHierarchyFromView:(UIView *)view intoContext:(SentryCrashJSONEncodeContext *)context; diff --git a/Tests/SentryTests/Integrations/ViewHierarchy/TestSentryViewHierarchy.swift b/Tests/SentryTests/Integrations/ViewHierarchy/TestSentryViewHierarchy.swift index eb5e714594..02d2d60e93 100644 --- a/Tests/SentryTests/Integrations/ViewHierarchy/TestSentryViewHierarchy.swift +++ b/Tests/SentryTests/Integrations/ViewHierarchy/TestSentryViewHierarchy.swift @@ -6,6 +6,7 @@ class TestSentryViewHierarchy: SentryViewHierarchy { var result: Data? var viewHierarchyResult: Int32 = 0 var processViewHierarchyCallback: (() -> Void)? + var saveFilePathUsed: String? override func fetch() -> Data? { guard let result = self.result @@ -15,6 +16,11 @@ class TestSentryViewHierarchy: SentryViewHierarchy { return result } + override func save(_ filePath: String) -> Bool { + saveFilePathUsed = filePath + return true + } + override func viewHierarchy(from view: UIView!, into context: UnsafeMutablePointer!) -> Int32 { return viewHierarchyResult != 0 ? viewHierarchyResult : super.viewHierarchy(from: view, into: context) } From 9e96fd678a889469e645130bf769d9a6558a6095 Mon Sep 17 00:00:00 2001 From: Andrew McKnight Date: Wed, 22 Mar 2023 10:41:49 -0800 Subject: [PATCH 19/25] fix: typo Existense->Existence (#2822) --- Samples/iOS-Swift/iOS-SwiftUITests/LaunchUITests.swift | 6 +++--- Samples/iOS-Swift/iOS13-SwiftTests/LaunchUITest.swift | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Samples/iOS-Swift/iOS-SwiftUITests/LaunchUITests.swift b/Samples/iOS-Swift/iOS-SwiftUITests/LaunchUITests.swift index f2f3360e78..5a3a78c4ba 100644 --- a/Samples/iOS-Swift/iOS-SwiftUITests/LaunchUITests.swift +++ b/Samples/iOS-Swift/iOS-SwiftUITests/LaunchUITests.swift @@ -11,7 +11,7 @@ class LaunchUITests: XCTestCase { XCUIDevice.shared.orientation = .portrait app.launch() - waitForExistenseOfMainScreen() + waitForExistenceOfMainScreen() checkSlowAndFrozenFrames() } @@ -31,7 +31,7 @@ class LaunchUITests: XCTestCase { } app.launch() - waitForExistenseOfMainScreen() + waitForExistenceOfMainScreen() } } @@ -88,7 +88,7 @@ class LaunchUITests: XCTestCase { } } - private func waitForExistenseOfMainScreen() { + private func waitForExistenceOfMainScreen() { app.buttons["captureMessageButton"].waitForExistence( "Home Screen doesn't exist.") } diff --git a/Samples/iOS-Swift/iOS13-SwiftTests/LaunchUITest.swift b/Samples/iOS-Swift/iOS13-SwiftTests/LaunchUITest.swift index 02446f6fea..7eb93026a9 100644 --- a/Samples/iOS-Swift/iOS13-SwiftTests/LaunchUITest.swift +++ b/Samples/iOS-Swift/iOS13-SwiftTests/LaunchUITest.swift @@ -12,7 +12,7 @@ class LaunchUITests: XCTestCase { app.launch() XCUIDevice.shared.orientation = .portrait - waitForExistenseOfMainScreen() + waitForExistenceOfMainScreen() } override func tearDownWithError() throws { @@ -25,7 +25,7 @@ class LaunchUITests: XCTestCase { XCTAssertTrue(app.staticTexts["SwiftUI!"].waitForExistence(timeout: timeout), "SwiftUI not loaded.") } - private func waitForExistenseOfMainScreen() { + private func waitForExistenceOfMainScreen() { XCTAssertTrue(app.buttons["captureMessage"].waitForExistence(timeout: timeout), "Home Screen doesn't exist.") } } From 9d5623218051d36e447a50515fad0f0252e48d65 Mon Sep 17 00:00:00 2001 From: Andrew McKnight Date: Wed, 22 Mar 2023 16:18:10 -0800 Subject: [PATCH 20/25] docs: call out beta status for all public-facing profiling APIs (#2804) --- Sources/Sentry/Public/SentryOptions.h | 24 ++++++++++++-------- Sources/SentrySwiftUI/SentryTracedView.swift | 7 ++---- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/Sources/Sentry/Public/SentryOptions.h b/Sources/Sentry/Public/SentryOptions.h index 782609f45b..9adbf50308 100644 --- a/Sources/Sentry/Public/SentryOptions.h +++ b/Sources/Sentry/Public/SentryOptions.h @@ -160,8 +160,8 @@ NS_SWIFT_NAME(Options) @property (nonatomic, assign) BOOL attachStacktrace; /** - * Attention: This is an experimental feature. Turning this feature on can have an impact on - * the grouping of your issues. + * @warning This is an experimental feature and may still have bugs. Turning this feature on can + * have an impact on the grouping of your issues. * * When enabled, the SDK stitches stack traces of asynchronous code together. * @@ -213,7 +213,7 @@ NS_SWIFT_NAME(Options) @property (nonatomic, assign) BOOL attachScreenshot; /** - * This feature is EXPERIMENTAL. + * @warning This is an experimental feature and may still have bugs. * * Automatically attaches a textual representation of the view hierarchy when capturing an error * event. @@ -235,7 +235,7 @@ NS_SWIFT_NAME(Options) @property (nonatomic, assign) NSTimeInterval idleTimeout; /** - * This feature is EXPERIMENTAL. + * @warning This is an experimental feature and may still have bugs. * * Report pre-warmed app starts by dropping the first app start spans if pre-warming paused during * these steps. This approach will shorten the app start duration, but it represents the duration a @@ -349,7 +349,8 @@ NS_SWIFT_NAME(Options) #if SENTRY_TARGET_PROFILING_SUPPORTED /** - * This feature is experimental. Profiling is not supported on watchOS or tvOS. + * @warning This is a beta feature and may still have bugs. + * @note Profiling is not supported on watchOS or tvOS. * * Indicates the percentage profiles being sampled out of the sampled transactions. * @@ -363,7 +364,8 @@ NS_SWIFT_NAME(Options) @property (nullable, nonatomic, strong) NSNumber *profilesSampleRate; /** - * This feature is experimental. Profiling is not supported on watchOS or tvOS. + * @warning This is a beta feature and may still have bugs. + * @note Profiling is not supported on watchOS or tvOS. * * A callback to a user defined profiles sampler function. This is similar to setting * `profilesSampleRate`, but instead of a static value, the callback function will be called to @@ -372,6 +374,9 @@ NS_SWIFT_NAME(Options) @property (nullable, nonatomic) SentryTracesSamplerCallback profilesSampler; /** + * @warning This is a beta feature and may still have bugs. + * @note Profiling is not supported on watchOS or tvOS. + * * If profiling should be enabled or not. Returns YES if either a profilesSampleRate > 0 and * <=1 or a profilesSampler is set otherwise NO. */ @@ -380,11 +385,12 @@ NS_SWIFT_NAME(Options) /** * DEPRECATED: Use `profilesSampleRate` instead. Setting `enableProfiling` to YES is the equivalent * of setting `profilesSampleRate` to `1.0`. If `profilesSampleRate` is set, it will take precedence + * @warning This is a beta feature and may still have bugs. + * @note Profiling is not supported on watchOS or tvOS. + * * over this setting. * * Whether to enable the sampling profiler. Default is NO. - * @note This is a beta feature that is currently not available to all Sentry customers. This - * feature is not supported on watchOS or tvOS. */ @property (nonatomic, assign) BOOL enableProfiling DEPRECATED_MSG_ATTRIBUTE( "Use profilesSampleRate or profilesSampler instead. This property will be removed in a future " @@ -460,7 +466,7 @@ NS_SWIFT_NAME(Options) #if SENTRY_HAS_METRIC_KIT /** - * ATTENTION: This is an experimental feature. + * @warning This is an experimental feature and may still have bugs. * * This feature is disabled by default. When enabled, the SDK sends * ``MXDiskWriteExceptionDiagnostic``, ``MXCPUExceptionDiagnostic`` and ``MXHangDiagnostic`` to diff --git a/Sources/SentrySwiftUI/SentryTracedView.swift b/Sources/SentrySwiftUI/SentryTracedView.swift index 36ca4afc72..f1a791a563 100644 --- a/Sources/SentrySwiftUI/SentryTracedView.swift +++ b/Sources/SentrySwiftUI/SentryTracedView.swift @@ -5,8 +5,7 @@ import SwiftUI import SentryInternal #endif -/// -/// This feature is EXPERIMENTAL. +/// - warning: This is an experimental feature and may still have bugs. /// /// A control to measure the performance of your views and send the result as a transaction to Sentry.io. /// @@ -93,11 +92,9 @@ public struct SentryTracedView: View { } } -/// -/// This feature is EXPERIMENTAL. -/// @available(iOS 13, macOS 10.15, tvOS 13, watchOS 6.0, *) public extension View { + /// - warning: This is an experimental feature and may still have bugs. func sentryTrace(_ viewName: String? = nil) -> some View { return SentryTracedView(viewName) { return self From 6472ce5533a1b3c6de38035d0266b3e5991ef02d Mon Sep 17 00:00:00 2001 From: Andrew McKnight Date: Thu, 23 Mar 2023 13:19:42 -0800 Subject: [PATCH 21/25] test: fix raw log output ids for ui tests (#2826) --- .github/workflows/test.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index e9ba8a42fc..eadba7c2c9 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -287,7 +287,7 @@ jobs: uses: actions/upload-artifact@v3 if: ${{ failure() || cancelled() }} with: - name: raw-test-output-${{matrix.platform}}-xcode-${{matrix.xcode}}-os-${{matrix.test-destination-os}} + name: raw-uitest-output-${{matrix.target}} path: | ~/Library/Logs/scan/*.log ./fastlane/test_output/** @@ -353,7 +353,7 @@ jobs: uses: actions/upload-artifact@v3 if: ${{ failure() || cancelled() }} with: - name: raw-test-output-${{matrix.platform}}-xcode-${{matrix.xcode}}-os-${{matrix.test-destination-os}} + name: raw-uitest-output-${{matrix.target}}-ios-12 path: | ~/Library/Logs/scan/*.log ./fastlane/test_output/** @@ -375,7 +375,7 @@ jobs: uses: actions/upload-artifact@v3 if: ${{ failure() || cancelled() }} with: - name: raw-test-output-${{matrix.platform}}-xcode-${{matrix.xcode}}-os-${{matrix.test-destination-os}} + name: raw-uitest-output-asan path: | ~/Library/Logs/scan/*.log ./fastlane/test_output/** From fb53d975c2f35e1292f42c3c96eb77349d3cffeb Mon Sep 17 00:00:00 2001 From: Andrew McKnight Date: Thu, 23 Mar 2023 13:25:07 -0800 Subject: [PATCH 22/25] docs: clean up headerdocs (#2829) --- Sources/Sentry/Public/SentryAttachment.h | 24 +- Sources/Sentry/Public/SentryBreadcrumb.h | 6 +- Sources/Sentry/Public/SentryClient.h | 41 +- .../Sentry/Public/SentryDebugImageProvider.h | 9 +- Sources/Sentry/Public/SentryDebugMeta.h | 18 +- Sources/Sentry/Public/SentryDefines.h | 19 +- Sources/Sentry/Public/SentryEvent.h | 58 +- Sources/Sentry/Public/SentryException.h | 2 +- .../Sentry/Public/SentryHttpStatusCodeRange.h | 18 +- Sources/Sentry/Public/SentryHub.h | 56 +- Sources/Sentry/Public/SentryId.h | 13 +- Sources/Sentry/Public/SentryMeasurementUnit.h | 123 ++-- Sources/Sentry/Public/SentryMechanism.h | 2 +- Sources/Sentry/Public/SentryMechanismMeta.h | 5 +- Sources/Sentry/Public/SentryMessage.h | 6 +- Sources/Sentry/Public/SentryNSError.h | 13 +- Sources/Sentry/Public/SentryOptions.h | 310 +++++------ Sources/Sentry/Public/SentrySDK.h | 73 +-- Sources/Sentry/Public/SentrySamplingContext.h | 2 - Sources/Sentry/Public/SentryScope.h | 14 +- Sources/Sentry/Public/SentrySpanContext.h | 27 +- Sources/Sentry/Public/SentrySpanProtocol.h | 12 +- Sources/Sentry/Public/SentryTraceHeader.h | 4 - .../Sentry/Public/SentryTransactionContext.h | 12 - Sources/Sentry/Public/SentryUserFeedback.h | 1 - Sources/Sentry/SentryAppStateManager.m | 7 +- Sources/Sentry/SentryCrashReportConverter.m | 31 +- Sources/Sentry/SentryDevice.mm | 2 +- Sources/Sentry/SentryHttpTransport.m | 2 +- Sources/Sentry/SentryHub.m | 6 +- Sources/Sentry/SentryMetricKitIntegration.m | 7 +- Sources/Sentry/SentryNSURLSessionTaskSearch.m | 18 +- Sources/Sentry/SentryOptions.m | 12 +- Sources/Sentry/SentryReachability.m | 5 +- Sources/Sentry/SentrySDK.m | 2 +- Sources/Sentry/SentrySessionTracker.m | 21 +- Sources/Sentry/SentryStacktrace.m | 6 +- Sources/Sentry/SentrySysctl.m | 9 +- Sources/Sentry/SentryTracer.m | 8 +- ...SentryUIViewControllerPerformanceTracker.m | 7 +- .../Sentry/SentryUIViewControllerSwizzling.m | 23 +- .../HybridPublic/PrivateSentrySDKOnly.h | 27 +- .../include/HybridPublic/SentryEnvelope.h | 43 +- Sources/Sentry/include/SentryANRTracker.h | 17 +- Sources/Sentry/include/SentryAppState.h | 8 +- .../Sentry/include/SentryAppStateManager.h | 9 +- .../Sentry/include/SentryAttachment+Private.h | 10 +- Sources/Sentry/include/SentryCPU.h | 2 +- Sources/Sentry/include/SentryCompiler.h | 2 +- .../include/SentryCrashReportConverter.h | 3 +- .../Sentry/include/SentryCrashScopeObserver.h | 21 +- .../include/SentryCrashStackEntryMapper.h | 8 +- Sources/Sentry/include/SentryFileManager.h | 7 +- Sources/Sentry/include/SentryFrameRemover.h | 11 +- Sources/Sentry/include/SentryInAppLogic.h | 55 +- Sources/Sentry/include/SentryLog.h | 10 +- Sources/Sentry/include/SentryMetricProfiler.h | 9 +- .../Sentry/include/SentryMigrateSessionInit.h | 17 +- .../SentryNSNotificationCenterWrapper.h | 12 +- .../Sentry/include/SentryPerformanceTracker.h | 42 +- .../SentryPerformanceTrackingIntegration.h | 6 +- Sources/Sentry/include/SentryProfiler.h | 36 +- Sources/Sentry/include/SentryRateLimits.h | 22 +- Sources/Sentry/include/SentryReachability.h | 14 +- Sources/Sentry/include/SentryScreenshot.h | 3 +- Sources/Sentry/include/SentrySdkInfo.h | 15 +- Sources/Sentry/include/SentrySession.h | 10 +- Sources/Sentry/include/SentrySpan.h | 10 +- Sources/Sentry/include/SentrySubClassFinder.h | 5 +- Sources/Sentry/include/SentrySwizzle.h | 527 +++++++++--------- Sources/Sentry/include/SentrySystemWrapper.h | 4 +- Sources/Sentry/include/SentryTime.h | 4 +- Sources/Sentry/include/SentryTracer.h | 34 +- ...SentryUIViewControllerPerformanceTracker.h | 60 +- scripts/no-changes-in-high-risk-files.sh | 4 +- 75 files changed, 968 insertions(+), 1133 deletions(-) diff --git a/Sources/Sentry/Public/SentryAttachment.h b/Sources/Sentry/Public/SentryAttachment.h index b9217094dc..2f3e2253e2 100644 --- a/Sources/Sentry/Public/SentryAttachment.h +++ b/Sources/Sentry/Public/SentryAttachment.h @@ -11,8 +11,7 @@ NS_SWIFT_NAME(Attachment) SENTRY_NO_INIT /** - * Initializes an attachment with data. Sets the content type to "application/octet-stream". - * + * Initializes an attachment with data. Sets the content type to @c "application/octet-stream". * @param data The data for the attachment. * @param filename The name of the attachment to display in Sentry. */ @@ -20,32 +19,27 @@ SENTRY_NO_INIT /** * Initializes an attachment with data. - * * @param data The data for the attachment. * @param filename The name of the attachment to display in Sentry. - * @param contentType The content type of the attachment. Default is "application/octet-stream". + * @param contentType The content type of the attachment. @c Default is "application/octet-stream". */ - (instancetype)initWithData:(NSData *)data filename:(NSString *)filename contentType:(nullable NSString *)contentType; /** - * Initializes an attachment with a path. Uses the last path compontent of the path as a filename - * and sets the content type to "application/octet-stream". - * + * Initializes an attachment with a path. Uses the last path component of the path as a filename + * and sets the content type to @c "application/octet-stream". * @discussion The file located at the pathname is read lazily when the SDK captures an event or * transaction not when the attachment is initialized. - * * @param path The path of the file whose contents you want to upload to Sentry. */ - (instancetype)initWithPath:(NSString *)path; /** - * Initializes an attachment with a path. Sets the content type to "application/octet-stream". - * - * @discussion The file located at the pathname is read lazily when the SDK captures an event or + * Initializes an attachment with a path. Sets the content type to @c "application/octet-stream". + * @discussion The specified file is read lazily when the SDK captures an event or * transaction not when the attachment is initialized. - * * @param path The path of the file whose contents you want to upload to Sentry. * @param filename The name of the attachment to display in Sentry. */ @@ -53,13 +47,11 @@ SENTRY_NO_INIT /** * Initializes an attachment with a path. - * - * @discussion The file located at the pathname is read lazily when the SDK captures an event or + * @discussion The specifid file is read lazily when the SDK captures an event or * transaction not when the attachment is initialized. - * * @param path The path of the file whose contents you want to upload to Sentry. * @param filename The name of the attachment to display in Sentry. - * @param contentType The content type of the attachment. Default is "application/octet-stream". + * @param contentType The content type of the attachment. Default is @c "application/octet-stream". */ - (instancetype)initWithPath:(NSString *)path filename:(NSString *)filename diff --git a/Sources/Sentry/Public/SentryBreadcrumb.h b/Sources/Sentry/Public/SentryBreadcrumb.h index 0fa5034f61..d6a10b8ca7 100644 --- a/Sources/Sentry/Public/SentryBreadcrumb.h +++ b/Sources/Sentry/Public/SentryBreadcrumb.h @@ -19,7 +19,7 @@ NS_SWIFT_NAME(Breadcrumb) @property (nonatomic, copy) NSString *category; /** - * NSDate when the breadcrumb happened + * @c NSDate when the breadcrumb happened */ @property (nonatomic, strong) NSDate *_Nullable timestamp; @@ -40,11 +40,9 @@ NS_SWIFT_NAME(Breadcrumb) @property (nonatomic, strong) NSDictionary *_Nullable data; /** - * Initializer for SentryBreadcrumb - * + * Initializer for @c SentryBreadcrumb * @param level SentryLevel * @param category String - * @return SentryBreadcrumb */ - (instancetype)initWithLevel:(SentryLevel)level category:(NSString *)category; - (instancetype)init; diff --git a/Sources/Sentry/Public/SentryClient.h b/Sources/Sentry/Public/SentryClient.h index 6584591a10..facf674f3e 100644 --- a/Sources/Sentry/Public/SentryClient.h +++ b/Sources/Sentry/Public/SentryClient.h @@ -13,96 +13,78 @@ SENTRY_NO_INIT @property (nonatomic, strong) SentryOptions *options; /** - * Initializes a SentryClient. Pass in an dictionary of options. - * + * Initializes a @c SentryClient. Pass in a dictionary of options. * @param options Options dictionary - * @return SentryClient + * @return An initialized @c SentryClient or @c nil if an error occurred. */ - (_Nullable instancetype)initWithOptions:(SentryOptions *)options; /** * Captures a manually created event and sends it to Sentry. - * * @param event The event to send to Sentry. - * - * @return The SentryId of the event or SentryId.empty if the event is not sent. + * @return The @c SentryId of the event or @c SentryId.empty if the event is not sent. */ - (SentryId *)captureEvent:(SentryEvent *)event NS_SWIFT_NAME(capture(event:)); /** * Captures a manually created event and sends it to Sentry. - * * @param event The event to send to Sentry. * @param scope The scope containing event metadata. - * - * @return The SentryId of the event or SentryId.empty if the event is not sent. + * @return The @c SentryId of the event or @c SentryId.empty if the event is not sent. */ - (SentryId *)captureEvent:(SentryEvent *)event withScope:(SentryScope *)scope NS_SWIFT_NAME(capture(event:scope:)); /** * Captures an error event and sends it to Sentry. - * * @param error The error to send to Sentry. - * - * @return The SentryId of the event or SentryId.empty if the event is not sent. + * @return The @c SentryId of the event or @c SentryId.empty if the event is not sent. */ - (SentryId *)captureError:(NSError *)error NS_SWIFT_NAME(capture(error:)); /** * Captures an error event and sends it to Sentry. - * * @param error The error to send to Sentry. * @param scope The scope containing event metadata. - * - * @return The SentryId of the event or SentryId.empty if the event is not sent. + * @return The @c SentryId of the event or @c SentryId.empty if the event is not sent. */ - (SentryId *)captureError:(NSError *)error withScope:(SentryScope *)scope NS_SWIFT_NAME(capture(error:scope:)); /** * Captures an exception event and sends it to Sentry. - * * @param exception The exception to send to Sentry. - * - * @return The SentryId of the event or SentryId.empty if the event is not sent. + * @return The @c SentryId of the event or @c SentryId.empty if the event is not sent. */ - (SentryId *)captureException:(NSException *)exception NS_SWIFT_NAME(capture(exception:)); /** * Captures an exception event and sends it to Sentry. - * * @param exception The exception to send to Sentry. * @param scope The scope containing event metadata. - * - * @return The SentryId of the event or SentryId.empty if the event is not sent. + * @return The @c SentryId of the event or @c SentryId.empty if the event is not sent. */ - (SentryId *)captureException:(NSException *)exception withScope:(SentryScope *)scope NS_SWIFT_NAME(capture(exception:scope:)); /** * Captures a message event and sends it to Sentry. - * * @param message The message to send to Sentry. - * - * @return The SentryId of the event or SentryId.empty if the event is not sent. + * @return The @c SentryId of the event or @c SentryId.empty if the event is not sent. */ - (SentryId *)captureMessage:(NSString *)message NS_SWIFT_NAME(capture(message:)); /** * Captures a message event and sends it to Sentry. - * * @param message The message to send to Sentry. * @param scope The scope containing event metadata. - * - * @return The SentryId of the event or SentryId.empty if the event is not sent. + * @return The @c SentryId of the event or @c SentryId.empty if the event is not sent. */ - (SentryId *)captureMessage:(NSString *)message withScope:(SentryScope *)scope NS_SWIFT_NAME(capture(message:scope:)); /** * Captures a manually created user feedback and sends it to Sentry. - * * @param userFeedback The user feedback to send to Sentry. */ - (void)captureUserFeedback:(SentryUserFeedback *)userFeedback @@ -112,13 +94,12 @@ SENTRY_NO_INIT * Waits synchronously for the SDK to flush out all queued and cached items for up to the specified * timeout in seconds. If there is no internet connection, the function returns immediately. The SDK * doesn't dispose the client or the hub. - * * @param timeout The time to wait for the SDK to complete the flush. */ - (void)flush:(NSTimeInterval)timeout NS_SWIFT_NAME(flush(timeout:)); /** - * Disables the client and calls flush with ``SentryOptions/shutdownTimeInterval``. + * Disables the client and calls flush with @c SentryOptions.shutdownTimeInterval . */ - (void)close; diff --git a/Sources/Sentry/Public/SentryDebugImageProvider.h b/Sources/Sentry/Public/SentryDebugImageProvider.h index 5f2b9aba8b..9a4c27a7fe 100644 --- a/Sources/Sentry/Public/SentryDebugImageProvider.h +++ b/Sources/Sentry/Public/SentryDebugImageProvider.h @@ -14,21 +14,20 @@ NS_ASSUME_NONNULL_BEGIN /** * Returns a list of debug images that are being referenced in the given threads. - * - * @param threads A list of SentryThread that may or may not contains a stacktrace. + * @param threads A list of @c SentryThread that may or may not contain stacktracse. */ - (NSArray *)getDebugImagesForThreads:(NSArray *)threads; /** * Returns a list of debug images that are being referenced by the given frames. - * * @param frames A list of stack frames. */ - (NSArray *)getDebugImagesForFrames:(NSArray *)frames; /** - * Returns the current list of debug images. Be aware that the SentryDebugMeta is actually - * describing a debug image. This class should be renamed to SentryDebugImage in a future version. + * Returns the current list of debug images. Be aware that the @c SentryDebugMeta is actually + * describing a debug image. + * @todo This class should be renamed to @c SentryDebugImage in a future version. */ - (NSArray *)getDebugImages; diff --git a/Sources/Sentry/Public/SentryDebugMeta.h b/Sources/Sentry/Public/SentryDebugMeta.h index b846850cbd..b00133b26a 100644 --- a/Sources/Sentry/Public/SentryDebugMeta.h +++ b/Sources/Sentry/Public/SentryDebugMeta.h @@ -5,27 +5,25 @@ NS_ASSUME_NONNULL_BEGIN /** - * This class is actually a DebugImage: - * https://develop.sentry.dev/sdk/event-payloads/debugmeta/#debug-images and should be renamed to - * SentryDebugImage in a future version. - * * Contains information about a loaded library in the process and the memory address. - * * @discussion Since 8.2.0, the SDK changed the debug image type from "apple" to "macho". For macho, - * the SDK now sends ``debugID`` instead of ``uuid``, and ``codeFile`` instead of ``name``. For more + * the SDK now sends @c debugID instead of @c uuid , and @c codeFile instead of @c name . For more * information check https://develop.sentry.dev/sdk/event-payloads/debugmeta/#mach-o-images. + * @todo This class is actually a DebugImage: + * https://develop.sentry.dev/sdk/event-payloads/debugmeta/#debug-images and should be renamed to + * @c SentryDebugImage in a future version. */ NS_SWIFT_NAME(DebugMeta) @interface SentryDebugMeta : NSObject /** - * The UUID of the image. Use ``debugID`` when using ``type`` "macho". + * The UUID of the image. Use @c debugID when using "macho" as the @c type . */ @property (nonatomic, copy) NSString *_Nullable uuid; /** - * Identifier of the dynamic library or executable. It is the value of the LC_UUID load command in - * the Mach header, formatted as UUID. + * Identifier of the dynamic library or executable. It is the value of the @c LC_UUID load command + * in the Mach header, formatted as UUID. */ @property (nonatomic, copy) NSString *_Nullable debugID; @@ -35,7 +33,7 @@ NS_SWIFT_NAME(DebugMeta) @property (nonatomic, copy) NSString *_Nullable type; /** - * Name of the image. Use ``codeFile`` when using ``type`` "macho". + * Name of the image. Use @c codeFile when using "macho" as the @c type . */ @property (nonatomic, copy) NSString *_Nullable name; diff --git a/Sources/Sentry/Public/SentryDefines.h b/Sources/Sentry/Public/SentryDefines.h index ec8e709c39..2253a719bf 100644 --- a/Sources/Sentry/Public/SentryDefines.h +++ b/Sources/Sentry/Public/SentryDefines.h @@ -37,14 +37,14 @@ typedef void (^SentryRequestFinished)(NSError *_Nullable error); /** - * Block used for request operation finished, shouldDiscardEvent is YES if event + * Block used for request operation finished, @c shouldDiscardEvent is @c YES if event * should be deleted regardless if an error occurred or not */ typedef void (^SentryRequestOperationFinished)( NSHTTPURLResponse *_Nullable response, NSError *_Nullable error); /** * Block can be used to mutate a breadcrumb before it's added to the scope. - * To avoid adding the breadcrumb altogether, return nil instead. + * To avoid adding the breadcrumb altogether, return @c nil instead. */ typedef SentryBreadcrumb *_Nullable (^SentryBeforeBreadcrumbCallback)( SentryBreadcrumb *_Nonnull breadcrumb); @@ -71,24 +71,21 @@ typedef BOOL (^SentryShouldQueueEvent)( /** * Function pointer for a sampler callback. - * * @param samplingContext context of the sampling. - * - * @return A sample rate that is >= 0.0 and <= 1.0 or NIL if no sampling decision has been taken.. - * When returning a value out of range the SDK uses the default of 0. + * @return A sample rate that is >= @c 0.0 and \<= @c 1.0 or @c nil if no sampling decision has + * been taken. When returning a value out of range the SDK uses the default of @c 0. */ typedef NSNumber *_Nullable (^SentryTracesSamplerCallback)( SentrySamplingContext *_Nonnull samplingContext); /** * Function pointer for span manipulation. - * * @param span The span to be used. */ typedef void (^SentrySpanCallback)(id _Nullable span); /** - * Loglevel + * Log level. */ typedef NS_ENUM(NSInteger, SentryLogLevel) { kSentryLogLevelNone = 1, @@ -98,7 +95,7 @@ typedef NS_ENUM(NSInteger, SentryLogLevel) { }; /** - * Sentry level + * Sentry level. */ typedef NS_ENUM(NSUInteger, SentryLevel) { // Defaults to None which doesn't get serialized @@ -112,7 +109,7 @@ typedef NS_ENUM(NSUInteger, SentryLevel) { }; /** - * Static internal helper to convert enum to string + * Static internal helper to convert enum to string. */ static DEPRECATED_MSG_ATTRIBUTE( "Use nameForSentryLevel() instead.") NSString *_Nonnull const SentryLevelNames[] @@ -128,7 +125,7 @@ static DEPRECATED_MSG_ATTRIBUTE( static NSUInteger const defaultMaxBreadcrumbs = 100; /** - * Transaction name source + * Transaction name source. */ typedef NS_ENUM(NSInteger, SentryTransactionNameSource) { kSentryTransactionNameSourceCustom = 0, diff --git a/Sources/Sentry/Public/SentryEvent.h b/Sources/Sentry/Public/SentryEvent.h index 364f9d2629..56d2e00a8d 100644 --- a/Sources/Sentry/Public/SentryEvent.h +++ b/Sources/Sentry/Public/SentryEvent.h @@ -23,55 +23,55 @@ NS_SWIFT_NAME(Event) /** * The error of the event. This property adds convenience to access the error directly in - * beforeSend. This property is not serialized. Instead when preparing the event the SentryClient - * puts the error into exceptions. + * @c beforeSend. This property is not serialized. Instead when preparing the event the + * @c SentryClient puts the error into exceptions. */ @property (nonatomic, copy) NSError *_Nullable error; /** - * NSDate of when the event occurred + * @c NSDate of when the event occurred. */ @property (nonatomic, strong) NSDate *_Nullable timestamp; /** - * NSDate of when the event started, mostly useful if event type transaction + * @c NSDate of when the event started, mostly useful if event type transaction. */ @property (nonatomic, strong) NSDate *_Nullable startTimestamp; /** - * SentryLevel of the event + * @c SentryLevel of the event. */ @property (nonatomic) enum SentryLevel level; /** - * Platform this will be used for symbolicating on the server should be "cocoa" + * This will be used for symbolicating on the server should be "cocoa". */ @property (nonatomic, copy) NSString *platform; /** - * Define the logger name + * Define the logger name. */ @property (nonatomic, copy) NSString *_Nullable logger; /** - * Define the server name + * Define the server name. */ @property (nonatomic, copy) NSString *_Nullable serverName; /** - * This property will be filled before the event is sent. + * @note This property will be filled before the event is sent. * @warning This is maintained automatically, and shouldn't normally need to be modified. */ @property (nonatomic, copy) NSString *_Nullable releaseName; /** - * This property will be filled before the event is sent. + * @note This property will be filled before the event is sent. * @warning This is maintained automatically, and shouldn't normally need to be modified. */ @property (nonatomic, copy) NSString *_Nullable dist; /** - * The environment used for this event + * The environment used for this event. */ @property (nonatomic, copy) NSString *_Nullable environment; @@ -81,17 +81,17 @@ NS_SWIFT_NAME(Event) @property (nonatomic, copy) NSString *_Nullable transaction; /** - * The type of the event, null, default or transaction + * The type of the event, null, default or transaction. */ @property (nonatomic, copy) NSString *_Nullable type; /** - * Arbitrary key:value (string:string ) data that will be shown with the event + * Arbitrary key:value (string:string ) data that will be shown with the event. */ @property (nonatomic, strong) NSDictionary *_Nullable tags; /** - * Arbitrary additional information that will be sent with the event + * Arbitrary additional information that will be sent with the event. */ @property (nonatomic, strong) NSDictionary *_Nullable extra; @@ -111,7 +111,7 @@ NS_SWIFT_NAME(Event) @property (nonatomic, strong) NSDictionary *_Nullable sdk; /** - * Modules of the event + * Modules of the event. */ @property (nonatomic, strong) NSDictionary *_Nullable modules; @@ -121,7 +121,7 @@ NS_SWIFT_NAME(Event) @property (nonatomic, strong) NSArray *_Nullable fingerprint; /** - * Set the SentryUser for the event + * Set the @c SentryUser for the event. */ @property (nonatomic, strong) SentryUser *_Nullable user; @@ -133,56 +133,50 @@ NS_SWIFT_NAME(Event) NSDictionary *> *_Nullable context; /** - * Contains SentryThread if an crash occurred of it's an user reported exception + * Contains @c SentryThread if a crash occurred or for a user reported exception. */ @property (nonatomic, strong) NSArray *_Nullable threads; /** - * General information about the SentryException, usually there is only one - * exception in the array + * General information about the @c SentryException, usually there is only one + * exception in the array. */ @property (nonatomic, strong) NSArray *_Nullable exceptions; /** - * Separate SentryStacktrace that can be sent with the event, besides threads + * Separate @c SentryStacktrace that can be sent with the event, besides threads. */ @property (nonatomic, strong) SentryStacktrace *_Nullable stacktrace; /** - * Containing images loaded during runtime + * Containing images loaded during runtime. */ @property (nonatomic, strong) NSArray *_Nullable debugMeta; /** * This contains all breadcrumbs available at the time when the event - * occurred/will be sent + * occurred/will be sent. */ @property (nonatomic, strong) NSArray *_Nullable breadcrumbs; /** - * Set the Http request information. + * Set the HTTP request information. */ @property (nonatomic, strong, nullable) SentryRequest *request; /** - * Init an SentryEvent will set all needed fields by default - * @return SentryEvent + * Init an @c SentryEvent will set all needed fields by default. */ - (instancetype)init; /** - * Init an SentryEvent will set all needed fields by default - * @param level SentryLevel - * @return SentryEvent + * Init a @c SentryEvent with a @c SentryLevelError and set all needed fields by default. */ - (instancetype)initWithLevel:(enum SentryLevel)level NS_DESIGNATED_INITIALIZER; /** - * Initializes a SentryEvent with an NSError and sets the level to SentryLevelError. - * + * Initializes a @c SentryEvent with an @c NSError and sets the level to @c SentryLevelError. * @param error The error of the event. - * - * @return The initialized SentryEvent. */ - (instancetype)initWithError:(NSError *)error; diff --git a/Sources/Sentry/Public/SentryException.h b/Sources/Sentry/Public/SentryException.h index 37eac9d846..344566a90b 100644 --- a/Sources/Sentry/Public/SentryException.h +++ b/Sources/Sentry/Public/SentryException.h @@ -32,7 +32,7 @@ SENTRY_NO_INIT @property (nonatomic, copy) NSString *_Nullable module; /** - * An optional value which refers to a thread in `SentryEvent.threads`. + * An optional value which refers to a thread in @c SentryEvent.threads */ @property (nonatomic, copy) NSNumber *_Nullable threadId; diff --git a/Sources/Sentry/Public/SentryHttpStatusCodeRange.h b/Sources/Sentry/Public/SentryHttpStatusCodeRange.h index 38e6f53457..ce50f0bb98 100644 --- a/Sources/Sentry/Public/SentryHttpStatusCodeRange.h +++ b/Sources/Sentry/Public/SentryHttpStatusCodeRange.h @@ -3,11 +3,7 @@ NS_ASSUME_NONNULL_BEGIN /** - * The Http status code range. - * The range is inclusive so the min and max is considered part of the range. - * - * Example for a range: 400 to 499, 500 to 599, 400 to 599. - * Example for a single status code 400, 500. + * An HTTP status code range. */ NS_SWIFT_NAME(HttpStatusCodeRange) @interface SentryHttpStatusCodeRange : NSObject @@ -18,17 +14,15 @@ SENTRY_NO_INIT @property (nonatomic, readonly) NSInteger max; /** - * The Http status code min and max. - * The range is inclusive so the min and max is considered part of the range. - * - * Example for a range: 400 to 499, 500 to 599, 400 to 599. + * The HTTP status code min and max. + * @discussion The range is inclusive so the min and max is considered part of the range. + * @example For a range: 400 to 499; 500 to 599; 400 to 599. */ - (instancetype)initWithMin:(NSInteger)min max:(NSInteger)max; /** - * The Http status code. - * - * Example for a single status code 400, 500. + * The HTTP status code. + * @example For a single status code: 400; 500. */ - (instancetype)initWithStatusCode:(NSInteger)statusCode; diff --git a/Sources/Sentry/Public/SentryHub.h b/Sources/Sentry/Public/SentryHub.h index 02d4e2dd88..caf5fc5bbb 100644 --- a/Sources/Sentry/Public/SentryHub.h +++ b/Sources/Sentry/Public/SentryHub.h @@ -28,26 +28,21 @@ SENTRY_NO_INIT /** * Ends the current session with the given timestamp. - * * @param timestamp The timestamp to end the session with. */ - (void)endSessionWithTimestamp:(NSDate *)timestamp; /** * Captures a manually created event and sends it to Sentry. - * * @param event The event to send to Sentry. - * * @return The SentryId of the event or SentryId.empty if the event is not sent. */ - (SentryId *)captureEvent:(SentryEvent *)event NS_SWIFT_NAME(capture(event:)); /** * Captures a manually created event and sends it to Sentry. - * * @param event The event to send to Sentry. * @param scope The scope containing event metadata. - * * @return The SentryId of the event or SentryId.empty if the event is not sent. */ - (SentryId *)captureEvent:(SentryEvent *)event @@ -55,10 +50,8 @@ SENTRY_NO_INIT /** * Creates a transaction, binds it to the hub and returns the instance. - * * @param name The transaction name. * @param operation Short code identifying the type of operation the span is measuring. - * * @return The created transaction. */ - (id)startTransactionWithName:(NSString *)name @@ -67,11 +60,9 @@ SENTRY_NO_INIT /** * Creates a transaction, binds it to the hub and returns the instance. - * * @param name The transaction name. * @param operation Short code identifying the type of operation the span is measuring. * @param bindToScope Indicates whether the SDK should bind the new transaction to the scope. - * * @return The created transaction. */ - (id)startTransactionWithName:(NSString *)name @@ -81,9 +72,7 @@ SENTRY_NO_INIT /** * Creates a transaction, binds it to the hub and returns the instance. - * * @param transactionContext The transaction context. - * * @return The created transaction. */ - (id)startTransactionWithContext:(SentryTransactionContext *)transactionContext @@ -91,10 +80,8 @@ SENTRY_NO_INIT /** * Creates a transaction, binds it to the hub and returns the instance. - * * @param transactionContext The transaction context. * @param bindToScope Indicates whether the SDK should bind the new transaction to the scope. - * * @return The created transaction. */ - (id)startTransactionWithContext:(SentryTransactionContext *)transactionContext @@ -103,11 +90,9 @@ SENTRY_NO_INIT /** * Creates a transaction, binds it to the hub and returns the instance. - * * @param transactionContext The transaction context. * @param bindToScope Indicates whether the SDK should bind the new transaction to the scope. * @param customSamplingContext Additional information about the sampling context. - * * @return The created transaction. */ - (id)startTransactionWithContext:(SentryTransactionContext *)transactionContext @@ -117,10 +102,8 @@ SENTRY_NO_INIT /** * Creates a transaction, binds it to the hub and returns the instance. - * * @param transactionContext The transaction context. * @param customSamplingContext Additional information about the sampling context. - * * @return The created transaction. */ - (id)startTransactionWithContext:(SentryTransactionContext *)transactionContext @@ -129,67 +112,54 @@ SENTRY_NO_INIT /** * Captures an error event and sends it to Sentry. - * * @param error The error to send to Sentry. - * - * @return The SentryId of the event or SentryId.empty if the event is not sent. + * @return The @c SentryId of the event or @c SentryId.empty if the event is not sent. */ - (SentryId *)captureError:(NSError *)error NS_SWIFT_NAME(capture(error:)); /** * Captures an error event and sends it to Sentry. - * * @param error The error to send to Sentry. * @param scope The scope containing event metadata. - * - * @return The SentryId of the event or SentryId.empty if the event is not sent. + * @return The @c SentryId of the event or @c SentryId.empty if the event is not sent. */ - (SentryId *)captureError:(NSError *)error withScope:(SentryScope *)scope NS_SWIFT_NAME(capture(error:scope:)); /** * Captures an exception event and sends it to Sentry. - * * @param exception The exception to send to Sentry. - * - * @return The SentryId of the event or SentryId.empty if the event is not sent. + * @return The @c SentryId of the event or @c SentryId.empty if the event is not sent. */ - (SentryId *)captureException:(NSException *)exception NS_SWIFT_NAME(capture(exception:)); /** * Captures an exception event and sends it to Sentry. - * * @param exception The exception to send to Sentry. * @param scope The scope containing event metadata. - * - * @return The SentryId of the event or SentryId.empty if the event is not sent. + * @return The @c SentryId of the event or @c SentryId.empty if the event is not sent. */ - (SentryId *)captureException:(NSException *)exception withScope:(SentryScope *)scope NS_SWIFT_NAME(capture(exception:scope:)); /** * Captures a message event and sends it to Sentry. - * * @param message The message to send to Sentry. - * - * @return The SentryId of the event or SentryId.empty if the event is not sent. + * @return The @c SentryId of the event or @c SentryId.empty if the event is not sent. */ - (SentryId *)captureMessage:(NSString *)message NS_SWIFT_NAME(capture(message:)); /** * Captures a message event and sends it to Sentry. - * * @param message The message to send to Sentry. * @param scope The scope containing event metadata. - * - * @return The SentryId of the event or SentryId.empty if the event is not sent. + * @return The @c SentryId of the event or @c SentryId.empty if the event is not sent. */ - (SentryId *)captureMessage:(NSString *)message withScope:(SentryScope *)scope NS_SWIFT_NAME(capture(message:scope:)); /** * Captures a manually created user feedback and sends it to Sentry. - * * @param userFeedback The user feedback to send to Sentry. */ - (void)captureUserFeedback:(SentryUserFeedback *)userFeedback @@ -198,14 +168,12 @@ SENTRY_NO_INIT /** * Use this method to modify the Scope of the Hub. The SDK uses the Scope to attach * contextual data to events. - * * @param callback The callback for configuring the Scope of the Hub. */ - (void)configureScope:(void (^)(SentryScope *scope))callback; /** * Adds a breadcrumb to the Scope of the Hub. - * * @param crumb The Breadcrumb to add to the Scope of the Hub. */ - (void)addBreadcrumb:(SentryBreadcrumb *)crumb; @@ -216,7 +184,7 @@ SENTRY_NO_INIT - (SentryClient *_Nullable)getClient; /** - * Returns either the current scope and if nil a new one. + * Returns either the current scope or a new one if it was @c nil . */ @property (nonatomic, readonly, strong) SentryScope *scope; @@ -231,15 +199,14 @@ SENTRY_NO_INIT - (BOOL)hasIntegration:(NSString *)integrationName; /** - * Checks if a specific Integration (`integrationClass`) has been installed. - * - * @return BOOL If instance of `integrationClass` exists within `SentryHub.installedIntegrations`. + * Checks if a specific Integration (@c integrationClass) has been installed. + * @return @c YES if instance of @c integrationClass exists within + * @c SentryHub.installedIntegrations */ - (BOOL)isIntegrationInstalled:(Class)integrationClass; /** * Set user to the Scope of the Hub. - * * @param user The user to set to the Scope. */ - (void)setUser:(SentryUser *_Nullable)user; @@ -248,13 +215,12 @@ SENTRY_NO_INIT * Waits synchronously for the SDK to flush out all queued and cached items for up to the specified * timeout in seconds. If there is no internet connection, the function returns immediately. The SDK * doesn't dispose the client or the hub. - * * @param timeout The time to wait for the SDK to complete the flush. */ - (void)flush:(NSTimeInterval)timeout NS_SWIFT_NAME(flush(timeout:)); /** - * Calls flush with ``SentryOptions/shutdownTimeInterval``. + * Calls flush with @c SentryOptions/shutdownTimeInterval . */ - (void)close; diff --git a/Sources/Sentry/Public/SentryId.h b/Sources/Sentry/Public/SentryId.h index dba269d2e5..2024a374ff 100644 --- a/Sources/Sentry/Public/SentryId.h +++ b/Sources/Sentry/Public/SentryId.h @@ -6,13 +6,13 @@ NS_ASSUME_NONNULL_BEGIN * A wrapper around UUID. * UUIDs are declared as either 32 character hexadecimal strings without dashes * "12c2d058d58442709aa2eca08bf20986", or 36 character strings with dashes - * "12c2d058-d584-4270-9aa2-eca08bf20986". It is recommended to omit dashes and use UUID v4 in all - * cases. + * "12c2d058-d584-4270-9aa2-eca08bf20986". + * @note It is recommended to omit dashes and use UUID v4 in cases. */ @interface SentryId : NSObject /** - * Creates a SentryId with a random SentryId. + * Creates a @c SentryId with a random UUID. */ - (instancetype)init; @@ -22,22 +22,21 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)initWithUUID:(NSUUID *)uuid; /** - * Creates a SentryId from a 32 character hexadecimal string without dashes such as + * Creates a @c SentryId from a 32 character hexadecimal string without dashes such as * "12c2d058d58442709aa2eca08bf20986" or a 36 character hexadecimal string such as such as * "12c2d058-d584-4270-9aa2-eca08bf20986". - * * @return SentryId.empty for invalid strings. */ - (instancetype)initWithUUIDString:(NSString *)string; /** - * Returns a 32 lowercase character hexadecimal string description of the SentryId, such as + * Returns a 32 lowercase character hexadecimal string description of the @c SentryId, such as * "12c2d058d58442709aa2eca08bf20986". */ @property (readonly, copy) NSString *sentryIdString; /** - * A SentryId with an empty UUID "00000000000000000000000000000000". + * A @c SentryId with an empty UUID "00000000000000000000000000000000". */ @property (class, nonatomic, readonly, strong) SentryId *empty; diff --git a/Sources/Sentry/Public/SentryMeasurementUnit.h b/Sources/Sentry/Public/SentryMeasurementUnit.h index e7a5b3462a..3e2183bcf6 100644 --- a/Sources/Sentry/Public/SentryMeasurementUnit.h +++ b/Sources/Sentry/Public/SentryMeasurementUnit.h @@ -4,13 +4,12 @@ NS_ASSUME_NONNULL_BEGIN /** * The unit of measurement of a metric value. - * - * Units augment metric values by giving them a magnitude and semantics. There are certain types - * of units that are subdivided in their precision, such as the ``SentryMeasurementUnitDuration`` - * for time measurements. The following unit types are available: ``SentryMeasurementUnitDuration``, - * ``SentryMeasurementUnitInformation``, and``SentryMeasurementUnitFraction``. - * - * When using the units to custom measurements, Sentry will apply formatting to display + * @discussion Units augment metric values by giving them a magnitude and semantics. There are + * certain types of units that are subdivided in their precision, such as the + * @c SentryMeasurementUnitDuration for time measurements. The following unit types are available: + * @c SentryMeasurementUnitDuration , + * @c SentryMeasurementUnitInformation , and @c SentryMeasurementUnitFraction . + * @note When using the units to custom measurements, Sentry will apply formatting to display * measurement values in the UI. */ NS_SWIFT_NAME(MeasurementUnit) @@ -19,17 +18,18 @@ SENTRY_NO_INIT /** * Returns an initialized SentryMeasurementUnit with a custom measurement unit. - * * @param unit Your own custom unit without built-in conversion in Sentry. */ - (instancetype)initWithUnit:(NSString *)unit; /** - * The NSString representation of the measurement unit. + * The @c NSString representation of the measurement unit. */ @property (readonly, copy) NSString *unit; -/** Untyped value without a unit. */ +/** + * Untyped value without a unit. + */ @property (class, readonly, copy) SentryMeasurementUnit *none; @end @@ -41,81 +41,124 @@ NS_SWIFT_NAME(MeasurementUnitDuration) @interface SentryMeasurementUnitDuration : SentryMeasurementUnit SENTRY_NO_INIT -/** Nanosecond, 10^-9 seconds. */ +/** + * Nanosecond, 10^-9 seconds. + */ @property (class, readonly, copy) SentryMeasurementUnitDuration *nanosecond; -/** Microsecond , 10^-6 seconds. */ +/** + * Microsecond , 10^-6 seconds. + */ @property (class, readonly, copy) SentryMeasurementUnitDuration *microsecond; -/** Millisecond, 10^-3 seconds. */ +/** + * Millisecond, 10^-3 seconds. + */ @property (class, readonly, copy) SentryMeasurementUnitDuration *millisecond; -/** Full second. */ +/** + * Full second. + */ @property (class, readonly, copy) SentryMeasurementUnitDuration *second; -/** Minute, 60 seconds. */ +/** + * Minute, 60 seconds. + */ @property (class, readonly, copy) SentryMeasurementUnitDuration *minute; -/** Hour, 3600 seconds. */ +/** + * Hour, 3600 seconds. + */ @property (class, readonly, copy) SentryMeasurementUnitDuration *hour; -/** Day, 86,400 seconds. */ +/** + * Day, 86,400 seconds. + */ @property (class, readonly, copy) SentryMeasurementUnitDuration *day; -/** Week, 604,800 seconds. */ +/** + * Week, 604,800 seconds. + */ @property (class, readonly, copy) SentryMeasurementUnitDuration *week; @end /** * Size of information units derived from bytes. - * - * See also [Units of information](https://en.wikipedia.org/wiki/Units_of_information) + * @see https://en.wikipedia.org/wiki/Units_of_information */ NS_SWIFT_NAME(MeasurementUnitInformation) @interface SentryMeasurementUnitInformation : SentryMeasurementUnit SENTRY_NO_INIT -/** Bit, corresponding to 1/8 of a byte. */ +/** + * Bit, corresponding to 1/8 of a byte + */ @property (class, readonly, copy) SentryMeasurementUnitInformation *bit; -/** Byte. */ +/** + * Byte. + */ @property (class, readonly, copy) SentryMeasurementUnitInformation *byte; -/** Kilobyte, 10^3 bytes. */ +/** + * Kilobyte, 10^3 bytes + */ @property (class, readonly, copy) SentryMeasurementUnitInformation *kilobyte; -/** Kibibyte, 2^10 bytes. */ +/** + * Kibibyte, 2^10 bytes. + */ @property (class, readonly, copy) SentryMeasurementUnitInformation *kibibyte; -/** Megabyte, 10^6 bytes. */ +/** + * Megabyte, 10^6 bytes + */ @property (class, readonly, copy) SentryMeasurementUnitInformation *megabyte; -/** Mebibyte, 2^20 bytes. */ +/** + * Mebibyte, 2^20 bytes. + */ @property (class, readonly, copy) SentryMeasurementUnitInformation *mebibyte; -/** Gigabyte, 10^9 bytes. */ +/** + * Gigabyte, 10^9 bytes + */ @property (class, readonly, copy) SentryMeasurementUnitInformation *gigabyte; -/** Gibibyte, 2^30 bytes. */ +/** + * Gibibyte, 2^30 bytes. + */ @property (class, readonly, copy) SentryMeasurementUnitInformation *gibibyte; -/** Terabyte, 10^12 bytes. */ +/** + * Terabyte, 10^12 bytes + */ @property (class, readonly, copy) SentryMeasurementUnitInformation *terabyte; -/** Tebibyte, 2^40 bytes. */ +/** + * Tebibyte, 2^40 bytes. + */ @property (class, readonly, copy) SentryMeasurementUnitInformation *tebibyte; -/** Petabyte, 10^15 bytes. */ +/** + * Petabyte, 10^15 bytes + */ @property (class, readonly, copy) SentryMeasurementUnitInformation *petabyte; -/** Pebibyte, 2^50 bytes. */ +/** + * Pebibyte, 2^50 bytes. + */ @property (class, readonly, copy) SentryMeasurementUnitInformation *pebibyte; -/** Exabyte, 10^18 bytes. */ +/** + * Exabyte, 10^18 bytes + */ @property (class, readonly, copy) SentryMeasurementUnitInformation *exabyte; -/** Exbibyte, 2^60 bytes. */ +/** + * Exbibyte, 2^60 bytes. + */ @property (class, readonly, copy) SentryMeasurementUnitInformation *exbibyte; @end @@ -123,14 +166,18 @@ SENTRY_NO_INIT /** * Units of fraction. */ -NS_SWIFT_NAME(MeasurementUnitFraction) -@interface SentryMeasurementUnitFraction : SentryMeasurementUnit +NS_SWIFT_NAME(MeasurementUnitFraction) @interface SentryMeasurementUnitFraction + : SentryMeasurementUnit SENTRY_NO_INIT -/** Floating point fraction of `1`. */ +/** + * Floating point fraction of @c 1 . g + */ @property (class, readonly, copy) SentryMeasurementUnitFraction *ratio; -/** Ratio expressed as a fraction of `100`. `100%` equals a ratio of `1.0`. */ +/** + * Ratio expressed as a fraction of @c 100 @c 100% equals a ratio of @c 1.0 + */ @property (class, readonly, copy) SentryMeasurementUnitFraction *percent; @end diff --git a/Sources/Sentry/Public/SentryMechanism.h b/Sources/Sentry/Public/SentryMechanism.h index 4c997741c9..eb295e8dc7 100644 --- a/Sources/Sentry/Public/SentryMechanism.h +++ b/Sources/Sentry/Public/SentryMechanism.h @@ -31,7 +31,7 @@ SENTRY_NO_INIT /** * Flag indicating whether the exception has been handled by the user - * (e.g. via ``try..catch``) + * (e.g. via @c try..catch ) */ @property (nonatomic, copy) NSNumber *_Nullable handled; diff --git a/Sources/Sentry/Public/SentryMechanismMeta.h b/Sources/Sentry/Public/SentryMechanismMeta.h index 891f9794b3..6a0099667e 100644 --- a/Sources/Sentry/Public/SentryMechanismMeta.h +++ b/Sources/Sentry/Public/SentryMechanismMeta.h @@ -9,8 +9,7 @@ NS_ASSUME_NONNULL_BEGIN /** * The mechanism metadata usually carries error codes reported by the runtime or operating system, * along with a platform-dependent interpretation of these codes. - * - * See https://develop.sentry.dev/sdk/event-payloads/exception/#meta-information. + * @see https://develop.sentry.dev/sdk/event-payloads/exception/#meta-information. */ NS_SWIFT_NAME(MechanismMeta) @interface SentryMechanismMeta : NSObject @@ -29,7 +28,7 @@ NS_SWIFT_NAME(MechanismMeta) @property (nullable, nonatomic, strong) NSDictionary *machException; /** - * Sentry uses the NSErrors domain and code for grouping. Only domain and code are serialized. + * Sentry uses the @c NSErrors domain and code for grouping. Only domain and code are serialized. */ @property (nullable, nonatomic, strong) SentryNSError *error; diff --git a/Sources/Sentry/Public/SentryMessage.h b/Sources/Sentry/Public/SentryMessage.h index bd61581b3b..68269a6820 100644 --- a/Sources/Sentry/Public/SentryMessage.h +++ b/Sources/Sentry/Public/SentryMessage.h @@ -7,15 +7,13 @@ NS_ASSUME_NONNULL_BEGIN /** * Carries a log message that describes an event or error. Optionally, it can carry a format string * and structured parameters. This can help to group similar messages into the same issue. - * - * For more info checkout: https://develop.sentry.dev/sdk/event-payloads/message/ + * @see https://develop.sentry.dev/sdk/event-payloads/message/ */ @interface SentryMessage : NSObject SENTRY_NO_INIT /** - * Returns a SentyMessage with setting formatted. - * + * Returns a @c SentryMessage with setting formatted. * @param formatted The fully formatted message. If missing, Sentry will try to interpolate the * message. It must not exceed 8192 characters. Longer messages will be truncated. */ diff --git a/Sources/Sentry/Public/SentryNSError.h b/Sources/Sentry/Public/SentryNSError.h index af74383bd2..a4e6fd8d53 100644 --- a/Sources/Sentry/Public/SentryNSError.h +++ b/Sources/Sentry/Public/SentryNSError.h @@ -5,26 +5,25 @@ NS_ASSUME_NONNULL_BEGIN /** - * Sentry representation of an NSError to send to Sentry. + * Sentry representation of an @c NSError to send to Sentry. */ @interface SentryNSError : NSObject SENTRY_NO_INIT /** - * The domain of an NSError. + * The domain of an @c NSError . */ @property (nonatomic, copy) NSString *domain; /** - * The error code of an NSError + * The error code of an @c NSError . */ @property (nonatomic, assign) NSInteger code; /** - * Initializes SentryNSError and sets the domain and code. - * - * @param domain The domain of an NSError. - * @param code The error code of an NSError. + * Initializes @c SentryNSError and sets the domain and code. + * @param domain The domain of an @c NSError. + * @param code The error code of an @c NSError. */ - (instancetype)initWithDomain:(NSString *)domain code:(NSInteger)code; diff --git a/Sources/Sentry/Public/SentryOptions.h b/Sources/Sentry/Public/SentryOptions.h index 9adbf50308..6f93464e3b 100644 --- a/Sources/Sentry/Public/SentryOptions.h +++ b/Sources/Sentry/Public/SentryOptions.h @@ -21,12 +21,14 @@ NS_SWIFT_NAME(Options) /** * Turns debug mode on or off. If debug is enabled SDK will attempt to print out useful debugging - * information if something goes wrong. Default is disabled. + * information if something goes wrong. + * @note Default is @c NO. */ @property (nonatomic, assign) BOOL debug; /** - * Minimum LogLevel to be used if debug is enabled. Default is debug. + * Minimum LogLevel to be used if debug is enabled. + * @note Default is @c kSentryLevelDebug. */ @property (nonatomic, assign) SentryLevel diagnosticLevel; @@ -37,79 +39,78 @@ NS_SWIFT_NAME(Options) /** * The distribution of the application. - * * @discussion Distributions are used to disambiguate build or deployment variants of the same - * release of an application. For example, the dist can be the build number of an Xcode build. + * release of an application. For example, the @c dist can be the build number of an Xcode build. * */ @property (nullable, nonatomic, copy) NSString *dist; /** - * The environment used for this event. Default value is "production". + * The environment used for this event. + * @note Default value is @c @"production". */ @property (nonatomic, copy) NSString *environment; /** - * Specifies wether this SDK should send events to Sentry. If set to NO events will be - * dropped in the client and not sent to Sentry. Default is YES. + * Specifies wether this SDK should send events to Sentry. If set to @c NO events will be + * dropped in the client and not sent to Sentry. Default is @c YES. */ @property (nonatomic, assign) BOOL enabled; /** - * Controls the flush duration when calling ``SentrySDK/close``. + * Controls the flush duration when calling @c SentrySDK/close . */ @property (nonatomic, assign) NSTimeInterval shutdownTimeInterval; /** - * When enabled, the SDK sends crashes to Sentry. Default value is YES. - * - * Disabling this feature disables the ``SentryWatchdogTerminationTrackingIntegration``, cause the - * ``SentryWatchdogTerminationTrackingIntegration`` would falsely report every crash as watchdog + * When enabled, the SDK sends crashes to Sentry. + * @note Disabling this feature disables the @c SentryWatchdogTerminationTrackingIntegration , + * because + * @c SentryWatchdogTerminationTrackingIntegration would falsely report every crash as watchdog * termination. + * @note Default value is @c YES . */ @property (nonatomic, assign) BOOL enableCrashHandler; /** * How many breadcrumbs do you want to keep in memory? - * Default is 100. + * @note Default is @c 100 . */ @property (nonatomic, assign) NSUInteger maxBreadcrumbs; /** - * When enabled, the SDK adds breadcrumbs for each network request. Default value is - * YES. As this feature uses swizzling, disabling enableSwizzling also - * disables this feature. - * + * When enabled, the SDK adds breadcrumbs for each network request. As this feature uses swizzling, + * disabling @c enableSwizzling also disables this feature. * @discussion If you want to enable or disable network tracking for performance monitoring, please - * use enableNetworkTracking instead. + * use @c enableNetworkTracking instead. + * @note Default value is @c YES . */ @property (nonatomic, assign) BOOL enableNetworkBreadcrumbs; /** - * The maximum number of envelopes to keep in cache. Default is 30. + * The maximum number of envelopes to keep in cache. + * @note Default is @c 30 . */ @property (nonatomic, assign) NSUInteger maxCacheItems; /** - * This block can be used to modify the event before it will be serialized and - * sent + * This block can be used to modify the event before it will be serialized and sent. */ @property (nullable, nonatomic, copy) SentryBeforeSendEventCallback beforeSend; /** - * This block can be used to modify the event before it will be serialized and - * sent + * This block can be used to modify the event before it will be serialized and sent. */ @property (nullable, nonatomic, copy) SentryBeforeBreadcrumbCallback beforeBreadcrumb; /** - * This gets called shortly after the initialization of the SDK when the last program execution - * terminated with a crash. It is not guaranteed that this is called on the main thread. - * + * A block called shortly after the initialization of the SDK when the last program execution + * terminated with a crash. * @discussion This callback is only executed once during the entire run of the program to avoid * multiple callbacks if there are multiple crash events to send. This can happen when the program - * terminates with a crash before the SDK can send the crash event. You can look into beforeSend if - * you prefer a callback for every event. + * terminates with a crash before the SDK can send the crash event. You can look into @c beforeSend + * if you prefer a callback for every event. + * @warning It is not guaranteed that this is called on the main thread. */ @property (nullable, nonatomic, copy) SentryOnCrashedLastRunCallback onCrashedLastRun; @@ -119,34 +120,37 @@ NS_SWIFT_NAME(Options) @property (nullable, nonatomic, copy) NSArray *integrations; /** - * Array of default integrations. Will be used if integrations are nil + * Array of default integrations. Will be used if @c integrations is @c nil . */ + (NSArray *)defaultIntegrations; /** - * Indicates the percentage of events being sent to Sentry. Setting this to 0 discards all - * events, 1.0 or NIL sends all events, 0.01 collects 1% of all events. The default is 1. The value - * needs to be >= 0.0 and <= 1.0. When setting a value out of range the SDK sets it to the default - * of 1.0. + * Indicates the percentage of events being sent to Sentry. + * @discussion Specifying @c 0 discards all events, @c 1.0 or @c nil sends all events, @c 0.01 + * collects 1% of all events. + * @note The value needs to be >= @c 0.0 and \<= @c 1.0. When setting a value out of range the SDK + * sets it to the default of @c 1.0. + * @note The default is @c 1 . */ @property (nullable, nonatomic, copy) NSNumber *sampleRate; /** - * Whether to enable automatic session tracking or not. Default is YES. + * Whether to enable automatic session tracking or not. + * @note Default is @c YES. */ @property (nonatomic, assign) BOOL enableAutoSessionTracking; /** - * Whether to enable Watchdog Termination tracking or not. Default is YES. - * - * This feature requires the ``SentryCrashIntegration`` being enabled, cause otherwise it would + * Whether to enable Watchdog Termination tracking or not. + * @note This feature requires the @c SentryCrashIntegration being enabled, otherwise it would * falsely report every crash as watchdog termination. + * @note Default is @c YES. */ @property (nonatomic, assign) BOOL enableWatchdogTerminationTracking; /** * The interval to end a session after the App goes to the background. - * The default is 30 seconds. + * @note The default is 30 seconds. */ @property (nonatomic, assign) NSUInteger sessionTrackingIntervalMillis; @@ -154,37 +158,33 @@ NS_SWIFT_NAME(Options) * When enabled, stack traces are automatically attached to all messages logged. Stack traces are * always attached to exceptions but when this is set stack traces are also sent with messages. * Stack traces are only attached for the current thread. - * - * This feature is enabled by default. + * @note This feature is enabled by default. */ @property (nonatomic, assign) BOOL attachStacktrace; /** * @warning This is an experimental feature and may still have bugs. Turning this feature on can * have an impact on the grouping of your issues. - * - * When enabled, the SDK stitches stack traces of asynchronous code together. - * - * This feature is disabled by default. + * @brief When enabled, the SDK stitches stack traces of asynchronous code together. + * @note This feature is disabled by default. */ @property (nonatomic, assign) BOOL stitchAsyncCode; /** - * The maximum size for each attachment in bytes. Default is 20 MiB / 20 * 1024 * 1024 bytes. - * - * Please also check the maximum attachment size of relay to make sure your attachments don't get - * discarded there: https://docs.sentry.io/product/relay/options/ + * The maximum size for each attachment in bytes. + * @note Default is 20 MiB (20 ✕ 1024 ✕ 1024 bytes). + * @note Please also check the maximum attachment size of relay to make sure your attachments don't + * get discarded there: https://docs.sentry.io/product/relay/options/ */ @property (nonatomic, assign) NSUInteger maxAttachmentSize; /** - * When enabled, the SDK sends personal identifiable along with events. The default is - * NO. - * + * When enabled, the SDK sends personal identifiable along with events. + * @note The default is @c NO . * @discussion When the user of an event doesn't contain an IP address, and this flag is - * YES, the SDK sets it to {{auto}} to instruct the server to use the + * @c YES, the SDK sets it to @c {{auto}} to instruct the server to use the * connection IP address as the user address. Due to backward compatibility concerns, Sentry set the - * IP address to {{auto}} out of the box for Cocoa. If you want to stop Sentry from + * IP address to @c {{auto}} out of the box for Cocoa. If you want to stop Sentry from * using the connections IP address, you have to enable Prevent Storing of IP Addresses in your * project settings in Sentry. */ @@ -192,59 +192,56 @@ NS_SWIFT_NAME(Options) /** * When enabled, the SDK tracks performance for UIViewController subclasses and HTTP requests - * automatically. It also measures the app start and slow and frozen frames. The default is - * YES. Note: Performance Monitoring must be enabled for this flag to take effect. See: + * automatically. It also measures the app start and slow and frozen frames. + * @note The default is @c YES . + * @note Performance Monitoring must be enabled for this flag to take effect. See: * https://docs.sentry.io/platforms/apple/performance/ */ @property (nonatomic, assign) BOOL enableAutoPerformanceTracing; #if SENTRY_HAS_UIKIT /** - * When enabled, the SDK tracks performance for UIViewController subclasses. The default is - * YES. + * When enabled, the SDK tracks performance for UIViewController subclasses. + * @note The default is @c YES . */ @property (nonatomic, assign) BOOL enableUIViewControllerTracing; /** * Automatically attaches a screenshot when capturing an error or exception. - * - * Default value is NO + * @note Default value is @c NO . */ @property (nonatomic, assign) BOOL attachScreenshot; /** * @warning This is an experimental feature and may still have bugs. - * - * Automatically attaches a textual representation of the view hierarchy when capturing an error - * event. - * - * Default value is NO + * @brief Automatically attaches a textual representation of the view hierarchy when capturing an + * error event. + * @note Default value is @c NO . */ @property (nonatomic, assign) BOOL attachViewHierarchy; /** * When enabled, the SDK creates transactions for UI events like buttons clicks, switch toggles, - * and other ui elements that uses UIControl `sendAction:to:forEvent:`. + * and other ui elements that uses UIControl @c sendAction:to:forEvent: */ @property (nonatomic, assign) BOOL enableUserInteractionTracing; /** * How long an idle transaction waits for new children after all its child spans finished. Only UI - * event transactions are idle transactions. The default is 3 seconds. + * event transactions are idle transactions. + * @note The default is 3 seconds. */ @property (nonatomic, assign) NSTimeInterval idleTimeout; /** * @warning This is an experimental feature and may still have bugs. - * - * Report pre-warmed app starts by dropping the first app start spans if pre-warming paused during - * these steps. This approach will shorten the app start duration, but it represents the duration a - * user has to wait after clicking the app icon until the app is responsive. - * - * You can filter for different app start types in Discover with app_start_type:cold.prewarmed, - * app_start_type:warm.prewarmed, app_start_type:cold, and app_start_type:warm. - * - * Default value is NO + * @brief Report pre-warmed app starts by dropping the first app start spans if pre-warming paused + * during these steps. This approach will shorten the app start duration, but it represents the + * duration a user has to wait after clicking the app icon until the app is responsive. + * @note You can filter for different app start types in Discover with + * @c app_start_type:cold.prewarmed , + * @c app_start_type:warm.prewarmed , @c app_start_type:cold , and @c app_start_type:warm . + * @note Default value is @c NO . */ @property (nonatomic, assign) BOOL enablePreWarmedAppStartTracing; @@ -252,97 +249,101 @@ NS_SWIFT_NAME(Options) /** * When enabled, the SDK tracks performance for HTTP requests if auto performance tracking and - * enableSwizzling are enabled. The default is YES. - * + * @c enableSwizzling are enabled. + * @note The default is @c YES . * @discussion If you want to enable or disable network breadcrumbs, please use - * enableNetworkBreadcrumbs instead. + * @c enableNetworkBreadcrumbs instead. */ @property (nonatomic, assign) BOOL enableNetworkTracking; /** * When enabled, the SDK tracks performance for file IO reads and writes with NSData if auto - * performance tracking and enableSwizzling are enabled. The default is YES. + * performance tracking and enableSwizzling are enabled. + * @note The default is @c YES . */ @property (nonatomic, assign) BOOL enableFileIOTracing; /** * Indicates whether tracing should be enabled. - * Enabling this sets `tracesSampleRate` to 1 if both - * `tracesSampleRate` and `tracesSampler` are nil. - * - * Changing either `tracesSampleRate` or `tracesSampler` to - * a value other then nil will enable this in case this was never changed before. + * @discussion Enabling this sets @c tracesSampleRate to @c 1 if both @c tracesSampleRate and + * @c tracesSampler are @c nil. Changing either @c tracesSampleRate or @c tracesSampler to a value + * other then @c nil will enable this in case this was never changed before. */ @property (nonatomic) BOOL enableTracing; /** - * Indicates the percentage of the tracing data that is collected. Setting this to 0 or NIL discards - * all trace data, 1.0 collects all trace data, 0.01 collects 1% of all trace data. The default is - * 0. The value needs to be >= 0.0 and <= 1.0. When setting a value out of range the SDK sets it to - * the default of 0. + * Indicates the percentage of the tracing data that is collected. + * @discussion Specifying @c 0 or @c nil discards all trace data, @c 1.0 collects all trace data, + * @c 0.01 collects 1% of all trace data. + * @note The value needs to be >= 0.0 and \<= 1.0. When setting a value out of range the SDK sets it + * to the default. + * @note The default is @c 0 . */ @property (nullable, nonatomic, strong) NSNumber *tracesSampleRate; /** - * A callback to a user defined traces sampler function. Returning 0 or NIL discards all trace - * data, 1.0 collects all trace data, 0.01 collects 1% of all trace data. The sample rate needs to - * be >= 0.0 and <= 1.0 or NIL. When returning a value out of range the SDK uses the default of 0. + * A callback to a user defined traces sampler function. + * @discussion Specifying @c 0 or @c nil discards all trace data, @c 1.0 collects all trace data, + * @c 0.01 collects 1% of all trace data. + * @note The value needs to be >= 0.0 and \<= 1.0. When setting a value out of range the SDK sets it + * to the default of @c 0 . */ @property (nullable, nonatomic) SentryTracesSamplerCallback tracesSampler; /** - * If tracing is enabled or not. Returns YES if enabledTracing is YES and either a tracesSampleRate - * > 0 and <=1 or a tracesSampler is set otherwise NO. + * If tracing is enabled or not. + * @discussion @c YES if @c enabledTracing is @c YES and @c tracesSampleRate + * is > @c 0 and \<= @c 1 or a @c tracesSampler is set, otherwise @c NO. */ @property (nonatomic, assign, readonly) BOOL isTracingEnabled; /** - * A list of string prefixes of framework names that belong to the app. This option takes precedence - * over inAppExcludes. Per default this contains CFBundleExecutable to mark it as inApp. + * A list of string prefixes of framework names that belong to the app. + * @note This option takes precedence over @c inAppExcludes. + * @note By default, this contains @c CFBundleExecutable to mark it as "in-app". */ @property (nonatomic, readonly, copy) NSArray *inAppIncludes; /** - * Adds an item to the list of inAppIncludes. - * + * Adds an item to the list of @c inAppIncludes. * @param inAppInclude The prefix of the framework name. */ - (void)addInAppInclude:(NSString *)inAppInclude; /** * A list of string prefixes of framework names that do not belong to the app, but rather to - * third-party frameworks. Frameworks considered not part of the app will be hidden from stack - * traces by default. - * - * This option can be overridden using inAppIncludes. + * third-party frameworks. + * @note By default, frameworks considered not part of the app will be hidden from stack + * traces. + * @note This option can be overridden using @c inAppIncludes. */ @property (nonatomic, readonly, copy) NSArray *inAppExcludes; /** - * Adds an item to the list of inAppExcludes. - * + * Adds an item to the list of @c inAppExcludes. * @param inAppExclude The prefix of the frameworks name. */ - (void)addInAppExclude:(NSString *)inAppExclude; /** - * Set as delegate on the NSURLSession used for all network data-transfer tasks performed by Sentry. + * Set as delegate on the @c NSURLSession used for all network data-transfer tasks performed by + * Sentry. */ @property (nullable, nonatomic, weak) id urlSessionDelegate; /** - * Wether the SDK should use swizzling or not. Default is YES. - * + * Wether the SDK should use swizzling or not. * @discussion When turned off the following features are disabled: breadcrumbs for touch events and - * navigation with UIViewControllers, automatic instrumentation for UIViewControllers, automatic - * instrumentation for HTTP requests, automatic instrumentation for file IO with NSData, and - * automatically added sentry-trace header to HTTP requests for distributed tracing. + * navigation with @c UIViewControllers, automatic instrumentation for @c UIViewControllers, + * automatic instrumentation for HTTP requests, automatic instrumentation for file IO with + * @c NSData, and automatically added sentry-trace header to HTTP requests for distributed tracing. + * @note Default is @c YES. */ @property (nonatomic, assign) BOOL enableSwizzling; /** * When enabled, the SDK tracks the performance of Core Data operations. It requires enabling - * performance monitoring. The default is YES. + * performance monitoring. The default is @c YES. * @see */ @property (nonatomic, assign) BOOL enableCoreDataTracing; @@ -351,24 +352,21 @@ NS_SWIFT_NAME(Options) /** * @warning This is a beta feature and may still have bugs. * @note Profiling is not supported on watchOS or tvOS. - * * Indicates the percentage profiles being sampled out of the sampled transactions. - * - * The default is 0. The value needs to be >= 0.0 and <= 1.0. When setting a value out of range - * the SDK sets it to the default of 0. - * - * This property is dependent on `tracesSampleRate` -- if `tracesSampleRate` is 0 (default), + * @note The default is @c 0. + * @note The value needs to be >= @c 0.0 and \<= @c 1.0. When setting a value out of range + * the SDK sets it to the default of @c 0. + * This property is dependent on @c tracesSampleRate -- if @c tracesSampleRate is @c 0 (default), * no profiles will be collected no matter what this property is set to. This property is - * used to undersample profiles *relative to* `tracesSampleRate`. + * used to undersample profiles *relative to* @c tracesSampleRate */ @property (nullable, nonatomic, strong) NSNumber *profilesSampleRate; /** * @warning This is a beta feature and may still have bugs. * @note Profiling is not supported on watchOS or tvOS. - * * A callback to a user defined profiles sampler function. This is similar to setting - * `profilesSampleRate`, but instead of a static value, the callback function will be called to + * @c profilesSampleRate but instead of a static value, the callback function will be called to * determine the sample rate. */ @property (nullable, nonatomic) SentryTracesSamplerCallback profilesSampler; @@ -376,21 +374,19 @@ NS_SWIFT_NAME(Options) /** * @warning This is a beta feature and may still have bugs. * @note Profiling is not supported on watchOS or tvOS. - * - * If profiling should be enabled or not. Returns YES if either a profilesSampleRate > 0 and - * <=1 or a profilesSampler is set otherwise NO. + * If profiling should be enabled or not. Returns @c YES if either a profilesSampleRate > @c 0 and + * \<= @c 1 or a profilesSampler is set otherwise @c NO. */ @property (nonatomic, assign, readonly) BOOL isProfilingEnabled; /** - * DEPRECATED: Use `profilesSampleRate` instead. Setting `enableProfiling` to YES is the equivalent - * of setting `profilesSampleRate` to `1.0`. If `profilesSampleRate` is set, it will take precedence * @warning This is a beta feature and may still have bugs. + * @brief Whether to enable the sampling profiler. * @note Profiling is not supported on watchOS or tvOS. - * - * over this setting. - * - * Whether to enable the sampling profiler. Default is NO. + * @deprecated Use @c profilesSampleRate instead. Setting @c enableProfiling to @c YES is the + * equivalent of setting @c profilesSampleRate to @c 1.0 If @c profilesSampleRate is set, it will + * take precedence over this setting. + * @note Default is @c NO. */ @property (nonatomic, assign) BOOL enableProfiling DEPRECATED_MSG_ATTRIBUTE( "Use profilesSampleRate or profilesSampler instead. This property will be removed in a future " @@ -398,68 +394,66 @@ NS_SWIFT_NAME(Options) #endif /** - * Whether to send client reports, which contain statistics about discarded events. The default is - * YES. - * + * Whether to send client reports, which contain statistics about discarded events. + * @note The default is @c YES. * @see */ @property (nonatomic, assign) BOOL sendClientReports; /** * When enabled, the SDK tracks when the application stops responding for a specific amount of - * time defined by the `appHangsTimeoutInterval` option. The default is - * YES + * time defined by the @c appHangsTimeoutInterval option. + * @note The default is @c YES */ @property (nonatomic, assign) BOOL enableAppHangTracking; /** * The minimum amount of time an app should be unresponsive to be classified as an App Hanging. - * The actual amount may be a little longer. - * Avoid using values lower than 100ms, which may cause a lot of app hangs events being transmitted. - * The default value is 2 seconds. + * @note The actual amount may be a little longer. + * @note Avoid using values lower than 100ms, which may cause a lot of app hangs events being + * transmitted. + * @note The default value is 2 seconds. */ @property (nonatomic, assign) NSTimeInterval appHangTimeoutInterval; /** - * When enabled, the SDK adds breadcrumbs for various system events. Default value is YES. + * When enabled, the SDK adds breadcrumbs for various system events. + * @note Default value is @c YES. */ @property (nonatomic, assign) BOOL enableAutoBreadcrumbTracking; /** * An array of hosts or regexes that determines if outgoing HTTP requests will get - * extra `trace_id` and `baggage` headers added. - * - * This array can contain instances of NSString which should match the URL (using `contains`), - * and instances of NSRegularExpression, which will be used to check the whole URL. - * - * The default value adds the header to all outgoing requests. - * + * extra @c trace_id and @c baggage headers added. + * @discussion This array can contain instances of @c NSString which should match the URL (using + * @c contains ), and instances of @c NSRegularExpression, which will be used to check the whole + * URL. + * @note The default value adds the header to all outgoing requests. * @see https://docs.sentry.io/platforms/apple/configuration/options/#trace-propagation-targets */ @property (nonatomic, retain) NSArray *tracePropagationTargets; /** * When enabled, the SDK captures HTTP Client errors. - * This feature requires enableSwizzling enabled as well, Default value is YES. + * @note This feature requires @c enableSwizzling enabled as well. + * @note Default value is @c YES. */ @property (nonatomic, assign) BOOL enableCaptureFailedRequests; /** * The SDK will only capture HTTP Client errors if the HTTP Response status code is within the * defined range. - * - * Defaults to 500 - 599. + * @note Defaults to 500 - 599. */ @property (nonatomic, strong) NSArray *failedRequestStatusCodes; /** * An array of hosts or regexes that determines if HTTP Client errors will be automatically * captured. - * - * This array can contain instances of NSString which should match the URL (using `contains`), - * and instances of NSRegularExpression, which will be used to check the whole URL. - * - * The default value automatically captures HTTP Client errors of all outgoing requests. + * @discussion This array can contain instances of @c NSString which should match the URL (using + * @c contains ), and instances of @c NSRegularExpression, which will be used to check the whole + * URL. + * @note The default value automatically captures HTTP Client errors of all outgoing requests. */ @property (nonatomic, strong) NSArray *failedRequestTargets; @@ -467,12 +461,12 @@ NS_SWIFT_NAME(Options) /** * @warning This is an experimental feature and may still have bugs. - * - * This feature is disabled by default. When enabled, the SDK sends - * ``MXDiskWriteExceptionDiagnostic``, ``MXCPUExceptionDiagnostic`` and ``MXHangDiagnostic`` to - * Sentry. The SDK supports this feature from iOS 15 and later and macOS 12 and later because, on - * these versions, MetricKit delivers diagnostic reports immediately, which allows the Sentry SDK to - * apply the current data from the scope. + * @brief When enabled, the SDK sends @c MXDiskWriteExceptionDiagnostic, @c MXCPUExceptionDiagnostic + * and + * @c MXHangDiagnostic to Sentry. The SDK supports this feature from iOS 15 and later and macOS 12 + * and later because, on these versions, @c MetricKit delivers diagnostic reports immediately, which + * allows the Sentry SDK to apply the current data from the scope. + * @note This feature is disabled by default. */ @property (nonatomic, assign) BOOL enableMetricKit API_AVAILABLE( ios(15.0), macos(12.0), macCatalyst(15.0)) API_UNAVAILABLE(tvos, watchos); diff --git a/Sources/Sentry/Public/SentrySDK.h b/Sources/Sentry/Public/SentrySDK.h index 6ceee4f6c2..ec2a04547d 100644 --- a/Sources/Sentry/Public/SentrySDK.h +++ b/Sources/Sentry/Public/SentrySDK.h @@ -9,8 +9,7 @@ NS_ASSUME_NONNULL_BEGIN /** * The main entry point for the SentrySDK. - * - * We recommend using `[Sentry startWithConfigureOptions]` to initialize Sentry. + * We recommend using @c +[startWithConfigureOptions:] to initialize Sentry. */ @interface SentrySDK : NSObject SENTRY_NO_INIT @@ -40,21 +39,19 @@ SENTRY_NO_INIT /** * Captures a manually created event and sends it to Sentry. - * * @param event The event to send to Sentry. + * @return The @c SentryId of the event or @c SentryId.empty if the event is not sent. * - * @return The SentryId of the event or SentryId.empty if the event is not sent. */ + (SentryId *)captureEvent:(SentryEvent *)event NS_SWIFT_NAME(capture(event:)); /** * Captures a manually created event and sends it to Sentry. Only the data in this scope object will * be added to the event. The global scope will be ignored. - * * @param event The event to send to Sentry. * @param scope The scope containing event metadata. + * @return The @c SentryId of the event or @c SentryId.empty if the event is not sent. * - * @return The SentryId of the event or SentryId.empty if the event is not sent. */ + (SentryId *)captureEvent:(SentryEvent *)event withScope:(SentryScope *)scope NS_SWIFT_NAME(capture(event:scope:)); @@ -62,21 +59,18 @@ SENTRY_NO_INIT /** * Captures a manually created event and sends it to Sentry. Maintains the global scope but mutates * scope data for only this call. - * * @param event The event to send to Sentry. * @param block The block mutating the scope only for this call. + * @return The @c SentryId of the event or @c SentryId.empty if the event is not sent. * - * @return The SentryId of the event or SentryId.empty if the event is not sent. */ + (SentryId *)captureEvent:(SentryEvent *)event withScopeBlock:(void (^)(SentryScope *scope))block NS_SWIFT_NAME(capture(event:block:)); /** * Creates a transaction, binds it to the hub and returns the instance. - * * @param name The transaction name. * @param operation Short code identifying the type of operation the span is measuring. - * * @return The created transaction. */ + (id)startTransactionWithName:(NSString *)name @@ -85,11 +79,9 @@ SENTRY_NO_INIT /** * Creates a transaction, binds it to the hub and returns the instance. - * * @param name The transaction name. * @param operation Short code identifying the type of operation the span is measuring. * @param bindToScope Indicates whether the SDK should bind the new transaction to the scope. - * * @return The created transaction. */ + (id)startTransactionWithName:(NSString *)name @@ -99,9 +91,7 @@ SENTRY_NO_INIT /** * Creates a transaction, binds it to the hub and returns the instance. - * * @param transactionContext The transaction context. - * * @return The created transaction. */ + (id)startTransactionWithContext:(SentryTransactionContext *)transactionContext @@ -109,10 +99,8 @@ SENTRY_NO_INIT /** * Creates a transaction, binds it to the hub and returns the instance. - * * @param transactionContext The transaction context. * @param bindToScope Indicates whether the SDK should bind the new transaction to the scope. - * * @return The created transaction. */ + (id)startTransactionWithContext:(SentryTransactionContext *)transactionContext @@ -121,11 +109,9 @@ SENTRY_NO_INIT /** * Creates a transaction, binds it to the hub and returns the instance. - * * @param transactionContext The transaction context. * @param bindToScope Indicates whether the SDK should bind the new transaction to the scope. * @param customSamplingContext Additional information about the sampling context. - * * @return The created transaction. */ + (id)startTransactionWithContext:(SentryTransactionContext *)transactionContext @@ -135,10 +121,8 @@ SENTRY_NO_INIT /** * Creates a transaction, binds it to the hub and returns the instance. - * * @param transactionContext The transaction context. * @param customSamplingContext Additional information about the sampling context. - * * @return The created transaction. */ + (id)startTransactionWithContext:(SentryTransactionContext *)transactionContext @@ -147,21 +131,19 @@ SENTRY_NO_INIT /** * Captures an error event and sends it to Sentry. - * * @param error The error to send to Sentry. + * @return The @c SentryId of the event or @c SentryId.empty if the event is not sent. * - * @return The SentryId of the event or SentryId.empty if the event is not sent. */ + (SentryId *)captureError:(NSError *)error NS_SWIFT_NAME(capture(error:)); /** * Captures an error event and sends it to Sentry. Only the data in this scope object will be added * to the event. The global scope will be ignored. - * * @param error The error to send to Sentry. * @param scope The scope containing event metadata. + * @return The @c SentryId of the event or @c SentryId.empty if the event is not sent. * - * @return The SentryId of the event or SentryId.empty if the event is not sent. */ + (SentryId *)captureError:(NSError *)error withScope:(SentryScope *)scope NS_SWIFT_NAME(capture(error:scope:)); @@ -169,32 +151,29 @@ SENTRY_NO_INIT /** * Captures an error event and sends it to Sentry. Maintains the global scope but mutates scope data * for only this call. - * * @param error The error to send to Sentry. * @param block The block mutating the scope only for this call. + * @return The @c SentryId of the event or @c SentryId.empty if the event is not sent. * - * @return The SentryId of the event or SentryId.empty if the event is not sent. */ + (SentryId *)captureError:(NSError *)error withScopeBlock:(void (^)(SentryScope *scope))block NS_SWIFT_NAME(capture(error:block:)); /** * Captures an exception event and sends it to Sentry. - * * @param exception The exception to send to Sentry. + * @return The @c SentryId of the event or @c SentryId.empty if the event is not sent. * - * @return The SentryId of the event or SentryId.empty if the event is not sent. */ + (SentryId *)captureException:(NSException *)exception NS_SWIFT_NAME(capture(exception:)); /** * Captures an exception event and sends it to Sentry. Only the data in this scope object will be * added to the event. The global scope will be ignored. - * * @param exception The exception to send to Sentry. * @param scope The scope containing event metadata. + * @return The @c SentryId of the event or @c SentryId.empty if the event is not sent. * - * @return The SentryId of the event or SentryId.empty if the event is not sent. */ + (SentryId *)captureException:(NSException *)exception withScope:(SentryScope *)scope NS_SWIFT_NAME(capture(exception:scope:)); @@ -202,11 +181,10 @@ SENTRY_NO_INIT /** * Captures an exception event and sends it to Sentry. Maintains the global scope but mutates scope * data for only this call. - * * @param exception The exception to send to Sentry. * @param block The block mutating the scope only for this call. + * @return The @c SentryId of the event or @c SentryId.empty if the event is not sent. * - * @return The SentryId of the event or SentryId.empty if the event is not sent. */ + (SentryId *)captureException:(NSException *)exception withScopeBlock:(void (^)(SentryScope *scope))block @@ -214,21 +192,19 @@ SENTRY_NO_INIT /** * Captures a message event and sends it to Sentry. - * * @param message The message to send to Sentry. + * @return The @c SentryId of the event or @c SentryId.empty if the event is not sent. * - * @return The SentryId of the event or SentryId.empty if the event is not sent. */ + (SentryId *)captureMessage:(NSString *)message NS_SWIFT_NAME(capture(message:)); /** * Captures a message event and sends it to Sentry. Only the data in this scope object will be added * to the event. The global scope will be ignored. - * * @param message The message to send to Sentry. * @param scope The scope containing event metadata. + * @return The @c SentryId of the event or @c SentryId.empty if the event is not sent. * - * @return The SentryId of the event or SentryId.empty if the event is not sent. */ + (SentryId *)captureMessage:(NSString *)message withScope:(SentryScope *)scope NS_SWIFT_NAME(capture(message:scope:)); @@ -236,11 +212,10 @@ SENTRY_NO_INIT /** * Captures a message event and sends it to Sentry. Maintains the global scope but mutates scope * data for only this call. - * * @param message The message to send to Sentry. * @param block The block mutating the scope only for this call. + * @return The @c SentryId of the event or @c SentryId.empty if the event is not sent. * - * @return The SentryId of the event or SentryId.empty if the event is not sent. */ + (SentryId *)captureMessage:(NSString *)message withScopeBlock:(void (^)(SentryScope *scope))block @@ -248,7 +223,6 @@ SENTRY_NO_INIT /** * Captures a manually created user feedback and sends it to Sentry. - * * @param userFeedback The user feedback to send to Sentry. */ + (void)captureUserFeedback:(SentryUserFeedback *)userFeedback @@ -256,8 +230,7 @@ SENTRY_NO_INIT /** * Adds a Breadcrumb to the current Scope of the current Hub. If the total number of breadcrumbs - * exceeds the `SentryOptions.maxBreadcrumbs`, the SDK removes the oldest breadcrumb. - * + * exceeds the @c SentryOptions.maxBreadcrumbs the SDK removes the oldest breadcrumb. * @param crumb The Breadcrumb to add to the current Scope of the current Hub. */ + (void)addBreadcrumb:(SentryBreadcrumb *)crumb NS_SWIFT_NAME(addBreadcrumb(_:)); @@ -265,7 +238,6 @@ SENTRY_NO_INIT /** * Use this method to modify the current Scope of the current Hub. The SDK uses the Scope to attach * contextual data to events. - * * @param callback The callback for configuring the current Scope of the current Hub. */ + (void)configureScope:(void (^)(SentryScope *scope))callback; @@ -277,27 +249,27 @@ SENTRY_NO_INIT /** * Set user to the current Scope of the current Hub. - * * @param user The user to set to the current Scope. */ + (void)setUser:(nullable SentryUser *)user; /** - * Starts a new SentrySession. If there's a running SentrySession, it ends it before starting the - * new one. You can use this method in combination with endSession to manually track SentrySessions. - * The SDK uses SentrySession to inform Sentry about release and project associated project health. + * Starts a new SentrySession. If there's a running @c SentrySession, it ends it before starting the + * new one. You can use this method in combination with endSession to manually track + * @c SentrySessions. The SDK uses SentrySession to inform Sentry about release and project + * associated project health. */ + (void)startSession; /** - * Ends the current SentrySession. You can use this method in combination with startSession to - * manually track SentrySessions. The SDK uses SentrySession to inform Sentry about release and + * Ends the current @c SentrySession. You can use this method in combination with @c startSession to + * manually track @c SentrySessions. The SDK uses SentrySession to inform Sentry about release and * project associated project health. */ + (void)endSession; /** - * This forces a crash, useful to test the SentryCrash integration + * This forces a crash, useful to test the @c SentryCrash integration */ + (void)crash; @@ -305,14 +277,13 @@ SENTRY_NO_INIT * Waits synchronously for the SDK to flush out all queued and cached items for up to the specified * timeout in seconds. If there is no internet connection, the function returns immediately. The SDK * doesn't dispose the client or the hub. - * * @param timeout The time to wait for the SDK to complete the flush. */ + (void)flush:(NSTimeInterval)timeout NS_SWIFT_NAME(flush(timeout:)); /** * Closes the SDK, uninstalls all the integrations, and calls flush with - * ``SentryOptions/shutdownTimeInterval``. + * @c SentryOptions.shutdownTimeInterval . */ + (void)close; diff --git a/Sources/Sentry/Public/SentrySamplingContext.h b/Sources/Sentry/Public/SentrySamplingContext.h index dd16e71457..557d5c2322 100644 --- a/Sources/Sentry/Public/SentrySamplingContext.h +++ b/Sources/Sentry/Public/SentrySamplingContext.h @@ -19,14 +19,12 @@ NS_SWIFT_NAME(SamplingContext) /** * Init a SentryTransactionSamplingContext. - * * @param transactionContext The context of the transaction being sampled. */ - (instancetype)initWithTransactionContext:(SentryTransactionContext *)transactionContext; /** * Init a SentryTransactionSamplingContext. - * * @param transactionContext The context of the transaction being sampled. * @param customSamplingContext Custom data used for sampling. */ diff --git a/Sources/Sentry/Public/SentryScope.h b/Sources/Sentry/Public/SentryScope.h index 8f0f294c4b..85df60ff1f 100644 --- a/Sources/Sentry/Public/SentryScope.h +++ b/Sources/Sentry/Public/SentryScope.h @@ -9,8 +9,7 @@ NS_ASSUME_NONNULL_BEGIN /** * The scope holds useful information that should be sent along with the event. For instance tags or * breadcrumbs are stored on the scope. - * - * For more information see: + * @see * https://docs.sentry.io/platforms/apple/enriching-events/scopes/#whats-a-scope-whats-a-hub */ NS_SWIFT_NAME(Scope) @@ -18,7 +17,6 @@ NS_SWIFT_NAME(Scope) /** * Returns current Span or Transaction. - * * @return current Span or Transaction or null if transaction has not been set. */ @property (nullable, nonatomic, strong) id span; @@ -66,22 +64,22 @@ NS_SWIFT_NAME(Scope) - (void)removeExtraForKey:(NSString *)key NS_SWIFT_NAME(removeExtra(key:)); /** - * Set dist in the scope + * Set @c dist in the scope */ - (void)setDist:(NSString *_Nullable)dist; /** - * Set environment in the scope + * Set @c environment in the scope */ - (void)setEnvironment:(NSString *_Nullable)environment; /** - * Sets the fingerprint in the scope + * Sets the @c fingerprint in the scope */ - (void)setFingerprint:(NSArray *_Nullable)fingerprint; /** - * Sets the level in the scope + * Sets the @c level in the scope */ - (void)setLevel:(enum SentryLevel)level; @@ -118,7 +116,6 @@ NS_SWIFT_NAME(Scope) /** * Adds an attachment to the Scope's list of attachments. The SDK adds the attachment to every event * sent to Sentry. - * * @param attachment The attachment to add to the Scope's list of attachments. */ - (void)addAttachment:(SentryAttachment *)attachment NS_SWIFT_NAME(addAttachment(_:)); @@ -140,7 +137,6 @@ NS_SWIFT_NAME(Scope) /** * Mutates the current transaction atomically. - * * @param callback the SentrySpanCallback. */ - (void)useSpan:(SentrySpanCallback)callback; diff --git a/Sources/Sentry/Public/SentrySpanContext.h b/Sources/Sentry/Public/SentrySpanContext.h index 9fa7bec732..7922dda051 100644 --- a/Sources/Sentry/Public/SentrySpanContext.h +++ b/Sources/Sentry/Public/SentrySpanContext.h @@ -45,36 +45,27 @@ SENTRY_NO_INIT @property (nullable, nonatomic, copy, readonly) NSString *spanDescription; /** - * Init a SentryContext with an operation code, - * traceId and spanId with be randomly created, - * sampled by default is Undecided. - * - * @return SentryContext + * Init a @c SentryContext with an operation code. + * @note @c traceId and @c spanId with be randomly created; @c sampled by default is + * @c kSentrySampleDecisionUndecided . */ - (instancetype)initWithOperation:(NSString *)operation; /** - * Init a SentryContext with an operation code and mark it as sampled or not. + * Init a @c SentryContext with an operation code and mark it as sampled or not. * TraceId and SpanId with be randomly created. - * * @param operation The operation this span is measuring. * @param sampled Determines whether the trace should be sampled. - * - * @return SentryContext */ - (instancetype)initWithOperation:(NSString *)operation sampled:(SentrySampleDecision)sampled; /** - * Init a SentryContext with given traceId, spanId and parentId. - * * @param traceId Determines which trace the Span belongs to. - * @param spanId The Span Id + * @param spanId The Span Id. * @param operation The operation this span is measuring. * @param parentId Id of a parent span. * @param sampled Determines whether the trace should be sampled. - * - * @return SentryContext */ - (instancetype)initWithTraceId:(SentryId *)traceId spanId:(SentrySpanId *)spanId @@ -83,16 +74,12 @@ SENTRY_NO_INIT sampled:(SentrySampleDecision)sampled; /** - * Init a SentryContext with given traceId, spanId and parentId. - * * @param traceId Determines which trace the Span belongs to. - * @param spanId The Span Id + * @param spanId The Span Id. * @param operation The operation this span is measuring. * @param parentId Id of a parent span. - * @param description The span description + * @param description The span description. * @param sampled Determines whether the trace should be sampled. - * - * @return SentryContext */ - (instancetype)initWithTraceId:(SentryId *)traceId spanId:(SentrySpanId *)spanId diff --git a/Sources/Sentry/Public/SentrySpanProtocol.h b/Sources/Sentry/Public/SentrySpanProtocol.h index deffb0af78..c416388e93 100644 --- a/Sources/Sentry/Public/SentrySpanProtocol.h +++ b/Sources/Sentry/Public/SentrySpanProtocol.h @@ -72,9 +72,7 @@ NS_SWIFT_NAME(Span) /** * Starts a child span. - * * @param operation Short code identifying the type of operation the span is measuring. - * * @return SentrySpan */ - (id)startChildWithOperation:(NSString *)operation @@ -82,10 +80,8 @@ NS_SWIFT_NAME(Span) /** * Starts a child span. - * * @param operation Defines the child span operation. * @param description Define the child span description. - * * @return SentrySpan */ - (id)startChildWithOperation:(NSString *)operation @@ -98,7 +94,7 @@ NS_SWIFT_NAME(Span) - (void)setDataValue:(nullable id)value forKey:(NSString *)key NS_SWIFT_NAME(setData(value:key:)); /** - * Use setDataValue instead. This method calls setDataValue, was added by mistake, and will be + * Use @c setDataValue instead. This method calls @c setDataValue, was added by mistake, and will be * removed in a future version. */ - (void)setExtraValue:(nullable id)value @@ -123,10 +119,8 @@ NS_SWIFT_NAME(Span) * Set a measurement without unit. When setting the measurement without the unit, no formatting * will be applied to the measurement value in the Sentry product, and the value will be shown as * is. - * * @discussion Setting a measurement with the same name on the same transaction multiple times only * keeps the last value. - * * @param name the name of the measurement * @param value the value of the measurement */ @@ -135,10 +129,8 @@ NS_SWIFT_NAME(Span) /** * Set a measurement with specific unit. - * * @discussion Setting a measurement with the same name on the same transaction multiple times only * keeps the last value. - * * @param name the name of the measurement * @param value the value of the measurement * @param unit the unit the value is measured in @@ -155,14 +147,12 @@ NS_SWIFT_NAME(Span) /** * Finishes the span by setting the end time and span status. - * * @param status The status of this span * */ - (void)finishWithStatus:(SentrySpanStatus)status NS_SWIFT_NAME(finish(status:)); /** * Returns the trace information that could be sent as a sentry-trace header. - * * @return SentryTraceHeader. */ - (SentryTraceHeader *)toTraceHeader; diff --git a/Sources/Sentry/Public/SentryTraceHeader.h b/Sources/Sentry/Public/SentryTraceHeader.h index 92f3d200cd..7c9801b177 100644 --- a/Sources/Sentry/Public/SentryTraceHeader.h +++ b/Sources/Sentry/Public/SentryTraceHeader.h @@ -26,13 +26,9 @@ SENTRY_NO_INIT @property (nonatomic, readonly) SentrySampleDecision sampled; /** - * Initialize a SentryTraceHeader with given trace id, span id and sample decision. - * * @param traceId The trace id. * @param spanId The span id. * @param sampled The decision made to sample the trace related to this header. - * - * @return A SentryTraceHeader. */ - (instancetype)initWithTraceId:(SentryId *)traceId spanId:(SentrySpanId *)spanId diff --git a/Sources/Sentry/Public/SentryTransactionContext.h b/Sources/Sentry/Public/SentryTransactionContext.h index 16384bf07c..06ca0612d2 100644 --- a/Sources/Sentry/Public/SentryTransactionContext.h +++ b/Sources/Sentry/Public/SentryTransactionContext.h @@ -27,40 +27,28 @@ SENTRY_NO_INIT @property (nonatomic, strong, nullable) NSNumber *sampleRate; /** - * Init a SentryTransactionContext with given name and set other fields by default - * * @param name Transaction name * @param operation The operation this span is measuring. - * * @return SentryTransactionContext */ - (instancetype)initWithName:(NSString *)name operation:(NSString *)operation; /** - * Init a SentryTransactionContext with given name and set other fields by default - * * @param name Transaction name * @param operation The operation this span is measuring. * @param sampled Determines whether the trace should be sampled. - * - * @return SentryTransactionContext */ - (instancetype)initWithName:(NSString *)name operation:(NSString *)operation sampled:(SentrySampleDecision)sampled; /** - * Init a SentryTransactionContext with given name, traceId, SpanId, parentSpanId and whether the - * parent is sampled. - * * @param name Transaction name * @param operation The operation this span is measuring. * @param traceId Trace Id * @param spanId Span Id * @param parentSpanId Parent span id * @param parentSampled Whether the parent is sampled - * - * @return SentryTransactionContext */ - (instancetype)initWithName:(NSString *)name operation:(NSString *)operation diff --git a/Sources/Sentry/Public/SentryUserFeedback.h b/Sources/Sentry/Public/SentryUserFeedback.h index 1878c369e2..430c5dec1f 100644 --- a/Sources/Sentry/Public/SentryUserFeedback.h +++ b/Sources/Sentry/Public/SentryUserFeedback.h @@ -14,7 +14,6 @@ SENTRY_NO_INIT /** * Initializes SentryUserFeedback and sets the required eventId. - * * @param eventId The eventId of the event to which the user feedback is associated. */ - (instancetype)initWithEventId:(SentryId *)eventId; diff --git a/Sources/Sentry/SentryAppStateManager.m b/Sources/Sentry/SentryAppStateManager.m index 68bb9974f6..d50465849f 100644 --- a/Sources/Sentry/SentryAppStateManager.m +++ b/Sources/Sentry/SentryAppStateManager.m @@ -134,10 +134,9 @@ - (void)dealloc /** * It is called when an app is receiving events / it is in the foreground and when we receive a - * SentryHybridSdkDidBecomeActiveNotification. - * - * This also works when using SwiftUI or Scenes, as UIKit posts a didBecomeActiveNotification - * regardless of whether your app uses scenes, see + * @c SentryHybridSdkDidBecomeActiveNotification. + * @discussion This also works when using SwiftUI or Scenes, as UIKit posts a + * @c didBecomeActiveNotification regardless of whether your app uses scenes, see * https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1622956-applicationdidbecomeactive. */ - (void)didBecomeActive diff --git a/Sources/Sentry/SentryCrashReportConverter.m b/Sources/Sentry/SentryCrashReportConverter.m index d6672fad01..41f2cc49e6 100644 --- a/Sources/Sentry/SentryCrashReportConverter.m +++ b/Sources/Sentry/SentryCrashReportConverter.m @@ -462,27 +462,26 @@ - (void)enhanceValueFromNotableAddresses:(SentryException *)exception * Get the message of fatalError, assert, and precondition to set it as the exception value if the * crashInfo contains the message. * - * Swift puts the messages of fatalError, assert, and precondition into the crashInfo of the - * libswiftCore.dylib. We found somewhat proof that the swift runtime uses __crash_info: fatalError - * (1) calls swift_reportError (2) calls reportOnCrash (3) which uses (4) the __crash_info (5). The - * documentation of Apple and Swift doesn't mention anything about where the __crash_info ends up. - * Trying fatalError, assert, and precondition on iPhone, iPhone simulator, and macOS all showed - * that the message ends up in the crashInfo of the libswiftCore.dylib. For example, on the - * simulator, other binary images also contain a crash_info_message with information about the - * stacktrace. We only care about the message of fatalError, assert, or precondition, and we already - * get the stacktrace from the threads, retrieving it from libswiftCore.dylib seems to be the most - * reliable option. + * Swift puts the messages of fatalError, assert, and precondition into the @c crashInfo of the + * @c libswiftCore.dylib. We found somewhat proof that the swift runtime uses @c __crash_info: + * fatalError (1) calls @c swift_reportError (2) calls @c reportOnCrash (3) which uses (4) the + * @c __crash_info (5). The documentation of Apple and Swift doesn't mention anything about where + * the @c __crash_info ends up. Trying fatalError, assert, and precondition on iPhone, iPhone + * simulator, and macOS all showed that the message ends up in the crashInfo of the + * @c libswiftCore.dylib. For example, on the simulator, other binary images also contain a + * @c crash_info_message with information about the stacktrace. We only care about the message of + * fatalError, assert, or precondition, and we already get the stacktrace from the threads, + * retrieving it from @c libswiftCore.dylib seems to be the most reliable option. * - * Links: - * 1. + * @seealso * https://github.com/apple/swift/blob/d1bb98b11ede375a1cee739f964b7d23b6657aaf/stdlib/public/runtime/Errors.cpp#L365-L377 - * 2. + * @seealso * https://github.com/apple/swift/blob/d1bb98b11ede375a1cee739f964b7d23b6657aaf/stdlib/public/runtime/Errors.cpp#L361 - * 3. + * @seealso * https://github.com/apple/swift/blob/d1bb98b11ede375a1cee739f964b7d23b6657aaf/stdlib/public/runtime/Errors.cpp#L269-L293 - * 4. + * @seealso * https://github.com/apple/swift/blob/d1bb98b11ede375a1cee739f964b7d23b6657aaf/stdlib/public/runtime/Errors.cpp#L264-L293 - * 5. + * @seealso * https://github.com/apple/swift/blob/d1bb98b11ede375a1cee739f964b7d23b6657aaf/include/swift/Runtime/Debug.h#L29-L58 */ - (void)enhanceValueFromCrashInfoMessage:(SentryException *)exception diff --git a/Sources/Sentry/SentryDevice.mm b/Sources/Sentry/SentryDevice.mm index c831c438e0..f27cf1c56d 100644 --- a/Sources/Sentry/SentryDevice.mm +++ b/Sources/Sentry/SentryDevice.mm @@ -26,7 +26,7 @@ /** * @brief Get an iOS hardware model name, or for mac devices, either the hardware model name or CPU * architecture of the device, depending on the option provided. - * @note For an iOS CPU architecture name, `getArchitectureName` must be used. + * @note For an iOS CPU architecture name, @c getArchitectureName must be used. * @discussion The values returned are different between iOS and macOS depending on which option is * provided. Some examples of values returned on different devices: * @code diff --git a/Sources/Sentry/SentryHttpTransport.m b/Sources/Sentry/SentryHttpTransport.m index 6010789f0d..61919c5922 100644 --- a/Sources/Sentry/SentryHttpTransport.m +++ b/Sources/Sentry/SentryHttpTransport.m @@ -39,7 +39,7 @@ * Relay expects the discarded events split by data category and reason; see * https://develop.sentry.dev/sdk/client-reports/#envelope-item-payload. * We could use nested dictionaries, but instead, we use a dictionary with key - * `data-category:reason` and value `SentryDiscardedEvent` because it's easier to read and type. + * @c data-category:reason and value @c SentryDiscardedEvent because it's easier to read and type. */ @property (nonatomic, strong) NSMutableDictionary *discardedEvents; diff --git a/Sources/Sentry/SentryHub.m b/Sources/Sentry/SentryHub.m index 0abe5bdefd..420986fd9c 100644 --- a/Sources/Sentry/SentryHub.m +++ b/Sources/Sentry/SentryHub.m @@ -563,9 +563,9 @@ - (void)configureScope:(void (^)(SentryScope *scope))callback } /** - * Checks if a specific Integration (`integrationClass`) has been installed. - * @return BOOL If instance of `integrationClass` exists within - * `SentryHub.installedIntegrations`. + * Checks if a specific Integration (@c integrationClass) has been installed. + * @return @c YES if instance of @c integrationClass exists within + * @c SentryHub.installedIntegrations . */ - (BOOL)isIntegrationInstalled:(Class)integrationClass { diff --git a/Sources/Sentry/SentryMetricKitIntegration.m b/Sources/Sentry/SentryMetricKitIntegration.m index 1050c2d31e..874aaef3b2 100644 --- a/Sources/Sentry/SentryMetricKitIntegration.m +++ b/Sources/Sentry/SentryMetricKitIntegration.m @@ -225,16 +225,16 @@ - (void)captureMXEvent:(SentryMXCallStackTree *)callStackTree } /** - * If callStackPerThread is false, MetricKit organizes the stacktraces in a tree structure. See + * If @c callStackPerThread is @c NO , MetricKit organizes the stacktraces in a tree structure. See * https://developer.apple.com/videos/play/wwdc2020/10078/?time=224. The stacktrace consists of the - * last sibbling leaf frame plus its ancestors. + * last sibling leaf frame plus its ancestors. * * The algorithm adds all frames to a list until it finds a leaf frame being the last sibling. Then * it reports that frame with its siblings and ancestors as a stacktrace. * * In the following example, the algorithm starts with frame 0, continues until frame 6, and reports * a stacktrace. Then it pops all sibling, goes back up to frame 3, and continues the search. - * + * @code * | frame 0 | * | frame 1 | * | frame 2 | @@ -249,6 +249,7 @@ - (void)captureMXEvent:(SentryMXCallStackTree *)callStackTree * | frame 11 | * | frame 12 | * | frame 13 | -> stack trace consists of [10, 11, 12, 13] + * @endcode */ - (void)buildAndCaptureMXEventFor:(NSArray *)rootFrames params:(SentryMXExceptionParams *)params diff --git a/Sources/Sentry/SentryNSURLSessionTaskSearch.m b/Sources/Sentry/SentryNSURLSessionTaskSearch.m index 42eb04104c..192943813f 100644 --- a/Sources/Sentry/SentryNSURLSessionTaskSearch.m +++ b/Sources/Sentry/SentryNSURLSessionTaskSearch.m @@ -19,16 +19,16 @@ @implementation SentryNSURLSessionTaskSearch /** * In order to be able to track a network request, we need to know when it starts and when it - * finishes. NSURLSessionTask has a `resume` method that starts the request, and the only way to - * know when it finishes is to check the task `state`. Using KVO is not working, - * It randomly crashs an app. We hade two issues open because of this, #1328 and #1448. Instead - * we are swizzling `setState:`. From iOS 10 to 13, NSURLSessionTask does not implement - * `setState:` and Apple uses a subclass returned by NSURLSession that implementes `setState:`. - * We need to discover which class to swizzle. + * finishes. @c NSURLSessionTask has a @c resume method that starts the request, and the only + * way to know when it finishes is to check the task @c state. Using KVO is not working, It + * randomly crashes an app. We had two issues open because of this, #1328 and #1448. Instead we + * are swizzling @c setState:. From iOS 10 to 13, @c NSURLSessionTask does not implement + * @c setState: and Apple uses a subclass returned by NSURLSession that implements @c setState: + * . We need to discover which class to swizzle. * - * Apples intermediate classes for iOS does not call [super resume], so we can swizzle both - * classes. This Apple approach may change in the future, we need to have enough tests to detect - * it early. + * Apple's intermediate classes for iOS does not call @c [super @c resume], so we can swizzle + * both classes. This Apple approach may change in the future, we need to have enough tests to + * detect it early. */ // WARNING START diff --git a/Sources/Sentry/SentryOptions.m b/Sources/Sentry/SentryOptions.m index 8f509bc1ac..4828aae3f3 100644 --- a/Sources/Sentry/SentryOptions.m +++ b/Sources/Sentry/SentryOptions.m @@ -223,7 +223,7 @@ - (void)setDsn:(NSString *)dsn } /** - * Populates all `SentryOptions` values from `options` dict using fallbacks/defaults if needed. + * Populates all @c SentryOptions values from @c options dict using fallbacks/defaults if needed. */ - (BOOL)validateOptions:(NSDictionary *)options didFailWithError:(NSError *_Nullable *_Nullable)error @@ -565,11 +565,11 @@ - (BOOL)enableProfiling_DEPRECATED_TEST_ONLY /** * Checks if the passed in block is actually of type block. We can't check if the block matches a - * specific block without some complex objc runtime method calls and therefore we only check if its - * a block or not. Assigning a wrong block to the SentryOption blocks still could lead to crashes at - * runtime, but when someone uses the initWithDict they should better know what they are doing. - * - * Taken from https://gist.github.com/steipete/6ee378bd7d87f276f6e0 + * specific block without some complex objc runtime method calls and therefore we only check if it's + * a block or not. Assigning a wrong block to the @c SentryOptions blocks still could lead to + * crashes at runtime, but when someone uses the @c initWithDict they should better know what they + * are doing. + * @see Taken from https://gist.github.com/steipete/6ee378bd7d87f276f6e0 */ - (BOOL)isBlock:(nullable id)block { diff --git a/Sources/Sentry/SentryReachability.m b/Sources/Sentry/SentryReachability.m index 70d882a31c..75c9108ccc 100644 --- a/Sources/Sentry/SentryReachability.m +++ b/Sources/Sentry/SentryReachability.m @@ -42,8 +42,7 @@ /** * Check whether the connectivity change should be noted or ignored. - * - * @return YES if the connectivity change should be reported + * @return @c YES if the connectivity change should be reported */ BOOL SentryConnectivityShouldReportChange(SCNetworkReachabilityFlags flags) @@ -91,7 +90,7 @@ } /** - * Callback invoked by SCNetworkReachability, which calls an Objective-C block + * Callback invoked by @c SCNetworkReachability, which calls an Objective-C block * that handles the connection change. */ void diff --git a/Sources/Sentry/SentrySDK.m b/Sources/Sentry/SentrySDK.m index f4568f0b3f..c5a5eb875f 100644 --- a/Sources/Sentry/SentrySDK.m +++ b/Sources/Sentry/SentrySDK.m @@ -351,7 +351,7 @@ + (void)endSession } /** - * Install integrations and keeps ref in `SentryHub.integrations` + * Install integrations and keeps ref in @c SentryHub.integrations */ + (void)installIntegrations { diff --git a/Sources/Sentry/SentrySessionTracker.m b/Sources/Sentry/SentrySessionTracker.m index a668ad15c5..ed8afe8ed9 100644 --- a/Sources/Sentry/SentrySessionTracker.m +++ b/Sources/Sentry/SentrySessionTracker.m @@ -132,18 +132,17 @@ - (void)endCachedSession /** * It is called when an App. is receiving events / It is in the foreground and when we receive a - * SentryHybridSdkDidBecomeActiveNotification. There is no guarantee that this method is called once - * or twice. We need to ensure that we execute it only once. - * - * This also works when using SwiftUI or Scenes, as UIKit posts a didBecomeActiveNotification - * regardless of whether your app uses scenes, see + * @c SentryHybridSdkDidBecomeActiveNotification. There is no guarantee that this method is called + * once or twice. We need to ensure that we execute it only once. + * @discussion This also works when using SwiftUI or Scenes, as UIKit posts a + * @c didBecomeActiveNotification regardless of whether your app uses scenes, see * https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1622956-applicationdidbecomeactive. - * - * Hybrid SDKs must only post this notification if they are running in the foreground because the - * auto session tracking logic doesn't support background tasks. Posting the notification from the - * background would mess up the session stats. Hybrid SDKs must only post this notification if they - * are running in the foreground because the auto session tracking logic doesn't support background - * tasks. Posting the notification from the background would mess up the session stats. + * @warning Hybrid SDKs must only post this notification if they are running in the foreground + * because the auto session tracking logic doesn't support background tasks. Posting the + * notification from the background would mess up the session stats. Hybrid SDKs must only post this + * notification if they are running in the foreground because the auto session tracking logic + * doesn't support background tasks. Posting the notification from the background would mess up the + * session stats. */ - (void)didBecomeActive { diff --git a/Sources/Sentry/SentryStacktrace.m b/Sources/Sentry/SentryStacktrace.m index d63b881b76..6c4250f096 100644 --- a/Sources/Sentry/SentryStacktrace.m +++ b/Sources/Sentry/SentryStacktrace.m @@ -18,8 +18,10 @@ - (instancetype)initWithFrames:(NSArray *)frames return self; } -/// This function fixes duplicate frames and removes the first duplicate -/// https://github.com/kstenerud/KSCrash/blob/05cdc801cfc578d256f85de2e72ec7877cbe79f8/Source/KSCrash/Recording/Tools/KSStackCursor_MachineContext.c#L84 +/** + * This function fixes duplicate frames and removes the first duplicate + * https://github.com/kstenerud/KSCrash/blob/05cdc801cfc578d256f85de2e72ec7877cbe79f8/Source/KSCrash/Recording/Tools/KSStackCursor_MachineContext.c#L84 + */ - (void)fixDuplicateFrames { if (self.frames.count < 2 || nil == self.registers) { diff --git a/Sources/Sentry/SentrySysctl.m b/Sources/Sentry/SentrySysctl.m index feaf8ae25e..7b526a704e 100644 --- a/Sources/Sentry/SentrySysctl.m +++ b/Sources/Sentry/SentrySysctl.m @@ -7,16 +7,15 @@ static NSDate *runtimeInit = nil; /** - * * Constructor priority must be bounded between 101 and 65535 inclusive, see * https://gcc.gnu.org/onlinedocs/gcc-4.7.0/gcc/Function-Attributes.html and * https://gcc.gnu.org/onlinedocs/gcc-4.7.0/gcc/C_002b_002b-Attributes.html#C_002b_002b-Attributes * The constructor attribute causes the function to be called automatically before execution enters - * main(). The lower the priority number, the sooner the constructor runs, which means 100 runs - * before 101. As we want to be as close to main() as possible, we choose a high number. + * @c main() . The lower the priority number, the sooner the constructor runs, which means 100 runs + * before 101. As we want to be as close to @c main() as possible, we choose a high number. * - * Previously, we used __DATA,__mod_init_func, which leads to compilation errors and runtime crashes - * when enabling the address sanitizer. + * Previously, we used @c __DATA,__mod_init_func , which leads to compilation errors and runtime + * crashes when enabling the address sanitizer. */ __used __attribute__((constructor(60000))) static void sentryModuleInitializationHook() diff --git a/Sources/Sentry/SentryTracer.m b/Sources/Sentry/SentryTracer.m index 64b718789f..ea94a6fcad 100644 --- a/Sources/Sentry/SentryTracer.m +++ b/Sources/Sentry/SentryTracer.m @@ -49,10 +49,10 @@ @property (nonatomic, strong) SentryHub *hub; @property (nonatomic) SentrySpanStatus finishStatus; -/** This property is different from isFinished. While isFinished states if the tracer is actually - * finished, this property tells you if finish was called on the tracer. Calling finish doesn't - * necessarily lead to finishing the tracer, because it could still wait for child spans to finish - * if waitForChildren is YES. */ +/** This property is different from @c isFinished. While @c isFinished states if the tracer is + * actually finished, this property tells you if finish was called on the tracer. Calling + * @c -[finish] doesn't necessarily lead to finishing the tracer, because it could still wait for + * child spans to finish if @c waitForChildren is @c YES . */ @property (nonatomic) BOOL wasFinishCalled; @property (nonatomic) NSTimeInterval idleTimeout; @property (nonatomic, nullable, strong) SentryDispatchQueueWrapper *dispatchQueueWrapper; diff --git a/Sources/Sentry/SentryUIViewControllerPerformanceTracker.m b/Sources/Sentry/SentryUIViewControllerPerformanceTracker.m index 56bac7d833..11000c055a 100644 --- a/Sources/Sentry/SentryUIViewControllerPerformanceTracker.m +++ b/Sources/Sentry/SentryUIViewControllerPerformanceTracker.m @@ -157,9 +157,10 @@ - (void)viewControllerViewDidAppear:(UIViewController *)controller * ‘will’ callback method, you end the process in both the corresponding ‘did’ and the opposite * ‘will’ callback method. * - * As stated above viewWillAppear doesn't need to be followed by a viewDidAppear. A viewWillAppear - * can also be followed by a viewWillDisappear. Therefore, we finish the transaction in - * viewWillDisappear, if it wasn't already finished in viewDidAppear. + * As stated above @c viewWillAppear doesn't need to be followed by a @c viewDidAppear. A + * @c viewWillAppear can also be followed by a @c viewWillDisappear. Therefore, we finish the + * transaction in + * @c viewWillDisappear, if it wasn't already finished in @c viewDidAppear. */ - (void)viewControllerViewWillDisappear:(UIViewController *)controller callbackToOrigin:(void (^)(void))callbackToOrigin diff --git a/Sources/Sentry/SentryUIViewControllerSwizzling.m b/Sources/Sentry/SentryUIViewControllerSwizzling.m index 2b7450f791..427d99359c 100644 --- a/Sources/Sentry/SentryUIViewControllerSwizzling.m +++ b/Sources/Sentry/SentryUIViewControllerSwizzling.m @@ -15,12 +15,12 @@ # import /** - * 'swizzleRootViewControllerFromUIApplication:' requires an object that conforms to - * 'SentryUIApplication' to swizzle it, this way, instead of relying on UIApplication, we can test - * with a mock class. + * @c swizzleRootViewControllerFromUIApplication: requires an object that conforms to + * @c SentryUIApplication to swizzle it, this way, instead of relying on @c UIApplication, we can + * test with a mock class. * - * This category makes UIApplication conform to - * SentryUIApplication in order to be used by 'SentryUIViewControllerSwizzling'. + * This category makes @c UIApplication conform to + * @c SentryUIApplication in order to be used by @c SentryUIViewControllerSwizzling . */ @interface UIApplication (SentryUIApplication) @@ -209,8 +209,8 @@ - (void)swizzleUIViewControllersOfImage:(NSString *)imageName /** * If the iOS version is 13 or newer, and the project does not use a custom Window initialization - * the app uses a UIScenes to manage windows instead of the old AppDelegate. - * We wait for the first scene to connect to the app in order to find the rootViewController. + * the app uses a @c UIScene to manage windows instead of the old AppDelegate. + * We wait for the first scene to connect to the app in order to find the @c rootViewController. */ - (void)swizzleRootViewControllerFromSceneDelegateNotification:(NSNotification *)notification { @@ -306,11 +306,10 @@ - (void)swizzleRootViewControllerAndDescendant:(UIViewController *)rootViewContr } /** - * We need to swizzle UIViewController 'loadView' - * because we can`t do it for controllers that use Nib files - * (see `swizzleLoadView` for more information). - * SentryUIViewControllerPerformanceTracker makes sure we don't get two spans - * if the loadView of an actual UIViewController is swizzled. + * We need to swizzle @c -[UIViewController @c loadView] because we can't do it for controllers that + * use Nib files (see @c swizzleLoadView for more information). + * @c SentryUIViewControllerPerformanceTracker makes sure we don't get two spans + * if the @c -[loadView] of an actual @c UIViewController is swizzled. */ - (void)swizzleUIViewController { diff --git a/Sources/Sentry/include/HybridPublic/PrivateSentrySDKOnly.h b/Sources/Sentry/include/HybridPublic/PrivateSentrySDKOnly.h index f788ce5981..d6a4001914 100644 --- a/Sources/Sentry/include/HybridPublic/PrivateSentrySDKOnly.h +++ b/Sources/Sentry/include/HybridPublic/PrivateSentrySDKOnly.h @@ -9,19 +9,18 @@ NS_ASSUME_NONNULL_BEGIN /** - * A callback to be notified when the AppStartMeasurement is available. + * A callback to be notified when the @c AppStartMeasurement is available. */ typedef void (^SentryOnAppStartMeasurementAvailable)( SentryAppStartMeasurement *_Nullable appStartMeasurement); /** - * ATTENTION: This class is reserved for hybrid SDKs. Methods may be changed, renamed or removed + * @warning This class is reserved for hybrid SDKs. Methods may be changed, renamed or removed * without notice. If you want to use one of these methods here please open up an issue and let us * know. - * - * The name of this class is supposed to be a bit weird and ugly. The name starts with private on - * purpose so users don't see it in code completion when typing Sentry. We also add only at the end - * to make it more obvious you shouldn't use it. + * @note The name of this class is supposed to be a bit weird and ugly. The name starts with private + * on purpose so users don't see it in code completion when typing Sentry. We also add only at the + * end to make it more obvious you shouldn't use it. */ @interface PrivateSentrySDKOnly : NSObject @@ -33,13 +32,14 @@ typedef void (^SentryOnAppStartMeasurementAvailable)( + (void)captureEnvelope:(SentryEnvelope *)envelope; /** - * Create an envelope from NSData. Needed for example by Flutter. + * Create an envelope from @c NSData. Needed for example by Flutter. */ + (nullable SentryEnvelope *)envelopeWithData:(NSData *)data; /** - * Returns the current list of debug images. Be aware that the SentryDebugMeta is actually - * describing a debug image. This class should be renamed to SentryDebugImage in a future version. + * Returns the current list of debug images. Be aware that the @c SentryDebugMeta is actually + * describing a debug image. + * @todo This class should be renamed to @c SentryDebugImage in a future version. */ + (NSArray *)getDebugImages; @@ -74,11 +74,12 @@ typedef void (^SentryOnAppStartMeasurementAvailable)( /** * If enabled, the SDK won't send the app start measurement with the first transaction. Instead, if - * enableAutoPerformanceTracing is enabled, the SDK measures the app start and then calls - * onAppStartMeasurementAvailable. Furthermore, the SDK doesn't set all values for the app start + * @c enableAutoPerformanceTracing is enabled, the SDK measures the app start and then calls + * @c onAppStartMeasurementAvailable. Furthermore, the SDK doesn't set all values for the app start * measurement because the HybridSDKs initialize the Cocoa SDK too late to receive all - * notifications. Instead, the SDK sets the appStartDuration to 0 and the - * didFinishLaunchingTimestamp to timeIntervalSinceReferenceDate. Default is NO. + * notifications. Instead, the SDK sets the @c appStartDuration to @c 0 and the + * @c didFinishLaunchingTimestamp to @c timeIntervalSinceReferenceDate. + * @note Default is @c NO. */ @property (class, nonatomic, assign) BOOL appStartMeasurementHybridSDKMode; diff --git a/Sources/Sentry/include/HybridPublic/SentryEnvelope.h b/Sources/Sentry/include/HybridPublic/SentryEnvelope.h index a7edf941dc..dfa3493539 100644 --- a/Sources/Sentry/include/HybridPublic/SentryEnvelope.h +++ b/Sources/Sentry/include/HybridPublic/SentryEnvelope.h @@ -22,33 +22,29 @@ NS_ASSUME_NONNULL_BEGIN SENTRY_NO_INIT /** - * Initializes an SentryEnvelopeHeader object with the specified eventId. - * - * Sets the sdkInfo from SentryMeta. - * + * Initializes an @c SentryEnvelopeHeader object with the specified eventId. + * @note Sets the @c sdkInfo from @c SentryMeta. * @param eventId The identifier of the event. Can be nil if no event in the envelope or attachment * related to event. */ - (instancetype)initWithId:(SentryId *_Nullable)eventId; /** - * Initializes an SentryEnvelopeHeader object with the specified eventId and traceContext. - * - * @param eventId The identifier of the event. Can be nil if no event in the envelope or attachment - * related to event. + * Initializes a @c SentryEnvelopeHeader object with the specified @c eventId and @c traceContext. + * @param eventId The identifier of the event. Can be @c nil if no event in the envelope or + * attachment related to event. * @param traceContext Current trace state. */ - (instancetype)initWithId:(nullable SentryId *)eventId traceContext:(nullable SentryTraceContext *)traceContext; /** - * Initializes an SentryEnvelopeHeader object with the specified eventId, skdInfo and traceContext. - * - * It is recommended to use initWithId:traceContext: because it sets the sdkInfo for you. - * - * @param eventId The identifier of the event. Can be nil if no event in the envelope or attachment - * related to event. - * @param sdkInfo sdkInfo Describes the Sentry SDK. Can be nil for backwards compatibility. New + * Initializes a @c SentryEnvelopeHeader object with the specified @c eventId, @c skdInfo and + * @c traceContext. It is recommended to use @c initWithId:traceContext: because it sets the + * @c sdkInfo for you. + * @param eventId The identifier of the event. Can be @c nil if no event in the envelope or + * attachment related to event. + * @param sdkInfo Describes the Sentry SDK. Can be @c nil for backwards compatibility. New * instances should always provide a version. * @param traceContext Current trace state. */ @@ -58,8 +54,8 @@ SENTRY_NO_INIT /** * The event identifier, if available. - * An event id exist if the envelope contains an event of items within it are - * related. i.e Attachments + * An event id exist if the envelope contains an event of items within it are related. i.e + * Attachments */ @property (nullable, nonatomic, readonly, copy) SentryId *eventId; @@ -104,25 +100,24 @@ SENTRY_NO_INIT - (instancetype)initWithId:(SentryId *_Nullable)id items:(NSArray *)items; /** - * Initializes a SentryEnvelope with a single session. + * Initializes a @c SentryEnvelope with a single session. * @param session to init the envelope with. - * @return an initialized SentryEnvelope */ - (instancetype)initWithSession:(SentrySession *)session; /** - * Initializes a SentryEnvelope with a list of sessions. - * Can be used when an operations that starts a session closes an ongoing - * session + * Initializes a @c SentryEnvelope with a list of sessions. + * Can be used when an operation that starts a session closes an ongoing session. * @param sessions to init the envelope with. - * @return an initialized SentryEnvelope */ - (instancetype)initWithSessions:(NSArray *)sessions; - (instancetype)initWithHeader:(SentryEnvelopeHeader *)header items:(NSArray *)items NS_DESIGNATED_INITIALIZER; -// Convenience init for a single event +/** + * Convenience init for a single event. + */ - (instancetype)initWithEvent:(SentryEvent *)event; - (instancetype)initWithUserFeedback:(SentryUserFeedback *)userFeedback; diff --git a/Sources/Sentry/include/SentryANRTracker.h b/Sources/Sentry/include/SentryANRTracker.h index 9bdd45659d..2178215b82 100644 --- a/Sources/Sentry/include/SentryANRTracker.h +++ b/Sources/Sentry/include/SentryANRTracker.h @@ -11,15 +11,14 @@ NS_ASSUME_NONNULL_BEGIN * This class detects ANRs with a dedicated watchdog thread. The thread schedules a simple block to * run on the main thread, sleeps for the configured timeout interval, and checks if the main thread * executed this block. - * - * @discussion We decided against using a CFRunLoopObserver or the CADisplayLink, which the - * SentryFramesTracker already uses, because they come with two disadvantages. First, the solution - * is expensive. Quick benchmarks showed that hooking into the main thread's run loop and checking - * for every event to process if the main thread executes it in time added around 0,5 % of CPU - * overhead. Furthermore, if the main thread runs all scheduled events in time, it doesn't mean that - * there is no ANR ongoing. It could be that the run loop of the main thread is busy for 20 seconds, - * and it executes all events in time. Instead, what matters is how long the main thread needs to - * execute a newly added event to the run loop. + * @discussion We decided against using a @c CFRunLoopObserver or the @c CADisplayLink, which the + * @c SentryFramesTracker already uses, because they come with two disadvantages. First, the + * solution is expensive. Quick benchmarks showed that hooking into the main thread's run loop and + * checking for every event to process if the main thread executes it in time added around 0,5 % of + * CPU overhead. Furthermore, if the main thread runs all scheduled events in time, it doesn't mean + * that there is no ANR ongoing. It could be that the run loop of the main thread is busy for 20 + * seconds, and it executes all events in time. Instead, what matters is how long the main thread + * needs to execute a newly added event to the run loop. */ @interface SentryANRTracker : NSObject SENTRY_NO_INIT diff --git a/Sources/Sentry/include/SentryAppState.h b/Sources/Sentry/include/SentryAppState.h index 1d099734fb..2b853f0563 100644 --- a/Sources/Sentry/include/SentryAppState.h +++ b/Sources/Sentry/include/SentryAppState.h @@ -13,11 +13,9 @@ SENTRY_NO_INIT systemBootTimestamp:(NSDate *)systemBootTimestamp; /** - * Initializes SentryAppState from a JSON object. - * - * @param jsonObject The jsonObject containing the session. - * - * @return The SentrySession or nil if the JSONObject contains an error. + * Initializes @c SentryAppState from a JSON object. + * @param jsonObject The @c jsonObject containing the session. + * @return The @c SentrySession or @c nil if @c jsonObject contains an error. */ - (nullable instancetype)initWithJSONObject:(NSDictionary *)jsonObject; diff --git a/Sources/Sentry/include/SentryAppStateManager.h b/Sources/Sentry/include/SentryAppStateManager.h index c1cb0017d1..0a77e32a4d 100644 --- a/Sources/Sentry/include/SentryAppStateManager.h +++ b/Sources/Sentry/include/SentryAppStateManager.h @@ -27,11 +27,10 @@ SENTRY_NO_INIT /** * Builds the current app state. - * - * @discussion The systemBootTimestamp is calculated by taking the current time and substracting - * NSProcesInfo.systemUptime. NSProcesInfo.systemUptime returns the amount of time the system has - * been awake since the last time it was restarted. This means This is a good enough approximation - * about the timestamp the system booted. + * @discussion The systemBootTimestamp is calculated by taking the current time and subtracting + * @c NSProcesInfo.systemUptime . @c NSProcesInfo.systemUptime returns the amount of time the system + * has been awake since the last time it was restarted. This means This is a good enough + * approximation about the timestamp the system booted. */ - (SentryAppState *)buildCurrentAppState; diff --git a/Sources/Sentry/include/SentryAttachment+Private.h b/Sources/Sentry/include/SentryAttachment+Private.h index 967b62d02e..2a8b7924ac 100644 --- a/Sources/Sentry/include/SentryAttachment+Private.h +++ b/Sources/Sentry/include/SentryAttachment+Private.h @@ -25,11 +25,10 @@ SENTRY_NO_INIT /** * Initializes an attachment with data. - * * @param data The data for the attachment. * @param filename The name of the attachment to display in Sentry. - * @param contentType The content type of the attachment. Default is "application/octet-stream". - * @param attachmentType The type of the attachment. Default is "EventAttachment". + * @param contentType The content type of the attachment. Default is @c "application/octet-stream". + * @param attachmentType The type of the attachment. Default is @c "EventAttachment". */ - (instancetype)initWithData:(NSData *)data filename:(NSString *)filename @@ -38,11 +37,10 @@ SENTRY_NO_INIT /** * Initializes an attachment with data. - * * @param path The path of the file whose contents you want to upload to Sentry. * @param filename The name of the attachment to display in Sentry. - * @param contentType The content type of the attachment. Default is "application/octet-stream". - * @param attachmentType The type of the attachment. Default is "EventAttachment". + * @param contentType The content type of the attachment. Default is @c "application/octet-stream". + * @param attachmentType The type of the attachment. Default is@c "EventAttachment". */ - (instancetype)initWithPath:(NSString *)path filename:(NSString *)filename diff --git a/Sources/Sentry/include/SentryCPU.h b/Sources/Sentry/include/SentryCPU.h index cb91d10543..dcc5ef0ec5 100644 --- a/Sources/Sentry/include/SentryCPU.h +++ b/Sources/Sentry/include/SentryCPU.h @@ -13,7 +13,7 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ''AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR diff --git a/Sources/Sentry/include/SentryCompiler.h b/Sources/Sentry/include/SentryCompiler.h index 1d097c011a..e00fc1e43b 100644 --- a/Sources/Sentry/include/SentryCompiler.h +++ b/Sources/Sentry/include/SentryCompiler.h @@ -11,7 +11,7 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ''AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR diff --git a/Sources/Sentry/include/SentryCrashReportConverter.h b/Sources/Sentry/include/SentryCrashReportConverter.h index d94ecfb903..a68a339ab4 100644 --- a/Sources/Sentry/include/SentryCrashReportConverter.h +++ b/Sources/Sentry/include/SentryCrashReportConverter.h @@ -11,8 +11,7 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)initWithReport:(NSDictionary *)report inAppLogic:(SentryInAppLogic *)inAppLogic; /** - * Converts the report to an SentryEvent. - * + * Converts the report to an @c SentryEvent. * @return The converted event or nil if an error occurred during the conversion. */ - (SentryEvent *_Nullable)convertReportToEvent; diff --git a/Sources/Sentry/include/SentryCrashScopeObserver.h b/Sources/Sentry/include/SentryCrashScopeObserver.h index 9e00073e51..f6bd51e25a 100644 --- a/Sources/Sentry/include/SentryCrashScopeObserver.h +++ b/Sources/Sentry/include/SentryCrashScopeObserver.h @@ -4,17 +4,16 @@ NS_ASSUME_NONNULL_BEGIN /** - * This class performs a fine-grained sync of the Scope to C memory, as when SentryCrash writes a - * crash report, we can't call Objective-C methods; see SentryCrash.onCrash. For every change to the - * Scope, this class serializes only the changed property to JSON and stores it in C memory. When a - * crash happens, the SentryCrashReport picks up the JSON of all properties and adds it to the crash - * report. - * - * Previously, the SDK used SentryCrash.setUserInfo, which required the serialization of the whole - * Scope on every modification of it. When having much data in the Scope this slowed down the caller - * of the scope change. Therefore, we had to move the Scope sync to a background thread. This has - * the downside of the scope not being 100% up to date when a crash happens and, of course, lots of - * CPU overhead. + * This class performs a fine-grained sync of the Scope to C memory, as when @c SentryCrash writes a + * crash report, we can't call Objective-C methods; see @c SentryCrash.onCrash. For every change to + * the Scope, this class serializes only the changed property to JSON and stores it in C memory. + * When a crash happens, the @c SentryCrashReport picks up the JSON of all properties and adds it to + * the crash report. + * @discussion Previously, the SDK used @c SentryCrash.setUserInfo, which required the serialization + * of the whole Scope on every modification of it. When having much data in the Scope this slowed + * down the caller of the scope change. Therefore, we had to move the Scope sync to a background + * thread. This has the downside of the scope not being 100% up to date when a crash happens and, of + * course, lots of CPU overhead. */ @interface SentryCrashScopeObserver : NSObject SENTRY_NO_INIT diff --git a/Sources/Sentry/include/SentryCrashStackEntryMapper.h b/Sources/Sentry/include/SentryCrashStackEntryMapper.h index 4dec4fc3cc..f7679c97b4 100644 --- a/Sources/Sentry/include/SentryCrashStackEntryMapper.h +++ b/Sources/Sentry/include/SentryCrashStackEntryMapper.h @@ -14,15 +14,13 @@ SENTRY_NO_INIT /** * Maps the stackEntry of a SentryCrashStackCursor to SentryFrame. - * - * @param stackCursor An with SentryCrash initialized stackCursor. You can use for example - * sentrycrashsc_initSelfThread. + * @param stackCursor An with @c SentryCrash initialized @c stackCursor. You can use for example + * @c sentrycrashsc_initSelfThread. */ - (SentryFrame *)mapStackEntryWithCursor:(SentryCrashStackCursor)stackCursor; /** - * Maps a SentryCrashStackEntry to SentryFrame. - * + * Maps a @c SentryCrashStackEntry to @c SentryFrame. * @param stackEntry A stack entry retrieved from a thread. */ - (SentryFrame *)sentryCrashStackEntryToSentryFrame:(SentryCrashStackEntry)stackEntry; diff --git a/Sources/Sentry/include/SentryFileManager.h b/Sources/Sentry/include/SentryFileManager.h index 85ab66f047..0f5ae265cd 100644 --- a/Sources/Sentry/include/SentryFileManager.h +++ b/Sources/Sentry/include/SentryFileManager.h @@ -52,15 +52,14 @@ SENTRY_NO_INIT - (void)deleteOldEnvelopeItems; /** - * Get all envelopes sorted ascending by the timeIntervalSince1970 the envelope was stored and if + * Get all envelopes sorted ascending by the @c timeIntervalSince1970 the envelope was stored and if * two envelopes are stored at the same time sorted by the order they were stored. */ - (NSArray *)getAllEnvelopes; /** - * Gets the oldest stored envelope. For the order see getAllEnvelopes. - * - * @return SentryFileContens if there is an envelope and nil if there are no envelopes. + * Gets the oldest stored envelope. For the order see @c getAllEnvelopes. + * @return @c SentryFileContents if there is an envelope and @c nil if there are no envelopes. */ - (SentryFileContents *_Nullable)getOldestEnvelope; diff --git a/Sources/Sentry/include/SentryFrameRemover.h b/Sources/Sentry/include/SentryFrameRemover.h index 77b8708394..16b5e315d7 100644 --- a/Sources/Sentry/include/SentryFrameRemover.h +++ b/Sources/Sentry/include/SentryFrameRemover.h @@ -8,12 +8,11 @@ NS_ASSUME_NONNULL_BEGIN /** * Removes Sentry SDK frames until a frame from a different package is found. - * - * When a user includes Sentry as a static library, the package is the same as the application. - * Therefore removing frames with a package containing "sentry" doesn't work. We can't look into the - * function name as in release builds, the function name can be obfuscated, or we remove functions - * that are not from this SDK and contain "sentry". Therefore this logic only works for apps - * including Sentry dynamically. + * @discussion When a user includes Sentry as a static library, the package is the same as the + * application. Therefore removing frames with a package containing "sentry" doesn't work. We can't + * look into the function name as in release builds, the function name can be obfuscated, or we + * remove functions that are not from this SDK and contain "sentry". Therefore this logic only works + * for apps including Sentry dynamically. */ + (NSArray *)removeNonSdkFrames:(NSArray *)frames; diff --git a/Sources/Sentry/include/SentryInAppLogic.h b/Sources/Sentry/include/SentryInAppLogic.h index 01b734f860..9afa5a1b8f 100644 --- a/Sources/Sentry/include/SentryInAppLogic.h +++ b/Sources/Sentry/include/SentryInAppLogic.h @@ -7,22 +7,23 @@ NS_ASSUME_NONNULL_BEGIN * This class detects whether a framework belongs to the app or not. We differentiate between three * different types of frameworks. * - * First, the main executable of the app, which's name can be retrieved by CFBundleExecutable. To - * mark this framework as inApp the caller needs to pass in the CFBundleExecutable to InAppIncludes. + * First, the main executable of the app, which's name can be retrieved by @c CFBundleExecutable. To + * mark this framework as "in-app" the caller needs to pass in the @c CFBundleExecutable to + * @c inAppIncludes. * * Next, there are private frameworks embedded in the application bundle. Both app supporting * frameworks as CocoaLumberJack, Sentry, RXSwift, etc., and frameworks written by the user fall - * into this category. These frameworks can be both inApp or not. As we expect most frameworks of - * this category to be supporting frameworks, we mark them not as inApp. If a user wants such a - * framework to be inApp, they need to pass the name into inAppInclude. For dynamic frameworks, the - * location is usually in the bundle under /Frameworks/FrameworkName.framework/FrameworkName. As for - * static frameworks, the location is the same as the main executable; this class marks all static - * frameworks as inApp. To remove static frameworks from being inApp, Sentry uses stack trace - * grouping rules on the server. + * into this category. These frameworks can be both "in-app" or not. As we expect most frameworks of + * this category to be supporting frameworks, we mark them not as "in-app". If a user wants such a + * framework to be "in-app", they need to pass the name into @c inAppIncludes. For dynamic + * frameworks, the location is usually in the bundle under + * /Frameworks/FrameworkName.framework/FrameworkName. As for static frameworks, the location is the + * same as the main executable; this class marks all static frameworks as "in-app". To remove static + * frameworks from being "in-app", Sentry uses stack trace grouping rules on the server. * - * Last, this class marks all public frameworks as not inApp. Such frameworks are bound dynamically - * and are usually located at /Library/Frameworks or ~/Library/Frameworks. For simulators, the - * location can be something like + * Last, this class marks all public frameworks as not "in-app". Such frameworks are bound + * dynamically and are usually located at /Library/Frameworks or ~/Library/Frameworks. For + * simulators, the location can be something like * /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/System/Library/... * */ @@ -30,13 +31,13 @@ NS_ASSUME_NONNULL_BEGIN SENTRY_NO_INIT /** - * Initializes SentryInAppLogic with inAppIncludes and inAppExcludes. + * Initializes @c SentryInAppLogic with @c inAppIncludes and @c inAppExcludes. * - * To work properly for Apple applications the inAppIncludes should contain the CFBundleExecutable, - * which is the name of the bundle’s executable file. + * To work properly for Apple applications the @c inAppIncludes should contain the + * @c CFBundleExecutable, which is the name of the bundle’s executable file. * * @param inAppIncludes A list of string prefixes of framework names that belong to the app. This - * option takes precedence over inAppExcludes. + * option takes precedence over @c inAppExcludes. * @param inAppExcludes A list of string prefixes of framework names that do not belong to the app, * but rather to third-party packages. Modules considered not part of the app will be hidden from * stack traces by default. @@ -45,25 +46,29 @@ SENTRY_NO_INIT inAppExcludes:(NSArray *)inAppExcludes; /** - * Determines if the framework belongs to the app by using inAppIncludes and inAppExcludes. Before - * checking this method lowercases the strings and uses only the lastPathComponent of the imagePath. + * Determines if the framework belongs to the app by using @c inAppIncludes and @c inAppExcludes. + * Before checking this method lowercases the strings and uses only the @c lastPathComponent of the + * @c imagePath. * * @param imagePath the full path of the binary image. * - * @return YES if the framework located at the imagePath starts with a prefix of inAppIncludes. NO - * if the framework located at the imagePath doesn't start with a prefix of inAppIncludes or start - * with a prefix of inAppExcludes. + * @return @c YES if the framework located at the @c imagePath starts with a prefix of + * @c inAppIncludes. @c NO if the framework located at the @c imagePath doesn't start with a prefix + * of + * @c inAppIncludes or start with a prefix of @c inAppExcludes. */ - (BOOL)isInApp:(nullable NSString *)imagePath; /** - * Determines if the class belongs to the app by getting its framework and checking with `isInApp:`. + * Determines if the class belongs to the app by getting its framework and checking with + * @c -[isInApp:] * * @param targetClass the class to check. * - * @return YES if the targetClass belongs to a framework included in inAppIncludes. - * NO if targetClass does not belong to a framework in inAppIncludes or belongs to a framework in - * inAppExcludes. + * @return @c YES if the @c targetClass belongs to a framework included in @c inAppIncludes. + * @c NO if targetClass does not belong to a framework in @c inAppIncludes or belongs to a framework + * in + * @c inAppExcludes. */ - (BOOL)isClassInApp:(Class)targetClass; diff --git a/Sources/Sentry/include/SentryLog.h b/Sources/Sentry/include/SentryLog.h index 0e2b502933..2cb2619e7c 100644 --- a/Sources/Sentry/include/SentryLog.h +++ b/Sources/Sentry/include/SentryLog.h @@ -11,8 +11,10 @@ SENTRY_NO_INIT + (void)logWithMessage:(NSString *)message andLevel:(SentryLevel)level; -/** @return @c YES if the current logging configuration will log statements at the current level, @c - * NO if not. */ +/** + * @return @c YES if the current logging configuration will log statements at the current level, + * @c NO if not. + */ + (BOOL)willLogAtLevel:(SentryLevel)level; @end @@ -31,8 +33,8 @@ NS_ASSUME_NONNULL_END #define SENTRY_LOG_FATAL(...) SENTRY_LOG(kSentryLevelFatal, __VA_ARGS__) /** - * If `errno` is set to a non-zero value after `statement` finishes executing, - * the error value is logged, and the original return value of `statement` is + * If @c errno is set to a non-zero value after @c statement finishes executing, + * the error value is logged, and the original return value of @c statement is * returned. */ #define SENTRY_LOG_ERRNO(statement) \ diff --git a/Sources/Sentry/include/SentryMetricProfiler.h b/Sources/Sentry/include/SentryMetricProfiler.h index 78655bf3b9..a644735ac6 100644 --- a/Sources/Sentry/include/SentryMetricProfiler.h +++ b/Sources/Sentry/include/SentryMetricProfiler.h @@ -23,14 +23,14 @@ SENTRY_EXTERN NSString *const kSentryMetricProfilerSerializationUnitPercentage; /** * A structure to hold a single metric reading and the time it was taken, as a dictionary with keyed - * values either of type NSNumber for the reading value, or NSString for the timestamp (we just - * encode @cuint64\_t as a string since JSON doesn't officially support it). + * values either of type @c NSNumber for the reading value, or @c NSString for the timestamp (we + * just encode @c uint64_t as a string since JSON doesn't officially support it). */ typedef NSDictionary */> SentrySerializedMetricReading; /** * A structure containing the timeseries of values for a particular metric type, as a dictionary - * with keyed values either of type NSString, for unit names, or an array of metrics entries + * with keyed values either of type @c NSString, for unit names, or an array of metrics entries * containing the values and timestamps in the above typedef. */ typedef NSDictionary> */> @@ -50,8 +50,7 @@ typedef NSDictionary": @{ * @"unit": @"", diff --git a/Sources/Sentry/include/SentryMigrateSessionInit.h b/Sources/Sentry/include/SentryMigrateSessionInit.h index e6d2e23ae3..4c0f447276 100644 --- a/Sources/Sentry/include/SentryMigrateSessionInit.h +++ b/Sources/Sentry/include/SentryMigrateSessionInit.h @@ -6,11 +6,12 @@ NS_ASSUME_NONNULL_BEGIN /** * For proper statistics in release health, we need to make sure we don't send session updates - without sending a session init first. In other words, we can't drop a session init. The -  SentryFileManager deletes an envelope once the maximum amount of envelopes is stored. When this - happens and the envelope to delete contains a session init we look for the next envelope containing - a session update for the same session. If such a session envelope is found we migrate the init - flag. If none is found we delete the envelope. We don't migrate other envelope items as events. + * without sending a session init first. In other words, we can't drop a session init. The + * @c SentryFileManager deletes an envelope once the maximum amount of envelopes is stored. When + * this happens and the envelope to delete contains a session init we look for the next envelope + * containing a session update for the same session. If such a session envelope is found we migrate + * the init flag. If none is found we delete the envelope. We don't migrate other envelope items as + * events. */ @interface SentryMigrateSessionInit : NSObject SENTRY_NO_INIT @@ -18,15 +19,13 @@ SENTRY_NO_INIT /** * Checks if the envelope of the passed file path contains an envelope item with a session init. If * it does it iterates over all envelopes and looks for a session with the same session id. If such - * a session is found the init flag is set to YES, the envelope is updated with keeping other + * a session is found the init flag is set to @c YES, the envelope is updated with keeping other * envelope items and headers, and the updated envelope is stored to the disk keeping its path. - * * @param envelope The envelope to delete * @param envelopesDirPath The path of the directory where the envelopes are stored. * @param envelopeFilePaths An array containing the file paths of envelopes to check if they contain * a session init. - * - * @return YES if the function migrated the session init. NO if not. + * @return @c YES if the function migrated the session init. @c NO if not. */ + (BOOL)migrateSessionInit:(SentryEnvelope *)envelope envelopesDirPath:(NSString *)envelopesDirPath diff --git a/Sources/Sentry/include/SentryNSNotificationCenterWrapper.h b/Sources/Sentry/include/SentryNSNotificationCenterWrapper.h index 0bb69def33..070f03384b 100644 --- a/Sources/Sentry/include/SentryNSNotificationCenterWrapper.h +++ b/Sources/Sentry/include/SentryNSNotificationCenterWrapper.h @@ -3,12 +3,12 @@ NS_ASSUME_NONNULL_BEGIN /** - * A wrapper around NSNotificationCenter functions for testability. - * - * Testing with NSNotificationCenter in CI leads to flaky tests for some classes. Therefore, we can - * use a wrapper around NSNotificationCenter to not depend on it. Instead, we call the methods - * NSNotificationCenter would call with Dynamic and ensure that sut properly subscribes to - * NSNotificationCenter. + * A wrapper around @c NSNotificationCenter functions for testability. + * @discussion Testing with @c NSNotificationCenter in CI leads to flaky tests for some classes. + * Therefore, we can use a wrapper around @c NSNotificationCenter to not depend on it. Instead, we + * call the methods + * @c NSNotificationCenter would call with Dynamic and ensure that sut properly subscribes to + * @c NSNotificationCenter. */ @interface SentryNSNotificationCenterWrapper : NSObject diff --git a/Sources/Sentry/include/SentryPerformanceTracker.h b/Sources/Sentry/include/SentryPerformanceTracker.h index 6aac41c35e..6f43d141d0 100644 --- a/Sources/Sentry/include/SentryPerformanceTracker.h +++ b/Sources/Sentry/include/SentryPerformanceTracker.h @@ -7,8 +7,8 @@ NS_ASSUME_NONNULL_BEGIN @class SentrySpanId; /** - * Tracks performance synchronizing span with its childs. - * A span will be finished only when all its children are finished. + * Tracks performance synchronizing span with its child's. + * @note A span will be finished only when all its children are finished. */ @interface SentryPerformanceTracker : NSObject @@ -18,31 +18,24 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, class, readonly) SentryPerformanceTracker *shared; /** - * Starts a new span if no span is active, - * then bind it to the scope if no span is binded. - * If there`s an active span, starts a child of the active span. - * + * Starts a new span if no span is active, then bind it to the scope if no span is bound. + * @note If there's an active span, starts a child of the active span. * @param name Span name. * @param operation Span operation. - * * @return The span id. */ - (SentrySpanId *)startSpanWithName:(NSString *)name operation:(NSString *)operation; /** - * Activate the span with `spanId` - * to create any call to startSpan as a child. - * If the there is no span with the fiven spanId - * block is executed anyway. - * + * Activate the span with @c spanId to create any call to @c startSpan as a child. + * @note If the there is no span with @c spanId , @c block is executed anyway. * @param spanId Id of the span to activate * @param block Block to invoke while span is active */ - (void)activateSpan:(SentrySpanId *)spanId duringBlock:(void (^)(void))block; /** - * Measure the given block execution. - * + * Measure the given @c block execution. * @param description The description of the span. * @param operation Span operation. * @param block Block to be measured. @@ -52,11 +45,8 @@ NS_ASSUME_NONNULL_BEGIN inBlock:(void (^)(void))block; /** - * Measure the given block execution - * adding it as a child of given parent span. - * If parentSpanId does not exist this - * measurement is not performed. - * + * Measure the given @c block execution adding it as a child of given parent span. + * @note If @c parentSpanId does not exist this measurement is not performed. * @param description The description of the span. * @param operation Span operation. * @param parentSpanId Id of the span to use as parent. @@ -74,18 +64,16 @@ NS_ASSUME_NONNULL_BEGIN /** * Marks a span to be finished. - * If the given span has no child it is finished immediately, - * otherwise it waits until all children are finished. - * + * If the given span has no child it is finished immediately, otherwise it waits until all children + * are finished. * @param spanId Id of the span to finish. */ - (void)finishSpan:(SentrySpanId *)spanId; /** * Marks a span to be finished with given status. - * If the given span has no child it is finished immediately, - * otherwise it waits until all children are finished. - * + * If the given span has no child it is finished immediately, otherwise it waits until all children + * are finished. * @param spanId Id of the span to finish. * @param status Span finish status. */ @@ -93,18 +81,14 @@ NS_ASSUME_NONNULL_BEGIN /** * Checks if given span is waiting to be finished. - * * @param spanId Id of the span to be checked. - * * @return A boolean value indicating whether the span still waiting to be finished. */ - (BOOL)isSpanAlive:(SentrySpanId *)spanId; /** * Return the SentrySpan associated with the given spanId. - * * @param spanId Id of the span to return. - * * @return SentrySpan */ - (nullable id)getSpan:(SentrySpanId *)spanId; diff --git a/Sources/Sentry/include/SentryPerformanceTrackingIntegration.h b/Sources/Sentry/include/SentryPerformanceTrackingIntegration.h index dcce55eb22..4c9861d406 100644 --- a/Sources/Sentry/include/SentryPerformanceTrackingIntegration.h +++ b/Sources/Sentry/include/SentryPerformanceTrackingIntegration.h @@ -6,10 +6,8 @@ NS_ASSUME_NONNULL_BEGIN /** * Integration to setup automatic performance tracking. - * - * Automatic UI performance setup can be avoided by setting - * enableAutoPerformanceTracing to NO - * in SentryOptions during SentrySDK initialization. + * Automatic UI performance setup can be avoided by setting @c enableAutoPerformanceTracing to @c NO + * in @c SentryOptions during SentrySDK initialization. */ @interface SentryPerformanceTrackingIntegration : SentryBaseIntegration diff --git a/Sources/Sentry/include/SentryProfiler.h b/Sources/Sentry/include/SentryProfiler.h index 1412a47e27..1a9116a06e 100644 --- a/Sources/Sentry/include/SentryProfiler.h +++ b/Sources/Sentry/include/SentryProfiler.h @@ -30,15 +30,16 @@ SENTRY_EXTERN NSString *const kSentryProfilerSerializationKeyFrameRates; SENTRY_EXTERN_C_BEGIN -/* - * Parses a symbol that is returned from `backtrace_symbols()`, which encodes information - * like the frame index, image name, function name, and offset in a single string. e.g. - * For the input: - * 2 UIKitCore 0x00000001850d97ac -[UIFieldEditor - * _fullContentInsetsFromFonts] + 160 This function would return: -[UIFieldEditor - * _fullContentInsetsFromFonts] - * - * If the format does not match the expected format, this returns the input string. +/** + * Parses a symbol that is returned from @c backtrace_symbols() which encodes information + * like the frame index, image name, function name, and offset in a single string. + * @discussion For the input: + * @code + * 2 UIKitCore 0x00000001850d97ac -[UIFieldEditor _fullContentInsetsFromFonts] + 160 + * @endcode + * This function would return: + * @code -[UIFieldEditor _fullContentInsetsFromFonts] @endcode + * @note If the format does not match the expected format, this returns the input string. */ NSString *parseBacktraceSymbolsFunctionName(const char *symbol); @@ -47,21 +48,28 @@ NSString *profilerTruncationReasonName(SentryProfilerTruncationReason reason); SENTRY_EXTERN_C_END /** - * @warning: A main assumption is that profile start/stop must be contained within range of time of + * A wrapper around the low-level components used to gather sampled backtrace profiles. + * @warning A main assumption is that profile start/stop must be contained within range of time of * the first concurrent transaction's start time and last one's end time. */ @interface SentryProfiler : NSObject -/** Start the profiler, if it isn't already running. */ +/** + * Start the profiler, if it isn't already running. + */ + (void)startWithHub:(SentryHub *)hub; -/** Stop the profiler if it is running. */ +/** + * Stop the profiler if it is running. + */ + (void)stop; + (BOOL)isRunning; -/** Given a transaction, return an envelope item containing any corresponding profile data to be - * attached to the transaction envelope. */ +/** + * Given a transaction, return an envelope item containing any corresponding profile data to be + * attached to the transaction envelope. + * */ + (nullable SentryEnvelopeItem *)createProfilingEnvelopeItemForTransaction: (SentryTransaction *)transaction; diff --git a/Sources/Sentry/include/SentryRateLimits.h b/Sources/Sentry/include/SentryRateLimits.h index bfe7fc4ee4..bf39528757 100644 --- a/Sources/Sentry/include/SentryRateLimits.h +++ b/Sources/Sentry/include/SentryRateLimits.h @@ -4,26 +4,24 @@ NS_ASSUME_NONNULL_BEGIN /** - Parses HTTP responses from the Sentry server for rate limits. - When a rate limit is reached the SDK should stop data transmission - until the rate limit has expired. -*/ + * Parses HTTP responses from the Sentry server for rate limits. + * @discussion When a rate limit is reached, the SDK should stop data transmission + * until the rate limit has expired. + */ NS_SWIFT_NAME(RateLimits) @protocol SentryRateLimits /** -Check if a data category has reached a rate limit. - @param category the type e.g. event, error, session, transaction, etc. - - @return BOOL YES if limit is reached, NO otherwise. + * Check if a data category has reached a rate limit. + * @param category the type e.g. event, error, session, transaction, etc. + * @return @c YES if limit is reached, @c NO otherwise. */ - (BOOL)isRateLimitActive:(SentryDataCategory)category; /** -Should be called for each HTTP response of the Sentry - server. It checks the response for any communicated rate limits. - - @param response The response from the server + * Should be called for each HTTP response of the Sentry server. It checks the response for any + * communicated rate limits. + * @param response The response from the server */ - (void)update:(NSHTTPURLResponse *)response; diff --git a/Sources/Sentry/include/SentryReachability.h b/Sources/Sentry/include/SentryReachability.h index 06abc3ead2..539ba198c9 100644 --- a/Sources/Sentry/include/SentryReachability.h +++ b/Sources/Sentry/include/SentryReachability.h @@ -41,15 +41,14 @@ BOOL SentryConnectivityShouldReportChange(SCNetworkReachabilityFlags flags); #endif /** - * Function signature to connectivity monitoring callback of SentryReachability - * - * @param connected YES if the monitored URL is reachable + * Function signature to connectivity monitoring callback of @c SentryReachability + * @param connected @c YES if the monitored URL is reachable * @param typeDescription a textual representation of the connection type */ typedef void (^SentryConnectivityChangeBlock)(BOOL connected, NSString *typeDescription); /** - * Monitors network connectivity using SCNetworkReachability callbacks, + * Monitors network connectivity using @c SCNetworkReachability callbacks, * providing a customizable callback block invoked when connectivity changes. */ @interface SentryReachability : NSObject @@ -57,15 +56,14 @@ typedef void (^SentryConnectivityChangeBlock)(BOOL connected, NSString *typeDesc #if !TARGET_OS_WATCH /** * Invoke a block each time network connectivity changes - * - * @param URL The URL monitored for changes. Should be equivalent to - * BugsnagConfiguration.notifyURL + * @param URL The URL monitored for changes. Should be equivalent to + * @c BugsnagConfiguration.notifyURL . * @param block The block called when connectivity changes */ - (void)monitorURL:(NSURL *)URL usingCallback:(SentryConnectivityChangeBlock)block; /** - * Stop monitoring the URL previously configured with monitorURL:usingCallback: + * Stop monitoring the URL previously configured with @c monitorURL:usingCallback: */ - (void)stopMonitoring; diff --git a/Sources/Sentry/include/SentryScreenshot.h b/Sources/Sentry/include/SentryScreenshot.h index ccac8580cb..42e9c2f16b 100644 --- a/Sources/Sentry/include/SentryScreenshot.h +++ b/Sources/Sentry/include/SentryScreenshot.h @@ -8,8 +8,7 @@ NS_ASSUME_NONNULL_BEGIN /** * Get a screenshot of every open window in the app. - * - * @return An array of NSData containing a PNG image + * @return An array of @c NSData instances containing PNG images. */ - (nullable NSArray *)appScreenshots; diff --git a/Sources/Sentry/include/SentrySdkInfo.h b/Sources/Sentry/include/SentrySdkInfo.h index d3799c1326..15f58393bc 100644 --- a/Sources/Sentry/include/SentrySdkInfo.h +++ b/Sources/Sentry/include/SentrySdkInfo.h @@ -10,26 +10,21 @@ NS_ASSUME_NONNULL_BEGIN /** * Describes the Sentry SDK and its configuration used to capture and transmit an event. - * - * Both name and version are required. - * - * For more info checkout: https://develop.sentry.dev/sdk/event-payloads/sdk/ + * @note Both name and version are required. + * @see https://develop.sentry.dev/sdk/event-payloads/sdk/ */ @interface SentrySdkInfo : NSObject SENTRY_NO_INIT /** - * The name of the SDK. - * - * Examples: sentry.cocoa, sentry.cocoa.vapor, ... + * The name of the SDK. Examples: sentry.cocoa, sentry.cocoa.vapor, ... */ @property (nonatomic, readonly, copy) NSString *name; /** * The version of the SDK. It should have the Semantic Versioning format MAJOR.MINOR.PATCH, without - * any prefix (no v or anything else in front of the major version number). - * - * Examples: 0.1.0, 1.0.0, 2.0.0-beta0 + * any prefix (no v or anything else in front of the major version number). Examples: + * 0.1.0, 1.0.0, 2.0.0-beta0 */ @property (nonatomic, readonly, copy) NSString *version; diff --git a/Sources/Sentry/include/SentrySession.h b/Sources/Sentry/include/SentrySession.h index 4ecea99c97..43820850ae 100644 --- a/Sources/Sentry/include/SentrySession.h +++ b/Sources/Sentry/include/SentrySession.h @@ -21,11 +21,9 @@ SENTRY_NO_INIT - (instancetype)initWithReleaseName:(NSString *)releaseName; /** - * Initializes SentrySession from a JSON object. - * - * @param jsonObject The jsonObject containing the session. - * - * @return The SentrySession or nil if the JSONObject contains an error. + * Initializes @c SentrySession from a JSON object. + * @param jsonObject The @c jsonObject containing the session. + * @return The @c SentrySession or @c nil if @c jsonObject contains an error. */ - (nullable instancetype)initWithJSONObject:(NSDictionary *)jsonObject; @@ -42,7 +40,7 @@ SENTRY_NO_INIT @property (nonatomic, readonly) NSUInteger sequence; @property (nonatomic, readonly, strong) NSString *distinctId; /** - We can't use init because it overlaps with NSObject.init + * We can't use @c init because it overlaps with @c NSObject.init . */ @property (nonatomic, readonly, copy) NSNumber *_Nullable flagInit; @property (nonatomic, readonly, strong) NSDate *_Nullable timestamp; diff --git a/Sources/Sentry/include/SentrySpan.h b/Sources/Sentry/include/SentrySpan.h index 2c460893b7..bee51689b5 100644 --- a/Sources/Sentry/include/SentrySpan.h +++ b/Sources/Sentry/include/SentrySpan.h @@ -71,21 +71,15 @@ SENTRY_NO_INIT @property (nullable, nonatomic, strong) NSArray *frames; /** - * Init a SentrySpan with given transaction and context. - * + * Init a @c SentrySpan with given transaction and context. * @param transaction The @c SentryTracer managing the transaction this span is associated with. * @param context This span context information. - * - * @return SentrySpan */ - (instancetype)initWithTracer:(SentryTracer *)transaction context:(SentrySpanContext *)context; /** - * Init a SentrySpan with given context. - * + * Init a @c SentrySpan with given context. * @param context This span context information. - * - * @return SentrySpan */ - (instancetype)initWithContext:(SentrySpanContext *)context; diff --git a/Sources/Sentry/include/SentrySubClassFinder.h b/Sources/Sentry/include/SentrySubClassFinder.h index 6a65ad7074..889fdbaf0e 100644 --- a/Sources/Sentry/include/SentrySubClassFinder.h +++ b/Sources/Sentry/include/SentrySubClassFinder.h @@ -13,12 +13,11 @@ SENTRY_NO_INIT objcRuntimeWrapper:(id)objcRuntimeWrapper; /** - * Fetch all subclasses of UIViewController from given objc Image on a background thread and then + * Fetch all subclasses of @c UIViewController from given objc Image on a background thread and then * act on them on the main thread. As there is no straightforward way to get all sub-classes in * Objective-C, the code first retrieves all classes from the Image, iterates over all classes, and - * checks for every class if the parentClass is a UIViewController. Cause loading all classes can + * checks for every class if the parentClass is a @c UIViewController. Cause loading all classes can * take a few milliseconds, do this on a background thread. - * * @param imageName The objc Image (library) to get all subclasses for. * @param block The block to execute for each subclass. This block runs on the main thread. */ diff --git a/Sources/Sentry/include/SentrySwizzle.h b/Sources/Sentry/include/SentrySwizzle.h index 8efb795936..d0d8f5a7cb 100644 --- a/Sources/Sentry/include/SentrySwizzle.h +++ b/Sources/Sentry/include/SentrySwizzle.h @@ -2,74 +2,80 @@ #pragma mark - Macros Based API -/// A macro for wrapping the return type of the swizzled method. +/** + * A macro for wrapping the return type of the swizzled method. + */ #define SentrySWReturnType(type) type -/// A macro for wrapping arguments of the swizzled method. +/** + * A macro for wrapping arguments of the swizzled method. + */ #define SentrySWArguments(arguments...) _SentrySWArguments(arguments) -/// A macro for wrapping the replacement code for the swizzled method. +/** + * A macro for wrapping the replacement code for the swizzled method. + */ #define SentrySWReplacement(code...) code -/// A macro for casting and calling original implementation. -/// May be used only in SentrySwizzleInstanceMethod or SentrySwizzleClassMethod -/// macros. +/** + * A macro for casting and calling original implementation. + * @note May be used only in @c SentrySwizzleInstanceMethod or @c SentrySwizzleClassMethod macros. + */ #define SentrySWCallOriginal(arguments...) _SentrySWCallOriginal(arguments) #pragma mark └ Swizzle Instance Method /** - Swizzles the instance method of the class with the new implementation. - - Example for swizzling `-(int)calculate:(int)number;` method: - - @code - - SentrySwizzleInstanceMethod(classToSwizzle, - @selector(calculate:), - SentrySWReturnType(int), - SentrySWArguments(int number), - SentrySWReplacement( - { - // Calling original implementation. - int res = SentrySWCallOriginal(number); - // Returning modified return value. - return res + 1; - }), 0, NULL); - - @endcode - - Swizzling frequently goes along with checking whether this particular class (or - one of its superclasses) has been already swizzled. Here the - `SentrySwizzleMode` and `key` parameters can help. See +[SentrySwizzle - swizzleInstanceMethod:inClass:newImpFactory:mode:key:] for details. - - Swizzling is fully thread-safe. - - @param classToSwizzle The class with the method that should be swizzled. - - @param selector Selector of the method that should be swizzled. - - @param SentrySWReturnType The return type of the swizzled method wrapped in the - SentrySWReturnType macro. - - @param SentrySWArguments The arguments of the swizzled method wrapped in the - SentrySWArguments macro. - - @param SentrySWReplacement The code of the new implementation of the swizzled - method wrapped in the SentrySWReplacement macro. - - @param SentrySwizzleMode The mode is used in combination with the key to - indicate whether the swizzling should be done for the given class. You can pass - 0 for SentrySwizzleModeAlways. - - @param key The key is used in combination with the mode to indicate whether the - swizzling should be done for the given class. May be NULL if the mode is - SentrySwizzleModeAlways. - - @return YES if successfully swizzled and NO if swizzling has been already done - for given key and class (or one of superclasses, depends on the mode). - + * Swizzles the instance method of the class with the new implementation. + * + * Example for swizzling @c -(int)calculate:(int)number; method: + * + * @code + * + * SentrySwizzleInstanceMethod(classToSwizzle, + * @selector(calculate:), + * SentrySWReturnType(int), + * SentrySWArguments(int number), + * SentrySWReplacement( + * { + * // Calling original implementation. + * int res = SentrySWCallOriginal(number); + * // Returning modified return value. + * return res + 1; + * }), 0, NULL); + * + * @endcode + * + * Swizzling frequently goes along with checking whether this particular class (or + * one of its superclasses) has been already swizzled. Here the + * @c SentrySwizzleMode and @c key parameters can help. + * @see @code +[SentrySwizzle swizzleInstanceMethod:inClass:newImpFactory:mode:key:] @endcode + * + * Swizzling is fully thread-safe. + * + * @param classToSwizzle The class with the method that should be swizzled. + * + * @param selector Selector of the method that should be swizzled. + * + * @param SentrySWReturnType The return type of the swizzled method wrapped in the + * @c SentrySWReturnType macro. + * + * @param SentrySWArguments The arguments of the swizzled method wrapped in the + * @c SentrySWArguments macro. + * + * @param SentrySWReplacement The code of the new implementation of the swizzled + * method wrapped in the @c SentrySWReplacement macro. + * + * @param SentrySwizzleMode The mode is used in combination with the key to + * indicate whether the swizzling should be done for the given class. You can pass + * @c 0 for @c SentrySwizzleModeAlways. + * + * @param key The key is used in combination with the mode to indicate whether the + * swizzling should be done for the given class. May be @c NULL if the mode is + * @c SentrySwizzleModeAlways. + * + * @return @c YES if successfully swizzled and @c NO if swizzling has been already done + * for given key and class (or one of superclasses, depends on the mode). */ #define SentrySwizzleInstanceMethod(classToSwizzle, selector, SentrySWReturnType, \ SentrySWArguments, SentrySWReplacement, SentrySwizzleMode, key) \ @@ -80,41 +86,40 @@ #pragma mark └ Swizzle Class Method /** - Swizzles the class method of the class with the new implementation. - - Example for swizzling `+(int)calculate:(int)number;` method: - - @code - - SentrySwizzleClassMethod(classToSwizzle, - @selector(calculate:), - SentrySWReturnType(int), - SentrySWArguments(int number), - SentrySWReplacement( - { - // Calling original implementation. - int res = SentrySWCallOriginal(number); - // Returning modified return value. - return res + 1; - })); - - @endcode - - Swizzling is fully thread-safe. - - @param classToSwizzle The class with the method that should be swizzled. - - @param selector Selector of the method that should be swizzled. - - @param SentrySWReturnType The return type of the swizzled method wrapped in the - SentrySWReturnType macro. - - @param SentrySWArguments The arguments of the swizzled method wrapped in the - SentrySWArguments macro. - - @param SentrySWReplacement The code of the new implementation of the swizzled - method wrapped in the SentrySWReplacement macro. - + * Swizzles the class method of the class with the new implementation. + * + * Example for swizzling @c +(int)calculate:(int)number; method: + * + * @code + * + * SentrySwizzleClassMethod(classToSwizzle, + * @selector(calculate:), + * SentrySWReturnType(int), + * SentrySWArguments(int number), + * SentrySWReplacement( + * { + * // Calling original implementation. + * int res = SentrySWCallOriginal(number); + * // Returning modified return value. + * return res + 1; + * })); + * + * @endcode + * + * Swizzling is fully thread-safe. + * + * @param classToSwizzle The class with the method that should be swizzled. + * + * @param selector Selector of the method that should be swizzled. + * + * @param SentrySWReturnType The return type of the swizzled method wrapped in the + * SentrySWReturnType macro. + * + * @param SentrySWArguments The arguments of the swizzled method wrapped in the + * SentrySWArguments macro. + * + * @param SentrySWReplacement The code of the new implementation of the swizzled + * method wrapped in the SentrySWReplacement macro. */ #define SentrySwizzleClassMethod( \ classToSwizzle, selector, SentrySWReturnType, SentrySWArguments, SentrySWReplacement) \ @@ -124,69 +129,79 @@ #pragma mark - Main API /** - A function pointer to the original implementation of the swizzled method. + * A function pointer to the original implementation of the swizzled method. */ typedef void (*SentrySwizzleOriginalIMP)(void /* id, SEL, ... */); /** - SentrySwizzleInfo is used in the new implementation block to get and call - original implementation of the swizzled method. + * @c SentrySwizzleInfo is used in the new implementation block to get and call + * original implementation of the swizzled method. */ @interface SentrySwizzleInfo : NSObject /** - Returns the original implementation of the swizzled method. - - It is actually either an original implementation if the swizzled class - implements the method itself; or a super implementation fetched from one of the - superclasses. - - @note You must always cast returned implementation to the appropriate function - pointer when calling. - - @return A function pointer to the original implementation of the swizzled - method. + * Returns the original implementation of the swizzled method. + * + * It is actually either an original implementation if the swizzled class + * implements the method itself; or a super implementation fetched from one of the + * superclasses. + * + * @note You must always cast returned implementation to the appropriate function + * pointer when calling. + * + * @return A function pointer to the original implementation of the swizzled + * method. */ - (SentrySwizzleOriginalIMP)getOriginalImplementation; -/// The selector of the swizzled method. +/** + * The selector of the swizzled method. + */ @property (nonatomic, readonly) SEL selector; #if TEST -// A flag to check whether the original implementation was called. +/** + * A flag to check whether the original implementation was called. + */ @property (nonatomic) BOOL originalCalled; #endif @end /** - A factory block returning the block for the new implementation of the swizzled - method. - - You must always obtain original implementation with swizzleInfo and call it - from the new implementation. - - @param swizzleInfo An info used to get and call the original implementation of - the swizzled method. - - @return A block that implements a method. - Its signature should be: `method_return_type ^(id self, method_args...)`. - The selector is not available as a parameter to this block. + * A factory block returning the block for the new implementation of the swizzled + * method. + * + * You must always obtain original implementation with @c swizzleInfo and call it + * from the new implementation. + * + * @param swizzleInfo An info used to get and call the original implementation of + * the swizzled method. + * + * @return A block providing an implementation for the swizzled method. The selector is not + * available as a parameter to this block. Its signature should be: @code method_return_type ^(id + * self, method_args...) @endcode */ typedef id (^SentrySwizzleImpFactoryBlock)(SentrySwizzleInfo *swizzleInfo); typedef NS_ENUM(NSUInteger, SentrySwizzleMode) { - /// SentrySwizzle always does swizzling. + /** + * @c SentrySwizzle always does swizzling. + */ SentrySwizzleModeAlways = 0, - /// SentrySwizzle does not do swizzling if the same class has been swizzled - /// earlier with the same key. + /** + * @c SentrySwizzle does not do swizzling if the same class has been swizzled + * earlier with the same key. + */ SentrySwizzleModeOncePerClass = 1, - /// SentrySwizzle does not do swizzling if the same class or one of its - /// superclasses have been swizzled earlier with the same key. - /// @note There is no guarantee that your implementation will be called only - /// once per method call. If the order of swizzling is: first inherited - /// class, second superclass, then both swizzlings will be done and the new - /// implementation will be called twice. + /** + * @c SentrySwizzle does not do swizzling if the same class or one of its + * superclasses have been swizzled earlier with the same key. + * @note There is no guarantee that your implementation will be called only + * once per method call. If the order of swizzling is: first inherited + * class, second superclass, then both swizzlings will be done and the new + * implementation will be called twice. + */ SentrySwizzleModeOncePerClassAndSuperclasses = 2 }; @@ -195,91 +210,91 @@ typedef NS_ENUM(NSUInteger, SentrySwizzleMode) { #pragma mark └ Swizzle Instance Method /** - Swizzles the instance method of the class with the new implementation. - - Original implementation must always be called from the new implementation. And - because of the the fact that for safe and robust swizzling original - implementation must be dynamically fetched at the time of calling and not at - the time of swizzling, swizzling API is a little bit complicated. - - You should pass a factory block that returns the block for the new - implementation of the swizzled method. And use swizzleInfo argument to retrieve - and call original implementation. - - Example for swizzling `-(int)calculate:(int)number;` method: - - @code - - SEL selector = @selector(calculate:); - [SentrySwizzle - swizzleInstanceMethod:selector - inClass:classToSwizzle - newImpFactory:^id(SentrySwizzleInfo *swizzleInfo) { - // This block will be used as the new implementation. - return ^int(__unsafe_unretained id self, int num){ - // You MUST always cast implementation to the correct function - pointer. int (*originalIMP)(__unsafe_unretained id, SEL, int); originalIMP = - (__typeof(originalIMP))[swizzleInfo getOriginalImplementation]; - // Calling original implementation. - int res = originalIMP(self,selector,num); - // Returning modified return value. - return res + 1; - }; - } - mode:SentrySwizzleModeAlways - key:NULL]; - - @endcode - - Swizzling frequently goes along with checking whether this particular class (or - one of its superclasses) has been already swizzled. Here the `mode` and `key` - parameters can help. - - Here is an example of swizzling `-(void)dealloc;` only in case when neither - class and no one of its superclasses has been already swizzled with our key. - However "Deallocating ..." message still may be logged multiple times per - method call if swizzling was called primarily for an inherited class and later - for one of its superclasses. - - @code - - static const void *key = &key; - SEL selector = NSSelectorFromString(@"dealloc"); - [SentrySwizzle - swizzleInstanceMethod:selector - inClass:classToSwizzle - newImpFactory:^id(SentrySwizzleInfo *swizzleInfo) { - return ^void(__unsafe_unretained id self){ - NSLog(@"Deallocating %@.",self); - - void (*originalIMP)(__unsafe_unretained id, SEL); - originalIMP = (__typeof(originalIMP))[swizzleInfo - getOriginalImplementation]; originalIMP(self,selector); - }; - } - mode:SentrySwizzleModeOncePerClassAndSuperclasses - key:key]; - - @endcode - - Swizzling is fully thread-safe. - - @param selector Selector of the method that should be swizzled. - - @param classToSwizzle The class with the method that should be swizzled. - - @param factoryBlock The factory block returning the block for the new - implementation of the swizzled method. - - @param mode The mode is used in combination with the key to indicate whether - the swizzling should be done for the given class. - - @param key The key is used in combination with the mode to indicate whether the - swizzling should be done for the given class. May be NULL if the mode is - SentrySwizzleModeAlways. - - @return YES if successfully swizzled and NO if swizzling has been already done - for given key and class (or one of superclasses, depends on the mode). + * Swizzles the instance method of the class with the new implementation. + * + * Original implementation must always be called from the new implementation. And + * because of the the fact that for safe and robust swizzling original + * implementation must be dynamically fetched at the time of calling and not at + * the time of swizzling, swizzling API is a little bit complicated. + * + * You should pass a factory block that returns the block for the new + * implementation of the swizzled method. And use swizzleInfo argument to retrieve + * and call original implementation. + * + * Example for swizzling @c -(int)calculate:(int)number; method: + * + * @code + * + * SEL selector = @selector(calculate:); + * [SentrySwizzle + * swizzleInstanceMethod:selector + * inClass:classToSwizzle + * newImpFactory:^id(SentrySwizzleInfo *swizzleInfo) { + * // This block will be used as the new implementation. + * return ^int(__unsafe_unretained id self, int num){ + * // You MUST always cast implementation to the correct function + * pointer. int (*originalIMP)(__unsafe_unretained id, SEL, int); originalIMP = + * (__typeof(originalIMP))[swizzleInfo getOriginalImplementation]; + * // Calling original implementation. + * int res = originalIMP(self,selector,num); + * // Returning modified return value. + * return res + 1; + * }; + * } + * mode:SentrySwizzleModeAlways + * key:NULL]; + * + * @endcode + * + * Swizzling frequently goes along with checking whether this particular class (or + * one of its superclasses) has been already swizzled. Here the @c mode and @c key + * parameters can help. + * + * Here is an example of swizzling @c -(void)dealloc; only in case when neither + * class and no one of its superclasses has been already swizzled with our key. + * However "Deallocating ..." message still may be logged multiple times per + * method call if swizzling was called primarily for an inherited class and later + * for one of its superclasses. + * + * @code + * + * static const void *key = &key; + * SEL selector = NSSelectorFromString(@"dealloc"); + * [SentrySwizzle + * swizzleInstanceMethod:selector + * inClass:classToSwizzle + * newImpFactory:^id(SentrySwizzleInfo *swizzleInfo) { + * return ^void(__unsafe_unretained id self){ + * NSLog(@"Deallocating %@.",self); + * + * void (*originalIMP)(__unsafe_unretained id, SEL); + * originalIMP = (__typeof(originalIMP))[swizzleInfo + * getOriginalImplementation]; originalIMP(self,selector); + * }; + * } + * mode:SentrySwizzleModeOncePerClassAndSuperclasses + * key:key]; + * + * @endcode + * + * Swizzling is fully thread-safe. + * + * @param selector Selector of the method that should be swizzled. + * + * @param classToSwizzle The class with the method that should be swizzled. + * + * @param factoryBlock The factory block returning the block for the new + * implementation of the swizzled method. + * + * @param mode The mode is used in combination with the key to indicate whether + * the swizzling should be done for the given class. + * + * @param key The key is used in combination with the mode to indicate whether the + * swizzling should be done for the given class. May be @c NULL if the mode is + * SentrySwizzleModeAlways. + * + * @return @c YES if successfully swizzled and @c NO if swizzling has been already done + * for given key and class (or one of superclasses, depends on the mode). */ + (BOOL)swizzleInstanceMethod:(SEL)selector inClass:(Class)classToSwizzle @@ -290,48 +305,48 @@ typedef NS_ENUM(NSUInteger, SentrySwizzleMode) { #pragma mark └ Swizzle Class method /** - Swizzles the class method of the class with the new implementation. - - Original implementation must always be called from the new implementation. And - because of the the fact that for safe and robust swizzling original - implementation must be dynamically fetched at the time of calling and not at - the time of swizzling, swizzling API is a little bit complicated. - - You should pass a factory block that returns the block for the new - implementation of the swizzled method. And use swizzleInfo argument to retrieve - and call original implementation. - - Example for swizzling `+(int)calculate:(int)number;` method: - - @code - - SEL selector = @selector(calculate:); - [SentrySwizzle - swizzleClassMethod:selector - inClass:classToSwizzle - newImpFactory:^id(SentrySwizzleInfo *swizzleInfo) { - // This block will be used as the new implementation. - return ^int(__unsafe_unretained id self, int num){ - // You MUST always cast implementation to the correct function - pointer. int (*originalIMP)(__unsafe_unretained id, SEL, int); originalIMP = - (__typeof(originalIMP))[swizzleInfo getOriginalImplementation]; - // Calling original implementation. - int res = originalIMP(self,selector,num); - // Returning modified return value. - return res + 1; - }; - }]; - - @endcode - - Swizzling is fully thread-safe. - - @param selector Selector of the method that should be swizzled. - - @param classToSwizzle The class with the method that should be swizzled. - - @param factoryBlock The factory block returning the block for the new - implementation of the swizzled method. + * Swizzles the class method of the class with the new implementation. + * + * Original implementation must always be called from the new implementation. And + * because of the the fact that for safe and robust swizzling original + * implementation must be dynamically fetched at the time of calling and not at + * the time of swizzling, swizzling API is a little bit complicated. + * + * You should pass a factory block that returns the block for the new + * implementation of the swizzled method. And use @c swizzleInfo argument to retrieve + * and call original implementation. + * + * Example for swizzling @c +(int)calculate:(int)number; method: + * + * @code + * + * SEL selector = @selector(calculate:); + * [SentrySwizzle + * swizzleClassMethod:selector + * inClass:classToSwizzle + * newImpFactory:^id(SentrySwizzleInfo *swizzleInfo) { + * // This block will be used as the new implementation. + * return ^int(__unsafe_unretained id self, int num){ + * // You MUST always cast implementation to the correct function + * pointer. int (*originalIMP)(__unsafe_unretained id, SEL, int); originalIMP = + * (__typeof(originalIMP))[swizzleInfo getOriginalImplementation]; + * // Calling original implementation. + * int res = originalIMP(self,selector,num); + * // Returning modified return value. + * return res + 1; + * }; + * }]; + * + * @endcode + * + * Swizzling is fully thread-safe. + * + * @param selector Selector of the method that should be swizzled. + * + * @param classToSwizzle The class with the method that should be swizzled. + * + * @param factoryBlock The factory block returning the block for the new + * implementation of the swizzled method. */ + (void)swizzleClassMethod:(SEL)selector inClass:(Class)classToSwizzle diff --git a/Sources/Sentry/include/SentrySystemWrapper.h b/Sources/Sentry/include/SentrySystemWrapper.h index 03ecc7d52f..09d01a67d1 100644 --- a/Sources/Sentry/include/SentrySystemWrapper.h +++ b/Sources/Sentry/include/SentrySystemWrapper.h @@ -12,8 +12,8 @@ typedef void (^SentryMemoryPressureNotification)(uintptr_t); typedef mach_vm_size_t SentryRAMBytes; /** - * A wrapper around low-level system APIs that are found in headers such as @c and @c - * . + * A wrapper around low-level system APIs that are found in headers such as @c and + * @c . */ @interface SentrySystemWrapper : NSObject diff --git a/Sources/Sentry/include/SentryTime.h b/Sources/Sentry/include/SentryTime.h index 1fa8586c2b..d236fc38de 100644 --- a/Sources/Sentry/include/SentryTime.h +++ b/Sources/Sentry/include/SentryTime.h @@ -6,8 +6,8 @@ SENTRY_EXTERN_C_BEGIN /** - * Given a fractional amount of seconds in a @c double from a Cocoa API like @c -[NSDate @c - * timeIntervalSinceDate:], return an integer representing the amount of nanoseconds. + * Given a fractional amount of seconds in a @c double from a Cocoa API like @c -[NSDate + * @c timeIntervalSinceDate:], return an integer representing the amount of nanoseconds. */ uint64_t timeIntervalToNanoseconds(double seconds); diff --git a/Sources/Sentry/include/SentryTracer.h b/Sources/Sentry/include/SentryTracer.h index 8999c467e4..1e1bd2377c 100644 --- a/Sources/Sentry/include/SentryTracer.h +++ b/Sources/Sentry/include/SentryTracer.h @@ -28,7 +28,7 @@ static NSTimeInterval const SentryTracerDefaultTimeout = 3.0; /** * Indicates whether this tracer will be finished only if all children have been finished. - * If this property is YES and the finish function is called before all children are finished + * If this property is @c YES and the finish function is called before all children are finished * the tracer will automatically finish when the last child finishes. */ @property (readonly) BOOL waitForChildren; @@ -38,12 +38,12 @@ static NSTimeInterval const SentryTracerDefaultTimeout = 3.0; */ @property (nonatomic, readonly) SentryTraceContext *traceContext; -/* - All the spans that where created with this tracer but rootSpan. +/** + * All the spans that where created with this tracer but rootSpan. */ @property (nonatomic, readonly) NSArray> *children; -/* +/** * A delegate that provides extra information for the transaction. */ @property (nullable, nonatomic, weak) id delegate; @@ -59,41 +59,32 @@ static NSTimeInterval const SentryTracerDefaultTimeout = 3.0; @property (strong, nonatomic, readonly) NSDate *originalStartTimestamp; /** - * Init a SentryTracer with given transaction context and hub and set other fields by default - * + * Init a @c SentryTracer with given transaction context and hub and set other fields by default * @param transactionContext Transaction context * @param hub A hub to bind this transaction - * - * @return SentryTracer */ - (instancetype)initWithTransactionContext:(SentryTransactionContext *)transactionContext hub:(nullable SentryHub *)hub; /** - * Init a SentryTracer with given transaction context, hub and whether the tracer should wait + * Init a @c SentryTracer with given transaction context, hub and whether the tracer should wait * for all children to finish before it finishes. - * * @param transactionContext Transaction context * @param hub A hub to bind this transaction * @param waitForChildren Whether this tracer should wait all children to finish. - * - * @return SentryTracer */ - (instancetype)initWithTransactionContext:(SentryTransactionContext *)transactionContext hub:(nullable SentryHub *)hub waitForChildren:(BOOL)waitForChildren; /** - * Init a SentryTracer with given transaction context, hub and whether the tracer should wait + * Init a @c SentryTracer with given transaction context, hub and whether the tracer should wait * for all children to finish before it finishes. - * * @param transactionContext Transaction context - * @param hub A hub to bind this transaction - * @param profilesSamplerDecision Whether to sample a profile corresponding to this transaction + * @param hub A hub to bind this transaction. + * @param profilesSamplerDecision Whether to sample a profile corresponding to this transaction. * @param waitForChildren Whether this tracer should wait all children to finish. - * @param timerWrapper A writer around NSTimer, to make it testable - * - * @return SentryTracer + * @param timerWrapper A wrapper around @c NSTimer, to make it testable. */ - (instancetype)initWithTransactionContext:(SentryTransactionContext *)transactionContext hub:(nullable SentryHub *)hub @@ -103,15 +94,12 @@ static NSTimeInterval const SentryTracerDefaultTimeout = 3.0; timerWrapper:(nullable SentryNSTimerWrapper *)timerWrapper; /** - * Init a SentryTracer with given transaction context, hub and whether the tracer should wait + * Init a @c SentryTracer with given transaction context, hub and whether the tracer should wait * for all children to finish before it finishes. - * * @param transactionContext Transaction context * @param hub A hub to bind this transaction * @param profilesSamplerDecision Whether to sample a profile corresponding to this transaction * @param idleTimeout The idle time to wait until to finish the transaction. - * - * @return SentryTracer */ - (instancetype)initWithTransactionContext:(SentryTransactionContext *)transactionContext hub:(nullable SentryHub *)hub diff --git a/Sources/Sentry/include/SentryUIViewControllerPerformanceTracker.h b/Sources/Sentry/include/SentryUIViewControllerPerformanceTracker.h index cd534248f1..d6b7d1446b 100644 --- a/Sources/Sentry/include/SentryUIViewControllerPerformanceTracker.h +++ b/Sources/Sentry/include/SentryUIViewControllerPerformanceTracker.h @@ -25,33 +25,30 @@ static NSString *const SENTRY_UI_PERFORMANCE_TRACKER_SPANS_IN_EXECUTION_SET @property (nonatomic, readonly, class) SentryUIViewControllerPerformanceTracker *shared; /** - * Measures viewController`s loadView method. - * This method starts a span that will be finished when - * viewControllerDidAppear:callBackToOrigin: is called. - * - * @param controller UIViewController to be measured - * @param callback A callback that indicates the swizzler to call the original view controller - * LoadView method. + * Measures @c controller's @c loadView method. + * This method starts a span that will be finished when @c viewControllerDidAppear:callBackToOrigin: + * is called. + * @param controller @c UIViewController to be measured + * @param callback A callback that indicates the swizzler to call @c controller's original + * @c loadView method. */ - (void)viewControllerLoadView:(UIViewController *)controller callbackToOrigin:(void (^)(void))callback; /** - * Measures viewController`s viewDidLoad method. - * - * @param controller UIViewController to be measured - * @param callback A callback that indicates the swizzler to call the original view controller - * viewDidLoad method. + * Measures @c controller's @c viewDidLoad method. + * @param controller @c UIViewController to be measured + * @param callback A callback that indicates the swizzler to call @c controller's original + * @c viewDidLoad method. */ - (void)viewControllerViewDidLoad:(UIViewController *)controller callbackToOrigin:(void (^)(void))callback; /** - * Measures viewController`s viewWillAppear: method. - * - * @param controller UIViewController to be measured - * @param callback A callback that indicates the swizzler to call the original view controller - * viewWillAppear: method. + * Measures @c controller's @c viewWillAppear: method. + * @param controller @c UIViewController to be measured + * @param callback A callback that indicates the swizzler to call @c controller's original + * @c viewWillAppear: method. */ - (void)viewControllerViewWillAppear:(UIViewController *)controller callbackToOrigin:(void (^)(void))callback; @@ -60,39 +57,36 @@ static NSString *const SENTRY_UI_PERFORMANCE_TRACKER_SPANS_IN_EXECUTION_SET callbackToOrigin:(void (^)(void))callbackToOrigin; /** - * Measures viewController`s viewDidAppear: method. + * Measures @c controller's @c viewDidAppear: method. * This method also finishes the span created at - * viewControllerLoadView:callbackToOrigin: allowing + * @c viewControllerLoadView:callbackToOrigin: allowing * the transaction to be send to Sentry when all spans are finished. - * - * @param controller UIViewController to be measured - * @param callback A callback that indicates the swizzler to call the original view controller - * viewDidAppear: method. + * @param controller @c UIViewController to be measured + * @param callback A callback that indicates the swizzler to call @c controller's original + * @c viewDidAppear: method. */ - (void)viewControllerViewDidAppear:(UIViewController *)controller callbackToOrigin:(void (^)(void))callback; /** - * Measures viewController`s viewWillLayoutSubViews method. + * Measures @c controller's @c viewWillLayoutSubViews method. * This method starts a span that is only finish when - * viewControllerViewDidLayoutSubViews:callbackToOrigin: is called. - * + * @c viewControllerViewDidLayoutSubViews:callbackToOrigin: is called. * @param controller UIViewController to be measured - * @param callback A callback that indicates the swizzler to call the original view controller - * viewWillLayoutSubViews method. + * @param callback A callback that indicates the swizzler to call @c controller's original + * @c viewWillLayoutSubViews method. */ - (void)viewControllerViewWillLayoutSubViews:(UIViewController *)controller callbackToOrigin:(void (^)(void))callback; /** - * Measures viewController`s viewDidLayoutSubViews method. + * Measures @c controller's @c viewDidLayoutSubViews method. * This method also finished the span created at - * viewControllerViewWillLayoutSubViews:callbackToOrigin: + * @c viewControllerViewWillLayoutSubViews:callbackToOrigin: * that measures all work done in views between this two methods. - * * @param controller UIViewController to be measured - * @param callback A callback that indicates the swizzler to call the original view controller - * viewDidLayoutSubViews method. + * @param callback A callback that indicates the swizzler to call @c controller's original + * @c viewDidLayoutSubViews method. */ - (void)viewControllerViewDidLayoutSubViews:(UIViewController *)controller callbackToOrigin:(void (^)(void))callback; diff --git a/scripts/no-changes-in-high-risk-files.sh b/scripts/no-changes-in-high-risk-files.sh index 34ea684b51..714f165415 100755 --- a/scripts/no-changes-in-high-risk-files.sh +++ b/scripts/no-changes-in-high-risk-files.sh @@ -4,12 +4,12 @@ set -euo pipefail # To update the sha run shasum -a 256 ./Sources/Sentry/SentryNSURLSessionTaskSearch.m and copy the result in EXPECTED. ACTUAL=$(shasum -a 256 ./Sources/Sentry/SentryNSURLSessionTaskSearch.m) -EXPECTED="54a41f19ca05866605bf05da4d27f4df34143701c2d70a82221d52fc7c895ebc ./Sources/Sentry/SentryNSURLSessionTaskSearch.m" +EXPECTED="819d5ca5e3db2ac23c859b14c149b7f0754d3ae88bea1dba92c18f49a81da0e1 ./Sources/Sentry/SentryNSURLSessionTaskSearch.m" if [ "$ACTUAL" = "$EXPECTED" ]; then echo "No changes in high risk files." exit 0 else - echo "Changes in high risk files. If your changes are intended please update the sha in ./scripts/no-changes-in-high-risk-files.sh." + echo "Changes in high risk files. If your changes are intended please update the sha in ./scripts/no-changes-in-high-risk-files.sh to $ACTUAL." exit 1 fi From cce35c6e70ee8ad2847502258fc7b0794d833cb7 Mon Sep 17 00:00:00 2001 From: Philipp Hofmann Date: Fri, 24 Mar 2023 10:05:37 +0100 Subject: [PATCH 23/25] ref: Use dispatch queue in dependency container (#2833) Avoid allocating one extra dispatch queue in the dependency container. --- Sources/Sentry/SentryDependencyContainer.m | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Sources/Sentry/SentryDependencyContainer.m b/Sources/Sentry/SentryDependencyContainer.m index 005cdaca00..77c0f6f051 100644 --- a/Sources/Sentry/SentryDependencyContainer.m +++ b/Sources/Sentry/SentryDependencyContainer.m @@ -8,7 +8,6 @@ #import #import #import -#import #import #import #import @@ -204,7 +203,7 @@ - (SentryANRTracker *)getANRTracker:(NSTimeInterval)timeout initWithTimeoutInterval:timeout currentDateProvider:[SentryDefaultCurrentDateProvider sharedInstance] crashWrapper:self.crashWrapper - dispatchQueueWrapper:[[SentryDispatchQueueWrapper alloc] init] + dispatchQueueWrapper:self.dispatchQueueWrapper threadWrapper:self.threadWrapper]; } } From 85b619d38f06e8db47bcb9fd91dbca05178c6155 Mon Sep 17 00:00:00 2001 From: Philipp Hofmann Date: Fri, 24 Mar 2023 11:26:20 +0100 Subject: [PATCH 24/25] fix: Crash in Tracer for idle timeout (#2834) dispatch_block_create can return NULL. If it does, we finish the transaction, and don't schedule the timeout. Fixes GH-2832, GH-2769 --- CHANGELOG.md | 1 + .../TestSentryDispatchQueueWrapper.swift | 9 +++++++++ Sources/Sentry/SentryDispatchQueueWrapper.m | 5 +++++ Sources/Sentry/SentryTracer.m | 13 +++++++++--- .../include/SentryDispatchQueueWrapper.h | 2 ++ .../Performance/SentryTracerTests.swift | 20 +++++++++++++++++++ 6 files changed, 47 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f5b6867061..822ed9864b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ### Fixes - View hierarchy not sent for crashes (#2781) +- Crash in Tracer for idle timeout (#2834) ## 8.3.2 diff --git a/SentryTestUtils/TestSentryDispatchQueueWrapper.swift b/SentryTestUtils/TestSentryDispatchQueueWrapper.swift index ced28591b7..0dafb6b855 100644 --- a/SentryTestUtils/TestSentryDispatchQueueWrapper.swift +++ b/SentryTestUtils/TestSentryDispatchQueueWrapper.swift @@ -62,4 +62,13 @@ public class TestSentryDispatchQueueWrapper: SentryDispatchQueueWrapper { public override func dispatchOnce(_ predicate: UnsafeMutablePointer, block: @escaping () -> Void) { block() } + + public var createDispatchBlockReturnsNULL = false + public override func createDispatchBlock(_ block: @escaping () -> Void) -> (() -> Void)? { + if createDispatchBlockReturnsNULL { + return nil + } + return super.createDispatchBlock(block) + } + } diff --git a/Sources/Sentry/SentryDispatchQueueWrapper.m b/Sources/Sentry/SentryDispatchQueueWrapper.m index 88a89fef3e..9703570dcb 100644 --- a/Sources/Sentry/SentryDispatchQueueWrapper.m +++ b/Sources/Sentry/SentryDispatchQueueWrapper.m @@ -77,6 +77,11 @@ - (void)dispatchOnce:(dispatch_once_t *)predicate block:(void (^)(void))block dispatch_once(predicate, block); } +- (nullable dispatch_block_t)createDispatchBlock:(void (^)(void))block +{ + return dispatch_block_create(0, block); +} + @end NS_ASSUME_NONNULL_END diff --git a/Sources/Sentry/SentryTracer.m b/Sources/Sentry/SentryTracer.m index ea94a6fcad..44245d23f3 100644 --- a/Sources/Sentry/SentryTracer.m +++ b/Sources/Sentry/SentryTracer.m @@ -217,14 +217,21 @@ - (void)dispatchIdleTimeout [self.dispatchQueueWrapper dispatchCancel:_idleTimeoutBlock]; } __weak SentryTracer *weakSelf = self; - _idleTimeoutBlock = dispatch_block_create(0, ^{ + _idleTimeoutBlock = [self.dispatchQueueWrapper createDispatchBlock:^{ if (weakSelf == nil) { SENTRY_LOG_DEBUG(@"WeakSelf is nil. Not doing anything."); return; } [weakSelf finishInternal]; - }); - [self.dispatchQueueWrapper dispatchAfter:self.idleTimeout block:_idleTimeoutBlock]; + }]; + if (_idleTimeoutBlock == NULL) { + SENTRY_LOG_WARN(@"Couln't create idle time out block. Can't schedule idle timeout. " + @"Finishing transaction"); + // If the transaction has no children, the SDK will discard it. + [self finishInternal]; + } else { + [self.dispatchQueueWrapper dispatchAfter:self.idleTimeout block:_idleTimeoutBlock]; + } } - (BOOL)hasIdleTimeout diff --git a/Sources/Sentry/include/SentryDispatchQueueWrapper.h b/Sources/Sentry/include/SentryDispatchQueueWrapper.h index 06bcfaba1e..0a7948fedc 100644 --- a/Sources/Sentry/include/SentryDispatchQueueWrapper.h +++ b/Sources/Sentry/include/SentryDispatchQueueWrapper.h @@ -21,6 +21,8 @@ NS_ASSUME_NONNULL_BEGIN - (void)dispatchOnce:(dispatch_once_t *)predicate block:(void (^)(void))block; +- (nullable dispatch_block_t)createDispatchBlock:(void (^)(void))block; + @end NS_ASSUME_NONNULL_END diff --git a/Tests/SentryTests/Performance/SentryTracerTests.swift b/Tests/SentryTests/Performance/SentryTracerTests.swift index 6d79b6d136..2e870726a6 100644 --- a/Tests/SentryTests/Performance/SentryTracerTests.swift +++ b/Tests/SentryTests/Performance/SentryTracerTests.swift @@ -224,6 +224,26 @@ class SentryTracerTests: XCTestCase { XCTAssertEqual(status, sut.status) } + func testIdleTransaction_CreatingDispatchBlockFails_NoTransactionCaptured() { + fixture.dispatchQueue.createDispatchBlockReturnsNULL = true + + let sut = fixture.getSut(idleTimeout: fixture.idleTimeout, dispatchQueueWrapper: fixture.dispatchQueue) + + assertTransactionNotCaptured(sut) + } + + func testIdleTransaction_CreatingDispatchBlockFailsForFirstChild_FinishesTransaction() { + let sut = fixture.getSut(idleTimeout: fixture.idleTimeout, dispatchQueueWrapper: fixture.dispatchQueue) + + fixture.dispatchQueue.createDispatchBlockReturnsNULL = true + + let child = sut.startChild(operation: fixture.transactionOperation) + advanceTime(bySeconds: 0.1) + child.finish() + + assertOneTransactionCaptured(sut) + } + func testWaitForChildrenTransactionWithStatus_OverwriteStatusInFinish() { let sut = fixture.getSut() sut.status = .aborted From ac224c437a3070ffe34460137ac8761eddaf2852 Mon Sep 17 00:00:00 2001 From: getsentry-bot Date: Fri, 24 Mar 2023 10:27:43 +0000 Subject: [PATCH 25/25] release: 8.3.3 --- CHANGELOG.md | 2 +- Sentry.podspec | 4 ++-- SentryPrivate.podspec | 2 +- SentrySwiftUI.podspec | 4 ++-- Sources/Configuration/Sentry.xcconfig | 2 +- Sources/Configuration/SentryPrivate.xcconfig | 2 +- Sources/Sentry/SentryMeta.m | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 822ed9864b..6f0c4a93b4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## Unreleased +## 8.3.3 ### Fixes diff --git a/Sentry.podspec b/Sentry.podspec index 37436e6f6d..7d6ab2bf13 100644 --- a/Sentry.podspec +++ b/Sentry.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "Sentry" - s.version = "8.3.2" + s.version = "8.3.3" s.summary = "Sentry client for cocoa" s.homepage = "https://github.com/getsentry/sentry-cocoa" s.license = "mit" @@ -27,7 +27,7 @@ Pod::Spec.new do |s| } s.default_subspecs = ['Core'] - s.dependency "SentryPrivate", "8.3.2" + s.dependency "SentryPrivate", "8.3.3" s.subspec 'Core' do |sp| sp.source_files = "Sources/Sentry/**/*.{h,hpp,m,mm,c,cpp}", diff --git a/SentryPrivate.podspec b/SentryPrivate.podspec index bd5668d444..e591b96c7a 100644 --- a/SentryPrivate.podspec +++ b/SentryPrivate.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "SentryPrivate" - s.version = "8.3.2" + s.version = "8.3.3" s.summary = "Sentry Private Library." s.homepage = "https://github.com/getsentry/sentry-cocoa" s.license = "mit" diff --git a/SentrySwiftUI.podspec b/SentrySwiftUI.podspec index 2320e16083..453e32ce1d 100644 --- a/SentrySwiftUI.podspec +++ b/SentrySwiftUI.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "SentrySwiftUI" - s.version = "8.3.2" + s.version = "8.3.3" s.summary = "Sentry client for SwiftUI" s.homepage = "https://github.com/getsentry/sentry-cocoa" s.license = "mit" @@ -19,5 +19,5 @@ Pod::Spec.new do |s| s.watchos.framework = 'WatchKit' s.source_files = "Sources/SentrySwiftUI/**/*.{swift,h,m}" - s.dependency 'Sentry', "8.3.2" + s.dependency 'Sentry', "8.3.3" end diff --git a/Sources/Configuration/Sentry.xcconfig b/Sources/Configuration/Sentry.xcconfig index 7eb85ee32b..4a5df2947c 100644 --- a/Sources/Configuration/Sentry.xcconfig +++ b/Sources/Configuration/Sentry.xcconfig @@ -2,6 +2,6 @@ PRODUCT_NAME = Sentry INFOPLIST_FILE = Sources/Sentry/Info.plist PRODUCT_BUNDLE_IDENTIFIER = io.sentry.Sentry -CURRENT_PROJECT_VERSION = 8.3.2 +CURRENT_PROJECT_VERSION = 8.3.3 MODULEMAP_FILE = $(SRCROOT)/Sources/Sentry/Sentry.modulemap diff --git a/Sources/Configuration/SentryPrivate.xcconfig b/Sources/Configuration/SentryPrivate.xcconfig index bcfb92ec30..58d56958be 100644 --- a/Sources/Configuration/SentryPrivate.xcconfig +++ b/Sources/Configuration/SentryPrivate.xcconfig @@ -1,3 +1,3 @@ PRODUCT_NAME = SentryPrivate MACH_O_TYPE = staticlib -CURRENT_PROJECT_VERSION = 8.3.2 +CURRENT_PROJECT_VERSION = 8.3.3 diff --git a/Sources/Sentry/SentryMeta.m b/Sources/Sentry/SentryMeta.m index 4574b4dbfa..78f7c75ee5 100644 --- a/Sources/Sentry/SentryMeta.m +++ b/Sources/Sentry/SentryMeta.m @@ -5,7 +5,7 @@ @implementation SentryMeta // Don't remove the static keyword. If you do the compiler adds the constant name to the global // symbol table and it might clash with other constants. When keeping the static keyword the // compiler replaces all occurrences with the value. -static NSString *versionString = @"8.3.2"; +static NSString *versionString = @"8.3.3"; static NSString *sdkName = @"sentry.cocoa"; + (NSString *)versionString