Skip to content
Open
Show file tree
Hide file tree
Changes from 5 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
17 changes: 14 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,23 @@ Upgrading from 4.x? See [Migrating from 4.x](Documentation~/migrating-from-4x.md

### Added

- **BugSplat initializes itself — nothing needs to be placed in a scene.** Select or create a `BugSplatOptions` asset in the new **Edit > Project Settings > BugSplat** page and BugSplat initializes from it before the first scene loads, in the editor and in every player. That is the whole setup. It also closes a coverage gap: nothing ran until a `BugSplatManager`'s `Awake`, so a native crash during the first scene's load, or in a bootstrap scene without a manager, was never reported. `BugSplatOptions.InitializeAutomatically` (default `true`) turns this off for projects that must wait — for a consent screen, say — and call `BugSplat.Initialize(options)` themselves ([#253](https://github.com/BugSplat-Git/bugsplat-unity/issues/253)).
- `BugSplat.Instance`, `BugSplat.IsInitialized`, and `BugSplat.Initialize(BugSplatOptions)`. `Instance` replaces `FindAnyObjectByType<BugSplatManager>().BugSplat` — a scene search that was null-prone and depended on `Start` running after the manager's `Awake`; it is set before the first scene loads, so any `Awake` can read it. `Initialize` is idempotent: a second call logs a warning and returns the existing instance rather than throwing.
- **Edit > Project Settings > BugSplat** (also **BugSplat > Settings...**): choose the project's options asset or create one, edit it in place, and see at a glance whether the project is configured. The selection is stored as an `EditorBuildSettings` config object, so it is versioned with the project and survives the asset being moved or renamed.
- **Release** builds fail when no options asset is selected, when several exist and none is selected, when the selected asset's database is empty, or when a *different* `BugSplatOptions` sits in **Player Settings > Preloaded Assets** — a player takes its options from the first one loaded, so two would make the choice depend on load order. A **development** build only warns, so iterating never requires BugSplat to be configured first. A misconfigured project previously built a player that silently reported nothing.
- `BugSplatOptions.RegisterLogMessageReceived`, `CaptureExceptionsOnBackgroundThreads`, and `CaptureUnobservedTaskExceptions`, moved from `BugSplatManager` so automatic initialization can honor them.
- **Setup without the Editor UI**, for scripts, CI, and AI agents ([Automation](Documentation~/automation.md)). A project's single `BugSplatOptions` asset is selected automatically, so writing one file configures the project. `BugSplatUnity.Editor.BugSplatSetup.Configure` and `BugSplatProjectOptions` are public, and `-executeMethod BugSplatUnity.Editor.BugSplatSetup.ConfigureFromCommandLine -bugsplatDatabase <name>` does the whole thing from a shell, exiting `0` or `1`. Every "not configured" message names the file-based fix alongside the menu, so a log is enough to act on.
- `BUGSPLAT_MANUAL_INITIALIZE` scripting define for projects that build their options in code and call `BugSplat.Initialize` themselves: no automatic initialization, no startup warning, no build check.
- **`BugSplatOptions.Enabled` and the `BUGSPLAT_DISABLED` define turn BugSplat off**, so a project is never forced to fill in a database it does not want yet. Off means no initialization and no build validation; an explicit `BugSplat.Initialize` call is still honored. `Enabled` is the project-wide switch and the define is the per-build-target one, for keeping BugSplat out of development builds while leaving it on for QA and release. Unchecking `Enabled` logs one line in a development build, so a build that reports nothing is never a mystery. See [Turning BugSplat on and off](Documentation~/api.md#turning-bugsplat-on-and-off).
- **Native Windows crash reporting** via [bugsplat-windows](https://github.com/BugSplat-Git/bugsplat-windows). Unity P/Invokes the SDK's `BugSplat_*` C API exports from `BugSplat.dll`, so native crashes are captured with **both the Mono and IL2CPP** scripting backends, on x86 (32-bit), x64, and ARM64. Enable it with `BugSplatOptions.UseNativeCrashReportingForWindows`. Binaries come from the official signed bugsplat-windows v8.1.0 release.
- `BugSplatOptions.WindowsShowCrashDialog` — show the BugSplat crash dialog when a native crash occurs on Windows. Defaults to `true`; disable it to upload silently.
- `BugSplatOptions.WindowsHangDetectionTimeoutMs` — out-of-process hang detection for Windows. Defaults to `0` (disabled). When a hang is detected, BugSplat uploads a hang report and terminates the process, so choose a timeout longer than your longest expected frame.
- **Windows Error Reporting coverage** for fail-fast terminations — stack buffer overrun (`0xC0000409`), heap corruption (`0xC0000374`), and `__fastfail` — which bypass every in-process exception filter. Capture requires an `HKLM\...\RuntimeExceptionHelperModules` value naming `BugSplatWer.dll`:
- `BugSplat.WindowsWerEnabled` reports whether the handler actually registered, and init logs what is lost and how to fix it when it hasn't (a warning in development builds, informational otherwise).
- **BugSplat > Windows > Register WER Handler**, **Unregister WER Handler**, and **Check WER Handler Registration** write and verify that value elevated for a built player, in both registry views.
- Unsent native Windows crash reports are uploaded automatically at startup; init also attaches `Player.log` and syncs attributes, user, email, key, description, and notes to the native reporter.
- **Capture of unhandled exceptions thrown on background threads.** Unity only raises `logMessageReceived` for main-thread logs, so these were previously written to the player log and never reported. Background exceptions are buffered in a bounded (64-slot) thread-safe queue and posted from the main thread on the next frame, with main-thread logs rejected by thread id so nothing reports twice. On by default; opt out via **Capture Exceptions On Background Threads** on `BugSplatManager`.
- **Capture of exceptions from `Task`s that were never awaited.** A faulted `Task` nobody awaits never writes to Unity's log at all, so neither log callback sees it and the failure is invisible. BugSplat now subscribes to `TaskScheduler.UnobservedTaskException` directly. Two things are worth knowing about the timing: the runtime raises this only when a garbage collection notices the faulted `Task`, so reports arrive well after the failure and a `Task` that is never collected is never reported; and BugSplat deliberately does not call `SetObserved()`, since marking the exception observed would suppress whatever your project does with it next. On by default; opt out via **Capture Unobserved Task Exceptions** on `BugSplatManager`.
- **Capture of unhandled exceptions thrown on background threads.** Unity only raises `logMessageReceived` for main-thread logs, so these were previously written to the player log and never reported. Background exceptions are buffered in a bounded (64-slot) thread-safe queue and posted from the main thread on the next frame, with main-thread logs rejected by thread id so nothing reports twice. On by default; opt out via **Capture Exceptions On Background Threads** on `BugSplatOptions`.
- **Capture of exceptions from `Task`s that were never awaited.** A faulted `Task` nobody awaits never writes to Unity's log at all, so neither log callback sees it and the failure is invisible. BugSplat now subscribes to `TaskScheduler.UnobservedTaskException` directly. Two things are worth knowing about the timing: the runtime raises this only when a garbage collection notices the faulted `Task`, so reports arrive well after the failure and a `Task` that is never collected is never reported; and BugSplat deliberately does not call `SetObserved()`, since marking the exception observed would suppress whatever your project does with it next. On by default; opt out via **Capture Unobserved Task Exceptions** on `BugSplatOptions`.
- Editor menu for symbol upload credentials: **BugSplat > Symbol Upload > Set Credentials**, **Clear Credentials**, and **Check Credentials**.
- `Description`, `Email`, `Key`, `Notes`, and `User` gained getters — they were previously set-only.
- Continuous integration (`.github/workflows/tests.yml`): the test suite runs on StandaloneLinux64, StandaloneWindows64, StandaloneOSX, and WebGL, plus player-script compile checks for iOS and Android that cover the code behind `!UNITY_EDITOR`, which tests cannot link against.
Expand All @@ -41,13 +49,15 @@ Upgrading from 4.x? See [Migrating from 4.x](Documentation~/migrating-from-4x.md

### Changed

- The `my-unity-crasher` sample enables symbol upload for **all four platforms** rather than iOS alone, so a sample build produces symbolicated stacks on whichever platform you run it on. Credentials are still never stored on the asset; without them a build warns and succeeds. The sample's asset also drops the dead `SymbolUploadClientId` and `SymbolUploadClientSecret` keys, which named fields this release removed.
- **`BugSplatManager` is obsolete.** A scene that still has one keeps working: the component adopts the instance created at startup and logs that it is no longer needed, or — with Initialize Automatically off — initializes from its own asset exactly as before, its own capture flags winning. Two managers, or a manager plus automatic initialization, no longer install two sets of log hooks, so nothing reports twice ([#174](https://github.com/BugSplat-Git/bugsplat-unity/issues/174)). It is hidden from **Add Component** and will be removed in 6.0.
- The editor resolves the project's options asset from the Project Settings selection instead of `AssetDatabase.FindAssets("t:BugSplatOptions")[0]`, so a project with more than one asset no longer builds, uploads symbols, or stores credentials against an arbitrary one. A project with exactly one asset has it selected automatically.
- `BugSplatOptions.PersistentDataFileAttachmentPaths` now attaches its files to **native crash reports** as well as managed reports, on every platform whose native crash reporting is enabled. Previously the list reached managed exception reports, feedback, and minidumps only, so files configured there were silently absent from the native crash reports most users expected them on. The files are handed to the native reporter through the constructor, before it starts: on macOS and iOS a report uploads at the next launch and its attachments are gathered once, while the reporter starts, so anything registered after construction would miss it.

- iOS crash auto-submit is now configurable rather than hard-coded. The iOS bridge always set `autoSubmitCrashReport = YES`; it is now driven by `BugSplatOptions.IosAutoSubmitCrashReport`, which still defaults to `true`, so iOS behavior is unchanged. macOS gets its own `MacAutoSubmitCrashReport`, defaulting to `false`. The split is deliberate: silent on mobile and a prompt on desktop is the platform convention, and it is what bugsplat-apple's own per-platform defaults already encode.
- **Breaking:** the `BugSplat` constructor gained `autoSubmitCrashReport`, `autoSubmitFatalHangReport`, `hangDetectionThresholdSeconds` and `nativeAttachments` parameters after `capturePlayerLog`. All four are optional and default to `null`, meaning "leave bugsplat-apple's own per-platform defaults alone", so a caller that passes nothing gets exactly the behavior it got before. Only code passing arguments positionally past `capturePlayerLog` needs changing.
- The iOS and macOS native bridges now export the same symbol names instead of `Ios`/`Mac`-suffixed pairs. The two plugins are gated to mutually exclusive platforms and can never be compiled into the same binary, so the suffixes bought nothing while forcing every Apple call site in `BugSplat.cs` to be written twice; eight duplicated `#if UNITY_IOS … #elif UNITY_STANDALONE_OSX` branches and one whole `DllImport` block collapsed as a result. These symbols are internal P/Invoke targets, so no public API changed.
- **Breaking:** the package's public types no longer sit in the global namespace, where they were injected into every consumer project. `BuildPostprocessors`, `BugSplatOptionsEditor`, and `BugSplatSymbolUploadCredentials` moved to `BugSplatUnity.Editor`, and `BugSplatRef` moved to `BugSplatUnity.Runtime.Manager`. Unity finds the editor types by attribute, and scenes and prefabs reference scripts by file GUID, so no asset needs re-linking — but code that named these types needs a `using`. The `my-unity-crasher` sample's own scripts moved into its existing `Crasher` namespace for the same reason.
- **Breaking:** `BugSplatRef` is now `internal` and exposes its `BugSplat` property as get-only. It is an implementation detail of `BugSplatManager` and appears nowhere in the public API; use `BugSplatManager.BugSplat` instead.
- **Breaking:** `BugSplatOptions.Attributes` is now `List<BugSplatAttribute>` instead of `Dictionary<string, string>`. Unity cannot serialize a dictionary, so the field could never be authored in the inspector. Unity drops the old serialized value silently when a 4.x options asset is opened.
- **Breaking:** the symbol upload environment variables are renamed from `BUGSPLAT_CLIENT_ID`/`BUGSPLAT_CLIENT_SECRET` to `SYMBOL_UPLOAD_CLIENT_ID`/`SYMBOL_UPLOAD_CLIENT_SECRET`, the names the `symbol-upload` CLI already reads. The old names are no longer read.
- **Breaking for coroutines that yield on `Post`:** report uploads are now awaited. `yield return Task.Run(...)` waits a single frame rather than for the task, so `yield return bugsplat.Post(ex); Application.Quit();` lost reports nondeterministically. Those coroutines now genuinely wait for the upload.
Expand All @@ -59,6 +69,7 @@ Upgrading from 4.x? See [Migrating from 4.x](Documentation~/migrating-from-4x.md

### Removed

- **Breaking:** `BugSplatRef`. It was an implementation detail of `BugSplatManager` and appears nowhere in the public API; use `BugSplat.Instance`.
- The orphaned `UNITY_WSA` player-log branch in `DotNetStandardExceptionReporter`. It was the only WSA/UWP code in the package — no options, no README claim, no platform-support row, no CI target — so it read as support that did not exist. Removing it in a release that is already breaking avoids either a needless break later or carrying dead code for two more versions ([#196](https://github.com/BugSplat-Git/bugsplat-unity/issues/196)).

- **Breaking:** `WindowsReporter` and `INativeCrashReporter`. Unity's `CrashReporting.crashReportFolder` minidumps are no longer read or uploaded — native Windows crashes are captured by bugsplat-windows instead.
Expand Down
2 changes: 1 addition & 1 deletion Documentation~/android.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

# 🤖 Android

The bugsplat-unity plugin supports crash reporting for native C++ crashes on Android via Crashpad. To configure crash reporting for Android, set the `UseNativeCrashReportingForAndroid` and `UploadDebugSymbolsForAndroid` properties to `true` on the BugSplatManager instance.
The bugsplat-unity plugin supports crash reporting for native C++ crashes on Android via Crashpad. To configure crash reporting for Android, set the `UseNativeCrashReportingForAndroid` and `UploadDebugSymbolsForAndroid` properties to `true` on your `BugSplatOptions` asset (**Edit > Project Settings > BugSplat**).

You'll also need to configure the scripting backend to use IL2CPP, target **ARM64**, and set the Minimum API Level to **Android 8.0 (API level 26)** or higher. ARM64 is the only configuration BugSplat tests; the bundled `bugsplat-android-release.aar` also ships `armeabi-v7a` and `x86_64` native libraries, but those ABIs are untested and unsupported.

Expand Down
Loading
Loading