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
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
- Attachment APIs now use `sentry_value_t` and `sentry_uuid_t` instead of `sentry_attachment_t *` handles. Most attachment APIs, function names and arguments, are otherwise unchanged. ([#1974](https://github.com/getsentry/sentry-native/pull/1974))
- `sentry_init()` now consumes `<db>/last_crash` after caching its value, aligning crashed-last-run behavior with other Sentry SDKs. ([#2023](https://github.com/getsentry/sentry-native/pull/2023))
- Change the `hint` parameter of `before_send` callbacks (`sentry_event_function_t`) from `void *` to `sentry_hint_t *`. Update callbacks registered with `sentry_options_set_before_send` to use the new parameter type. ([#2099](https://github.com/getsentry/sentry-native/pull/2099))
- Add a `sentry_hint_t *hint` argument to `on_crash` callbacks. ([#2112](https://github.com/getsentry/sentry-native/pull/2112))
- Add a `sentry_hint_t *hint` argument to `sentry_scope_capture_event`. Pass `NULL` if no hint is needed. ([#2099](https://github.com/getsentry/sentry-native/pull/2099))
- Remove `sentry_options_get/set_enable_logs` and `sentry_options_get/set_enable_metrics`. ([#1980](https://github.com/getsentry/sentry-native/pull/1980))
> Structured logs and metrics have been enabled by default since `0.13`, and the options were deprecated and made no-ops in `0.16`.
Expand All @@ -18,7 +19,7 @@
- Add `sentry_attachment_from_file/bytes` (and their wide-string variants) for creating attachment values that can be fully configured before they are added. ([#2079](https://github.com/getsentry/sentry-native/pull/2079))
- Add `sentry_add_attachment`, `sentry_scope_add_attachment`, and `sentry_hint_add_attachment` for adding configured attachments to the global scope, a specific scope, or a hint. These functions consume and freeze the attachment value. ([#2079](https://github.com/getsentry/sentry-native/pull/2079), [#1974](https://github.com/getsentry/sentry-native/pull/1974))
- Add `sentry_start_new_trace()` as a clearer name for starting a new trace. ([#2095](https://github.com/getsentry/sentry-native/pull/2095))
- Add hint support to `sentry_scope_capture_event` to pass event-specific attachments. The hint is also passed to `before_send`, which can modify attachments before the event is sent. ([#2099](https://github.com/getsentry/sentry-native/pull/2099))
- Add hint support to `sentry_scope_capture_event` to pass event-specific attachments. The hint is also passed to `before_send` and `on_crash`, which can modify attachments before the event is sent. ([#2099](https://github.com/getsentry/sentry-native/pull/2099), [#2112](https://github.com/getsentry/sentry-native/pull/2112))
- Add `sentry_hint_get_attachments`, `sentry_hint_remove_attachment`, and `sentry_hint_clear_attachments`. ([#2099](https://github.com/getsentry/sentry-native/pull/2099))

**Fixes**:
Expand Down
25 changes: 18 additions & 7 deletions examples/example.c
Original file line number Diff line number Diff line change
Expand Up @@ -129,9 +129,13 @@ traces_sampler_callback(const sentry_transaction_context_t *transaction_ctx,
static sentry_value_t
before_send_callback(sentry_value_t event, sentry_hint_t *hint, void *user_data)
{
(void)hint;
(void)user_data;

sentry_hint_clear_attachments(hint);
sentry_hint_add_attachment(hint,
sentry_attachment_from_bytes(
"before_send", strlen("before_send"), "callback.txt"));

// make our mark on the event
sentry_value_set_by_key(
event, "adapted_by", sentry_value_new_string("before_send"));
Expand All @@ -153,10 +157,11 @@ discarding_before_send_callback(
}

static sentry_value_t
discarding_on_crash_callback(
const sentry_ucontext_t *uctx, sentry_value_t event, void *user_data)
discarding_on_crash_callback(const sentry_ucontext_t *uctx,
sentry_value_t event, sentry_hint_t *hint, void *user_data)
{
(void)uctx;
(void)hint;
(void)user_data;

// discard event and signal backend to stop further processing
Expand All @@ -165,12 +170,17 @@ discarding_on_crash_callback(
}

static sentry_value_t
on_crash_callback(
const sentry_ucontext_t *uctx, sentry_value_t event, void *user_data)
on_crash_callback(const sentry_ucontext_t *uctx, sentry_value_t event,
sentry_hint_t *hint, void *user_data)
{
(void)uctx;
(void)user_data;

sentry_hint_clear_attachments(hint);
sentry_hint_add_attachment(hint,
sentry_attachment_from_bytes(
"on_crash", strlen("on_crash"), "callback.txt"));

// tell the backend to retain the event
return event;
}
Expand Down Expand Up @@ -230,10 +240,11 @@ on_crashed_last_run_callback(const sentry_envelope_t *envelope, void *user_data)
}

static sentry_value_t
restart_on_crash(
const sentry_ucontext_t *uctx, sentry_value_t event, void *user_data)
restart_on_crash(const sentry_ucontext_t *uctx, sentry_value_t event,
sentry_hint_t *hint, void *user_data)
{
(void)uctx;
(void)hint;

#ifdef SENTRY_PLATFORM_WINDOWS
wchar_t **argv = user_data;
Expand Down
7 changes: 5 additions & 2 deletions include/sentry.h
Original file line number Diff line number Diff line change
Expand Up @@ -1540,6 +1540,9 @@ SENTRY_API void sentry_options_set_before_send(
* `sentry_value_decref` on the provided event and return a
* `sentry_value_new_null()` instead.
*
* The hint is always provided and can be used to modify attachments on the
* event.
*
* Only the `inproc` backend currently fills the passed-in event with crash
* meta-data. Since both `breakpad` and `crashpad` use minidumps to capture the
* crash state, the passed-in event is empty when using these backends. Changes
Expand Down Expand Up @@ -1580,8 +1583,8 @@ SENTRY_API void sentry_options_set_before_send(
* exception-handler, it will not be invoked when such a crash happened, even
* though a crash report will be sent.
*/
typedef sentry_value_t (*sentry_crash_function_t)(
const sentry_ucontext_t *uctx, sentry_value_t event, void *user_data);
typedef sentry_value_t (*sentry_crash_function_t)(const sentry_ucontext_t *uctx,
sentry_value_t event, sentry_hint_t *hint, void *user_data);

/**
* Sets the `on_crash` callback.
Expand Down
19 changes: 15 additions & 4 deletions src/backends/sentry_backend_breakpad.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ extern "C" {
#include "sentry_core.h"
#include "sentry_database.h"
#include "sentry_envelope.h"
#include "sentry_hint.h"
#include "sentry_logger.h"
#include "sentry_options.h"
#ifdef SENTRY_PLATFORM_WINDOWS
Expand Down Expand Up @@ -143,6 +144,9 @@ breakpad_backend_callback(const google_breakpad::MinidumpDescriptor &descriptor,
= sentry__trace_finish(SENTRY_SPAN_STATUS_ABORTED);
sentry_uuid_t event_id = sentry_uuid_nil();

sentry_hint_t hint;
sentry__hint_init(&hint);

bool should_handle = true;

if (options->on_crash_func) {
Expand All @@ -161,8 +165,7 @@ breakpad_backend_callback(const google_breakpad::MinidumpDescriptor &descriptor,
uctx = &uctx_data;
#endif

SENTRY_SIGNAL_SAFE_LOG("DEBUG invoking `on_crash` hook");
event = options->on_crash_func(uctx, event, options->on_crash_data);
event = sentry__invoke_on_crash(options, uctx, event, &hint);
should_handle = !sentry_value_is_null(event);
}

Expand All @@ -183,8 +186,15 @@ breakpad_backend_callback(const google_breakpad::MinidumpDescriptor &descriptor,
}
#endif

sentry_envelope_t *envelope = sentry__prepare_event(options, event,
nullptr, !options->on_crash_func, nullptr, nullptr);
event = sentry__prepare_event(options, event, nullptr);
if (!options->on_crash_func) {
event = sentry__invoke_before_send(options, event, &hint);
}
sentry_value_t attachments
= sentry__hint_resolve_attachments(&hint);
sentry_envelope_t *envelope
= sentry__enclose_event(options, event, nullptr, attachments);
sentry_value_decref(attachments);
if (envelope) {
event_id = sentry__envelope_get_event_id(envelope);
}
Expand Down Expand Up @@ -280,6 +290,7 @@ breakpad_backend_callback(const google_breakpad::MinidumpDescriptor &descriptor,
sentry_value_decref(event);
sentry_value_decref(transaction);
}
sentry__hint_deinit(&hint);

// after capturing the crash event, try to dump all the in-flight
// data of the previous transports
Expand Down
69 changes: 39 additions & 30 deletions src/backends/sentry_backend_crashpad.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ extern "C" {
#include "sentry_cpu_relax.h"
#include "sentry_database.h"
#include "sentry_envelope.h"
#include "sentry_hint.h"
#include "sentry_logger.h"
#include "sentry_options.h"
#ifdef SENTRY_PLATFORM_WINDOWS
Expand Down Expand Up @@ -398,22 +399,22 @@ flush_scope_attachments(crashpad_state_t *data, const sentry_options_t *options)
}

static sentry_path_t *
prepare_initial_attachment(
sentry_value_t attachment, const sentry_path_t *run_path)
prepare_attachment(sentry_value_t attachment, const sentry_path_t *run_path)
{
size_t bytes_len = 0;
const char *bytes = sentry__attachment_get_bytes(attachment, &bytes_len);
sentry_path_t *path
= sentry__attachment_make_run_path(run_path, attachment);
if (!path) {
return nullptr;
}

size_t bytes_len = 0;
const char *bytes = sentry__attachment_get_bytes(attachment, &bytes_len);
if (bytes) {
sentry_path_t *dir = sentry__path_dir(path);
int rv = dir ? sentry__path_create_dir_all(dir) : 1;
sentry__path_free(dir);
if (rv != 0 || sentry__path_write_buffer(path, bytes, bytes_len) != 0) {
SENTRY_WARN("failed to prepare initial scope attachment");
SENTRY_WARN("failed to prepare crashpad attachment");
sentry__path_remove(path);
sentry__path_free(path);
return nullptr;
Expand All @@ -422,6 +423,28 @@ prepare_initial_attachment(
return path;
}

#if defined(SENTRY_PLATFORM_LINUX) || defined(SENTRY_PLATFORM_WINDOWS)
static void
write_attachment_manifest(crashpad_state_t *state, sentry_value_t attachments)
{
sentry_path_t *path
= sentry__path_join_str(state->run_path, "__sentry-attachments");
if (!path) {
return;
}

size_t len = sentry_value_get_length(attachments);
for (size_t i = 0; i < len; i++) {
sentry_value_t attachment = sentry_value_get_by_index(attachments, i);
if (!sentry__attachment_get_path(attachment)) {
sentry__path_free(prepare_attachment(attachment, state->run_path));
}
}
sentry__write_attachment_manifest(path, attachments);
sentry__path_free(path);
}
#endif

static void
preload_scope_breadcrumbs(
sentry_backend_t *backend, const sentry_options_t *options)
Expand Down Expand Up @@ -549,6 +572,8 @@ crashpad_handler(int signum, siginfo_t *info, ucontext_t *user_context)
= sentry__value_new_event_with_id(&state->crash_event_id);
sentry_value_set_by_key(
crash_event, "level", sentry__value_new_level(SENTRY_LEVEL_FATAL));
sentry_hint_t hint;
sentry__hint_init(&hint);

if (options->on_crash_func) {
sentry_ucontext_t uctx;
Expand All @@ -560,12 +585,11 @@ crashpad_handler(int signum, siginfo_t *info, ucontext_t *user_context)
uctx.user_context = user_context;
# endif

SENTRY_DEBUG("invoking `on_crash` hook");
crash_event = options->on_crash_func(
&uctx, crash_event, options->on_crash_data);
crash_event
= sentry__invoke_on_crash(options, &uctx, crash_event, &hint);
} else if (options->before_send_func) {
crash_event
= sentry__invoke_before_send(options, crash_event, nullptr);
= sentry__invoke_before_send(options, crash_event, &hint);
}

sentry__transport_suspend(options->transport);
Expand All @@ -576,6 +600,9 @@ crashpad_handler(int signum, siginfo_t *info, ucontext_t *user_context)
should_dump = !sentry_value_is_null(crash_event);

if (should_dump) {
if (sentry__hint_is_modified(&hint)) {
write_attachment_manifest(state, hint.attachments);
Comment thread
jpnurmi marked this conversation as resolved.
}
Comment thread
cursor[bot] marked this conversation as resolved.
sentry_value_incref(crash_event);
flush_scope_from_handler(options, crash_event);
sentry__write_crash_marker(options);
Expand Down Expand Up @@ -606,6 +633,7 @@ crashpad_handler(int signum, siginfo_t *info, ucontext_t *user_context)
} else {
SENTRY_DEBUG("event was discarded");
}
sentry__hint_deinit(&hint);
sentry__transport_dump_queue(options->transport, options->run);
}

Expand Down Expand Up @@ -889,29 +917,10 @@ add_attachment(void *state, sentry_value_t attachment)
return;
}

size_t bytes_len = 0;
const char *bytes = sentry__attachment_get_bytes(attachment, &bytes_len);
sentry_path_t *path
= sentry__attachment_make_run_path(data->run_path, attachment);
sentry_path_t *path = prepare_attachment(attachment, data->run_path);
if (!path) {
const char *filename = sentry__attachment_get_filename(attachment);
SENTRY_WARNF("failed to create path for crashpad attachment \"%s\"",
filename ? filename : "<unknown>");
return;
}

if (bytes) {
sentry_path_t *dir = sentry__path_dir(path);
int rv = dir ? sentry__path_create_dir_all(dir) : 1;
sentry__path_free(dir);
if (rv != 0 || sentry__path_write_buffer(path, bytes, bytes_len) != 0) {
SENTRY_WARNF(
"failed to write crashpad attachment \"%s\"", path->path);
sentry__path_remove(path);
sentry__path_free(path);
return;
}
}
data->client->AddAttachment(base::FilePath(SENTRY_PATH_PLATFORM_STR(path)));
sentry__path_free(path);
}
Expand Down Expand Up @@ -1013,7 +1022,7 @@ crashpad_backend_startup(
sentry_value_t attachment
= sentry_value_get_by_index(scope_attachments, i);
sentry_path_t *path
= prepare_initial_attachment(attachment, current_run_folder);
= prepare_attachment(attachment, current_run_folder);
if (path) {
attachments.emplace_back(SENTRY_PATH_PLATFORM_STR(path));
sentry__path_free(path);
Expand Down
19 changes: 15 additions & 4 deletions src/backends/sentry_backend_inproc.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "sentry_cpu_relax.h"
#include "sentry_database.h"
#include "sentry_envelope.h"
#include "sentry_hint.h"
#include "sentry_logger.h"
#include "sentry_options.h"
#include "sentry_os.h"
Expand Down Expand Up @@ -1077,9 +1078,11 @@ process_ucontext_deferred(const sentry_ucontext_t *uctx,
= sentry__trace_finish(SENTRY_SPAN_STATUS_ABORTED);
sentry_uuid_t event_id = sentry_uuid_nil();

sentry_hint_t hint;
sentry__hint_init(&hint);

if (options->on_crash_func && !skip_hooks) {
SENTRY_DEBUG("invoking `on_crash` hook");
event = options->on_crash_func(uctx, event, options->on_crash_data);
event = sentry__invoke_on_crash(options, uctx, event, &hint);
should_handle = !sentry_value_is_null(event);
} else if (skip_hooks && options->on_crash_func) {
SENTRY_DEBUG("skipping `on_crash` hook due to recursive crash");
Expand All @@ -1101,8 +1104,15 @@ process_ucontext_deferred(const sentry_ucontext_t *uctx,
}
#endif

sentry_envelope_t *envelope = sentry__prepare_event(options, event,
NULL, !options->on_crash_func && !skip_hooks, NULL, NULL);
event = sentry__prepare_event(options, event, NULL);
if (!options->on_crash_func && !skip_hooks) {
event = sentry__invoke_before_send(options, event, &hint);
}
Comment thread
cursor[bot] marked this conversation as resolved.
sentry_value_t attachments
= sentry__hint_resolve_attachments(&hint);
sentry_envelope_t *envelope
= sentry__enclose_event(options, event, NULL, attachments);
sentry_value_decref(attachments);
if (envelope) {
event_id = sentry__envelope_get_event_id(envelope);
}
Expand Down Expand Up @@ -1161,6 +1171,7 @@ process_ucontext_deferred(const sentry_ucontext_t *uctx,
sentry_value_decref(event);
sentry_value_decref(transaction);
}
sentry__hint_deinit(&hint);

// after capturing the crash event, dump all the envelopes to disk
sentry__transport_dump_queue(options->transport, options->run);
Expand Down
Loading
Loading