From 178c7c95c0c6778a4aa296aa3f32f09db707d596 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Wed, 21 Jan 2026 12:39:51 +0100 Subject: [PATCH 1/3] ref(crashpad): pass predefined report ID --- external/crashpad | 2 +- src/backends/sentry_backend_crashpad.cpp | 6 +++++- tests/assertions.py | 1 + tests/test_integration_crashpad.py | 5 ++++- 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/external/crashpad b/external/crashpad index d4694e6e9..eb5fa6e85 160000 --- a/external/crashpad +++ b/external/crashpad @@ -1 +1 @@ -Subproject commit d4694e6e94f9a63a4ed4443263a83bb78d93510f +Subproject commit eb5fa6e8576e79113b21296bd6af7e2a542839db diff --git a/src/backends/sentry_backend_crashpad.cpp b/src/backends/sentry_backend_crashpad.cpp index 781481359..eaf44c52d 100644 --- a/src/backends/sentry_backend_crashpad.cpp +++ b/src/backends/sentry_backend_crashpad.cpp @@ -539,6 +539,9 @@ crashpad_backend_startup( std::vector arguments { "--no-rate-limit" }; + char report_id[37]; + sentry_uuid_as_string(&data->crash_event_id, report_id); + // Initialize database first, flushing the consent later on as part of // `sentry_init` will persist the upload flag. data->db = crashpad::CrashReportDatabase::Initialize(database).release(); @@ -564,7 +567,8 @@ crashpad_backend_startup( minidump_url ? minidump_url : "", proxy_url, annotations, arguments, /* restartable */ true, /* asynchronous_start */ false, attachments, screenshot, - options->crashpad_wait_for_upload, crash_reporter, crash_envelope); + options->crashpad_wait_for_upload, crash_reporter, crash_envelope, + report_id); sentry_free(minidump_url); #ifdef SENTRY_PLATFORM_WINDOWS diff --git a/tests/assertions.py b/tests/assertions.py index 05d3ea320..d0204276e 100644 --- a/tests/assertions.py +++ b/tests/assertions.py @@ -475,6 +475,7 @@ def assert_crashpad_upload(req, expect_attachment=False, expect_view_hierarchy=F and b"\n\nMDMP" in part.as_bytes() for part in msg.walk() ) + return attachments def assert_gzip_file_header(output): diff --git a/tests/test_integration_crashpad.py b/tests/test_integration_crashpad.py index 0a501dd7d..3583d24c4 100644 --- a/tests/test_integration_crashpad.py +++ b/tests/test_integration_crashpad.py @@ -410,11 +410,14 @@ def test_crashpad_dumping_crash(cmake, httpserver, run_args, build_args): envelope = Envelope.deserialize(session) assert_session(envelope, {"status": "crashed", "errors": 1}) - assert_crashpad_upload( + attachments = assert_crashpad_upload( multipart, expect_attachment="clear-attachments" not in run_args, expect_view_hierarchy="clear-attachments" not in run_args, ) + event_id = attachments.event["event_id"] + minidump = tmp_path / ".sentry-native" / "completed" / f"{event_id}.dmp" + assert minidump.exists() @pytest.mark.parametrize( From e5a4111d40d772df614a8a89a6a5a484b17f879d Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Thu, 22 Jan 2026 17:17:11 +0100 Subject: [PATCH 2/3] Check reports/ on Windows --- tests/test_integration_crashpad.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/test_integration_crashpad.py b/tests/test_integration_crashpad.py index 3583d24c4..09615c4e5 100644 --- a/tests/test_integration_crashpad.py +++ b/tests/test_integration_crashpad.py @@ -416,7 +416,10 @@ def test_crashpad_dumping_crash(cmake, httpserver, run_args, build_args): expect_view_hierarchy="clear-attachments" not in run_args, ) event_id = attachments.event["event_id"] - minidump = tmp_path / ".sentry-native" / "completed" / f"{event_id}.dmp" + if sys.platform == "win32": + minidump = tmp_path / ".sentry-native" / "reports" / f"{event_id}.dmp" + else: + minidump = tmp_path / ".sentry-native" / "completed" / f"{event_id}.dmp" assert minidump.exists() From 89d9958235e6cc24c61afaf68d07da1f326f852c Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Mon, 26 Jan 2026 13:51:04 +0100 Subject: [PATCH 3/3] fix(tests): fix flaky test_crashpad_dumping_crash test Add wait_for_file helper to handle the race condition where crashpad moves the minidump file asynchronously after the HTTP upload completes, so the file is not guaranteed to be present immediately after waiting for the HTTP request. Co-Authored-By: Claude Opus 4.5 --- tests/assertions.py | 11 +++++++++++ tests/test_integration_crashpad.py | 3 ++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/tests/assertions.py b/tests/assertions.py index d0204276e..0cc4f5a72 100644 --- a/tests/assertions.py +++ b/tests/assertions.py @@ -496,3 +496,14 @@ def assert_failed_proxy_auth_request(stdout): and "407 Proxy Authentication Required" in stdout and "200 OK" not in stdout ) + + +def wait_for_file(path, timeout=10.0, poll_interval=0.1): + import time + + deadline = time.time() + timeout + while time.time() < deadline: + if path.exists(): + return True + time.sleep(poll_interval) + return False diff --git a/tests/test_integration_crashpad.py b/tests/test_integration_crashpad.py index 09615c4e5..815cd9ea6 100644 --- a/tests/test_integration_crashpad.py +++ b/tests/test_integration_crashpad.py @@ -31,6 +31,7 @@ assert_gzip_file_header, assert_logs, assert_user_feedback, + wait_for_file, ) pytestmark = pytest.mark.skipif( @@ -420,7 +421,7 @@ def test_crashpad_dumping_crash(cmake, httpserver, run_args, build_args): minidump = tmp_path / ".sentry-native" / "reports" / f"{event_id}.dmp" else: minidump = tmp_path / ".sentry-native" / "completed" / f"{event_id}.dmp" - assert minidump.exists() + assert wait_for_file(minidump) @pytest.mark.parametrize(