Skip to content

Crash reports

Tom_XV edited this page Sep 23, 2026 · 2 revisions

English | 日本語

Experimental. This came in with core 1.3.0 (framework 1.3.0, 2026-09-19).

When the game crashes, whatever happened just before is usually lost. BepInEx's log stops mid-line, and Unity's crash folder has a native stack but no idea which mod was doing what. So the core keeps a short record of each session, and if the game didn't exit cleanly, it turns that record into a report. Everything stays on this computer. Nothing is sent anywhere.

Where the reports are

In the game's folder, under BepInEx/CrashReports/:

What Where
The record of the session being played session.log (and session.1.log when a long session rolled over)
A report after a crash <date>_<time>/, with report.txt, the session record and, when Unity made one, crash.dmp
A memory dump after a freeze <date>_<time>_hang/

You get a report when the game crashed, froze and was closed, or was killed. On Windows it's made as soon as the game closes (see the window below), and elsewhere at the next start. The log says where it is. The last ten reports are kept.

The crash report window (Windows)

On Windows, when the game crashes or freezes, a separate window opens as soon as the game is gone. It's drawn by Windows rather than the game, so it works however the game went down. It shows:

  • What happened, in plain words: a known Direct3D 12 crash (Unity issue UUM-140564), the graphics device that stopped responding, a freeze, a stop without a crash (killed, power loss), or another crash inside Unity.
  • What you can do about it, when there's something you can do.
  • Details: when it happened, the scene, how long the session ran, the last error, the graphics, and where the report is.
  • Open report folder, Copy report (copies report.txt for a bug report) and Close.

The window uses the language chosen in the game (English, Japanese or Chinese, which needs Assets 1.1.1 or later, as Drag'n Wash Localization ships). Otherwise it uses Windows' language. After a clean exit, nothing appears.

The window is a small program, CrashReporter.exe, next to the core's DLL. The core starts it along with the game, and it waits for the game to close. It isn't started under Wine or Proton (Steam Deck, Linux), so there the report is written at the next start. CrashReporter.exe --show <report folder> opens a report again.

Asking for help

  • Attach report.txt (or paste what Copy report copied) to the bug report or issue. It's made to go in public reports, and holds the versions, the mods, the last notes and the native stack.
  • A memory dump (crash.dmp, or the .dmp in a _hang folder) holds part of the game's memory. Share it only privately with whoever investigates, never in a public issue.
  • Framework issues go to TomXV/dragnwash-modframework.

Settings

You'll find these in Options → Mods → Drag'n Wash ModFramework → Settings, in the Diagnostics section (the advanced ones only show after you turn on Show advanced settings at the top of the page):

Setting Config entry Default
Crash reports [Diagnostics] CrashReports on The session record and the reports. Takes effect at the next start.
Crash report window [Diagnostics] CrashReporterWindow on The separate window on Windows. Takes effect at the next start.
Memory dump when the game freezes [Diagnostics] HangDumps on, advanced The freeze watchdog's dump (Windows). Needs Crash reports on.
Trace GPU uploads (Direct3D 12 investigation) [Diagnostics] TraceGpuUploads off, advanced, experimental Adds a note for every GPU upload, for investigating. Needs Crash reports on. Takes effect at the next start.

The Direct3D 12 section has one more: Batch font atlas uploads (Direct3D 12) ([Direct3D12] BatchFontAtlasUploads, on, advanced, takes effect at the next start). See The Direct3D 12 crash.

What is recorded

Notes go into BepInEx/CrashReports/session.log, one line each. Every line is written and flushed straight away, so the last one survives a crash:

04:22:07.528 f18344 main scene loaded 'Wash' (Single)
04:22:07.611 f18351 main unity-error NullReferenceException: ...
04:22:09.002 f18470 main beat 16.7 ms/frame
  • At the start: the framework and Unity versions, the graphics API and card, the screen mode and the launch options, then every loaded mod with its version.
  • Scene loads and unloads, mod reloads, and the language chosen in the game.
  • Unity errors, exceptions and graphics device messages.
  • A heartbeat every 10 seconds (every second while GPU uploads are traced), which shows how long after the last note the game stopped.
  • Notes that mods add (see For mod authors).

A clean exit ends the file with END clean exit. When a long session reaches 4 MB, the file rolls over and the previous part is kept as session.1.log.

The report

At the next start (or on Windows, as soon as the game closes), a session.log without that marker means the game didn't exit cleanly. The report folder BepInEx/CrashReports/<date>_<time>/ then gets:

  • report.txt: when it ended, the versions and mods, the last 40 notes, and the native stack from Unity's own crash folder (%TEMP%/<company>/<product>/Crashes/Crash_*) when one was made within two minutes of the end;
  • session.log (and session.1.log if the session rolled over);
  • crash.dmp: Unity's own memory dump of the crash, copied from its crash folder.

The window and the next start use the same code. Whichever runs first marks the record as reported, so each crash only gets one report.

Memory dumps

A dump is a snapshot of the game process, with every thread's stack and the loaded modules. You open it in a debugger (WinDbg, Visual Studio) together with the game's PDB files (the game ships UnityPlayer_Win64_player_mono_x64.pdb). It tells you something a log can't: where each thread was when things went wrong.

  • For crashes, Unity writes crash.dmp itself, and the report keeps a copy.
  • For freezes, Unity writes nothing when the game hangs, so a watchdog thread does it instead. If the main thread hasn't finished a frame for 15 seconds while the game window is in front, the watchdog writes a minidump of the process (a few MB, Windows) into BepInEx/CrashReports/<date>_<time>_hang/ and notes it in the session record. If the game starts running again, that gets noted too. A game in the background doesn't count, since it may stop running frames on purpose. The watchdog asks Windows which window is in front, so it also catches a game that freezes the moment it comes back to the front.

The Direct3D 12 crash

On Direct3D 12 (the default on Windows), this Unity version can crash on the render thread in D3D12ScratchAllocator::DestroyScratch. It happens when a frame trims the scratch memory that GPU uploads go through (Unity issue UUM-140564). The crash reports showed that these uploads come from the font engines. A window full of new text lays out dozens of labels, and each one uploaded the whole font atlas again. That's what was crashing the Tool window.

Since core 1.3.0, on Direct3D 12 the core uploads each changed font atlas just once, at the end of the frame (Batch font atlas uploads, on). A newly added character may show up blank for that one frame. Other graphics APIs are left alone. GameInfo.FontAtlasUploadsBatched tells you whether the core is doing this.

Trace GPU uploads helps you find any other upload behind a crash. It adds a note for every texture upload and creation, dynamic font and TextMeshPro atlas growth, mesh upload, asset bundle load and released GPU resource, with its size and the mod on the calling stack. It patches Unity methods and walks the stack for each one, so only turn it on when you're investigating. If the game still crashes on Direct3D 12, the workaround is -force-d3d11 in the Steam launch options (see Assets).

For mod authors

CrashReports.Note(MyPlugin.Guid, "load", $"importing {count} textures from {folder}");

CrashReports.Note(ownerGuid, category, message) adds a line to the session record. Notes are cheap, and you can safely add them from any thread. Leave one before something heavy or risky, so if the game crashes right after, the note points at what was going on. Keep them short, and never put personal data in them, because reports are meant to be attached to public bug reports.

Clone this wiki locally