CLI Reference
Synopsis
Section titled “Synopsis”dotsider <assembly.dll|.exe|.wasm> # TUI — interactive assembly/native module explorerdotsider <package.nupkg> # TUI — browse NuGet package contentsdotsider diff <left> <right> # TUI — assembly comparison, or AOT size diff for mstat inputs
dotsider analyze <file> [opts] # CLI — headless analysisdotsider size-check <target> # CLI — AOT size regression report and CI budget gatedotsider sessions <command> # CLI — interact with running instancesdotsider agent <command> # CLI — MCP server and agent skill generationTUI options
Section titled “TUI options”| Option | Description |
|---|---|
-t, --tab <1-8> |
Start on a specific tab |
-n, --min-len <n> |
Minimum raw string length (default: 4) |
-v, --version |
Show version |
-h, --help |
Show help |
dotsider analyze
Section titled “dotsider analyze”Run analysis without the TUI — pipe to other tools, write to files, or output JSON.
Human-readable output escapes terminal controls and Unicode formatting characters recovered from
the analyzed file. The same safe representation is used for stdout, redirected output, and -o
text files; JSON preserves the exact values after decoding.
dotsider analyze MyLib.dll # assembly info (default)dotsider analyze MyLib.dll --types # list type definitionsdotsider analyze MyLib.dll --methods # list method definitionsdotsider analyze MyLib.dll --il Type.Method # disassemble a methoddotsider analyze MyLib.dll --embedded-source Type.Method # print embedded sourcedotsider analyze MyLib.dll --deps # assembly referencesdotsider analyze MyLib.dll --strings # extract stringsdotsider analyze MyLib.dll --fields # list field definitionsdotsider analyze MyLib.dll --size # size breakdowndotsider analyze MyLib.dll --bundle # show single-file bundle manifestdotsider analyze MyLib.dll --json # any of the above as JSONdotsider analyze MyLib.dll --types -o out.txt # write to filedotsider analyze MyApp.exe # apphost .exe → auto-redirects to MyApp.dlldotsider analyze MyApp # single-file bundle → extracts entry assemblydotsider analyze MyAotApp.exe # Native AOT → binary kind, RTR format, importsdotsider analyze MyAotApp.exe --why System.Text.Json.JsonSerializer # AOT dependency chaindotsider analyze MyAotApp.exe --symbols # native symbols with addresses, sizes, and file:linedotsider analyze MyAotApp.exe --disasm 'Program.<Main>$' # disassemble a native function by namedotsider analyze MyAotApp.exe --disasm 0x140001300 # disassemble a native function by addressdotsider analyze dotnet.native.wasm --symbols # SDK Wasm function symbolsdotsider analyze dotnet.native.wasm --disasm 0x1234 # Wasm function body by file/code offsetdotsider analyze dotnet.native.wasm --disasm func:42 # Wasm function body by function indexdotsider analyze WasmConsole.wasm --il WasmCalculator.Add # Webcil app assembly → managed ILIf the file is a native apphost with a companion .dll, analyze auto-redirects. If it’s a self-contained single-file bundle, analyze extracts the entry assembly from the bundle. Both cases print a note to stderr.
If the file is a Native AOT executable (a validated ReadyToRun header with no CLR metadata), the default output adds Kind, RTR Format, Runtime, Imports, R2R, Recovered, and Frozen lines, and JSON output gains binaryKind, nativeAotInfo, readyToRunSections, recoveredTypeCount, and frozenStringCount. --types falls back to the types recovered from the embedded metadata, --strings adds the raw ASCII and UTF-16 scans plus the frozen string literals, since AOT binaries have no metadata string heaps.
NativeFormat recovery is bounded to 1,048,576 encoded handles, 256 relationship levels, 4,096 bytes per name component, and 16,777,216 decoded or composed name characters. For cyclic, malformed, or oversized embedded metadata, --types returns the fully decoded prefix while the other Native AOT analysis remains available.
With the ILC sidecars next to the binary (publish with IlcGenerateMstatFile and IlcGenerateDgmlFile, then copy the .mstat and .codegen.dgml.xml out of obj/.../native/), --size prints the compiler’s own per-assembly breakdown with the binary’s data categories (without an mstat it falls back to the binary’s native symbols), --symbols lists native symbols with their provenance — the platform’s PDB, .dbg, or dSYM, or unwind-data boundaries when none exists, --deps shows the compiled-in assemblies and native import modules, and --why <name> prints the dependency chain that kept a type or method in the binary — root first, one step per line with the compiler’s reason. Names match exactly first, then by unambiguous substring.
Native DWARF materialization from ELF images and dSYM bundles is limited to 256 MiB total per symbol read. Line-table prologues and entry counts are bounded; malformed line metadata omits file-and-line attribution from otherwise readable symbols. Oversized or wholly unreadable DWARF does not abort analysis: --symbols reports corrupt symbol data and uses .eh_frame boundaries when the image contains them.
Native PDB MSF directories and CodeView module ranges are validated before allocation or decoding. A malformed companion PDB reports corrupt symbol data and uses .pdata boundaries when the image provides them.
When portable PDB data is available, default output reports where it came from, and --il includes source spans, local names, and Source Link markers. Use --json when you need the exact URLs. --embedded-source prints source embedded in the PDB. Embedded portable PDBs are limited to 256 MiB after decompression and individual embedded source documents to 16 MiB. Oversized or malformed debug data does not abort assembly analysis; pdbProvenance.kind is invalidEmbeddedPdb when no valid sidecar fallback is available.
--disasm <name-or-0xVA> disassembles one native function of a Native AOT (or other native) binary to the image’s native architecture: x64, Arm64, x86, Arm32/Thumb-2, RISC-V64, LoongArch64, or Wasm32. It resolves call and branch targets to names (call Foo, Foo+0x12, intra-function loc_… labels), RIP-relative loads to the referenced data symbol, and indirect calls through the import table to MODULE!Function. Identify the function by an exact managed name, its raw symbol name, a suffix, or a hex virtual address; an ambiguous name lists the candidates and exits non-zero. --json carries the structured operands and per-instruction metadata. A managed assembly (no native symbols) exits 1. For a ReadyToRun image, --disasm <method> resolves to the method and renders all its code ranges (hot, funclets, cold) as one body.
A ReadyToRun (crossgen2) image keeps its full metadata and adds precompiled native bodies. The default output reports a ReadyToRun line (version, status, architecture, composite/component). --r2r-correlate with no argument prints the precompiled-method stats; with a Type.Method, a 0x06… token, or a 0x… native address it prints the method’s IL beside its native code ranges, resolving call targets through the import tables. Method-map NativeFormat containers share a 1,048,576-unit traversal budget across MethodDef indices, instance buckets, and instance entries; import sections have a separate 1,048,576-slot budget. Malformed or oversized method maps preserve header, section, and managed-metadata output and report correlation as unavailable. Import decoding preserves its complete named prefix when the slot budget is reached. An overloaded name lists the candidates and exits non-zero. A composite *.r2r.dll resolves its component assemblies by name and MVID from the siblings beside it; a component DLL routes its native code to the owner composite. --json carries the structured per-range IL and native arrays.
Raw dotnet.native.wasm modules from a browser-wasm publish open directly. Default output reports a WebAssembly (.NET) block with section, type/table/memory/global, function, code, data, import/export, and symbol-map counts. Structured vectors must fit their containing region and share a 1,048,576-item decoding budget. If a standard section is malformed, output retains the safely decoded prefix and adds a Note with the diagnostic. --symbols lists file-backed Wasm functions named from dotnet.native.js.symbols, the Wasm name section, exports, or func_N fallbacks. --disasm <0xoffset-or-name-or-func:index> decodes a Wasm32 function body, resolves direct calls through the module’s function index, and annotates locals, globals, tables, and indirect-call types from the parsed standard sections. Webcil app assemblies such as WasmConsole.wasm are different: dotsider unwraps their managed metadata, reports a Webcil line, and uses the normal --types, --methods, --il, PDB, and Source Link paths.
| Option | Description |
|---|---|
--types |
List type definitions |
--methods |
List method definitions |
--il <name> |
Disassemble a specific method |
--embedded-source <name> |
Print embedded source for a method |
--deps |
Show assembly references |
--strings |
Extract strings |
-n, --min-len <n> |
Minimum length for raw string extraction (default: 4) |
--fields |
List field definitions |
--size |
Show size breakdown |
--symbols |
List native symbols with provenance (Native AOT, ReadyToRun, Wasm, and native binaries) |
--disasm <name-or-0xVA> |
Disassemble a native or Wasm function |
--why <name> |
Explain why a type or method is in a Native AOT binary |
--r2r-correlate [name-or-0xVA] |
ReadyToRun stats, or a method’s IL beside its precompiled native code |
--bundle |
Show single-file bundle manifest |
--json |
Output as JSON |
-o, --output <file> |
Write output to a file |
dotsider diff
Section titled “dotsider diff”Compares two inputs side by side. The input kinds decide the mode:
- Two managed assemblies open the metadata diff TUI (types, methods, references) — see Diff Mode.
- Two mstat-backed inputs — bare
.mstatsize reports, or Native AOT binaries with mstat sidecars beside them — open the size-diff TUI (Summary + delta treemap). With the global--jsonflag the TUI is skipped and the machine-readable size-diff document prints instead. - A mixed pair (mstat-backed against anything else) is an error and exits 1: the two sides would measure different things.
dotsider diff v1.dll v2.dll # metadata diff TUIdotsider diff before.mstat after.mstat # AOT size-diff TUIdotsider diff bin/v1/publish/app bin/v2/publish/app # same, via mstat sidecarsdotsider diff before.mstat after.mstat --json # headless size-diff document| Option | Description |
|---|---|
-e, --escape-timeout <ms> |
Escape key timeout in milliseconds (default 100) |
--json |
For mstat-backed pairs: print the size-diff JSON document instead of the TUI |
dotsider size-check
Section titled “dotsider size-check”Headless size-regression checking for CI: compares a Native AOT build against a baseline via their mstat size reports and enforces size budgets. See Size Regression for the workflow and pipeline recipes.
dotsider size-check out/pr/app --baseline baseline/app.mstat --top 20dotsider size-check out/pr/app --baseline baseline/app.mstat \ --budget max=25mb --budget growth=1% --budget ns=System.Text.Json:growth=10kbdotsider size-check out/pr/app --baseline baseline/app.mstat \ --format markdown --summary-file "$GITHUB_STEP_SUMMARY"The target and baseline are each a bare .mstat or a Native AOT binary with the sidecar
beside it. Binaries measure file size on disk; a bare .mstat anywhere makes both sides
measure mstat attributable totals — the report always states which basis applied. Namespace
and assembly budgets always measure mstat aggregates, with frozen objects attributed via
their owning type and ownerless bytes (string literals) in an explicit (unattributed)
bucket.
Budgets use the grammar [scope:]limit(,limit)* with scope total (default), ns=<Namespace>
(covers sub-namespaces), or asm=<Assembly>, and limits max=SIZE and growth=SIZE|PERCENT
(sizes like 25mb, 10kb, 4096; 1 kb = 1024). Growth limits need --baseline; max=
works without one. --budget-file adds a JSON document whose entries are spec strings or
objects (name, description, scope, max, growth, severity, topN) — severity: "warning" reports a breach without failing the gate.
| Option | Description |
|---|---|
--baseline <file> |
Baseline binary or .mstat to diff against |
--budget <spec> |
Size budget in the grammar above; repeatable |
--budget-file <file> |
JSON budgets document (string and object entries) |
--top <n> |
Top contributors per section and per violated budget (default 10) |
--why |
Attach ILC dependency chains for top added contributors (needs the target’s DGML sidecar) |
--format <text|json|markdown> |
Output format (default text; --json ≡ --format json) |
--summary-file <file> |
Additionally write the markdown report to a file (e.g. $GITHUB_STEP_SUMMARY) |
-o, --output <file> |
Write output to a file |
| Exit code | Meaning |
|---|---|
| 0 | Report produced; every error-severity budget passed |
| 1 | Usage or input error |
| 2 | An error-severity budget was exceeded |
dotsider sessions
Section titled “dotsider sessions”Interact with running dotsider TUI instances. Each instance exposes a Unix domain socket for programmatic access.
dotsider sessions list # list running instancesdotsider sessions info <pid> # assembly info + current viewdotsider sessions view <pid> # current tab and view statedotsider sessions navigate <pid> <tab> # switch to tab (1-8)dotsider sessions capture <pid> # capture screen as textdotsider sessions trace start <pid> # start tracingdotsider sessions trace start <pid> -- --flag "two words"dotsider sessions trace events <pid> # get JIT, GC, exception eventsdotsider sessions trace counters <pid> # get performance countersdotsider sessions trace output <pid> # get stdout/stderrdotsider sessions trace stop <pid> # stop tracingArguments after trace start <pid> -- are passed as literal process arguments. The
delimiter lets child arguments begin with -; the launcher uses
ProcessStartInfo.ArgumentList.
dotsider agent
Section titled “dotsider agent”MCP server management and agent skill file generation.
dotsider agent mcp # launch the MCP serverdotsider agent init # write ./SKILL.mddotsider agent init --path ./dotsider/SKILL.md # write to an explicit pathdotsider agent init --stdout # print to stdoutBy default, init writes SKILL.md in the current directory. Use --path when your agent expects skills in a specific directory.