From ef3ae9dc682d8ab79b12d6c2bcd34b15f03252aa Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Sun, 5 Jul 2026 17:25:00 +0200 Subject: [PATCH 1/5] feat: Send crashpad event updates over IPC Send serialized crash event and external crash report data to the Crashpad handler for file writes. Keep the existing file-write fallback for payloads that cannot be sent through the handler IPC. Co-Authored-By: OpenAI Codex --- external/crashpad | 2 +- src/backends/sentry_backend_crashpad.cpp | 75 ++++++++++++++++++++---- 2 files changed, 64 insertions(+), 13 deletions(-) diff --git a/external/crashpad b/external/crashpad index 6a25bbac1..34bea010f 160000 --- a/external/crashpad +++ b/external/crashpad @@ -1 +1 @@ -Subproject commit 6a25bbac1cc8c7a49a37599a24d18eea214cff99 +Subproject commit 34bea010f63980a13dab4dd769e6177fceae07f9 diff --git a/src/backends/sentry_backend_crashpad.cpp b/src/backends/sentry_backend_crashpad.cpp index e6a38b479..36536e326 100644 --- a/src/backends/sentry_backend_crashpad.cpp +++ b/src/backends/sentry_backend_crashpad.cpp @@ -214,8 +214,32 @@ crashpad_register_wer_module( } #endif +static bool +write_crashpad_attachment(crashpad_state_t *state, const sentry_path_t *path, + const char *data, size_t size) +{ + if (!state || !state->client || !path) { + return false; + } + return state->client->WriteAttachment( + base::FilePath(SENTRY_PATH_PLATFORM_STR(path)), + std::string(data, size)); +} + +static bool +append_crashpad_attachment(crashpad_state_t *state, const sentry_path_t *path, + const char *data, size_t size) +{ + if (!state || !state->client || !path) { + return false; + } + return state->client->AppendAttachment( + base::FilePath(SENTRY_PATH_PLATFORM_STR(path)), + std::string(data, size)); +} + static void -flush_scope_to_event(const sentry_path_t *event_path, +flush_scope_to_event(crashpad_state_t *state, const sentry_path_t *event_path, const sentry_options_t *options, sentry_value_t crash_event) { SENTRY_WITH_SCOPE (scope) { @@ -231,7 +255,10 @@ flush_scope_to_event(const sentry_path_t *event_path, return; } - int rv = sentry__path_write_buffer(event_path, mpack, mpack_size); + int rv = 0; + if (!write_crashpad_attachment(state, event_path, mpack, mpack_size)) { + rv = sentry__path_write_buffer(event_path, mpack, mpack_size); + } sentry_free(mpack); if (rv != 0) { @@ -242,8 +269,9 @@ flush_scope_to_event(const sentry_path_t *event_path, // Prepares an envelope with DSN, event ID, and session if available, for an // external crash reporter. static void -flush_external_crash_report( - const sentry_options_t *options, const sentry_uuid_t *crash_event_id) +flush_external_crash_report(crashpad_state_t *state, + const sentry_path_t *external_report_path, const sentry_options_t *options, + const sentry_uuid_t *crash_event_id) { sentry_envelope_t *envelope = sentry__envelope_new(); if (!envelope) { @@ -258,8 +286,21 @@ flush_external_crash_report( sentry__envelope_set_header(envelope, "cache_dir", sentry_value_new_string(options->run->cache_path->path)); } - sentry__run_write_external(options->run, envelope); + + size_t envelope_size = 0; + char *serialized = sentry_envelope_serialize(envelope, &envelope_size); + int rv = 0; + if (!serialized + || !write_crashpad_attachment( + state, external_report_path, serialized, envelope_size)) { + rv = sentry__run_write_external(options->run, envelope) ? 0 : 1; + } + sentry_free(serialized); sentry_envelope_free(envelope); + + if (rv != 0) { + SENTRY_WARN("flushing external crash report failed"); + } } // This function is necessary for macOS since it has no `FirstChanceHandler`. @@ -294,9 +335,10 @@ crashpad_backend_flush_scope( sentry_value_set_by_key( event, "level", sentry__value_new_level(SENTRY_LEVEL_FATAL)); - flush_scope_to_event(data->event_path, options, event); + flush_scope_to_event(data, data->event_path, options, event); if (data->external_report_path) { - flush_external_crash_report(options, &data->crash_event_id); + flush_external_crash_report( + data, data->external_report_path, options, &data->crash_event_id); } data->scope_flush.store(false, std::memory_order_release); #endif @@ -321,9 +363,10 @@ flush_scope_from_handler( } // now we are the sole flusher and can flush into the crash event - flush_scope_to_event(state->event_path, options, crash_event); + flush_scope_to_event(state, state->event_path, options, crash_event); if (state->external_report_path) { - flush_external_crash_report(options, &state->crash_event_id); + flush_external_crash_report(state, state->external_report_path, options, + &state->crash_event_id); } } @@ -722,6 +765,7 @@ crashpad_backend_startup( sentry_free(filename); if (data->external_report_path) { + sentry__path_create_dir_all(options->run->external_path); crash_reporter = base::FilePath( SENTRY_PATH_PLATFORM_STR(options->external_crash_reporter)); crash_envelope = base::FilePath( @@ -896,9 +940,16 @@ crashpad_backend_add_breadcrumb(sentry_backend_t *backend, return; } - int rv = first_breadcrumb - ? sentry__path_write_buffer(breadcrumb_file, mpack, mpack_size) - : sentry__path_append_buffer(breadcrumb_file, mpack, mpack_size); + int rv = 0; + if (first_breadcrumb) { + if (!write_crashpad_attachment( + data, breadcrumb_file, mpack, mpack_size)) { + rv = sentry__path_write_buffer(breadcrumb_file, mpack, mpack_size); + } + } else if (!append_crashpad_attachment( + data, breadcrumb_file, mpack, mpack_size)) { + rv = sentry__path_append_buffer(breadcrumb_file, mpack, mpack_size); + } sentry_free(mpack); if (rv != 0) { From c1880bd943283a9ac509c710c4543af6c211fa0c Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Mon, 6 Jul 2026 15:12:14 +0200 Subject: [PATCH 2/5] ++ --- external/crashpad | 2 +- src/backends/sentry_backend_crashpad.cpp | 56 +++++++++++++----------- 2 files changed, 31 insertions(+), 27 deletions(-) diff --git a/external/crashpad b/external/crashpad index 34bea010f..b34cefdad 160000 --- a/external/crashpad +++ b/external/crashpad @@ -1 +1 @@ -Subproject commit 34bea010f63980a13dab4dd769e6177fceae07f9 +Subproject commit b34cefdadfb9f07e0624f7c6a99746326021e956 diff --git a/src/backends/sentry_backend_crashpad.cpp b/src/backends/sentry_backend_crashpad.cpp index 36536e326..29aaa13f1 100644 --- a/src/backends/sentry_backend_crashpad.cpp +++ b/src/backends/sentry_backend_crashpad.cpp @@ -214,28 +214,38 @@ crashpad_register_wer_module( } #endif -static bool -write_crashpad_attachment(crashpad_state_t *state, const sentry_path_t *path, +static int +write_attachment(crashpad_state_t *state, const sentry_path_t *path, const char *data, size_t size) { - if (!state || !state->client || !path) { - return false; + if (!path) { + return 1; + } + if (!state || !state->client) { + return sentry__path_write_buffer(path, data, size); } return state->client->WriteAttachment( - base::FilePath(SENTRY_PATH_PLATFORM_STR(path)), - std::string(data, size)); + base::FilePath(SENTRY_PATH_PLATFORM_STR(path)), + std::string(data, size)) + ? 0 + : 1; } -static bool -append_crashpad_attachment(crashpad_state_t *state, const sentry_path_t *path, +static int +append_attachment(crashpad_state_t *state, const sentry_path_t *path, const char *data, size_t size) { - if (!state || !state->client || !path) { - return false; + if (!path) { + return 1; + } + if (!state || !state->client) { + return sentry__path_append_buffer(path, data, size); } return state->client->AppendAttachment( - base::FilePath(SENTRY_PATH_PLATFORM_STR(path)), - std::string(data, size)); + base::FilePath(SENTRY_PATH_PLATFORM_STR(path)), + std::string(data, size)) + ? 0 + : 1; } static void @@ -255,10 +265,7 @@ flush_scope_to_event(crashpad_state_t *state, const sentry_path_t *event_path, return; } - int rv = 0; - if (!write_crashpad_attachment(state, event_path, mpack, mpack_size)) { - rv = sentry__path_write_buffer(event_path, mpack, mpack_size); - } + int rv = write_attachment(state, event_path, mpack, mpack_size); sentry_free(mpack); if (rv != 0) { @@ -290,10 +297,11 @@ flush_external_crash_report(crashpad_state_t *state, size_t envelope_size = 0; char *serialized = sentry_envelope_serialize(envelope, &envelope_size); int rv = 0; - if (!serialized - || !write_crashpad_attachment( - state, external_report_path, serialized, envelope_size)) { + if (!serialized) { rv = sentry__run_write_external(options->run, envelope) ? 0 : 1; + } else { + rv = write_attachment( + state, external_report_path, serialized, envelope_size); } sentry_free(serialized); sentry_envelope_free(envelope); @@ -942,13 +950,9 @@ crashpad_backend_add_breadcrumb(sentry_backend_t *backend, int rv = 0; if (first_breadcrumb) { - if (!write_crashpad_attachment( - data, breadcrumb_file, mpack, mpack_size)) { - rv = sentry__path_write_buffer(breadcrumb_file, mpack, mpack_size); - } - } else if (!append_crashpad_attachment( - data, breadcrumb_file, mpack, mpack_size)) { - rv = sentry__path_append_buffer(breadcrumb_file, mpack, mpack_size); + rv = write_attachment(data, breadcrumb_file, mpack, mpack_size); + } else { + rv = append_attachment(data, breadcrumb_file, mpack, mpack_size); } sentry_free(mpack); From cf0ad8f8246f005f23178f54ee747803d56d6b4b Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Mon, 6 Jul 2026 15:36:12 +0200 Subject: [PATCH 3/5] clarifying comments --- src/backends/sentry_backend_crashpad.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/backends/sentry_backend_crashpad.cpp b/src/backends/sentry_backend_crashpad.cpp index 29aaa13f1..3d768efba 100644 --- a/src/backends/sentry_backend_crashpad.cpp +++ b/src/backends/sentry_backend_crashpad.cpp @@ -224,6 +224,8 @@ write_attachment(crashpad_state_t *state, const sentry_path_t *path, if (!state || !state->client) { return sentry__path_write_buffer(path, data, size); } + // Do not fall back to direct writes on failed IPC updates; they would race + // queued IPC updates. return state->client->WriteAttachment( base::FilePath(SENTRY_PATH_PLATFORM_STR(path)), std::string(data, size)) @@ -241,6 +243,8 @@ append_attachment(crashpad_state_t *state, const sentry_path_t *path, if (!state || !state->client) { return sentry__path_append_buffer(path, data, size); } + // Do not fall back to direct writes on failed IPC updates; they would race + // queued IPC updates. return state->client->AppendAttachment( base::FilePath(SENTRY_PATH_PLATFORM_STR(path)), std::string(data, size)) From af67e45dc5a3b1f1c11f1332f78c311e86353341 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Mon, 6 Jul 2026 15:46:36 +0200 Subject: [PATCH 4/5] ext --- src/backends/sentry_backend_crashpad.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/backends/sentry_backend_crashpad.cpp b/src/backends/sentry_backend_crashpad.cpp index 3d768efba..e950b0eea 100644 --- a/src/backends/sentry_backend_crashpad.cpp +++ b/src/backends/sentry_backend_crashpad.cpp @@ -306,6 +306,9 @@ flush_external_crash_report(crashpad_state_t *state, } else { rv = write_attachment( state, external_report_path, serialized, envelope_size); + if (rv != 0) { + rv = sentry__run_write_external(options->run, envelope) ? 0 : 1; + } } sentry_free(serialized); sentry_envelope_free(envelope); From ed18914968acd30bfdda306f30158c615994d08f Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Mon, 6 Jul 2026 16:14:31 +0200 Subject: [PATCH 5/5] clean up --- src/backends/sentry_backend_crashpad.cpp | 44 ++++++------------------ 1 file changed, 10 insertions(+), 34 deletions(-) diff --git a/src/backends/sentry_backend_crashpad.cpp b/src/backends/sentry_backend_crashpad.cpp index e950b0eea..059f824c7 100644 --- a/src/backends/sentry_backend_crashpad.cpp +++ b/src/backends/sentry_backend_crashpad.cpp @@ -218,14 +218,9 @@ static int write_attachment(crashpad_state_t *state, const sentry_path_t *path, const char *data, size_t size) { - if (!path) { + if (!path || !state || !state->client) { return 1; } - if (!state || !state->client) { - return sentry__path_write_buffer(path, data, size); - } - // Do not fall back to direct writes on failed IPC updates; they would race - // queued IPC updates. return state->client->WriteAttachment( base::FilePath(SENTRY_PATH_PLATFORM_STR(path)), std::string(data, size)) @@ -237,14 +232,9 @@ static int append_attachment(crashpad_state_t *state, const sentry_path_t *path, const char *data, size_t size) { - if (!path) { + if (!path || !state || !state->client) { return 1; } - if (!state || !state->client) { - return sentry__path_append_buffer(path, data, size); - } - // Do not fall back to direct writes on failed IPC updates; they would race - // queued IPC updates. return state->client->AppendAttachment( base::FilePath(SENTRY_PATH_PLATFORM_STR(path)), std::string(data, size)) @@ -298,24 +288,13 @@ flush_external_crash_report(crashpad_state_t *state, sentry_value_new_string(options->run->cache_path->path)); } - size_t envelope_size = 0; - char *serialized = sentry_envelope_serialize(envelope, &envelope_size); - int rv = 0; - if (!serialized) { - rv = sentry__run_write_external(options->run, envelope) ? 0 : 1; - } else { - rv = write_attachment( - state, external_report_path, serialized, envelope_size); - if (rv != 0) { - rv = sentry__run_write_external(options->run, envelope) ? 0 : 1; - } + size_t size = 0; + char *serialized = sentry_envelope_serialize(envelope, &size); + if (serialized) { + write_attachment(state, external_report_path, serialized, size); + sentry_free(serialized); } - sentry_free(serialized); sentry_envelope_free(envelope); - - if (rv != 0) { - SENTRY_WARN("flushing external crash report failed"); - } } // This function is necessary for macOS since it has no `FirstChanceHandler`. @@ -955,12 +934,9 @@ crashpad_backend_add_breadcrumb(sentry_backend_t *backend, return; } - int rv = 0; - if (first_breadcrumb) { - rv = write_attachment(data, breadcrumb_file, mpack, mpack_size); - } else { - rv = append_attachment(data, breadcrumb_file, mpack, mpack_size); - } + int rv = first_breadcrumb + ? write_attachment(data, breadcrumb_file, mpack, mpack_size) + : append_attachment(data, breadcrumb_file, mpack, mpack_size); sentry_free(mpack); if (rv != 0) {