Skip to content
Merged
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
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## Unreleased

**Fixes**:

- Events captured while a crash is being handled, such as from the `on_crash` hook, are no longer dropped by `sample_rate`, matching the crash itself. ([#2269](https://github.com/getsentry/sentry-native/pull/2269))

## 0.17.5

**Fixes**:
Expand Down
12 changes: 11 additions & 1 deletion src/sentry_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ static sentry_mutex_t g_options_lock = SENTRY__MUTEX_INIT;
#endif
/// see sentry_get_crashed_last_run() for the possible values
static int g_last_crash = -1;
/// > 0 while a crash is handled; nests, e.g. inproc enters on both the
/// crashing and the handler thread
static volatile long g_crash_handler_depth = 0;

const sentry_options_t *
sentry__options_getref(void)
Expand Down Expand Up @@ -115,6 +118,8 @@ unregister_integrations(sentry_scope_t *scope, const sentry_options_t *options)
void
sentry__enter_crash_handler(void)
{
sentry__atomic_fetch_and_add(&g_crash_handler_depth, 1);

const sentry_options_t *options = g_options;
if (options) {
for (size_t i = 0; i < options->num_integrations; i++) {
Expand All @@ -138,6 +143,8 @@ sentry__exit_crash_handler(void)
}
}
}

sentry__atomic_fetch_and_add(&g_crash_handler_depth, -1);
}

int
Expand Down Expand Up @@ -703,7 +710,10 @@ sentry__capture_event(
sentry__mutex_unlock(&mut_options->session_lock);
}

bool should_skip = !sentry__roll_dice(options->sample_rate);
// events captured while handling a crash belong to the crash, which
// is never sampled
bool should_skip = sentry__atomic_fetch(&g_crash_handler_depth) == 0
&& !sentry__roll_dice(options->sample_rate);
if (should_skip) {
SENTRY_INFO("throwing away event due to sample rate");
sentry__client_report_discard(SENTRY_DISCARD_REASON_SAMPLE_RATE,
Expand Down
42 changes: 42 additions & 0 deletions tests/unit/test_basic.c
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,48 @@ SENTRY_TEST(sampling_before_send)
TEST_CHECK_INT_EQUAL(called_beforesend, 100);
}

static void
counting_event_transport_func(sentry_envelope_t *envelope, void *data)
{
uint64_t *called = data;
if (!sentry_value_is_null(sentry_envelope_get_event(envelope))) {
*called += 1;
}
sentry_envelope_free(envelope);
}

SENTRY_TEST(sampling_crash_handler)
{
uint64_t called_transport = 0;

SENTRY_TEST_OPTIONS_NEW(options);
sentry_options_set_dsn(options, "https://foo@sentry.invalid/42");
sentry_transport_t *transport
= sentry_transport_new(counting_event_transport_func);
sentry_transport_set_state(transport, &called_transport);
sentry_options_set_transport(options, transport);
sentry_options_set_sample_rate(options, 0.0);
sentry_init(options);

// events captured while handling a crash are not sampled, even nested
sentry__enter_crash_handler();
sentry__enter_crash_handler();
sentry_capture_event(
sentry_value_new_message_event(SENTRY_LEVEL_INFO, NULL, "foo"));
sentry__exit_crash_handler();
sentry_capture_event(
sentry_value_new_message_event(SENTRY_LEVEL_INFO, NULL, "foo"));
sentry__exit_crash_handler();

// sampling applies again once the crash handler is left
sentry_capture_event(
sentry_value_new_message_event(SENTRY_LEVEL_INFO, NULL, "foo"));

sentry_close();

TEST_CHECK_INT_EQUAL(called_transport, 2);
}

static sentry_value_t
discarding_before_send(
sentry_value_t event, sentry_hint_t *UNUSED(hint), void *data)
Expand Down
1 change: 1 addition & 0 deletions tests/unit/tests.inc
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,7 @@ XX(rwlock_stress)
XX(rwlock_write_blocks_reader)
XX(rwlock_write_blocks_writer)
XX(sampling_before_send)
XX(sampling_crash_handler)
XX(sampling_decision)
XX(sampling_transaction)
XX(scope_attachments)
Expand Down
Loading