Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
f197880
refactor(scope): hide direct data access
jpnurmi Jul 22, 2026
ffa73f7
WIP: observers
jpnurmi Jul 27, 2026
56f7f07
feat(sync): add platform rwlock primitive
jpnurmi Aug 5, 2026
47bba26
refactor(sync): make rwlock operations inline
jpnurmi Aug 5, 2026
aa0be8f
refactor(scope): guard simple fields with rwlock
jpnurmi Aug 5, 2026
ba2a876
refactor(scope): retain user and fingerprint values safely
jpnurmi Aug 5, 2026
6ff86c0
refactor(scope): store string fields as values
jpnurmi Aug 5, 2026
9a2b29a
refactor(scope): move locked payload into scope data
jpnurmi Aug 6, 2026
0828f8f
refactor(scope): hide direct scope data access
jpnurmi Aug 6, 2026
813b7b0
ref containers
jpnurmi Aug 6, 2026
d9ba2a8
breadcrumbs
jpnurmi Aug 7, 2026
9e3bbba
trace_context
jpnurmi Aug 7, 2026
e821d6e
propagation_context
jpnurmi Aug 7, 2026
2949eec
dsc
jpnurmi Aug 7, 2026
16b07d8
span/transaction_object
jpnurmi Aug 7, 2026
41717ae
restore
jpnurmi Aug 7, 2026
768a86a
lock observers
jpnurmi Aug 7, 2026
b3a38df
finally :D
jpnurmi Aug 7, 2026
61892ba
fix formatting
jpnurmi Aug 7, 2026
bc99dba
fix(scope): Keep global scope alive during access
jpnurmi Aug 9, 2026
8b02357
restore locks for attachments
jpnurmi Aug 12, 2026
2629b07
clone (cow) attachments guard against concurrent modifications
jpnurmi Aug 12, 2026
f70a7c6
clean up
jpnurmi Aug 18, 2026
fbbfaae
fix concurrent init
jpnurmi Aug 18, 2026
25a7e0c
breadcrumbs: fix use-after-free
jpnurmi Aug 18, 2026
f16f103
fix(attachments): Notify backends through scope observers
jpnurmi Aug 19, 2026
abcc49d
fix cleanup_observers
jpnurmi Aug 19, 2026
135c53c
load
jpnurmi Aug 19, 2026
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
2 changes: 1 addition & 1 deletion .clang-format
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ IndentPPDirectives: AfterHash
ColumnLimit: 80
AlwaysBreakAfterDefinitionReturnType: All
PointerAlignment: Right
ForEachMacros: ['SENTRY_WITH_SCOPE', 'SENTRY_WITH_SCOPE_MUT', 'SENTRY_WITH_SCOPE_MUT_NO_FLUSH', 'SENTRY_WITH_OPTIONS', 'SENTRY_WITH_OPTIONS_MUT']
ForEachMacros: ['SENTRY_WITH_SCOPE', 'SENTRY_WITH_SCOPE_MUT', 'SENTRY_WITH_SCOPE_MUT_NO_FLUSH', 'SENTRY_WITH_OPTIONS', 'SENTRY_WITH_OPTIONS_MUT', 'SENTRY_SCOPE_READ_LOCK', 'SENTRY_SCOPE_WRITE_LOCK']
InsertNewlineAtEOF: True
22 changes: 13 additions & 9 deletions src/backends/sentry_backend_crashpad.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -516,7 +516,7 @@ crashpad_handler(int signum, siginfo_t *info, ucontext_t *user_context)
// written above and stays breadcrumb-free
SENTRY_WITH_SCOPE (scope) {
sentry_value_set_by_key(crash_event, "breadcrumbs",
sentry__ringbuffer_to_list(scope->breadcrumbs));
sentry__scope_breadcrumbs_to_list(scope));
}

sentry__session_replay_flush_pending(
Expand Down Expand Up @@ -1167,10 +1167,9 @@ make_attachment_path(const sentry_path_t *run_path, sentry_value_t attachment)
}

static void
crashpad_backend_add_attachment(sentry_backend_t *backend,
sentry_value_t attachment, const sentry_options_t *UNUSED(options))
crashpad_backend_add_attachment(void *state, sentry_value_t attachment)
{
auto *data = static_cast<crashpad_state_t *>(backend->data);
auto *data = static_cast<crashpad_state_t *>(state);
if (!data || !data->client) {
return;
}
Expand Down Expand Up @@ -1199,10 +1198,9 @@ crashpad_backend_add_attachment(sentry_backend_t *backend,
}

static void
crashpad_backend_remove_attachment(
sentry_backend_t *backend, sentry_value_t attachment)
crashpad_backend_remove_attachment(void *state, sentry_value_t attachment)
{
auto *data = static_cast<crashpad_state_t *>(backend->data);
auto *data = static_cast<crashpad_state_t *>(state);
if (!data || !data->client) {
return;
}
Expand Down Expand Up @@ -1258,8 +1256,14 @@ sentry__backend_new(void)
backend->prune_database_func = crashpad_backend_prune_database;
#if defined(SENTRY_PLATFORM_WINDOWS) || defined(SENTRY_PLATFORM_LINUX) \
|| defined(SENTRY_PLATFORM_MACOS)
backend->add_attachment_func = crashpad_backend_add_attachment;
backend->remove_attachment_func = crashpad_backend_remove_attachment;
backend->scope_observer = sentry__scope_observer_new();
if (backend->scope_observer) {
backend->scope_observer->data = data;
backend->scope_observer->add_attachment
= crashpad_backend_add_attachment;
backend->scope_observer->remove_attachment
= crashpad_backend_remove_attachment;
}
#endif
backend->data = data;
backend->can_capture_after_shutdown = true;
Expand Down
27 changes: 20 additions & 7 deletions src/backends/sentry_backend_native.c
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ wer_register_module(uint64_t app_tid)
typedef struct {
sentry_crash_ipc_t *ipc;
pid_t daemon_pid;
sentry_path_t *run_path;
sentry_path_t *event_path;
sentry_path_t *breadcrumb1_path;
sentry_path_t *breadcrumb2_path;
Expand Down Expand Up @@ -244,6 +245,10 @@ native_backend_startup(
return 1;
}
backend->data = state;
state->run_path = sentry__path_clone(options->run->run_path);
if (backend->scope_observer) {
backend->scope_observer->data = state;
}

// Initialize IPC (protected by global synchronization for concurrent
// access)
Expand Down Expand Up @@ -725,6 +730,7 @@ native_backend_free(sentry_backend_t *backend)
sentry__path_free(state->breadcrumb1_path);
sentry__path_free(state->breadcrumb2_path);
sentry__path_free(state->envelope_path);
sentry__path_free(state->run_path);

sentry_free(state);
}
Expand Down Expand Up @@ -763,12 +769,14 @@ native_backend_write_attachments(const sentry_path_t *event_path)
return;
}
SENTRY_WITH_SCOPE (scope) {
sentry_value_t attachments = scope->attachments;
sentry_value_t attachments = sentry__scope_load_attachments(scope);
if (sentry_value_get_length(attachments) == 0) {
sentry_value_decref(attachments);
continue;
}
sentry_path_t *run_path = sentry__path_dir(event_path);
if (!run_path) {
sentry_value_decref(attachments);
continue;
}
sentry_path_t *attach_list_path
Expand Down Expand Up @@ -817,6 +825,7 @@ native_backend_write_attachments(const sentry_path_t *event_path)
sentry__path_free(attach_list_path);
}
sentry__path_free(run_path);
sentry_value_decref(attachments);
}
}

Expand Down Expand Up @@ -941,18 +950,19 @@ native_backend_add_breadcrumb(sentry_backend_t *backend,
}

static void
native_backend_add_attachment(sentry_backend_t *backend,
sentry_value_t attachment, const sentry_options_t *options)
native_backend_add_attachment(void *data, sentry_value_t attachment)
{
(void)backend; // Unused
native_backend_state_t *state = (native_backend_state_t *)data;
if (!state) {
return;
}

// For buffer attachments, derive a path in the run directory and write to
// disk
size_t bytes_len = 0;
const char *bytes = sentry__attachment_get_bytes(attachment, &bytes_len);
if (bytes) {
sentry_path_t *path
= make_attachment_path(options->run->run_path, attachment);
sentry_path_t *path = make_attachment_path(state->run_path, attachment);
if (!path) {
const char *filename = sentry__attachment_get_filename(attachment);
SENTRY_WARNF("failed to create path for native backend attachment "
Expand Down Expand Up @@ -1147,7 +1157,10 @@ sentry__backend_new(void)
backend->except_func = native_backend_except;
backend->flush_scope_func = native_backend_flush_scope;
backend->add_breadcrumb_func = native_backend_add_breadcrumb;
backend->add_attachment_func = native_backend_add_attachment;
backend->scope_observer = sentry__scope_observer_new();
if (backend->scope_observer) {
backend->scope_observer->add_attachment = native_backend_add_attachment;
}
backend->user_consent_changed_func = native_backend_user_consent_changed;
backend->can_capture_after_shutdown = false;

Expand Down
38 changes: 21 additions & 17 deletions src/integrations/sentry_integration_wer.c
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,18 @@ wer_remove_attachment(void *UNUSED(data), sentry_value_t attachment)
}
}

static void
wer_for_each_attachment(
sentry_scope_t *scope, void *data, void (*callback)(void *, sentry_value_t))
{
sentry_value_t attachments = sentry__scope_load_attachments(scope);
size_t len = sentry_value_get_length(attachments);
for (size_t i = 0; i < len; i++) {
callback(data, sentry_value_get_by_index(attachments, i));
}
sentry_value_decref(attachments);
}

static void
wer_cleanup_tag(const char *key, sentry_value_t UNUSED(value), void *data)
{
Expand All @@ -207,13 +219,11 @@ wer_clear(void *data)
return;
}

sentry__value_foreach_key_value(scope->tags, wer_cleanup_tag, wer_data);
sentry_value_t tags = sentry__scope_load_tags(scope);
sentry__value_foreach_key_value(tags, wer_cleanup_tag, wer_data);
sentry_value_decref(tags);
Comment thread
cursor[bot] marked this conversation as resolved.

size_t len = sentry_value_get_length(scope->attachments);
for (size_t i = 0; i < len; i++) {
wer_remove_attachment(
wer_data, sentry_value_get_by_index(scope->attachments, i));
}
wer_for_each_attachment(scope, wer_data, wer_remove_attachment);
}

static void
Expand All @@ -238,11 +248,7 @@ register_wer(
if (sentry__scope_add_observer(scope, observer)) {
wer_data->scope = scope;
wer_data->observer = observer;
size_t len = sentry_value_get_length(scope->attachments);
for (size_t i = 0; i < len; i++) {
wer_add_attachment(
wer_data, sentry_value_get_by_index(scope->attachments, i));
}
wer_for_each_attachment(scope, wer_data, wer_add_attachment);
}
}

Expand All @@ -256,13 +262,11 @@ unregister_wer(
return;
}

sentry__value_foreach_key_value(scope->tags, wer_cleanup_tag, wer_data);
sentry_value_t tags = sentry__scope_load_tags(scope);
sentry__value_foreach_key_value(tags, wer_cleanup_tag, wer_data);
sentry_value_decref(tags);

size_t len = sentry_value_get_length(scope->attachments);
for (size_t i = 0; i < len; i++) {
wer_remove_attachment(
wer_data, sentry_value_get_by_index(scope->attachments, i));
}
wer_for_each_attachment(scope, wer_data, wer_remove_attachment);

sentry__scope_remove_observer(scope, wer_data->observer);
wer_data->scope = NULL;
Expand Down
1 change: 1 addition & 0 deletions src/sentry_backend.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@ sentry__backend_free(sentry_backend_t *backend)
if (backend->free_func) {
backend->free_func(backend);
}
sentry_free(backend->scope_observer);
sentry_free(backend);
}
4 changes: 1 addition & 3 deletions src/sentry_backend.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,7 @@ struct sentry_backend_s {
void (*user_consent_changed_func)(sentry_backend_t *);
uint64_t (*get_last_crash_func)(sentry_backend_t *);
void (*prune_database_func)(sentry_backend_t *);
void (*add_attachment_func)(
sentry_backend_t *, sentry_value_t, const sentry_options_t *options);
void (*remove_attachment_func)(sentry_backend_t *, sentry_value_t);
sentry_scope_observer_t *scope_observer;
void *data;
// Whether this backend still runs after shutdown_func was called.
bool can_capture_after_shutdown;
Expand Down
Loading
Loading