Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
6 changes: 5 additions & 1 deletion src/backends/native/minidump/sentry_minidump_macos.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "sentry_boot.h"
#include "sentry_utils.h"

#if defined(SENTRY_PLATFORM_MACOS)

Expand Down Expand Up @@ -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);
Expand Down
12 changes: 2 additions & 10 deletions src/backends/native/sentry_crash_daemon.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
#include <time.h>

#if defined(SENTRY_PLATFORM_UNIX)
# include <arpa/inet.h>
# include <dirent.h>
# include <dlfcn.h>
# include <errno.h>
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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)
Comment on lines 2085 to 2092
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: On macOS, the native crash handler fails to byte-swap the module UUID, creating an incorrect debug_id in big-endian format, which will break symbolication.
Severity: HIGH

Suggested Fix

In build_native_crash_event() within sentry_crash_daemon.c, before creating the debug_id from the module's UUID, apply the same byte-swapping logic used for Linux and minidumps. Specifically, call sentry__uuid_swap_guid_bytes() on the mod->uuid to convert it from big-endian RFC 4122 format to the little-endian format expected by the symbolicator.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.

Location: src/backends/native/sentry_crash_daemon.c#L2085-L2092

Potential issue: On macOS, the native crash handler reads the module UUID from the
Mach-O `LC_UUID` load command, which is in big-endian format. This UUID is then used
directly in `build_native_crash_event()` to create the `debug_id` for the crash event.
However, the Sentry symbolicator expects the `debug_id` to be in the little-endian
Windows GUID format. Unlike the Linux path, which correctly byte-swaps the ID, the macOS
native crash path is missing this conversion. This will cause symbolication to fail for
native macOS crash reports, as the `debug_id` will not match the one stored for the
debug symbols.

Also affects:

  • src/backends/native/minidump/sentry_minidump_macos.c:247~251

Did we get this right? 👍 / 👎 to inform future reviews.

Expand Down
9 changes: 1 addition & 8 deletions src/modulefinder/sentry_modulefinder_linux.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
#include "sentry_utils.h"
#include "sentry_value.h"

#include <arpa/inet.h>
#include <elf.h>
#include <fcntl.h>
#include <string.h>
Expand Down Expand Up @@ -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;
Expand Down
29 changes: 29 additions & 0 deletions src/sentry_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@
# include <time.h>
#endif

#ifdef SENTRY_PLATFORM_WINDOWS
# include <stdlib.h>
#else
# include <arpa/inet.h>
#endif

#ifdef SENTRY_PLATFORM_PS
# undef MIN
# undef MAX
Expand All @@ -24,6 +30,29 @@
#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)
{
uint32_t *a = (uint32_t *)uuid;
uint16_t *b = (uint16_t *)((char *)uuid + 4);
uint16_t *c = (uint16_t *)((char *)uuid + 6);
#ifdef SENTRY_PLATFORM_WINDOWS
*a = _byteswap_ulong(*a);
*b = _byteswap_ushort(*b);
*c = _byteswap_ushort(*c);
#else
*a = htonl(*a);
*b = htons(*b);
*c = htons(*c);
#endif
}

#if defined(_MSC_VER) && !defined(__clang__)
# define UNREACHABLE(reason) assert(!reason)
#else
Expand Down
Loading