Run: Memory Snapshot Data Tool
A .NET 10 CLI (MemorySnapshotDataTools) that exports a Unity memory snapshot (.snap)
to a DuckDB/SQLite database, then runs SQL to render a self-contained HTML report.
The report is the real product, so the agent path drives the whole pipeline and
screenshots the rendered report with headless Chrome — a CLI run you can look at.
The driver is smoke.sh:
build → export → summary → report → screenshot, with a pass/fail check at each step.
Paths below are relative to the repo root (the directory containing MemorySnapshotDataTools.sln).
Prerequisites
- .NET 10 SDK — required. Verify:
dotnet --version(10.0.103 here). - A
.snapsnapshot — required, and NOT in this repo. Captures are large (16 MB–600+ MB) and user-specific. Get one from the Unity Memory Profiler ("Capture") or point at one you already have. You pass its path to the driver. - Google Chrome — optional, only for the screenshot step. Expected at
/Applications/Google Chrome.app/Contents/MacOS/Google Chrome. Without it the driver still runs and writes the HTML; it just skips the PNG.
Build
dotnet build MemorySnapshotDataTools.sln -c Release
Run (agent path) — the driver
The snapshot is required; supply it as an argument (or via MSDT_SNAP):
.claude/skills/run-memory-snapshot-data-tool/smoke.sh /path/to/snapshot.snap
End-to-end on a 16 MB snapshot this takes ~8s (most of it the build). Exit code 0
means every step passed. Artifacts land in /tmp/msdt-run/:
out.duckdb— the exported databasesummary.txt— thesummarycommand's text outputreport.html— the rendered reportreport.png— headless-Chrome screenshot of the report — open/Read this to see it
Useful env overrides (see the header of smoke.sh):
MSDT_SNAP_DIR=/path/to/captures— auto-pick the smallest.snapin a directory (handy when you don't care which snapshot; smallest = fastest).MSDT_OUT_DIR=/some/dir— write artifacts elsewhere (default/tmp/msdt-run).MSDT_NO_BUILD=1— skip the build (you just built).MSDT_SQLITE=1— also export+report via the SQLite backend. Slow — see Gotchas.
Direct CLI invocation
To run one command without the driver (export/report/summary/batch-export/
multi-report/validate):
dotnet run --project Cli/MemorySnapshotDataTools.Cli.csproj -c Release -- --help
dotnet run --project Cli/MemorySnapshotDataTools.Cli.csproj -c Release -- export /path/to/snapshot.snap /tmp/out.duckdb --validate minimal
dotnet run --project Cli/MemorySnapshotDataTools.Cli.csproj -c Release -- summary /tmp/out.duckdb
dotnet run --project Cli/MemorySnapshotDataTools.Cli.csproj -c Release -- report /tmp/out.duckdb --out /tmp/report.html --title "My Report"
.duckdbextension → DuckDB (default);.db+--destination sqlite→ SQLite.summaryaccepts either a.snapor an exported DB and prints a memory breakdown without writing a database (decoding a raw.snapis slower than reading a DB).report --outis optional; omit it and the tool writes a temp file and tries to open it in a browser (don't rely on the auto-open when running headless — always pass--out).
Run (human path)
dotnet run --project Cli/MemorySnapshotDataTools.Cli.csproj -- report foo.duckdb with no
--out opens the HTML in your default browser. Fine interactively; useless headless — use
the driver or pass --out instead.
Test
dotnet test MemorySnapshotDataTools.sln -c Release --no-build
19 tests, ~0.5s. (Build first, or drop --no-build.)
Gotchas
- SQLite report is ~1000× slower than DuckDB. On the same 16 MB snapshot, the DuckDB
reportquery was 0.1s; the SQLitereportquery was 146s. Export is fast for both (~1s). Default to DuckDB; only setMSDT_SQLITE=1when you specifically need to exercise the SQLite path, and expect it to take minutes. - Snapshots are not in the repo and are huge. The driver fails fast with a clear message if you don't pass one.
reportopens the DB read-only (defense-in-depth, perCLAUDE.md), so reporting can't mutate the database — but a second process holding a write lock on a DuckDB file can still block it. If you hit a DuckDB lock error on a pre-existing.duckdb, a GUI client (e.g. DataGrip) probably has it open — close it rather than copying the file. The driver sidesteps this by exporting a fresh DB into/tmp/msdt-run.- CLI exit codes are meaningful:
0success,1bad args / file not found,2cancelled (Ctrl-C),3validation/error (forvalidate). The driver asserts on them. - The built CLI lives in a RID-specific folder (
Cli/bin/Release/net10.0/osx-arm64/). The driver globs forMemorySnapshotDataTools.dllso it doesn't hard-code the RID.
Troubleshooting
SMOKE FAIL: No .snap provided— pass a snapshot path, or setMSDT_SNAP/MSDT_SNAP_DIR.SMOKE FAIL: CLI dll not found under Cli/bin/Release— you setMSDT_NO_BUILD=1without having built. Build first, or unset it.WARN: screenshot not produced/Chrome not found— Chrome isn't at the expected path; the HTML is still inMSDT_OUT_DIR. Open it in any browser.