Integration
sentry-android-ndk
Build System
Gradle
AGP Version
8.11.1
Proguard
Enabled
Other Error Monitoring Solution
No
Version
sentry_flutter 9.22.0 / sentry.native.android.flutter 0.15.2
Steps to Reproduce
- Create a Flutter Android app using
sentry_flutter: ^9.22.0.
- Initialize Sentry with
enableTombstone = true, attachThreads = true, enableUserInteractionBreadcrumbs = true, and enableAutoNativeBreadcrumbs = true.
- Wrap the app with
SentryWidget.
- Trigger a real JNI/C++ SIGSEGV from a Flutter button via
MethodChannel.
- Restart the app so the pending native/tombstone crash event is sent.
- Compare the regular native
signalhandler event with the TombstoneMerged event in Sentry.
Flutter init:
await SentryFlutter.init(
(options) {
options.dsn = '<dsn>';
options.release = 'sentry_demo@1.0.0+1';
options.dist = '1';
options.enableTombstone = true;
options.attachThreads = true;
options.enableUserInteractionBreadcrumbs = true;
options.enableAutoNativeBreadcrumbs = true;
},
appRunner: () => runApp(SentryWidget(child: const App())),
);
Dart trigger:
static const _nativeChannel = MethodChannel('sentry_demo/native');
Future<void> triggerNativeCrash() async {
await _nativeChannel.invokeMethod('triggerRealNativeCrash');
}
Android MainActivity.kt:
class MainActivity : FlutterActivity() {
external fun triggerNativeSegfault()
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, "sentry_demo/native")
.setMethodCallHandler { call, result ->
if (call.method == "triggerRealNativeCrash") {
triggerNativeSegfault()
} else {
result.notImplemented()
}
}
}
companion object {
init {
System.loadLibrary("sentry_demo_native")
}
}
}
Native crash source:
#include <jni.h>
extern "C" JNIEXPORT void JNICALL
Java_com_example_sentry_1demo_MainActivity_triggerNativeSegfault(JNIEnv *, jobject) {
volatile int *crash_address = nullptr;
*crash_address = 1;
}
Environment:
- Flutter app using
sentry_flutter: ^9.22.0
- Android Gradle Plugin: 8.11.1
- Sentry Android Gradle Plugin: 6.14.0
- Android 12 device
- Native SIGSEGV triggered from JNI/C++
- R8 enabled
- No other error monitoring solution
Expected Result
A TombstoneMerged event should preserve the same relevant scope data as the regular native crash event, including breadcrumbs added by the Flutter SDK/native SDK, without duplicating entries.
In particular:
- Flutter UI interaction breadcrumbs should be present once.
- Navigation/app lifecycle/device breadcrumbs should be present once.
- Custom breadcrumbs/tags/context already synced to the native scope before the crash should be preserved.
- Enabling tombstone reporting should not make breadcrumbs less reliable than the regular native signal handler event.
Actual Result
When enableTombstone is enabled in a Flutter Android app, native SIGSEGV crashes are reported as TombstoneMerged events. Compared with regular native signalhandler events for the same crash path, the merged tombstone events preserve some breadcrumbs, but the scope/breadcrumb merge appears inconsistent:
- The merged event contains duplicated breadcrumbs.
- Some Flutter/Dart scope data is not reliable in the final tombstone merged event.
- This makes the
TombstoneMerged event less useful for investigating what happened before the crash.
Regular native crash event:
- Issue:
131911518
- Event ID:
a0fc8e59e5a84631746cfb62af3cf072
- mechanism:
signalhandler
- entries:
exception, breadcrumbs, debugmeta
- breadcrumbs count: 4
- breadcrumbs include:
app.lifecycle
navigation
device.event
ui.click for the crash button
Tombstone merged crash events:
- Issue:
131935719
- Event IDs:
ba490da4525e4ec519f0fbf27c1966be
89c1281cbb7045a8091131c05ef45a0b
- mechanism:
TombstoneMerged
- entries:
message, exception, threads, breadcrumbs, debugmeta
- breadcrumbs count: 7
- breadcrumbs include duplicated entries:
navigation appears twice
device.event appears twice
ui.click appears twice
Example from a TombstoneMerged event:
{
"breadcrumbs": {
"count": 7,
"values": [
{ "category": "app.lifecycle", "data": { "state": "foreground" } },
{ "category": "navigation", "data": { "state": "didPush", "to": "home" } },
{ "category": "device.event", "data": { "action": "BATTERY_CHANGED", "charging": true, "level": 82 } },
{ "category": "ui.click", "data": { "label": "Android SIGSEGV", "view.id": "feature_button_Android SIGSEGV" } },
{ "category": "navigation", "data": { "state": "didPush", "to": "home" } },
{ "category": "device.event", "data": { "action": "BATTERY_CHANGED", "charging": true, "level": 82 } },
{ "category": "ui.click", "data": { "label": "Android SIGSEGV", "view.id": "feature_button_Android SIGSEGV" } }
]
}
}
Regular signalhandler event breadcrumb summary:
2026-07-03T06:40:19.472Z app.lifecycle
2026-07-03T06:40:19.475Z navigation
2026-07-03T06:40:20.907Z device.event
2026-07-03T06:40:57.818Z ui.click Android SIGSEGV
TombstoneMerged event breadcrumb summary:
2026-07-03T08:34:36.806Z app.lifecycle
2026-07-03T08:34:36.810Z navigation
2026-07-03T08:34:37.612Z device.event
2026-07-03T08:34:52.788Z ui.click Android SIGSEGV
2026-07-03T08:34:36.810Z navigation
2026-07-03T08:34:37.612Z device.event
2026-07-03T08:34:52.788Z ui.click Android SIGSEGV
This looks related to the tombstone merge path. The same crash path reported through the regular native signalhandler event has a clean breadcrumb list. Once tombstone reporting is enabled and the event becomes TombstoneMerged, breadcrumbs are duplicated and scope data appears less predictable.
It looks like the merge process combines breadcrumbs from both the original native SDK event and the parsed tombstone/Java-side event without deduplicating, or replaces/merges event fields in a way that makes Flutter/native scope data inconsistent.
Integration
sentry-android-ndk
Build System
Gradle
AGP Version
8.11.1
Proguard
Enabled
Other Error Monitoring Solution
No
Version
sentry_flutter 9.22.0 / sentry.native.android.flutter 0.15.2
Steps to Reproduce
sentry_flutter: ^9.22.0.enableTombstone = true,attachThreads = true,enableUserInteractionBreadcrumbs = true, andenableAutoNativeBreadcrumbs = true.SentryWidget.MethodChannel.signalhandlerevent with theTombstoneMergedevent in Sentry.Flutter init:
Dart trigger:
Android
MainActivity.kt:Native crash source:
Environment:
sentry_flutter: ^9.22.0Expected Result
A
TombstoneMergedevent should preserve the same relevant scope data as the regular native crash event, including breadcrumbs added by the Flutter SDK/native SDK, without duplicating entries.In particular:
Actual Result
When
enableTombstoneis enabled in a Flutter Android app, native SIGSEGV crashes are reported asTombstoneMergedevents. Compared with regular nativesignalhandlerevents for the same crash path, the merged tombstone events preserve some breadcrumbs, but the scope/breadcrumb merge appears inconsistent:TombstoneMergedevent less useful for investigating what happened before the crash.Regular native crash event:
131911518a0fc8e59e5a84631746cfb62af3cf072signalhandlerexception,breadcrumbs,debugmetaapp.lifecyclenavigationdevice.eventui.clickfor the crash buttonTombstone merged crash events:
131935719ba490da4525e4ec519f0fbf27c1966be89c1281cbb7045a8091131c05ef45a0bTombstoneMergedmessage,exception,threads,breadcrumbs,debugmetanavigationappears twicedevice.eventappears twiceui.clickappears twiceExample from a
TombstoneMergedevent:{ "breadcrumbs": { "count": 7, "values": [ { "category": "app.lifecycle", "data": { "state": "foreground" } }, { "category": "navigation", "data": { "state": "didPush", "to": "home" } }, { "category": "device.event", "data": { "action": "BATTERY_CHANGED", "charging": true, "level": 82 } }, { "category": "ui.click", "data": { "label": "Android SIGSEGV", "view.id": "feature_button_Android SIGSEGV" } }, { "category": "navigation", "data": { "state": "didPush", "to": "home" } }, { "category": "device.event", "data": { "action": "BATTERY_CHANGED", "charging": true, "level": 82 } }, { "category": "ui.click", "data": { "label": "Android SIGSEGV", "view.id": "feature_button_Android SIGSEGV" } } ] } }Regular
signalhandlerevent breadcrumb summary:TombstoneMergedevent breadcrumb summary:This looks related to the tombstone merge path. The same crash path reported through the regular native
signalhandlerevent has a clean breadcrumb list. Once tombstone reporting is enabled and the event becomesTombstoneMerged, breadcrumbs are duplicated and scope data appears less predictable.It looks like the merge process combines breadcrumbs from both the original native SDK event and the parsed tombstone/Java-side event without deduplicating, or replaces/merges event fields in a way that makes Flutter/native scope data inconsistent.