Summary
PaymobSDK.xcframework (iOS) statically embeds its own private copy of the
Sentry Cocoa SDK inside its binary. Any host app that also integrates Sentry
(directly, or via sentry_flutter for Flutter apps) ends up with two
different images in the same process both defining Objective-C/Swift classes
with the same names (SentrySDKInternal, SentryExperimentalOptions, etc.).
Because Objective-C classes are uniqued by name per-process, the runtime
resolves calls to whichever copy "wins" the uniquing race — which is often
not the caller's own copy. This causes a crash on app launch as soon as the
host app's Sentry SDK initializes.
Environment
- PaymobSDK version: 1.3.2 (
PaymobSDK.xcframework, vendored binary framework)
- Host app: Flutter, using
sentry_flutter: 9.22.0 (native sentry-cocoa 8.58.3)
- Platform: iOS (reproduced on iOS Simulator; Xcode 17 / iOS 26 toolchain)
- Integration: Flutter's Swift Package Manager plugin support for
sentry_flutter (native Sentry linked via SPM), PaymobSDK integrated via
CocoaPods vendored_frameworks
Note: we confirmed this is not specific to our integration method. The
official flutter_paymob_sdk Flutter plugin
(https://github.com/PaymobAccept/flutter_sdk) vendors the identical
PaymobSDK.xcframework binary (ios/Frameworks/PaymobSDK.xcframework in
that repo) — so any app using the official plugin alongside Sentry would hit
the same conflict. This is a problem in the PaymobSDK.xcframework binary
itself, not in how a given app wires it up.
Steps to reproduce
- Integrate
PaymobSDK.xcframework 1.3.2 into an iOS app.
- Integrate any version of Sentry's iOS SDK (directly, or via
sentry_flutter)
in the same app, and call SentrySDK.start / SentryFlutter.init during
app launch.
- Do a fully clean build (clear
DerivedData, SwiftPM package cache,
and Pods) so both frameworks are freshly linked from scratch.
- Launch the app.
Expected behavior
The app launches normally; both SDKs operate independently.
Actual behavior
The app crashes on launch. We reproduced two distinct crash signatures
depending on how our own Sentry copy is linked (static vs. dynamic) — both
stemming from the same root cause:
A) Our Sentry statically linked (default sentry_flutter configuration):
Could not cast value of type 'Sentry.SentryExperimentalOptions' (0x102af3800)
to 'Sentry.SentryExperimentalOptions' (0x101de55e0).
Swift's runtime detects two non-identical type metadata records for what
should be the same type and traps.
B) Our Sentry linked as a dynamic framework (Sentry-Dynamic product) —
tried as a workaround, made things worse rather than better:
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Subtype: KERN_INVALID_ADDRESS at 0x0000000000000001
Backtrace (trimmed):
SentryFlutterPlugin.handle(_:result:)
SentryFlutterPlugin.initNativeSdk(_:result:)
+[SentrySDKInternal startWithConfigureOptions:] <-- resolved into PaymobSDK.framework's image, not ours
SentryFlutter.update(options:with:)
swift_beginAccess
In this case, our own plugin code (built against our Sentry's expected
object layout) called +[SentrySDKInternal startWithConfigureOptions:], but
the Objective-C runtime resolved that class to PaymobSDK.framework's own
embedded copy instead of ours, since both images define a class with that
exact name. Calling into the wrong implementation with an object built for
the other one's layout corrupts memory and segfaults.
Root cause evidence
Running strings on PaymobSDK.xcframework's binary shows it contains
Sentry's own source paths and mangled Swift symbols, confirming Sentry is
statically embedded inside PaymobSDK itself:
Sentry SDK was loaded multiple times in the same binary
/Users/runner/work/sentry-cocoa/sentry-cocoa/Sources/Sentry/Processors/SentryWatchdogTerminationBreadcrumbProcessor.m
/Users/runner/work/sentry-cocoa/sentry-cocoa/Sources/Sentry/Profiling/SentryContinuousProfiler.mm
$s6Sentry0A12MaskRendererP
$s6Sentry0A13RedactOptionsP
...
Notably, the string "Sentry SDK was loaded multiple times in the same binary" is Sentry's own internal guard message for exactly this scenario —
this conflict is a known failure mode for the Sentry SDK itself, not
something specific to our integration.
Why this is a PaymobSDK issue, not something we can fix on our side
- We tried both static and dynamic linking for our own Sentry copy; both
crash, because the fundamental problem is two copies of Sentry's classes
existing in one process, not how either copy is linked.
- We cannot rename, strip, or otherwise patch symbols inside a closed-source,
vendored .xcframework we don't control.
- Removing Sentry from our own app entirely is not an acceptable workaround —
it would mean losing crash reporting for the whole app just to
accommodate a payment SDK.
Requested fix
Please ship a build of PaymobSDK.xcframework that does not statically
embed its own copy of Sentry — either by removing the Sentry dependency
entirely, or by properly namespacing/isolating it (e.g. via symbol hiding /
-fvisibility=hidden for embedded third-party dependencies, or dynamic
linking with a private install name) so it cannot collide with a host app's
own Sentry integration.
Happy to provide the full .ips crash report, a minimal repro project, or
test a candidate fix build — please let us know what would help.
Summary
PaymobSDK.xcframework(iOS) statically embeds its own private copy of theSentry Cocoa SDK inside its binary. Any host app that also integrates Sentry
(directly, or via
sentry_flutterfor Flutter apps) ends up with twodifferent images in the same process both defining Objective-C/Swift classes
with the same names (
SentrySDKInternal,SentryExperimentalOptions, etc.).Because Objective-C classes are uniqued by name per-process, the runtime
resolves calls to whichever copy "wins" the uniquing race — which is often
not the caller's own copy. This causes a crash on app launch as soon as the
host app's Sentry SDK initializes.
Environment
PaymobSDK.xcframework, vendored binary framework)sentry_flutter: 9.22.0(nativesentry-cocoa8.58.3)sentry_flutter(native Sentry linked via SPM), PaymobSDK integrated viaCocoaPods
vendored_frameworksNote: we confirmed this is not specific to our integration method. The
official
flutter_paymob_sdkFlutter plugin(https://github.com/PaymobAccept/flutter_sdk) vendors the identical
PaymobSDK.xcframeworkbinary (ios/Frameworks/PaymobSDK.xcframeworkinthat repo) — so any app using the official plugin alongside Sentry would hit
the same conflict. This is a problem in the
PaymobSDK.xcframeworkbinaryitself, not in how a given app wires it up.
Steps to reproduce
PaymobSDK.xcframework1.3.2 into an iOS app.sentry_flutter)in the same app, and call
SentrySDK.start/SentryFlutter.initduringapp launch.
DerivedData, SwiftPM package cache,and
Pods) so both frameworks are freshly linked from scratch.Expected behavior
The app launches normally; both SDKs operate independently.
Actual behavior
The app crashes on launch. We reproduced two distinct crash signatures
depending on how our own Sentry copy is linked (static vs. dynamic) — both
stemming from the same root cause:
A) Our Sentry statically linked (default
sentry_flutterconfiguration):Swift's runtime detects two non-identical type metadata records for what
should be the same type and traps.
B) Our Sentry linked as a dynamic framework (
Sentry-Dynamicproduct) —tried as a workaround, made things worse rather than better:
Backtrace (trimmed):
In this case, our own plugin code (built against our Sentry's expected
object layout) called
+[SentrySDKInternal startWithConfigureOptions:], butthe Objective-C runtime resolved that class to PaymobSDK.framework's own
embedded copy instead of ours, since both images define a class with that
exact name. Calling into the wrong implementation with an object built for
the other one's layout corrupts memory and segfaults.
Root cause evidence
Running
stringsonPaymobSDK.xcframework's binary shows it containsSentry's own source paths and mangled Swift symbols, confirming Sentry is
statically embedded inside PaymobSDK itself:
Notably, the string
"Sentry SDK was loaded multiple times in the same binary"is Sentry's own internal guard message for exactly this scenario —this conflict is a known failure mode for the Sentry SDK itself, not
something specific to our integration.
Why this is a PaymobSDK issue, not something we can fix on our side
crash, because the fundamental problem is two copies of Sentry's classes
existing in one process, not how either copy is linked.
vendored
.xcframeworkwe don't control.it would mean losing crash reporting for the whole app just to
accommodate a payment SDK.
Requested fix
Please ship a build of
PaymobSDK.xcframeworkthat does not staticallyembed its own copy of Sentry — either by removing the Sentry dependency
entirely, or by properly namespacing/isolating it (e.g. via symbol hiding /
-fvisibility=hiddenfor embedded third-party dependencies, or dynamiclinking with a private install name) so it cannot collide with a host app's
own Sentry integration.
Happy to provide the full
.ipscrash report, a minimal repro project, ortest a candidate fix build — please let us know what would help.