Trigger On
- the user mentions
pvanalyze, PerfView-style CLI trace analysis, or cross-platform.nettraceinspection - the task starts from an existing
.nettracefile and needs readable terminal or JSON output - an agent or CI workflow needs GC, JIT, CPU stack, allocation, event, exception, timeline, or call-tree summaries
- SpeedScope export is useful but the source artifact is a
.nettrace
Use dotnet-trace-collect or profiling first when the task is mostly about collecting the trace. Use pvanalyze once a trace artifact exists or when the user wants the specific command surface.
Workflow
- Confirm the trace path and whether it was collected with the events needed for the question.
- Run
pvanalyze info <trace.nettrace>first to verify the file opens and contains the expected processes. - Pick one focused analysis command:
gcstatsfor GC count, heap size, pause, and GC timeline questionsallocfor allocation-by-type questionsdatasfor Dynamic Adaptation To Application Sizes heap-count tuningjitstatsfor JIT compilation costcpustacksfor top CPU methods, module grouping, namespace grouping, or SpeedScope exportcalltreefor hot paths and caller/callee explorationeventsfor provider, event type, payload, PID, or TID filteringexceptionsfor thrown exception summaries and detailstimelineorsnapshotwhen an agent needs time-bucketed context
- Prefer
--format jsonwhen another tool or agent will consume the output. - Add
--fromand--toonly after the baseline command confirms the interesting time window. - Use
pvanalyze clean <trace-or-directory>when generated.pvanalyze.etlxcache files should be removed.
Current Upstream Notes
- The upstream README still positions
pvanalyzeas a cross-platform.nettraceanalyzer and explicitly says--helpplus the README are the intended agent context rather than a separate upstreamSKILL.mdorAGENTS.md. - Keep this catalog skill focused on practical command selection and trace prerequisites. Do not add pvanalyze as a broad diagnostics replacement for trace collection, counters, dumps, or Microsoft-only tooling.
Install
The upstream README documents two install paths:
# .NET 10+ one-shot execution path
dnx pvanalyze
# Global tool path
dotnet tool install --global pvanalyze
If the NuGet package is not resolvable in the current environment, build or pack from source:
git clone https://github.com/adityamandaleeka/pvanalyze
cd pvanalyze
dotnet build -c Release
dotnet run -c Release -- info ./trace.nettrace
The source project is configured as a .NET tool with PackageId pvanalyze, ToolCommandName pvanalyze, and VersionPrefix 0.1.0.
Install trace collection support when you need to create the input artifact:
dotnet tool install --global dotnet-trace
dotnet-trace --version
pvanalyze --help
Practical Usage
Read trace metadata and GC signal
pvanalyze info ./trace.nettrace
pvanalyze gcstats ./trace.nettrace --format json
pvanalyze gcstats ./trace.nettrace --timeline --longest 5
pvanalyze gcstats ./trace.nettrace --from 1000 --to 2000 --timeline --format json
Write CPU outputs for review
pvanalyze cpustacks ./trace.nettrace --top 20
pvanalyze cpustacks ./trace.nettrace --group-by module --top 10 --format json
pvanalyze cpustacks ./trace.nettrace --format speedscope --output ./trace.speedscope.json
Drill into events, exceptions, and call trees
pvanalyze events ./trace.nettrace --list --format json
pvanalyze events ./trace.nettrace --provider DotNETRuntime --type GCStart --limit 50
pvanalyze exceptions ./trace.nettrace --type NullReference --format json
pvanalyze calltree ./trace.nettrace --hot-path --depth 5 --format json
pvanalyze calltree ./trace.nettrace --caller-callee "Serialize"
Collect traces with required event detail
General trace:
dotnet-trace collect --process-id <PID> --output ./trace.nettrace
dotnet-trace collect -- dotnet run -c Release
Allocation analysis requires allocation events:
dotnet-trace collect --providers "Microsoft-Windows-DotNETRuntime:0x200001:5" -- dotnet run -c Release
pvanalyze alloc ./trace.nettrace --group-by type --top 20 --format json
DATAS analysis requires .NET 9+ DATAS events and verbose GC runtime events:
DOTNET_GCDynamicAdaptationMode=1 dotnet-trace collect -p <PID> --providers "Microsoft-Windows-DotNETRuntime:0x4C14FCCBD:5"
pvanalyze datas ./trace.nettrace --changes-only --format json
Option Patterns
- Use
--process <name>ongcstats,jitstats,alloc, ordataswhen a trace includes multiple .NET processes. - Use
--from <ms>and--to <ms>for GC, CPU, allocation, event, exception, timeline, and call-tree time windows. - Use
--format jsonfor automation and--format textfor human terminal review. - Use
cpustacks --group-by method|module|namespaceand--inclusiveto change CPU aggregation. - Use
calltree --hot-path,--caller-callee <method>,--depth <n>, and--min-percent <n>to keep stack output focused. - Use
timeline --lanes gc,cpu,exceptions,alloc,jit,events --buckets <n>for a compact multi-signal view. - Use
snapshot --at <ms> --window <ms>when the question is "what was happening around this timestamp?"
Constraints
pvanalyzeanalyzes trace artifacts; it does not replacedotnet-tracefor collection.- CPU stacks, allocations, DATAS, exceptions, and event filters only work when the trace contains the required events.
- The tool converts
.nettraceto a sibling.pvanalyze.etlxcache for repeated reads; this is useful but can surprise clean working directories. - SpeedScope output comes from
cpustacks; use SpeedScope or another viewer for interactive flame graph inspection. - The source currently targets
net8.0; the README also documentsdnx pvanalyzeas a .NET 10+ path. - If the global tool package is not available yet, use the source build path and record that in the investigation notes.
Deliver
- the exact
dotnet-trace collectcommand used or needed to capture the right events - the focused
pvanalyzecommand and output format - the relevant process, time window, provider, event type, or method filter
- any generated files such as
.speedscope.jsonor.pvanalyze.etlxcache paths that matter for follow-up
Validate
pvanalyze --helpordotnet run -c Release -- --helpsucceedsdotnet-trace --versionsucceeds when collection is part of the workflowpvanalyze info <trace.nettrace>reads the trace before deeper analysis begins- JSON output parses when
--format jsonis used pvanalyze clean <trace-or-directory>removes cache files when cache cleanup is required
References
- overview.md - source links, installation model, and tool positioning
- commands.md - command matrix, collection recipes, and option selection