fix: honor CapturePlayerLog on the native crash reporting path - #214
Draft
bobbyg603 wants to merge 1 commit into
Draft
fix: honor CapturePlayerLog on the native crash reporting path#214bobbyg603 wants to merge 1 commit into
bobbyg603 wants to merge 1 commit into
Conversation
Native init attached Application.consoleLogPath unconditionally, so a project that left CapturePlayerLog off still shipped Player.log with every native crash report. Player.log paths embed the OS username, so the opt-out has to hold for native reports too, not just managed posts. The decision has to be made during init: the Windows SDK snapshots the attachment list into shared memory, and the monitor copies those files at crash time, so anything attached before the first crash ships with it. The setting arrives from BugSplatOptions after the constructor returns, so it now travels as a constructor parameter and reaches the native reporter before any crash can be captured. Passing it through UseDotNetHandler keeps the managed setting and the native attachment from diverging; WebGL keeps its own default because it does not use that handler. CapturePlayerLog remains settable at runtime and now adds or removes the native attachment, guarded so a repeated add cannot attach the log twice -- BugSplat_AddAttachment does not de-duplicate. macOS gets the same treatment: it passed the log path into _startBugSplatMac at init, and an empty path leaves the log delegate unset. iOS and Android attach no log at init, so they need no change. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR ensures the BugSplatOptions.CapturePlayerLog setting is honored consistently across both managed reporting and native crash reporting (Windows/macOS), preventing unintended inclusion of Player.log (and therefore username-containing paths) when the option is disabled.
Changes:
- Adds a
capturePlayerLogconstructor parameter (defaulttrue) and forwards it throughCreateFromOptionsandUseDotNetHandler. - Updates
CapturePlayerLogto add/remove the nativePlayer.logattachment at runtime (with a guard to avoid duplicate attachments). - Updates documentation and adds a unit test to pin the
CapturePlayerLog=falsemapping behavior.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| Tests/Runtime/BugSplatCreateFromOptionsTests.cs | Adds a regression test asserting CapturePlayerLog=false is preserved through CreateFromOptions. |
| Runtime/BugSplat.cs | Threads CapturePlayerLog into native init + managed settings and syncs native attachments via the property setter. |
| README.md | Clarifies that native Windows/macOS Player.log attachment is controlled by CapturePlayerLog and can be toggled at runtime. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+322
to
+325
| var logPath = capturePlayerLog ? Application.consoleLogPath : null; | ||
| _startBugSplatMac(database, application, version, logPath ?? ""); | ||
| nativeCrashReportingEnabled = true; | ||
| nativePlayerLogAttached = !string.IsNullOrEmpty(logPath); |
bobbyg603
marked this pull request as draft
August 11, 2026 21:39
daveplunkett
approved these changes
Aug 12, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #152
Problem
Native init called
BugSplat_AddAttachment(Application.consoleLogPath)unconditionally, soPlayer.logshipped with every native Windows crash report even whenCapturePlayerLogwas off. The flag only ever governed managed posts.Player.loglives underC:\Users\<name>\AppData\..., so the path alone leaks the Windows username — the opt-out has to hold on the native path too.Verified against
origin/main:Runtime/BugSplat.csattached the log inside theUNITY_STANDALONE_WIN && !UNITY_EDITORbranch with no reference to any setting.Order of operations
The value was not known where it was needed, which is the crux of the fix:
CreateFromOptionsassignsCapturePlayerLogin an object initializer, i.e. after the constructor has already run native init.clientSettingsdoes not exist yet at that point either — on Windows,UseDotNetHandlerruns after the native block.BugSplatImpl::AddAttachmentwrites the attachment list into shared memory and the monitor process copies those files at crash time (CopyCrashFolderAttachments), so anything attached before the first crash ships with it. Removing the attachment a moment later only narrows the window rather than closing it.So the flag now travels as a new optional constructor parameter,
capturePlayerLog(defaults totrue, preserving today's behavior for anyone calling the constructor directly), and is applied beforeBugSplat_PostAllCrashesAsync. It is also forwarded toUseDotNetHandlerso the managed setting and the native attachment cannot diverge. WebGL is untouched: it does not use that handler and keeps its ownfalsedefault, which is whyCreateFromOptionsstill assigns theCapturePlayerLogproperty afterwards — removing that line would break the WebGL mapping.Other native platforms
_startBugSplatMac(db, app, ver, Application.consoleLogPath)attached the log at init; the path embeds the macOS username the same way. Fixed by passing an empty path when the flag is off, which leavesBugSplatBridgeMac.mm's log delegate unset (it only installs the delegate for a non-empty, existing path)._startBugSplattakes no log path; nothing is attached at init.AttachNativeLogFileremains the explicit opt-in. No change.BugSplatBridge.initBugSplattakes no log path, andAttachNativeLogFileis already documented as a no-op there. No change.Runtime changes (in scope)
Client settings are mutable, so I handled it rather than deferring: the
CapturePlayerLogsetter now adds or removes the native attachment. This works because attachments are read at crash time, not at init. It is guarded by anativePlayerLogAttachedfield becauseBugSplat_AddAttachmentdoes not de-duplicate — without the guard,CreateFromOptionssetting the property right after the constructor would attachPlayer.logtwice. On macOS the setter re-points the log delegate through_attachNativeLogFileMac.Behavior change worth flagging
BugSplatOptions.CapturePlayerLogis a plainpublic booland therefore defaults to false on the asset, while the managed client settings default totrue. Projects that never ticked the box gotPlayer.logon native reports but not on managed posts; after this change they get it on neither. That is the point of the issue, but it does mean existing native Windows/macOS users who want the log must tickCapturePlayerLog. The README now says so.Verification
Unity was not run — no editor invocation, no player build, no crash exercised on a real device. What was actually done:
Compiled
Runtime/**+Tests/Runtime/**against Unity's managed assemblies withdotnet build(the harness used on previous PRs in this repo). Build succeeded, 0 errors.Re-ran the same compile once per platform define to cover every
#ifpermutation the change touches — all succeeded with 0 errors:UNITY_STANDALONE_WINBugSplat_AddAttachment/BugSplat_RemoveAttachmentin the new helperUNITY_STANDALONE_OSX_attachNativeLogFileMacin the helperUNITY_IOSUNITY_ANDROIDUNITY_WEBGLUseDotNetHandler)UNITY_STANDALONE_WIN;UNITY_EDITOR#elsebranch, as in the editor and the test run#elsebranch, Runtime + TestsThe only warnings are
CS0649on the never-assigned-in-this-compilationnativeCrashReportingEnabled/windowsWerEnabled/ newnativePlayerLogAttachedfields — the same pre-existing pattern the two older fields already produce, and it disappears on the platform where each field is assigned.Hand-traced the paths no compile can prove:
CreateFromOptionswithCapturePlayerLog = true: constructor attaches and setsnativePlayerLogAttached = true; the object initializer's setter sees no change and skips — no double attach.CreateFromOptionswithCapturePlayerLog = false: constructor skips the attach; the setter sees no change and issues no pointlessBugSplat_RemoveAttachment.CapturePlayerLog = falseafter atrueinit:BugSplat_RemoveAttachment(logPath)runs;BugSplatImpl::RemoveAttachmentfull-paths the argument, erases it, and rebuilds the shared-memory slots, so later crashes carry no log.nativeCrashReportingEnabledis never true, so the helper returns before touching any native call — tests are unaffected.Test
CreateFromOptions_WhenCapturePlayerLogIsFalse_ShouldNotCapturePlayerLogpins thefalsedirection of the mapping, which is meaningful because the client settings default totrue. The native attachment itself is not unit-testable here — the native branches are compiled out in the editor, and asserting on them would need a player build plus a real crash.Out of scope (noted, not changed)
Samples~/my-unity-crasher/Scripts/BugSplatSettings.cscallsAttachNativeLogFile(Application.consoleLogPath)unconditionally afterCreateFromOptions. On Windows that already double-attachesPlayer.logtoday when the flag is on (the SDK does not de-duplicate), and it still overrides the opt-out because it is an explicit API call. Left alone since it is sample code demonstrating that API, but it is worth a follow-up.🤖 Generated with Claude Code