Skip to content
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

Add onCrashCallback #3408

Open
philipphofmann opened this issue Nov 14, 2023 · 0 comments
Open

Add onCrashCallback #3408

philipphofmann opened this issue Nov 14, 2023 · 0 comments

Comments

@philipphofmann
Copy link
Member

Description

Some users have some advanced use cases. They'd like to attach frequently changing information to crashes, but they can't add this info to the scope, cause it causes a considerable serialization overhead. Therefore, an idea is to add a C onCrashCallback similar to what we had in one of our first versions of SentryCrash SentryCrashReportWriteCallback.

/** Set the function to call when writing the user section of the report.
* This allows the user to add more fields to the user section at the time of the crash.
* Note: Only async-safe functions are allowed in the callback.
*
* @param userSectionWriteCallback The user section write callback.
*/
void sentrycrashreport_setUserSectionWriteCallback(const SentryCrashReportWriteCallback userSectionWriteCallback);

typedef void (*SentryCrashReportWriteCallback)(const SentryCrashReportWriter* writer);

We don't want to expose the SentryCrashReportWriter, because it is powerful and complex, limits our users on what they can do, and gives our users the possibility to shoot themselves into their feet by messing up the crash report, which we want to avoid. Instead, we want to give our users the flexibility to do whatever they want in this callback. Therefore, the SDK passes the eventID of the crash event when the SDK converts the crash report to a SentryEvent. With that approach our users can store information, add the eventID, and in beforeSend they can look up their information and add it to the crash event. Ideally, we would build a more user-friendly API, but our expectations are that only a subset of power users will use this API and it's not worth investing in that API at the moment. We can always iterate on it later.

The SentryCrash reports currently don't contain the eventID, but instead a reportID. Before we can add the callback with the eventID we need to either change the reportID to a UUID as the eventID of SentryEvents, or we generate a UUID / eventID when crashing, attach it to the SentryCrash report and then use it when creating the SentryEvent.

The SDK calls the callback after writing the crash report to disk and storing the screenshot and view hierarchy so if users mess things up in the callback the SDK can still write the crash report. If users crash in their callback or call non async-signal safe code the side effect will be that signal handlers coming after Sentry might not work correctly. We will add this information to the code docs of the callback.

/** Called when a crash occurs.
*
* This function gets passed as a callback to a crash handler.
*/
static void
onCrash(struct SentryCrash_MonitorContext *monitorContext)
{
SentryCrashLOG_DEBUG("Updating application state to note crash.");
sentrycrashstate_notifyAppCrash();
if (monitorContext->crashedDuringCrashHandling) {
sentrycrashreport_writeRecrashReport(monitorContext, g_lastCrashReportFilePath);
} else {
char crashReportFilePath[SentryCrashFU_MAX_PATH_LENGTH];
sentrycrashcrs_getNextCrashReportPath(crashReportFilePath);
strncpy(g_lastCrashReportFilePath, crashReportFilePath, sizeof(g_lastCrashReportFilePath));
sentrycrashreport_writeStandardReport(monitorContext, crashReportFilePath);
}
// Report is saved to disk, now we try to take screenshots
// and view hierarchies.
// Depending on the state of the crash this may not work
// because we gonna call into non async-signal safe code
// but since the app is already in a crash state we don't
// mind if this approach crashes.
if (g_saveScreenShot || g_saveViewHierarchy) {
char crashAttachmentsPath[SentryCrashCRS_MAX_PATH_LENGTH];
sentrycrashcrs_getAttachmentsPath_forReport(
g_lastCrashReportFilePath, crashAttachmentsPath);
if (sentrycrashfu_makePath(crashAttachmentsPath)) {
if (g_saveScreenShot) {
g_saveScreenShot(crashAttachmentsPath);
}
if (g_saveViewHierarchy) {
g_saveViewHierarchy(crashAttachmentsPath);
}
}
}
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Backlog
Development

No branches or pull requests

1 participant