From 88fee70e7a5e440740aa853e5032bcd6ee6f2851 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Thu, 6 Aug 2026 16:23:49 +0200 Subject: [PATCH 1/3] perf(native): avoid zeroing large shmem module array When creating native backend shmem, zero the crash context only up to modules[]. This initializes the header, configuration, paths, platform state, and module count that must start from zero before a crash. Leave modules[] uninitialized during startup. It is the multi-megabyte tail of the shmem crash context, and crash handling treats it as valid only up to module_count before filling it. Add a unit test that verifies the initialization boundary: the byte before modules[] is zeroed, while modules[] itself keeps its previous contents. See: https://github.com/getsentry/sentry-native/issues/1852 --- src/backends/native/sentry_crash_context.h | 28 +++++++++++++++++++++- src/backends/native/sentry_crash_ipc.c | 18 +++----------- tests/unit/test_native_backend.c | 26 ++++++++++++++++++++ tests/unit/tests.inc | 1 + 4 files changed, 57 insertions(+), 16 deletions(-) diff --git a/src/backends/native/sentry_crash_context.h b/src/backends/native/sentry_crash_context.h index be172a97b5..20681b812b 100644 --- a/src/backends/native/sentry_crash_context.h +++ b/src/backends/native/sentry_crash_context.h @@ -9,9 +9,12 @@ #include "sentry.h" // For sentry_minidump_mode_t #include "sentry_boot.h" +#include "sentry_sync.h" #include +#include #include +#include #if defined(SENTRY_PLATFORM_UNIX) # include @@ -326,12 +329,35 @@ typedef struct { // Minidump output path (filled by daemon) char minidump_path[SENTRY_CRASH_MAX_PATH]; + uint32_t module_count; // Guards modules[] (uninitialized) + + // === UNINITIALIZED MEMORY BEGIN === + // Module information (captured in signal handler from dyld) - uint32_t module_count; sentry_module_info_t modules[SENTRY_CRASH_MAX_MODULES]; + // NOTE: Any new members added here remain uninitialized by + // sentry__crash_context_init(). + } sentry_crash_context_t; +static inline void +sentry__crash_context_init(sentry_crash_context_t *ctx) +{ + if (!ctx) { + return; + } + + // Zero until the large modules[] array, and leave the rest uninitialized: + // https://github.com/getsentry/sentry-native/issues/1852 + memset(ctx, 0, offsetof(sentry_crash_context_t, modules)); + + ctx->magic = SENTRY_CRASH_MAGIC; + ctx->version = SENTRY_CRASH_VERSION; + sentry__atomic_store(&ctx->state, SENTRY_CRASH_STATE_READY); + sentry__atomic_store(&ctx->sequence, 0); +} + // Shared memory size: calculated at compile-time based on actual struct size // Add 8KB padding for safety and future additions #define SENTRY_CRASH_SHM_SIZE (sizeof(sentry_crash_context_t) + (8 * 1024)) diff --git a/src/backends/native/sentry_crash_ipc.c b/src/backends/native/sentry_crash_ipc.c index c929a07d5c..deafe3ca51 100644 --- a/src/backends/native/sentry_crash_ipc.c +++ b/src/backends/native/sentry_crash_ipc.c @@ -152,11 +152,7 @@ sentry__crash_ipc_init_app(sem_t *init_sem) // Initialize shared memory only if newly created if (!shm_exists) { - memset(ipc->shmem, 0, SENTRY_CRASH_SHM_SIZE); - ipc->shmem->magic = SENTRY_CRASH_MAGIC; - ipc->shmem->version = SENTRY_CRASH_VERSION; - sentry__atomic_store(&ipc->shmem->state, SENTRY_CRASH_STATE_READY); - sentry__atomic_store(&ipc->shmem->sequence, 0); + sentry__crash_context_init(ipc->shmem); } // Release semaphore after initialization @@ -450,11 +446,7 @@ sentry__crash_ipc_init_app(sentry_mutex_t *init_mutex) } if (!shm_exists) { - memset(ipc->shmem, 0, SENTRY_CRASH_SHM_SIZE); - ipc->shmem->magic = SENTRY_CRASH_MAGIC; - ipc->shmem->version = SENTRY_CRASH_VERSION; - sentry__atomic_store(&ipc->shmem->state, SENTRY_CRASH_STATE_READY); - sentry__atomic_store(&ipc->shmem->sequence, 0); + sentry__crash_context_init(ipc->shmem); } if (ipc->init_mutex) { @@ -707,11 +699,7 @@ sentry__crash_ipc_init_app(HANDLE init_mutex) // Initialize shared memory only if newly created if (!shm_exists) { - memset(ipc->shmem, 0, SENTRY_CRASH_SHM_SIZE); - ipc->shmem->magic = SENTRY_CRASH_MAGIC; - ipc->shmem->version = SENTRY_CRASH_VERSION; - sentry__atomic_store(&ipc->shmem->state, SENTRY_CRASH_STATE_READY); - sentry__atomic_store(&ipc->shmem->sequence, 0); + sentry__crash_context_init(ipc->shmem); } // Release mutex after initialization diff --git a/tests/unit/test_native_backend.c b/tests/unit/test_native_backend.c index 8125f23206..0bf86275aa 100644 --- a/tests/unit/test_native_backend.c +++ b/tests/unit/test_native_backend.c @@ -387,6 +387,32 @@ SENTRY_TEST(crash_context_transport_fields) #endif } +SENTRY_TEST(crash_context_init) +{ +#ifdef SENTRY_BACKEND_NATIVE + sentry_crash_context_t *ctx = sentry_malloc(sizeof(*ctx)); + TEST_ASSERT(!!ctx); + memset(ctx, 0xA5, sizeof(*ctx)); + + sentry__crash_context_init(ctx); + + TEST_CHECK_INT_EQUAL(ctx->magic, SENTRY_CRASH_MAGIC); + TEST_CHECK_INT_EQUAL(ctx->version, SENTRY_CRASH_VERSION); + TEST_CHECK_INT_EQUAL(ctx->state, SENTRY_CRASH_STATE_READY); + TEST_CHECK_INT_EQUAL(ctx->sequence, 0); + TEST_CHECK_INT_EQUAL(ctx->module_count, 0); + + TEST_CHECK( + ((unsigned char *)ctx)[offsetof(sentry_crash_context_t, modules) - 1] + == 0); + TEST_CHECK(((unsigned char *)&ctx->modules[0])[0] == 0xA5); + + sentry_free(ctx); +#else + SKIP_TEST(); +#endif +} + /** * Test that options transport configuration is propagated to crash context * during native backend startup. This verifies the fix for the daemon diff --git a/tests/unit/tests.inc b/tests/unit/tests.inc index 5f0265802e..8f487afec9 100644 --- a/tests/unit/tests.inc +++ b/tests/unit/tests.inc @@ -105,6 +105,7 @@ XX(cond_wait_timeout_overflow) XX(continuation_no_baggage_uses_sdk_dsc) XX(count_sampled_events) XX(crash_context_handler_path_propagation) +XX(crash_context_init) XX(crash_context_null_options) XX(crash_context_options_propagation) XX(crash_context_transport_fields) From 3e37ec31e95edb16c8c8d7396ec4a567c992da57 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Thu, 6 Aug 2026 16:40:27 +0200 Subject: [PATCH 2/3] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4d41267413..005e75711c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ - `sentry_attachment_set_filename`, `sentry_attachment_set_type`, and `sentry_attachment_set_content_type` now flush the scope, so changes applied after `sentry_attach_file`/`sentry_attach_bytes` also apply to hard-crash events instead of only to normal events. ([#1934](https://github.com/getsentry/sentry-native/pull/1934)) - Crashpad: fix a crash when calling `sentry_init` before C++ dynamic initializers have run. ([#1930](https://github.com/getsentry/sentry-native/issues/1930), [mini_chromium#8](https://github.com/getsentry/mini_chromium/pull/8)) - Reduce the size of native-generated minidumps on Windows ([#1929](https://github.com/getsentry/sentry-native/pull/1929)) +- Native/Linux: improve startup time by avoiding zeroing a large shmem module array during crash context initialization. ([#1966](https://github.com/getsentry/sentry-native/pull/1966)) ## 0.16.1 From a29d788f2cfeb5bd8fa87f1cc968170f5668e26b Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Mon, 10 Aug 2026 16:40:06 +0200 Subject: [PATCH 3/3] Update CHANGELOG.md --- CHANGELOG.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a3b7e1df1e..c43caaf8da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ - Report enabled Qt and WER integrations in event SDK metadata (`sdk.integrations`) alongside the configured crash backend. ([#1969](https://github.com/ getsentry/sentry-native/pull/1969)) +**Fixes**: + +- Native/Linux: improve startup time by avoiding zeroing a large shmem module array during crash context initialization. ([#1966](https://github.com/getsentry/sentry-native/pull/1966)) + ## 0.16.2 **Features**: @@ -22,7 +26,6 @@ - `sentry_attachment_set_filename`, `sentry_attachment_set_type`, and `sentry_attachment_set_content_type` now flush the scope, so changes applied after `sentry_attach_file`/`sentry_attach_bytes` also apply to hard-crash events instead of only to normal events. ([#1934](https://github.com/getsentry/sentry-native/pull/1934)) - Crashpad: fix a crash when calling `sentry_init` before C++ dynamic initializers have run. ([#1930](https://github.com/getsentry/sentry-native/issues/1930), [mini_chromium#8](https://github.com/getsentry/mini_chromium/pull/8)) - Reduce the size of native-generated minidumps on Windows ([#1929](https://github.com/getsentry/sentry-native/pull/1929)) -- Native/Linux: improve startup time by avoiding zeroing a large shmem module array during crash context initialization. ([#1966](https://github.com/getsentry/sentry-native/pull/1966)) ## 0.16.1