getsentry / sentry-native

Sentry SDK for C, C++ and native applications.
MIT License
381 stars 164 forks source link

inproc: backtrace() on recent macOS no longer produces a stack-trace in the signal-handler #906

Open MeijisIrlnd opened 8 months ago

MeijisIrlnd commented 8 months ago

Hiya, I've gotten sentry-native integrated into my VST3 / AU project, and managed to get super readable stack traces on Windows when the plugin crashes in a host by uploading the PDB debug symbols to the project with sentry-cli, which is great, (I temporarily made the callback from a mouseDown event just dereference a nullptr for testing) but on macOS (Ventura, M1 chip) with the same setup, (except DSYM files instead of PDBs), I end up with something along these lines:

Report Version: 104

Exception Type: Unknown (SIGILL)

Application Specific Information:
IllegalInstruction

EOF

and this warning at the top of the issue page:

image

Wondering if I'm missing something super obvious here, I'm using the inproc backend to avoid having to ship extra files, and my setup is very minimal, literally just setting some options and calling sentry_init in my constructor, and sentry_shutdown in my destructor,

Let me know if you have any ideas of where to start looking or need more info!

kahest commented 8 months ago

Hey @MeijisIrlnd would you be able to share a link to the event on Sentry, either here or via email to karl.struggl@sentry.io? Also, if you could share your init code that could also be helpful. Cheers!

supervacuus commented 8 months ago

Related: https://github.com/getsentry/sentry-native/discussions/897#discussioncomment-7378503

MeijisIrlnd commented 8 months ago

Hey, thanks for the quick response, link to the event on Sentry.io is here!

So for initialisation, I'm using the JUCE framework, so my entry point is the constuctor of my AudioProcessor class - that calls this free function:

    void initSentry() {
        auto* const options = sentry_options_new();
        sentry_options_set_dsn(options, "https://mydsn.com");
        // JUCE way to grab ~/Library/Aetherborne on mac and %APPDATA%/Aetherborne on windows
        const auto appDataDir = juce::File::getSpecialLocation(juce::File::SpecialLocationType::userApplicationDataDirectory).getChildFile("Aetherborne");
        const auto sentryDir = appDataDir.getChildFile(".sentry");
        const auto path = sentryDir.getFullPathName().toStdString();
        sentry_options_set_database_path(options, path.c_str());
        const auto versionString = fmt::format("Aetherborne@{}", AETHERBORNE_VERSION);
        sentry_options_set_release(options, versionString.c_str());
        sentry_options_set_debug(options, 1);
        // Saw another post mention this wasn't necessary, but thought I'd give it a try - same result with or without it
        sentry_options_set_symbolize_stacktraces(options, 1);
        sentry_init(options);
    }

Hope that helps, also had a look at @supervacuus 's linked post, maybe shipping with crashpad or breakpad is the way to go, but because this is going to be hosted within a different application, having an additional executable alongside our plugin can be a bit finnicky, hence us opting for inproc!

supervacuus commented 8 months ago

@MeijisIrlnd, breakpad doesn't require an additional executable to be shipped alongside your deployment artifact. There are practically very few reasons that would make inproc the right choice on macOS (or any platform). A separate build artifact is not one of them.

MeijisIrlnd commented 8 months ago

@supervacuus Oh my bad - I must have gotten it confused with crashpad - I'll try a build with -DSENTRY_BACKEND=breakpad and see if it resolves the issue!

MeijisIrlnd commented 8 months ago

Okay yeah - definitely much better with breakpad, here's that same nullptr deref crash taking down juce's plugin host, still not symbolising properly but I guess that's par for the course considering I don't have debug symbols for the host? - will experiment with it in Ableton and other hosts this evening in any case, thanks so much for your advice & the info!

supervacuus commented 7 months ago

still not symbolising properly but I guess that's par for the course considering I don't have debug symbols for the host?

Yeah, this is an issue when adding crash reporting to the plugin rather than to the host: you depend on the host to be willing to share debug symbols.

This is somewhat related to the topic here: https://github.com/getsentry/sentry-native/issues/900#issuecomment-1825457223. While you don't use crashpad the problem that every process typically has one global crash handler also affects you (imagine if the host or another plugin also installs a crash handler).

Of course, the problem goes beyond runtime issues. It also concerns the availability of debug symbols: even if crash handling were centralized in the host, the symbolication of crashes would require access to the symbols of all plugins involved in the crash. There are solutions to these problems, but they need coordination between the host and plugin developers.

steve-mackinnon commented 1 month ago

Hi there,

Is there any update on producing valid stack traces using inproc as a backend on macOS?

I'm in a similar boat to @MeijisIrlnd. We are adding Sentry for crash reporting for a VST audio plugin running inside of a host digital audio workstation process. Breakpad produces stack traces correctly, but it does not reinstall the DAW's handler. So I believe we will end up breaking crash reporting for the DAW without forking Breakpad to reinstall existing handlers like inproc does. @MeijisIrlnd were you able to use Breakpad without stealing crash reports from the DAW?

Thanks in advance!

kahest commented 1 month ago

Hey @steve-mackinnon no update regarding inproc as of now, we'll keep this issue updated