Skip to content

Native AOT / self-contained publish profile (blocked on TraceEvent AOT compatibility) #12

Description

@JeremyKuhne

Summary

Offer a Native AOT (and/or self-contained, single-file) publish profile for
filtrace - primarily for the MCP server (KlutzyNinja.Filtrace.Mcp), and
secondarily for the CLI (KlutzyNinja.Filtrace). This is blocked on an
external dependency
becoming AOT/trim-clean; this issue captures the dependency
need and tracks the upstream work so we can act when it lands.

This is the deferred "AOT / self-contained publish profiles" item from
docs/implementation-plan.md.

Motivation

  • MCP server cold start. The stdio server is launched on demand (dnx KlutzyNinja.Filtrace.Mcp). Native AOT would cut startup latency and working
    set for every agent tool call, and remove the shared-runtime acquisition step.
  • Self-contained distribution. A self-contained / single-file CLI runs with
    no .NET runtime prerequisite on the host - friendlier for CI agents and
    one-off use.
  • Smaller, hermetic deploy. AOT trims to just what we use and removes the
    reflection surface.

Current state (intentionally framework-dependent)

Both packages are framework-dependent today - no RuntimeIdentifiers, no
SelfContained, no PublishAot. The MCP project says so explicitly
(src/Filtrace.Mcp/Filtrace.Mcp.csproj):

Framework-dependent (no RuntimeIdentifiers or SelfContained): dnx supplies the
.NET 10 runtime, and the trace-reading dependency (TraceEvent) is not yet
trim/AOT/single-file clean
, so per-RID self-contained packaging stays a
deliberate, separately-validated follow-up.

The dependency need (the blocker)

Microsoft.Diagnostics.Tracing.TraceEvent (currently pinned at 3.2.3 in
Directory.Packages.props) is our trace
parsing/analysis core, and it is not AOT- or trim-compatible:

  • It targets netstandard2.0, which is not annotated for trimming/AOT, so trim
    warnings are not even surfaced without a multi-targeted build.
  • Its dynamic event-payload parsing uses reflection (System.Type,
    Type.GetType()), and parts use reflection-based serialization - both
    categorically unsafe under trimming/AOT.

Until TraceEvent ships an AOT/trim-compatible build, filtrace cannot produce a
warning-clean AOT or trimmed self-contained binary, because the analysis path
runs straight through TraceEvent.

Upstream tracking

There is no dedicated issue in microsoft/perfview for AOT (an issue search
returns none). The canonical upstream artifact is an open but stalled PR:

What that PR does:

  • Adds a net8.0 target with <IsAotCompatible> and PolySharp (attribute
    polyfills only, build-time).
  • Replaces the System.Type-based dynamic payload parsing with a FetchType
    enum + switch statements, removing reflection from the hot deserialization
    path (also a perf and security win - no Type.GetType() on untrusted input).
  • Adds trim/AOT annotations ([RequiresUnreferencedCode],
    [DynamicallyAccessedMembers], [SupportedOSPlatform("windows")]) and a
    trim-time feature switch.
  • @agocke reports that after the TraceEvent fix, dotnet-gcdump "just works"
    under Native AOT.

Why it is stalled (as of 2026):

  • The TraceEvent maintainer (@brianrob) has reservations about long-term cost: a
    new TFM to maintain, an added AOT row in the test matrix, and behavior
    differences across runtimes; he wants an "AOT-able subset" approach rather than
    "everything available, some behavior differs."
  • @noahfalk frames NativeAOT for the diagnostics tools as a long-term goal that
    has not been high enough priority to staff.
  • The PR has no approving review yet, and by April 2026 @agocke had floated
    moving TraceEvent out of the perfview repo to reduce review bottlenecks.

Acceptance criteria (when unblocked)

When a trim/AOT-compatible TraceEvent is available (a released package, or a
pinned build of microsoft/perfview#2251):

  • Add a per-RID self-contained + PublishAot profile for
    KlutzyNinja.Filtrace.Mcp (and evaluate the same for the CLI).
  • Build is trim/AOT-warning clean (treat trim/AOT warnings as errors in
    that profile).
  • Verify the native ETW support files (KernelTraceControl.dll /
    msdia140.dll, amd64/arm64/x86) still resolve at runtime under the
    self-contained/AOT layout on Windows.
  • Keep the framework-dependent packages as the default artifact; ship AOT /
    self-contained as additional per-RID outputs, not a replacement.
  • Re-validate the full analysis surface (CPU / alloc / thread-time / GC / JIT
    / exceptions, .nettrace + .etl + speedscope) against the AOT binary,
    since AOT behavior can differ from JIT.

Links

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions