Skip to content

fix: honor CapturePlayerLog on the native crash reporting path - #214

Draft
bobbyg603 wants to merge 1 commit into
mainfrom
fix/native-player-log-opt-out
Draft

fix: honor CapturePlayerLog on the native crash reporting path#214
bobbyg603 wants to merge 1 commit into
mainfrom
fix/native-player-log-opt-out

Conversation

@bobbyg603

Copy link
Copy Markdown
Member

Closes #152

Problem

Native init called BugSplat_AddAttachment(Application.consoleLogPath) unconditionally, so Player.log shipped with every native Windows crash report even when CapturePlayerLog was off. The flag only ever governed managed posts. Player.log lives under C:\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.cs attached the log inside the UNITY_STANDALONE_WIN && !UNITY_EDITOR branch 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:

  • CreateFromOptions assigns CapturePlayerLog in an object initializer, i.e. after the constructor has already run native init.
  • clientSettings does not exist yet at that point either — on Windows, UseDotNetHandler runs after the native block.
  • Deferring the decision is not safe. BugSplatImpl::AddAttachment writes 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 to true, preserving today's behavior for anyone calling the constructor directly), and is applied before BugSplat_PostAllCrashesAsync. It is also forwarded to UseDotNetHandler so the managed setting and the native attachment cannot diverge. WebGL is untouched: it does not use that handler and keeps its own false default, which is why CreateFromOptions still assigns the CapturePlayerLog property afterwards — removing that line would break the WebGL mapping.

Other native platforms

  • macOS — same bug. _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 leaves BugSplatBridgeMac.mm's log delegate unset (it only installs the delegate for a non-empty, existing path).
  • iOS_startBugSplat takes no log path; nothing is attached at init. AttachNativeLogFile remains the explicit opt-in. No change.
  • AndroidBugSplatBridge.initBugSplat takes no log path, and AttachNativeLogFile is 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 CapturePlayerLog setter now adds or removes the native attachment. This works because attachments are read at crash time, not at init. It is guarded by a nativePlayerLogAttached field because BugSplat_AddAttachment does not de-duplicate — without the guard, CreateFromOptions setting the property right after the constructor would attach Player.log twice. On macOS the setter re-points the log delegate through _attachNativeLogFileMac.

Behavior change worth flagging

BugSplatOptions.CapturePlayerLog is a plain public bool and therefore defaults to false on the asset, while the managed client settings default to true. Projects that never ticked the box got Player.log on 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 tick CapturePlayerLog. 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:

  1. Compiled Runtime/** + Tests/Runtime/** against Unity's managed assemblies with dotnet build (the harness used on previous PRs in this repo). Build succeeded, 0 errors.

  2. Re-ran the same compile once per platform define to cover every #if permutation the change touches — all succeeded with 0 errors:

    Defines Branch exercised Result
    UNITY_STANDALONE_WIN Windows native init + BugSplat_AddAttachment/BugSplat_RemoveAttachment in the new helper 0 errors, 0 warnings
    UNITY_STANDALONE_OSX macOS init with the conditional log path + _attachNativeLogFileMac in the helper 0 errors
    UNITY_IOS iOS init; helper compiles to the guards only 0 errors
    UNITY_ANDROID Android init; helper compiles to the guards only 0 errors
    UNITY_WEBGL WebGL settings repository path (no UseDotNetHandler) 0 errors
    UNITY_STANDALONE_WIN;UNITY_EDITOR #else branch, as in the editor and the test run 0 errors
    (no defines) #else branch, Runtime + Tests 0 errors

    The only warnings are CS0649 on the never-assigned-in-this-compilation nativeCrashReportingEnabled / windowsWerEnabled / new nativePlayerLogAttached fields — the same pre-existing pattern the two older fields already produce, and it disappears on the platform where each field is assigned.

  3. Hand-traced the paths no compile can prove:

    • CreateFromOptions with CapturePlayerLog = true: constructor attaches and sets nativePlayerLogAttached = true; the object initializer's setter sees no change and skips — no double attach.
    • CreateFromOptions with CapturePlayerLog = false: constructor skips the attach; the setter sees no change and issues no pointless BugSplat_RemoveAttachment.
    • Runtime CapturePlayerLog = false after a true init: BugSplat_RemoveAttachment(logPath) runs; BugSplatImpl::RemoveAttachment full-paths the argument, erases it, and rebuilds the shared-memory slots, so later crashes carry no log.
    • Editor and WebGL: nativeCrashReportingEnabled is never true, so the helper returns before touching any native call — tests are unaffected.

Test

CreateFromOptions_WhenCapturePlayerLogIsFalse_ShouldNotCapturePlayerLog pins the false direction of the mapping, which is meaningful because the client settings default to true. 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.cs calls AttachNativeLogFile(Application.consoleLogPath) unconditionally after CreateFromOptions. On Windows that already double-attaches Player.log today 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

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>
Copilot AI lite review requested due to automatic review settings August 11, 2026 21:23

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 capturePlayerLog constructor parameter (default true) and forwards it through CreateFromOptions and UseDotNetHandler.
  • Updates CapturePlayerLog to add/remove the native Player.log attachment at runtime (with a guard to avoid duplicate attachments).
  • Updates documentation and adds a unit test to pin the CapturePlayerLog=false mapping 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 thread Runtime/BugSplat.cs
Comment on lines +322 to +325
var logPath = capturePlayerLog ? Application.consoleLogPath : null;
_startBugSplatMac(database, application, version, logPath ?? "");
nativeCrashReportingEnabled = true;
nativePlayerLogAttached = !string.IsNullOrEmpty(logPath);
@bobbyg603
bobbyg603 marked this pull request as draft August 11, 2026 21:39
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.

D2: Native Windows reports attach Player.log even when CapturePlayerLog is false

3 participants