-
-
Notifications
You must be signed in to change notification settings - Fork 173
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: crashpad backend allows inspecting the event-id in the on_crash/before_send hooks #840
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -78,31 +78,36 @@ typedef struct { | |
sentry_path_t *breadcrumb1_path; | ||
sentry_path_t *breadcrumb2_path; | ||
size_t num_breadcrumbs; | ||
sentry_value_t event_id; | ||
} crashpad_state_t; | ||
|
||
static void | ||
sentry__crashpad_backend_user_consent_changed(sentry_backend_t *backend) | ||
crashpad_backend_user_consent_changed(sentry_backend_t *backend) | ||
{ | ||
crashpad_state_t *data = (crashpad_state_t *)backend->data; | ||
auto *data = static_cast<crashpad_state_t *>(backend->data); | ||
if (!data->db || !data->db->GetSettings()) { | ||
return; | ||
} | ||
data->db->GetSettings()->SetUploadsEnabled(!sentry__should_skip_upload()); | ||
} | ||
|
||
static void | ||
sentry__crashpad_backend_flush_scope( | ||
crashpad_backend_flush_scope( | ||
sentry_backend_t *backend, const sentry_options_t *options) | ||
{ | ||
const crashpad_state_t *data = (crashpad_state_t *)backend->data; | ||
auto *data = static_cast<crashpad_state_t *>(backend->data); | ||
if (!data->event_path) { | ||
return; | ||
} | ||
|
||
// This here is an empty object that we copy the scope into. | ||
// Even though the API is specific to `event`, an `event` has a few default | ||
// properties that we do not want here. | ||
// properties that we do not want here. But we want a stable event_id in | ||
// case of a crash. | ||
sentry_value_t event = sentry_value_new_object(); | ||
if (!sentry_value_is_null(data->event_id)) { | ||
sentry_value_set_by_key(event, "event_id", data->event_id); | ||
} | ||
SENTRY_WITH_SCOPE (scope) { | ||
// we want the scope without any modules or breadcrumbs | ||
sentry__scope_apply_to_event(scope, options, event, SENTRY_SCOPE_NONE); | ||
|
@@ -141,7 +146,9 @@ sentry__crashpad_handler(int signum, siginfo_t *info, ucontext_t *user_context) | |
sentry_value_t event = sentry_value_new_event(); | ||
|
||
SENTRY_WITH_OPTIONS (options) { | ||
|
||
auto *data = static_cast<crashpad_state_t *>(options->backend->data); | ||
data->event_id = sentry_value_get_by_key(event, "event_id"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess there should never be the situation where There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is a good question. If we end up in the handler function the way we currently return to the |
||
crashpad_backend_flush_scope(options->backend, options); | ||
if (options->on_crash_func) { | ||
sentry_ucontext_t uctx; | ||
# ifdef SENTRY_PLATFORM_WINDOWS | ||
|
@@ -231,10 +238,10 @@ sentry__crashpad_handler(int signum, siginfo_t *info, ucontext_t *user_context) | |
#endif | ||
|
||
static int | ||
sentry__crashpad_backend_startup( | ||
crashpad_backend_startup( | ||
sentry_backend_t *backend, const sentry_options_t *options) | ||
{ | ||
sentry_path_t *owned_handler_path = NULL; | ||
sentry_path_t *owned_handler_path = nullptr; | ||
sentry_path_t *handler_path = options->handler_path; | ||
if (!handler_path) { | ||
sentry_path_t *current_exe = sentry__path_current_exe(); | ||
|
@@ -272,7 +279,7 @@ sentry__crashpad_backend_startup( | |
"\"%" SENTRY_PATH_PRI "\"", | ||
absolute_handler_path->path); | ||
sentry_path_t *current_run_folder = options->run->run_path; | ||
crashpad_state_t *data = (crashpad_state_t *)backend->data; | ||
auto *data = static_cast<crashpad_state_t *>(backend->data); | ||
|
||
base::FilePath database(options->database_path->path); | ||
base::FilePath handler(absolute_handler_path->path); | ||
|
@@ -283,7 +290,7 @@ sentry__crashpad_backend_startup( | |
// register attachments | ||
for (sentry_attachment_t *attachment = options->attachments; attachment; | ||
attachment = attachment->next) { | ||
attachments.push_back(base::FilePath(attachment->path->path)); | ||
attachments.emplace_back(attachment->path->path); | ||
} | ||
|
||
// and add the serialized event, and two rotating breadcrumb files | ||
|
@@ -299,12 +306,12 @@ sentry__crashpad_backend_startup( | |
sentry__path_touch(data->breadcrumb1_path); | ||
sentry__path_touch(data->breadcrumb2_path); | ||
|
||
attachments.push_back(base::FilePath(data->event_path->path)); | ||
attachments.push_back(base::FilePath(data->breadcrumb1_path->path)); | ||
attachments.push_back(base::FilePath(data->breadcrumb2_path->path)); | ||
attachments.insert(attachments.end(), | ||
{ base::FilePath(data->event_path->path), | ||
base::FilePath(data->breadcrumb1_path->path), | ||
base::FilePath(data->breadcrumb2_path->path) }); | ||
|
||
std::vector<std::string> arguments; | ||
arguments.push_back("--no-rate-limit"); | ||
std::vector<std::string> arguments { "--no-rate-limit" }; | ||
|
||
// Initialize database first, flushing the consent later on as part of | ||
// `sentry_init` will persist the upload flag. | ||
|
@@ -395,7 +402,7 @@ sentry__crashpad_backend_startup( | |
} | ||
|
||
static void | ||
sentry__crashpad_backend_shutdown(sentry_backend_t *backend) | ||
crashpad_backend_shutdown(sentry_backend_t *backend) | ||
{ | ||
#ifdef SENTRY_PLATFORM_LINUX | ||
// restore signal handlers to their default state | ||
|
@@ -406,7 +413,7 @@ sentry__crashpad_backend_shutdown(sentry_backend_t *backend) | |
} | ||
#endif | ||
|
||
crashpad_state_t *data = (crashpad_state_t *)backend->data; | ||
auto *data = static_cast<crashpad_state_t *>(backend->data); | ||
delete data->db; | ||
data->db = nullptr; | ||
|
||
|
@@ -419,10 +426,10 @@ sentry__crashpad_backend_shutdown(sentry_backend_t *backend) | |
} | ||
|
||
static void | ||
sentry__crashpad_backend_add_breadcrumb(sentry_backend_t *backend, | ||
crashpad_backend_add_breadcrumb(sentry_backend_t *backend, | ||
sentry_value_t breadcrumb, const sentry_options_t *options) | ||
{ | ||
crashpad_state_t *data = (crashpad_state_t *)backend->data; | ||
auto *data = static_cast<crashpad_state_t *>(backend->data); | ||
|
||
size_t max_breadcrumbs = options->max_breadcrumbs; | ||
if (!max_breadcrumbs) { | ||
|
@@ -457,17 +464,18 @@ sentry__crashpad_backend_add_breadcrumb(sentry_backend_t *backend, | |
} | ||
|
||
static void | ||
sentry__crashpad_backend_free(sentry_backend_t *backend) | ||
crashpad_backend_free(sentry_backend_t *backend) | ||
{ | ||
crashpad_state_t *data = (crashpad_state_t *)backend->data; | ||
auto *data = static_cast<crashpad_state_t *>(backend->data); | ||
sentry__path_free(data->event_path); | ||
sentry__path_free(data->breadcrumb1_path); | ||
sentry__path_free(data->breadcrumb2_path); | ||
sentry_value_decref(data->event_id); | ||
sentry_free(data); | ||
} | ||
|
||
static void | ||
sentry__crashpad_backend_except( | ||
crashpad_backend_except( | ||
sentry_backend_t *UNUSED(backend), const sentry_ucontext_t *context) | ||
{ | ||
#ifdef SENTRY_PLATFORM_WINDOWS | ||
|
@@ -486,7 +494,7 @@ report_crash_time( | |
{ | ||
// we do a `+ 1` here, because crashpad timestamps are second resolution, | ||
// but our sessions are ms resolution. at least in our integration tests, we | ||
// can have a session that starts at, eg. `0.471`, whereas the crashpad | ||
// can have a session that starts at, e.g. `0.471`, whereas the crashpad | ||
// report will be `0`, which would mean our heuristic does not trigger due | ||
// to rounding. | ||
uint64_t time = ((uint64_t)report.creation_time + 1) * 1000; | ||
|
@@ -496,9 +504,9 @@ report_crash_time( | |
} | ||
|
||
static uint64_t | ||
sentry__crashpad_backend_last_crash(sentry_backend_t *backend) | ||
crashpad_backend_last_crash(sentry_backend_t *backend) | ||
{ | ||
crashpad_state_t *data = (crashpad_state_t *)backend->data; | ||
auto *data = static_cast<crashpad_state_t *>(backend->data); | ||
|
||
uint64_t crash_time = 0; | ||
|
||
|
@@ -514,9 +522,9 @@ sentry__crashpad_backend_last_crash(sentry_backend_t *backend) | |
} | ||
|
||
static void | ||
sentry__crashpad_backend_prune_database(sentry_backend_t *backend) | ||
crashpad_backend_prune_database(sentry_backend_t *backend) | ||
{ | ||
crashpad_state_t *data = (crashpad_state_t *)backend->data; | ||
auto *data = static_cast<crashpad_state_t *>(backend->data); | ||
|
||
// We want to eagerly clean up reports older than 2 days, and limit the | ||
// complete database to a maximum of 8M. That might still be a lot for | ||
|
@@ -532,29 +540,29 @@ sentry__crashpad_backend_prune_database(sentry_backend_t *backend) | |
sentry_backend_t * | ||
sentry__backend_new(void) | ||
{ | ||
sentry_backend_t *backend = SENTRY_MAKE(sentry_backend_t); | ||
auto *backend = SENTRY_MAKE(sentry_backend_t); | ||
if (!backend) { | ||
return NULL; | ||
return nullptr; | ||
} | ||
memset(backend, 0, sizeof(sentry_backend_t)); | ||
|
||
crashpad_state_t *data = SENTRY_MAKE(crashpad_state_t); | ||
auto *data = SENTRY_MAKE(crashpad_state_t); | ||
if (!data) { | ||
sentry_free(backend); | ||
return NULL; | ||
return nullptr; | ||
} | ||
memset(data, 0, sizeof(crashpad_state_t)); | ||
|
||
backend->startup_func = sentry__crashpad_backend_startup; | ||
backend->shutdown_func = sentry__crashpad_backend_shutdown; | ||
backend->except_func = sentry__crashpad_backend_except; | ||
backend->free_func = sentry__crashpad_backend_free; | ||
backend->flush_scope_func = sentry__crashpad_backend_flush_scope; | ||
backend->add_breadcrumb_func = sentry__crashpad_backend_add_breadcrumb; | ||
backend->user_consent_changed_func | ||
= sentry__crashpad_backend_user_consent_changed; | ||
backend->get_last_crash_func = sentry__crashpad_backend_last_crash; | ||
backend->prune_database_func = sentry__crashpad_backend_prune_database; | ||
data->event_id = sentry_value_new_null(); | ||
|
||
backend->startup_func = crashpad_backend_startup; | ||
backend->shutdown_func = crashpad_backend_shutdown; | ||
backend->except_func = crashpad_backend_except; | ||
backend->free_func = crashpad_backend_free; | ||
backend->flush_scope_func = crashpad_backend_flush_scope; | ||
backend->add_breadcrumb_func = crashpad_backend_add_breadcrumb; | ||
backend->user_consent_changed_func = crashpad_backend_user_consent_changed; | ||
backend->get_last_crash_func = crashpad_backend_last_crash; | ||
backend->prune_database_func = crashpad_backend_prune_database; | ||
backend->data = data; | ||
backend->can_capture_after_shutdown = true; | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is there a particular reason for renaming all these functions?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The main reason is that across the modules, it seemed that the naming scheme is (or was at some point):
sentry_*
for all publicly available interfaces viasentry.h
sentry__*
for all private interfaces which cross module boundaries (i.e., are only internally exposed via module headers)So one part is trivial consistency, but it also gets easier to navigate if I know from the name if there might be an external contract to consider.