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

frontend: Add automatic crash log upload after crashes for Windows and macOS #11943

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

PatTheMav
Copy link
Member

@PatTheMav PatTheMav commented Mar 10, 2025

Description

This PR refactors the current safe mode implementation to allow automatic uploading of the most recent crash report upon a detected crash while avoiding duplicate uploads and also enables the feature on macOS.

Motivation and Context

The primary ask for this work was to enable the automatic upload of crash reports after OBS Studio has crashed and also enable this functionality to more platforms than just Windows.

Note

An even better solution towards this goal would be to use separate minimal process that uses platform-specific methods to "attach" to the main process and be able to detect and react to a crash and thus offer to relaunch the application and uploading a crash log from within it itself. That kind of solution was out of scope for this first iterative step.

To that end the following changes have been implemented:

  • Crash mode detection and crash log uploading have been moved out of the application code base into their own separate CrashHandler class.
  • Direct interaction between CrashHandler, OBSApp, and OBSBasic has been decoupled and has been replaced by Qt signals which code can connect to and react accordingly
  • Each crash sentinel now represents a unique application launch, which potentially allows the CrashHandler class to distinguish between a "live" sentinel for the currently running instance versus an "old" sentinel, which would represent an unclean prior shutdown
  • The most recent crash log file and corresponding upload URL are retained in the application config to avoid multiple uploads of the same crash log.
    • When the most recent crash log file has not changed, the "Upload" menu action will just yield the prior URL.
    • This also allows users to yield the URL of an automatic crash log upload
  • When an unclean shutdown (or "crash") is detected, the user is still provided with a choice to run OBS Studio in "Safe Mode". An additional checkbox to automatically upload the most recent crash is also provided. The automatic upload is opt-in by default.

Platform differences

On Windows the existing custom crash log files are checked and used for crash log upload.

Changes: The CrashHandler class will look for the most recent file by actual creation date and not simply by the time code in its file name anymore.

On macOS the diagnostics reports generated by the operating system are used. No custom crash files are involved. As macOS "retires" active crash reports after some time, the subdirectory for retired reports is also taken into account when looking for a "most recent" crash, with the file creation date used for sorting the results.

On Linux and FreeBSD no searches for crash reports take place, the class methods are implemented as stubs to ensure the class implementation is complete on these platforms.

How Has This Been Tested?

Created custom crash logs in the locations used for macOS and Windows and checked that most recent crashes are found and uploaded from these locations accordingly.

  • Checked behaviour when a new crash file was found (file was uploaded, new URL yielded)
  • Checked behaviour when no new crash file was found but URL was empty (file was uploaded, new URL was displayed to user)
  • Checked behaviour when file upload was unsuccessful (error message was displayed)
  • Checked behaviour when file upload was successful but response JSON does not contain url field (error message was displayed)
  • Checked behaviour when no new crash file was found with available URL (no upload took place, old URL was displayed to user)
  • Checked behaviour when crash sentinel with old UUID was placed in OBS Studio settings directory (prior crash was "detected", safe mode choice was presented)
  • Checked behaviour when automatic crash upload was selected in safe mode dialog (crash log was uploaded, no URL dialog was displayed)
  • Checked behaviour when crash upload was selected after automatic crash upload (existing crash log URL was displayed to user)
  • Checked behaviour when application was compiled in Debug configuration (no safe mode dialogs appeared, crash log behaviour was unchanged)

Types of changes

  • New feature (non-breaking change which adds functionality)
  • Code cleanup (non-breaking change which makes code smaller or more readable)

Checklist:

  • My code has been run through clang-format.
  • I have read the contributing document.
  • My code is not on the master branch.
  • The code has been tested.
  • All commit messages are properly formatted and commits squashed where appropriate.
  • I have included updates to all appropriate documentation.

@PatTheMav PatTheMav force-pushed the macos-crash-reporting branch 2 times, most recently from 11f0370 to e952d18 Compare March 10, 2025 20:01
@jcm93
Copy link
Contributor

jcm93 commented Mar 10, 2025

Just things noticed after a quick test:
Screenshot 2025-03-10 at 4 22 10 PM
I think this text on the bottom could just say "Upload most recent OBS Studio crash report" rather than phrasing it as a question.

After checking this box, I also do not seem to get a popup showing the URL of the uploaded report like I do if I manually select in the menu "Help->Crash Reports->Upload Previous Crash Report". Is this expected or a bug?

@PatTheMav
Copy link
Member Author

After checking this box, I also do not seem to get a popup showing the URL of the uploaded report like I do if I manually select in the menu "Help->Crash Reports->Upload Previous Crash Report". Is this expected or a bug?

No that's intended - the requirement was that no further popups should be displayed to the user as we already have too many of those. Using the menu entry to get at that same URL was the proposed solution.

@jcm93
Copy link
Contributor

jcm93 commented Mar 10, 2025

So, if I check that box, and then I navigate to the aforementioned help menu item (Help->Crash Reports->Upload Previous Crash Report), does that not upload the same report twice? Or do we detect that the report was already uploaded and just show that URL?

Edit: I see this is covered in the original description; duplicate uploads don't happen if the 'most recent detected crash log' has not changed.

I do think it's a bit weird to have the redundancy of the checkbox if, no matter what, the Help menu is still required to yield the URL of the uploaded log.

@PatTheMav
Copy link
Member Author

I do think it's a bit weird to have the redundancy of the checkbox if, no matter what, the Help menu is still required to yield the URL of the uploaded log.

As I said, that's by design, maybe @Warchamp7 can chime in here as that was the solution we ended up with here.

The basic idea is to lower the barrier for crash reports to be uploaded, particularly as this would allow automatic analysis of "current crashes" server-side without the manual input by users.

@jcm93
Copy link
Contributor

jcm93 commented Mar 11, 2025

Got it; yeah, if part of the idea here is 'eventual server-side processing' then I think that makes sense enough to me.

The CrashHandler encapsulates all functionality for managing a crash
sentinel file as well as for detecting, caching, and uploading the most
recent crash log available on the local system.

If a crash is detected, the user has the choice to have the most recent
crash report automatically uploaded during the launch of OBS Studio.

If an existing crash log file has already been successfully uploaded,
the existing URL is provided to the user. This also allows users to
get the crash log URL for a crash log uploaded due to the choice made
at launch of the application.

Each supported platform has its own implementation to discover the
correct path for the most recent crash report. To ensure API stability,
stub implementations are provided for platforms who do not expose this
functionality via the user interface yet.

The CrashHandler implements 3 Qt signals to communicate the start and
result of a crash log upload for implementing clients to react to.

Instead of a single crash sentinel, each application launch uses a
UUID to identify its own "current" crash sentinel. If a sentinel file
with a different launch ID is detected, a prior crash is considered to
have taken place.

Upon a successful app shutdown, all remaining sentinels are removed.

If OBS Studio is launched with the --multi argument, the CrashHandler
becomes inert.

If OBS Studio is compiled in Debug configuration, the CrashHandler also
becomes inert.
The new CrashHandler class is used by the OBSApp class (as it's an
application concern) to handle detection of a prior crash and also to
provide crash upload functionality.

The concerns are separated by using Qt signals: The OBSBasic window
asks the application to upload the most recent crash log and is
informed by the OBSApp instance via bespoke signals about the result
(thus the OBSBasic instance can choose what to do in reaction to these
events).

The OBSApp class itself reacts to events emitted by its CrashHandler
instance, thus each part of the application is only concerned about its
own functionality and allows other parts to react to these events
accordingly.
@PatTheMav PatTheMav force-pushed the macos-crash-reporting branch from e952d18 to cc670f9 Compare March 11, 2025 17:06
@PatTheMav
Copy link
Member Author

Removed the intro text for every upload on macOS to upload the unchanged JSON contents of the crash log to the server. That way the file can be downloaded and parsed/opened directly (albeit with a possible change of file suffix) in Xcode or Console.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants