diff --git a/CHANGELOG.md b/CHANGELOG.md index d6c50be333..7eaef44afb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ - Improve log and metric delivery when telemetry is captured faster than envelopes can be serialized by offloading serialization to an internal thread pool. ([#1946](https://github.com/getsentry/sentry-native/pull/1946)) - Wine: fix OS version detection and cross-compiling Windows builds from Linux. ([#2001](https://github.com/getsentry/sentry-native/pull/2001)) - Destroy condition variables as approriate when no longer needed. ([#2004](https://github.com/getsentry/sentry-native/pull/2004)) +- Crashpad/Windows: preserve module CodeView UUIDs for minimal PDB70 records with empty PDB filenames. ([#2003](https://github.com/getsentry/sentry-native/pull/2003)) ## 0.16.3 diff --git a/external/crashpad b/external/crashpad index eb0cc3c7fa..95733c1ee6 160000 --- a/external/crashpad +++ b/external/crashpad @@ -1 +1 @@ -Subproject commit eb0cc3c7fac2bff0f8b79f080de66d5c3949e298 +Subproject commit 95733c1ee6fe77fc82ae6bb1bac2c34b9a6d0c17 diff --git a/tests/__init__.py b/tests/__init__.py index 5aa9af156f..a44d0f8648 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -14,6 +14,15 @@ sourcedir = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) +def lib_name(name): + if sys.platform == "win32": + prefix = "lib" if os.environ.get("TEST_MINGW") else "" + return prefix + name + ".dll" + elif sys.platform == "darwin": + return "lib" + name + ".dylib" + return "lib" + name + ".so" + + def adb(*args, **kwargs): return subprocess.run( ["{}/platform-tools/adb".format(os.environ["ANDROID_HOME"]), *args], **kwargs diff --git a/tests/assertions.py b/tests/assertions.py index 44ce4f5640..c78584633c 100644 --- a/tests/assertions.py +++ b/tests/assertions.py @@ -516,6 +516,7 @@ class CrashpadAttachments: view_hierarchy: dict cmake_cache: int bytes_bin: bytes = None + minidump: bytes = None def _unpack_breadcrumbs(payload): @@ -531,6 +532,7 @@ def _load_crashpad_attachments(msg): view_hierarchy = {} cmake_cache = -1 bytes_bin = None + minidump = None for part in msg.walk(): if part.get_filename() is not None: assert part.get("Content-Type") is None @@ -549,8 +551,20 @@ def _load_crashpad_attachments(msg): case "bytes.bin": bytes_bin = part.get_payload(decode=True) + if ( + part.get_param("name", header="content-disposition") + == "upload_file_minidump" + ): + minidump = part.get_payload(decode=True) + return CrashpadAttachments( - event, breadcrumb1, breadcrumb2, view_hierarchy, cmake_cache, bytes_bin + event, + breadcrumb1, + breadcrumb2, + view_hierarchy, + cmake_cache, + bytes_bin, + minidump, ) @@ -594,11 +608,8 @@ def assert_crashpad_upload(req, expect_attachment=False, expect_view_hierarchy=F assert attachments.bytes_bin == None if expect_view_hierarchy: assert_attachment_content_view_hierarchy(attachments.view_hierarchy) - assert any( - b'name="upload_file_minidump"' in part.as_bytes() - and b"\n\nMDMP" in part.as_bytes() - for part in msg.walk() - ) + assert attachments.minidump is not None, "minidump attachment missing" + assert attachments.minidump.startswith(b"MDMP"), "invalid minidump signature" return attachments diff --git a/tests/cmake.py b/tests/cmake.py index 6885cf4de1..fd98a01014 100644 --- a/tests/cmake.py +++ b/tests/cmake.py @@ -8,7 +8,7 @@ import pytest -from . import adb, exe_name +from . import adb, exe_name, lib_name from .conditions import has_sccache from .build_config import ( get_android_config, @@ -73,13 +73,6 @@ def destroy(self): if "llvm-cov" in os.environ.get("RUN_ANALYZER", ""): - def lib_name(name): - if sys.platform == "win32": - return name + ".dll" - elif sys.platform == "darwin": - return "lib" + name + ".dylib" - return "lib" + name + ".so" - for i, (d, _) in enumerate(self.runs.values()): # first merge the raw profiling runs files = [f for f in os.listdir(d) if f.endswith(".profraw")] diff --git a/tests/test_integration_crashpad.py b/tests/test_integration_crashpad.py index 0773639f84..e37ca5ca58 100644 --- a/tests/test_integration_crashpad.py +++ b/tests/test_integration_crashpad.py @@ -1,4 +1,5 @@ import os +import struct import subprocess import sys import time @@ -17,6 +18,7 @@ is_logs_envelope, is_feedback_envelope, is_replay_envelope, + lib_name, REPLAY_ID, ) from .conditions import has_crashpad, has_oom @@ -49,6 +51,28 @@ flushes_state = sys.platform != "darwin" +def _minidump_stream(minidump, stream_type): + stream_count, directory_rva = struct.unpack_from("