diff --git a/CHANGELOG.md b/CHANGELOG.md index 865e4cedd..c9ed84759 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ - Windows: add WER integration for syncing tags and attachments to WER. ([#1837](https://github.com/getsentry/sentry-native/pull/1837)) - Report `cache_overflow` discards due to `cache_max_items` or `cache_max_size`. ([#1884](https://github.com/getsentry/sentry-native/pull/1884)) +- Crashpad/Windows: optimize scope flushes for crash events and external crash reports. ([#1841](https://github.com/getsentry/sentry-native/pull/1841)) **Fixes**: diff --git a/external/crashpad b/external/crashpad index a40e3bdc1..7ac234db3 160000 --- a/external/crashpad +++ b/external/crashpad @@ -1 +1 @@ -Subproject commit a40e3bdc151f8dcd0bec6d3fb07901d3fa728e49 +Subproject commit 7ac234db350fcea825fd7e4ae680e4ad86191781 diff --git a/src/backends/sentry_backend_crashpad.cpp b/src/backends/sentry_backend_crashpad.cpp index 61a44a170..71fabc3d7 100644 --- a/src/backends/sentry_backend_crashpad.cpp +++ b/src/backends/sentry_backend_crashpad.cpp @@ -214,8 +214,36 @@ crashpad_register_wer_module( } #endif +static int +write_attachment(crashpad_state_t *state, const sentry_path_t *path, + const char *data, size_t size) +{ + if (!path || !state || !state->client) { + return 1; + } + return state->client->WriteAttachment( + base::FilePath(SENTRY_PATH_PLATFORM_STR(path)), + base::as_bytes(base::make_span(data, size))) + ? 0 + : 1; +} + +static int +append_attachment(crashpad_state_t *state, const sentry_path_t *path, + const char *data, size_t size) +{ + if (!path || !state || !state->client) { + return 1; + } + return state->client->AppendAttachment( + base::FilePath(SENTRY_PATH_PLATFORM_STR(path)), + base::as_bytes(base::make_span(data, size))) + ? 0 + : 1; +} + 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 +259,7 @@ flush_scope_to_event(const sentry_path_t *event_path, return; } - int 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) { @@ -242,8 +270,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,7 +287,13 @@ 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 size = 0; + char *serialized = sentry_envelope_serialize(envelope, &size); + if (serialized) { + write_attachment(state, external_report_path, serialized, size); + sentry_free(serialized); + } sentry_envelope_free(envelope); } @@ -334,9 +369,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 @@ -386,9 +422,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); } } @@ -796,10 +833,17 @@ crashpad_backend_startup( sentry_free(filename); if (data->external_report_path) { - crash_reporter = base::FilePath( - SENTRY_PATH_PLATFORM_STR(options->external_crash_reporter)); - crash_envelope = base::FilePath( - SENTRY_PATH_PLATFORM_STR(data->external_report_path)); + if (sentry__path_create_dir_all(options->run->external_path) == 0) { + crash_reporter = base::FilePath( + SENTRY_PATH_PLATFORM_STR(options->external_crash_reporter)); + crash_envelope = base::FilePath( + SENTRY_PATH_PLATFORM_STR(data->external_report_path)); + } else { + SENTRY_ERRORF( + "mkdir failed: \"%s\"", options->run->external_path->path); + sentry__path_free(data->external_report_path); + data->external_report_path = nullptr; + } } } @@ -968,8 +1012,8 @@ crashpad_backend_add_breadcrumb(sentry_backend_t *backend, } int rv = first_breadcrumb - ? sentry__path_write_buffer(breadcrumb_file, mpack, mpack_size) - : sentry__path_append_buffer(breadcrumb_file, mpack, mpack_size); + ? write_attachment(data, breadcrumb_file, mpack, mpack_size) + : append_attachment(data, breadcrumb_file, mpack, mpack_size); sentry_free(mpack); if (rv != 0) {