Table of Contents
Introduction
The Blue Triangle SDK captures and reports crashes and errors to help correlate user-experience issues with business impact. Because of this, you may see Blue Triangle SDK methods appear in a crash stack trace. This does not necessarily mean the SDK caused the crash—only that it detected the crash and was in the call chain when it reported it.
Example: UI Event Interception
To track user interactions such as taps, the Blue Triangle SDK intercepts UI events before they reach the application own code. This technique is common across analytics and monitoring SDKs.
As a result, if your app crashes during a user interaction—such as a tap—the SDK may appear in the stack trace even when the root cause is entirely within your app.
Consider the following example, where tapping a button triggers an exception:
private lazy var checkoutButton: UIButton = {
let action = UIAction(title: "Checkout") { [weak self] _ in
// This will crash because the array is empty
NSArray().object(at: 99)
}
return UIButton(primaryAction: action)
}()
When the user taps this button, the app will crash inside the button’s action. However, because the SDK intercepts the tap to record it, the crash stack trace will show SDK methods above the line where the exception occurred.
Sample Stack Trace
Below is what the resulting crash log looks like in Xcode. Note that the crash originates from RootViewController inside the app code, while Blue Triangle appear higher in the stack simply because it intercepts the user event:
0 CoreFoundation 0x1804f39dc __exceptionPreprocess + 160 1 libobjc.A.dylib 0x18009c084 objc_exception_throw + 72 2 CoreFoundation 0x1803bb2e8 -[__NSArray0 objectEnumerator] + 0 3 Example-UIKit 0x1007a0124 specialized RootViewController.causeNSException() + 64 (RootViewController.swift:177) 4 Example-UIKit 0x10079e8c0 closure #1 in closure #1 in RootViewController.crashButton.getter + 60 5 UIKitCore 0x1851aea08 0x185156000 + 363016 6 UIKitCore 0x1861b0fcc -[UIAction performWithSender:target:] + 104 7 UIKitCore 0x185ae7e6c -[UIControl _sendActionsForEvents:withEvent:] + 284 8 UIKitCore 0x185ae464c -[UIButton _sendActionsForEvents:withEvent:] + 200 9 UIKitCore 0x185ae7ed0 -[UIControl _sendActionsForEvents:withEvent:] + 384 10 UIKitCore 0x185ae464c -[UIButton sendActionsForEvents:withEvent:] + 200 11 UIKitCore 0x185ae6aec -[UIControl touchesEnded:withEvent:] + 428 12 UIKitCore 0x186299fe4 -[UIWindow sendTouchesForEvent:] + 976 13 UIKitCore 0x18629b3e4 -[UIWindow sendEvent:] + 2812 14 UIKitCore 0x186279714 -[UIApplication sendEvent:] + 376 15 Example-UIKit 0x100804148 UIApplication.swizzled_sendEvent(:) + 56 (UIApplication+Utils.swift:62) 16 Example-UIKit 0x100804544 @objc UIApplication.swizzled_sendEvent(:) + 52 17 UIKitCore 0x18630dc6c __dispatchPreprocessedEventFromEventQueue + 1184 18 UIKitCore 0x186310920 __processEventQueue + 4800 19 UIKitCore 0x186308ecc updateCycleEntry + 168 20 UIKitCore 0x185773878 _UIUpdateSequenceRunNext + 120 21 UIKitCore 0x18617ec90 schedulerStepScheduledMainSectionContinue + 56 22 UpdateCycle 0x2509462b4 UC::DriverCore::continueProcessing() + 80 23 CoreFoundation 0x1804114ac __CFMachPortPerform + 164 24 CoreFoundation 0x18044dbe0
Though Frames 15 and 16 show the file name and line number (UIApplication+Utils.swift:62), but this is not initiated from BlueTriangle SDK.
Since we intercept sendEvent(:) using swizzled implementation SDK forwards the event back to UIKit’s original sendEvent(:) which is indicated in stack trace frame 13, 14, 15.
13 UIKitCore 0x18629b3e4 -[UIWindow sendEvent:] + 2812
14 UIKitCore 0x186279714 -[UIApplication sendEvent:] + 376
15 Example-UIKit 0x100804148 UIApplication.swizzled_sendEvent(:) + 56 (UIApplication+Utils.swift:62)Hence presence of “14 UIKitCore [UIApplication sendEvent:] + 376” indicates that the event successfully passed through our interception layer and was handed back to UIKit, which ultimately leads to the app’s event handlers.
The real crash in this example actually occurs at frames 3 and 4:
2 CoreFoundation 0x1803bb2e8 -[__NSArray0 objectEnumerator] + 0
3 Example-UIKit 0x1007a0124 specialized RootViewController.causeNSException() + 64 (RootViewController.swift:177)Unlike the above example, in some special cases the first few frames may not indicate app code like frames 3 and 4 in the stack trace. Still, the presence of: 14 UIKitCore [UIApplication sendEvent:] + 376 indicates that the BlueTriangle interceptor passed execution successfully back to UIKit, and the issue could instead be related to memory handling within the event handlers.
Summary
When investigating an app crash:
Start by reviewing the crash in the Error Explorer within the portal. There, you can see details such as the device, OS version, application version, and SDK version. If you have session replay enabled, you can also view the user’s actions leading up to the crash. Together, these details can help narrow down the root cause.
Share the crash information—including app details, the stack trace, and any other relevant context—with Blue Triangle’s customer support team for further assistance.
Comments
0 comments
Please sign in to leave a comment.