diff --git a/CHANGELOG.md b/CHANGELOG.md index d2738e444c..3f7364fc48 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ - macOS: cache VM regions for FP validation in the new unwinder. ([#1634](https://github.com/getsentry/sentry-native/pull/1634)) - Linux: remove dependency on `stdio` in the unwinder pointer validation code to reduce exposure to async-signal-unsafe functions. ([#1637](https://github.com/getsentry/sentry-native/pull/1637)) - macOS: replace sandbox-incompatible IPC primitives (`sem_open`, `shm_open`, `fork`) with sandbox-safe alternatives (`pthread_mutex`, file-backed `mmap`, `posix_spawn`) so the native backend works inside App Sandbox. ([#1644](https://github.com/getsentry/sentry-native/pull/1644)) +- Fix minidump UUID byte order (swap GUID fields to match RSDS format) and use `int64` for image sizes to support modules larger than 2 GB. ([#1651](https://github.com/getsentry/sentry-native/pull/1651)) ## 0.13.6 diff --git a/src/backends/native/minidump/sentry_minidump_macos.c b/src/backends/native/minidump/sentry_minidump_macos.c index ee28419305..bde715c795 100644 --- a/src/backends/native/minidump/sentry_minidump_macos.c +++ b/src/backends/native/minidump/sentry_minidump_macos.c @@ -1,4 +1,5 @@ #include "sentry_boot.h" +#include "sentry_utils.h" #if defined(SENTRY_PLATFORM_MACOS) @@ -243,8 +244,11 @@ write_cv_record( cv_record->cv_signature = CV_SIGNATURE_RSDS; cv_record->age = 0; // Not used for Mach-O - // Copy UUID + // Copy UUID with byte-swap for GUID format. + // Mach-O LC_UUID is big-endian (RFC 4122), but the RSDS CV record uses + // Windows GUID layout where the first 3 fields are little-endian. memcpy(cv_record->signature, uuid, 16); + sentry__uuid_swap_guid_bytes(cv_record->signature); // Copy module path memcpy(cv_record->pdb_file_name, module_path, path_len + 1); diff --git a/src/backends/native/sentry_crash_daemon.c b/src/backends/native/sentry_crash_daemon.c index fea4fe03a7..6fcbd0af6a 100644 --- a/src/backends/native/sentry_crash_daemon.c +++ b/src/backends/native/sentry_crash_daemon.c @@ -29,7 +29,6 @@ #include #if defined(SENTRY_PLATFORM_UNIX) -# include # include # include # include @@ -1171,13 +1170,7 @@ capture_modules_from_proc_maps(sentry_crash_context_t *ctx) mod->name, mod->uuid, sizeof(mod->uuid)); // Convert to little-endian GUID format for Sentry debug_id - // (same byte swapping as sentry_modulefinder_linux.c) - uint32_t *a = (uint32_t *)mod->uuid; - *a = htonl(*a); - uint16_t *b = (uint16_t *)(mod->uuid + 4); - *b = htons(*b); - uint16_t *c = (uint16_t *)(mod->uuid + 6); - *c = htons(*c); + sentry__uuid_swap_guid_bytes(mod->uuid); SENTRY_DEBUGF("Captured module: %s base=0x%llx size=0x%llx", mod->name, (unsigned long long)mod->base_address, @@ -2092,9 +2085,8 @@ build_native_crash_event( sentry_value_set_by_key( image, "image_addr", sentry_value_new_string(addr_buf)); - // Set image_size as int32 (modules > 2GB are extremely rare) sentry_value_set_by_key(image, "image_size", - sentry_value_new_int32((int32_t)mod->size)); + sentry_value_new_int64((int64_t)mod->size)); #if defined(SENTRY_PLATFORM_WINDOWS) // Set code_id for PE modules (TimeDateStamp + SizeOfImage) diff --git a/src/modulefinder/sentry_modulefinder_linux.c b/src/modulefinder/sentry_modulefinder_linux.c index a826bb7bf3..8219d0cf72 100644 --- a/src/modulefinder/sentry_modulefinder_linux.c +++ b/src/modulefinder/sentry_modulefinder_linux.c @@ -10,7 +10,6 @@ #include "sentry_utils.h" #include "sentry_value.h" -#include #include #include #include @@ -493,13 +492,7 @@ sentry__procmaps_read_ids_from_elf( // https://getsentry.github.io/symbolicator/advanced/symbol-server-compatibility/#identifiers // in particular, the debug_id is a `little-endian GUID`, so we have // to do appropriate byte-flipping - char *uuid_bytes = uuid.bytes; - uint32_t *a = (uint32_t *)uuid_bytes; - *a = htonl(*a); - uint16_t *b = (uint16_t *)(uuid_bytes + 4); - *b = htons(*b); - uint16_t *c = (uint16_t *)(uuid_bytes + 6); - *c = htons(*c); + sentry__uuid_swap_guid_bytes(uuid.bytes); sentry_value_set_by_key(value, "debug_id", sentry__value_new_uuid(&uuid)); return true; diff --git a/src/sentry_utils.h b/src/sentry_utils.h index 75ea87d4c5..c74c293b4a 100644 --- a/src/sentry_utils.h +++ b/src/sentry_utils.h @@ -24,6 +24,34 @@ #define MIN(a, b) ((a) < (b) ? (a) : (b)) #define MAX(a, b) ((a) > (b) ? (a) : (b)) +/** + * Byte-swap the first three GUID fields (Data1, Data2, Data3) of a 16-byte + * UUID in place. This converts between RFC 4122 (big-endian) and Windows + * mixed-endian GUID layout, which is used by RSDS CodeView records and Sentry + * debug-id strings. + */ +static inline void +sentry__uuid_swap_guid_bytes(void *uuid) +{ + uint8_t *p = (uint8_t *)uuid; + uint8_t t; + // Swap Data1 (4 bytes) + t = p[0]; + p[0] = p[3]; + p[3] = t; + t = p[1]; + p[1] = p[2]; + p[2] = t; + // Swap Data2 (2 bytes) + t = p[4]; + p[4] = p[5]; + p[5] = t; + // Swap Data3 (2 bytes) + t = p[6]; + p[6] = p[7]; + p[7] = t; +} + #if defined(_MSC_VER) && !defined(__clang__) # define UNREACHABLE(reason) assert(!reason) #else