rickclephas / nsexceptionkt Goto Github PK
View Code? Open in Web Editor NEWA Kotlin Multiplatform Library to improve crash reports on Apple platforms
License: MIT License
A Kotlin Multiplatform Library to improve crash reports on Apple platforms
License: MIT License
We're seeing many Sentry crash reports showing up incorrectly under the same title/description as of the last couple weeks.
NSInvalidArgumentException
-[SentryOptions sdkInfo]: unrecognized selector sent to instance 0x...
I'm not sure if this might be linked to changes in a recent update to Sentry's iOS SDK, or if this is a problem with our project itself.
Environment:
isStatic = true
)kotlin.mpp.enableCInteropCommonization=true
Example stack trace:
OS Version: iOS 16.1 (20B82)
Report Version: 104
Exception Type: EXC_CRASH (SIGABRT)
Crashed Thread: 0
Application Specific Information:
-[SentryOptions sdkInfo]: unrecognized selector sent to instance 0x13a1065d0
Thread 0 Crashed:
0 CoreFoundation 0x35add9e88 __exceptionPreprocess
1 libobjc.A.dylib 0x34d5278d4 objc_exception_throw
2 CoreFoundation 0x35af4e848 -[NSObject(NSObject) doesNotRecognizeSelector:]
3 CoreFoundation 0x35adeff9c ___forwarding___
4 CoreFoundation 0x35ae5834c __forwarding_prep_0___
5 Shared 0x102d03384 kfun:com.rickclephas.kmp.nsexceptionkt.sentry.$setSentryUnhandledExceptionHook$lambda$1$FUNCTION_REFERENCE$477.$<T>invoke{}#internal
6 Shared 0x102cfeca0 kfun:com.rickclephas.kmp.nsexceptionkt.core.$wrapUnhandledExceptionHook$lambda$0$FUNCTION_REFERENCE$479.$<T>invoke{}#internal
7 Shared 0x103307ae0 (anonymous namespace)::processUnhandledException
8 Shared 0x103308b78 kotlin::ProcessUnhandledException
9 Shared 0x10330a544 Kotlin_ObjCExport_trapOnUndeclaredException
<useful part of stack trace mentioning app functions appears below, omitted>
Error when compiling main swift class:
iosApp.swift:5:8: No such module 'NSExceptionKtCrashlytics'
iosApp.swift
:
import UIKit
import SwiftUI
import ComposeApp
import FirebaseCore
import NSExceptionKtCrashlytics
@main
struct iosApp: App {
init() {
FirebaseApp.configure()
NSExceptionKt.addReporter(.crashlytics(causedByStrategy: .append))
MainKt.ContextInit()
KoinKt.doInitKoin()
}
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
build.gradle.kts
:
listOf(
iosX64(),
iosArm64(),
iosSimulatorArm64()
).forEach {
it.binaries.framework {
isStatic = true
export("com.rickclephas.kmp:nsexception-kt-core:1.0.0-BETA-1")
}
}
val iosX64Main by getting
val iosArm64Main by getting
val iosSimulatorArm64Main by getting
val iosMain by getting {
dependencies {
// ios ktor engine impl
implementation(libs.ktor.client.darwin)
// crashlytics special exception handling
api(libs.nsexception) // com.rickclephas.kmp:nsexception-kt-core:1.0.0-BETA-1
}
}
Header files for Sentry were generated with 7.21.0 (#7 (comment)). NSExceptionKt_SentryCrashStackCursorCleanup
calls sentrycrash_async_backtrace_decref
in https://github.com/rickclephas/NSExceptionKt/blob/master/nsexception-kt-sentry/src/nativeInterop/cinterop/Sentry/Private/SentryCrashMonitor_NSException%2BNSExceptionKt.h#L21
This was removed by the deletion of SentryHook
as of sentry-cocoa 8.7.1 getsentry/sentry-cocoa@8.7.0...8.7.1 which leads to a missing symbol called
crash when later Sentry versions are used in the iOS project. It seems Sentry decided the async dereferencing was no longer needed? getsentry/sentry-cocoa#3020
I'm not sure how to generate the headers in this project from Sentry's but I'll work on figuring that out and try to put up a PR. (fwiw, 8.7.1 was released over 3 months ago so I suspect this may come up more)
Hey Rick!
Thanks for building this library <3
I wonder: How does this compare to the sentry KMP library?
https://github.com/getsentry/sentry-kotlin-multiplatform
If we're using sentry: Does your integration do more than the official one?
It seems like FIRCLSExceptionRecordNSException
is not a public api? Wondering why not just raise the NSException
.
Hi, thanks for the work on this much-needed library.
I am having an issue installing it in my KMM project.
Everything works up to the addition of setSentryUnhandledExceptionHook()
, once imported the gradle command :shared:linkDebugFrameworkIosSimulatorArm64
Throws anUndefined symbols for architecture arm64
ld: warning: object file (/var/folders/r7/dm4kdzqd6fz1gf_wzxw0l4k00000gn/T/konan_temp2967256884621265590/result.o) was built for newer iOS Simulator version (14.0) than being linked (9.0)
Undefined symbols for architecture arm64:
"_OBJC_CLASS_$_SentryDependencyContainer", referenced from:
objc-class-ref in result.o
"_OBJC_CLASS_$_SentryEnvelope", referenced from:
objc-class-ref in result.o
"_OBJC_CLASS_$_SentryEnvelopeHeader", referenced from:
objc-class-ref in result.o
"_OBJC_CLASS_$_SentryEnvelopeItem", referenced from:
objc-class-ref in result.o
"_OBJC_CLASS_$_SentryEvent", referenced from:
objc-class-ref in result.o
"_OBJC_CLASS_$_SentryException", referenced from:
objc-class-ref in result.o
"_OBJC_CLASS_$_SentryMechanism", referenced from:
objc-class-ref in result.o
"_OBJC_CLASS_$_SentrySDK", referenced from:
objc-class-ref in result.o
"_sentrycrash_async_backtrace_decref", referenced from:
_com_rickclephas_kmp_nsexceptionkt_sentry_cinterop_NSExceptionKt_SentryCrashStackCursorCleanup_wrapper5 in result.o
"_sentrycrashsc_initWithBacktrace", referenced from:
_NSExceptionKt_SentryCrashStackCursorFromNSException in result.o
ld: symbol(s) not found for architecture arm64
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':shared:linkDebugFrameworkIosSimulatorArm64'.
> Compilation finished with errors
All the searches I have done, point to a minimum version mismatch in the sentry SDK (v9.0) but I don't understand why this would cause the symbols error.
One other issue may be I have not set the build to static (as per your sample project), as this causes issues with moko-resource library which I am using. Is this a requirement? (this is not stated in the documentation if it is :)
Any help would be much appreciated
Configuration:
Kotlin 1.7.20
IOS min deployment 14.1
NSExceptionKt 0.1.2
Sentry libraries latest
NSExceptionKt has firebase as dependency and if the project already has firebase installed through cocoapods then we are facing an error saying something like - "Firebase module already exists".
I am thinking about adding cocopods support to NSExceptionKt. Is there any potential blockers for this to be done?
While testing this library with both Crashlytics and Sentry. I found that Crashlytics is working as expected, but on Sentry the crash is still the same i.e., WatchdogTermination with no stack trace.
Screenshot: https://imgur.com/a/mLtCZ6r
Version: 0.1.16
Sentry-cocoa : 8.15.0
As title, I add Crashlytics through SPM and archive my app as .ipa. I've added setCrashlyticsUnhandledExceptionHook()
at start also. Open app will crash instantly. Check the crash log:
"symbol not found in flat namespace (_OBJC_CLASS_$_FIRCrashlytics)"
I am seeing a similar build issue to this other issue. It is closed but the owner did not specify the solution.
Interesting that when I get linked to the NSExceptionKt
class when clicking on it:
build.gradle setup uses a bit more modern approach, but should output the same:
listOf(
iosX64(),
iosArm64(),
iosSimulatorArm64()
).forEach {
it.binaries.framework {
baseName = "Shared"
isStatic = true
export(libs.ios.nsexception.tracker)
}
}
...
sourceSets {
iosMain {
dependencies {
implementation(libs.ktor.client.darwin)
api(libs.ios.nsexception.tracker)
}
}
Tried using string dependency (com.rickclephas.kmp:nsexception-kt-core:1.0.0-BETA-4
) instead of version catalogs, issue persists.
Bumping back to BETA1 did not work too.
Just FYI, when looking at a sample, I see that the dependency does not contain version.
When running a release build of our app on device, the app immediately crashes at launch. Debug builds are unaffected.
Exception Type: EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Termination Reason: DYLD 9
symbol not found in flat namespace '_OBJC_CLASS_$_SentryDependencyContainer'
Triggered by Thread: 0
Thread 0 Crashed:
0 dyld 0x1b93a3f6c __abort_with_payload + 8
1 dyld 0x1b93aea98 abort_with_payload_wrapper_internal + 104
2 dyld 0x1b93aeacc abort_with_payload + 16
3 dyld 0x1b9351004 dyld4::halt(char const*) + 328
4 dyld 0x1b934f30c dyld4::prepare(dyld4::APIs&, dyld3::MachOAnalyzer const*) + 4124
5 dyld 0x1b934ccdc start + 1948
Thread 0 crashed with ARM Thread State (64-bit):
x0: 0x0000000000000006 x1: 0x0000000000000009 x2: 0x000000016f07c320 x3: 0x0000000000000014
x4: 0x000000016f07bf20 x5: 0x0000000000000000 x6: 0x0000000000000000 x7: 0x000000016f07b908
x8: 0x0000000000000020 x9: 0x0000000000000009 x10: 0x0000000000000001 x11: 0x000000000000000a
x12: 0x0000000000000000 x13: 0x0000000000000038 x14: 0x000000023e2d7cae x15: 0x000000016f07b0c8
x16: 0x0000000000000209 x17: 0x00000001b93a146c x18: 0x0000000000000000 x19: 0x0000000000000000
x20: 0x000000016f07bf20 x21: 0x0000000000000014 x22: 0x000000016f07c320 x23: 0x0000000000000009
x24: 0x0000000000000006 x25: 0x0000000101611888 x26: 0x0000000000000001 x27: 0x0000000000001470
x28: 0x0000000101611888 fp: 0x000000016f07bef0 lr: 0x00000001b93aea98
sp: 0x000000016f07beb0 pc: 0x00000001b93a3f6c cpsr: 0x40001000
far: 0x00000001f17f19f0 esr: 0x56000080 Address size fault
Commenting out our usage of NSExceptionKt (dropKotlinCrashEvent
& setSentryUnhandledExceptionHook
) resolves the issue for the time being.
Environment:
kotlin.mpp.enableCInteropCommonization=true
in gradle.properties
xcodebuild: error: Could not resolve package dependencies:
Dependencies could not be resolved because 'nsexceptionkt' depends on 'firebase-ios-sdk' 9.3.0..<11.0.0 and root depends on 'firebase-ios-sdk' 11.0.0.
I'm trying to add NSExceptionKt to my project, which currently uses separate platform-native Sentry dependencies in the Android (Gradle) and iOS (Swift Package via Xcode) projects.
Following the instructions in the README for Sentry support, adding the dropSentryKotlinCrashEvent
and setupSentry
functions as shown results in Kotlin compiler errors that SentryEvent
cannot be resolved – presumably because Sentry is unknown to the shared/iosMain
code.
I've instead done the following:
build.gradle.kts
so that it can be used from iOS
export("com.rickclephas.kmp:nsexception-kt-sentry:0.1.0")
api(..)
rather than implementation(..)
SentryKt.dropKotlinCrashEvent
and SentryKt.setSentryUnhandledExceptionHook
directly from my Swift iOS codeFor my tests so far, this seems to work well – our crash reports are looking much improved in Sentry!
Do you see any potential issues with this method? If not, perhaps it could be worth documenting somewhere
I follow this guide but failed.
Interop library /Users/yuhsuanlin/.gradle/caches/modules-2/files-2.1/com.rickclephas.kmp/nsexception-kt-core-iossimulatorarm64/1.0.0-BETA-1/88e07bce40ac9786ccad5f354aef39e0fd1e6ae4/nsexception-kt-core-cinterop-NSExceptionKtCoreObjC can't be exported with -Xexport-library
Could not find or use auto-linked framework 'CoreAudioTypes': framework 'CoreAudioTypes' not found
Undefined symbols:
Linker command failed with exit code 1 (use -v to see invocation)
I'm following the "Add dependencies on a Pod library" docs to add Sentry as a dependency on the Kotlin side because I want to be able to write my own Kermit integration, also on the Kotlin side.
After integrating NSExceptionKt, I realized I'm unable to finish the setup because when I try to call this:
options?.setBeforeSend { event ->
dropKotlinCrashEvent(event)
}
I get this error:
Type mismatch.
Required: cocoapods.Sentry.SentryEvent?
Found: com.rickclephas.kmp.nsexceptionkt.sentry.cinterop.SentryEvent?
I believe this is the culprit, as we're trying to add Sentry already as part of NSExceptionKt. Is there anything I can do on my end to work around this issue?
I don't know enough about Swift to know why this crash is happening, but I get this after an unrelated crash on iOS 18 with library version 1.0.0-BETA-4.
Project source is here: https://github.com/zacharee/ArcadyanKVD21Control/.
Steps to reproduce:
google_play_test_user
and google_play_test_pass
for the credentials and log in.EXC_BREAKPOINT: Fatal error: NSArray element failed to match the Swift Array Element type
Expected BugsnagFeatureFlag but found BugsnagFeatureFlag
0 libswiftCore.dylib +0x109c4 _ArrayBuffer._getElementSlowPath(_:)
1 libswiftCore.dylib +0x15f8c Array.subscript.read
2 libswiftCore.dylib +0x15e94 protocol witness for Collection.subscript.read in conformance [A]
3 libswiftCore.dylib +0x61880 protocol witness for IteratorProtocol.next() in conformance IndexingIterator<A>
4 libswiftCore.dylib +0x16f5e4 Sequence.contains(where:)
5 HINT Control.debug.dylib +0x7c9c closure #1 in static NSExceptionKtReporter<>.bugsnag(_:) (BugsnagNSExceptionKtReporter.swift:18:30)
6 HINT Control.debug.dylib +0x7e40 thunk for @escaping @callee_guaranteed (@guaranteed BugsnagEvent) -> (@unowned Bool) (<compiler-generated>)
7 HINT Control.debug.dylib +0x24b1c -[BSGEventUploadOperation runWithDelegate:completionHandler:] (BSGEventUploadOperation.m:87:18)
8 HINT Control.debug.dylib +0x25dc8 -[BSGEventUploadOperation start] (BSGEventUploadOperation.m:220:9)
9 Foundation +0x723d88 __NSOPERATIONQUEUE_IS_STARTING_AN_OPERATION__
10 Foundation +0x723a90 __NSOQSchedule_f
11 libdispatch.dylib +0x135e8 _dispatch_block_async_invoke2
12 libdispatch.dylib +0x3e5c _dispatch_client_callout
13 libdispatch.dylib +0x77fc _dispatch_continuation_pop
14 libdispatch.dylib +0x69d4 _dispatch_async_redirect_invoke
15 libdispatch.dylib +0x1656c _dispatch_root_queue_drain
16 libdispatch.dylib +0x16fb4 _dispatch_worker_thread2
17 libsystem_pthread.dylib +0x3b34 _pthread_wqthread
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.