|
1 | 1 | --- |
2 | | -title: AOT diagnostics |
3 | | -description: Learn about diagnostics in native AOT applications |
| 2 | +title: Diagnostics and instrumentation |
| 3 | +description: Learn about diagnostics in Native AOT applications |
4 | 4 | author: lakshanf |
5 | 5 | ms.author: lakshanf |
6 | 6 | ms.date: 08/07/2023 |
7 | 7 | --- |
8 | | -# Diagnostics in native AOT applications |
9 | 8 |
|
10 | | -The long-term goal for native AOT application diagnostics is to provide the rich diagnostic experience that developers expect out of a .NET application. The .NET diagnostic experience was built over multiple releases, and a critical part of that journey was customer feedback. Native AOT diagnostics will follow a similar path where the right diagnostic experience is built from prioritized customer feedback in multiple releases. |
| 9 | +# Diagnostics and instrumentation |
11 | 10 |
|
12 | | -## Native AOT application features |
| 11 | +Native AOT shares some, but not all, diagnostics and instrumentation capabilities with CoreCLR. Because of CoreCLR's rich selection of diagnostic utilities, it's sometimes appropriate to diagnose and debug problems in CoreCLR. Apps that are [trim-compatible](../trimming/prepare-libraries-for-trimming.md) should not have behavioral differences, so investigations often apply to both runtimes. Nonetheless, some information can only be gathered after publishing, so Native AOT also provides post-publish diagnostic tooling. |
13 | 12 |
|
14 | | -Native AOT applications have the following characteristics that are important to keep in mind in diagnostic scenarios. |
| 13 | +## .NET 8 Native AOT diagnostic support |
15 | 14 |
|
16 | | -### Trimming as a first-class feature |
| 15 | +The following table summarizes diagnostic features supported for Native AOT deployments: |
17 | 16 |
|
18 | | -Unused code in a native AOT application is stripped out of the final binary. Any unbounded reflection used by the application, including its dependent libraries, is trimmed. The native AOT compiler will generate warnings in such cases, and it's critical that these warnings are fixed. For example, if you suppress any warnings without careful analysis, it can lead to hard-to-debug production failures. |
| 17 | +| Feature | Fully supported | Partially supported | Not supported | |
| 18 | +| - | - | - | - | |
| 19 | +| [Observability and telemetry](#observability-and-telemetry) | | <span aria-hidden="true">✔️</span><span class="visually-hidden">Partially supported</span> | | |
| 20 | +| [Development-time diagnostics](#development-time-diagnostics) | <span aria-hidden="true">✔️</span><span class="visually-hidden">Fully supported</span> | | | |
| 21 | +| [Native debugging](#native-debugging) | | <span aria-hidden="true">✔️</span><span class="visually-hidden">Partially supported</span> | | |
| 22 | +| [CPU Profiling](#cpu-profiling) | | <span aria-hidden="true">✔️</span><span class="visually-hidden">Partially supported</span> | | |
| 23 | +| [Heap analysis](#heap-analysis) | | | <span aria-hidden="true">❌</span><span class="visually-hidden">Not supported</span> | |
19 | 24 |
|
20 | | -### Importance of the symbol file |
| 25 | +## Observability and telemetry |
21 | 26 |
|
22 | | -In native AOT, symbol-file-dependent diagnostics (such as debugging [PerfView](https://github.com/microsoft/perfview) callstacks) don't work at all unless the diagnostic tool has access to the monolithic PDB that was generated when the application was compiled. In .NET, symbol-file-dependent diagnostics generally work just fine, or even great, even if the diagnostic tool has no access to any PDBs that were generated when the application was compiled. That is, symbols for the .NET runtime and the .NET libraries can be pulled from symbol servers, and diagnostic tools can still show function names and accurate call stacks even without access to the compile-time PDBs. |
| 27 | +As of .NET 8, the Native AOT runtime supports [EventPipe](../../diagnostics/eventpipe.md), which is the base layer used by many logging and tracing libraries. You can interface with EventPipe directly through APIs like `EventSource.WriteEvent` or you can use libraries built on top, like [OpenTelemetry](../../diagnostics/observability-with-otel.md). EventPipe support also allows .NET diagnostic tools like [dotnet-trace](../../diagnostics/dotnet-trace.md), [dotnet-counter](../../diagnostics/dotnet-counters.md), and [dotnet-monitor](../../diagnostics/dotnet-monitor.md) to work seamlessly with Native AOT or CoreCLR applications. EventPipe is an optional component in Native AOT. To include EventPipe support, set the `EventSourceSupport` MSBuild property to `true`. |
23 | 28 |
|
24 | | -### Application type |
| 29 | +```xml |
| 30 | +<PropertyGroup> |
| 31 | + <EventSourceSupport>true</EventSourceSupport> |
| 32 | +</PropertyGroup> |
| 33 | +``` |
25 | 34 |
|
26 | | -Native AOT apps aren't typical managed applications (for example, no JIT). They also aren't typical native applications (for example, they have full GC support). The intent for diagnostics is to meet a reasonable expectation of a product in the .NET family, but the experience should also feel familiar to those using production diagnostics on C++ apps. |
| 35 | +Native AOT provides partial support for some [well-known event providers](../../diagnostics/well-known-event-providers.md). Not all [runtime events](../../../fundamentals/diagnostics/runtime-events.md) are supported in Native AOT. |
27 | 36 |
|
28 | | -## .NET 8 native AOT diagnostic support |
| 37 | +## Development-time diagnostics |
29 | 38 |
|
30 | | -The following table summarizes diagnostic features supported for native AOT deployments: |
| 39 | +The .NET CLI tooling (`dotnet` SDK) and Visual Studio offer separate commands for `build` and |
| 40 | +`publish`. `build` (or `Start` in Visual Studio) uses CoreCLR. Only `publish` creates a |
| 41 | +Native AOT application. Publishing your app as Native AOT produces an app that has been |
| 42 | +ahead-of-time (AOT) compiled to native code. As mentioned previously, this means that not all diagnostic |
| 43 | +tools will work seamlessly with published Native AOT applications in .NET 8. However, all .NET |
| 44 | +diagnostic tools are available for developers during the application building stage. We recommend |
| 45 | +developing, debugging, and testing the applications as usual and publishing the working app with Native |
| 46 | +AOT as one of the last steps. |
31 | 47 |
|
32 | | -| Feature | Fully supported | Partially supported | Not supported | |
33 | | -| - | - | - | - | |
34 | | -| Build (Inner dev loop) diagnostics | <span aria-hidden="true">✔️</span><span class="visually-hidden">Fully supported</span> | | | |
35 | | -| Observability | | <span aria-hidden="true">✔️</span><span class="visually-hidden">Partially supported</span> | | |
36 | | -| CPU Profiling | | <span aria-hidden="true">✔️</span><span class="visually-hidden">Partially supported</span> | | |
37 | | -| Production debugging | | <span aria-hidden="true">✔️</span><span class="visually-hidden">Partially supported</span> | | |
38 | | -| Heap analysis | | | <span aria-hidden="true">❌</span><span class="visually-hidden">Not supported</span> | |
| 48 | +## Native debugging |
39 | 49 |
|
40 | | -### Build (inner dev loop) diagnostics |
| 50 | +When you run your app during development, like inside Visual Studio, or with `dotnet run`, `dotnet build`, or `dotnet test`, it runs on CoreCLR by default. However, if `PublishAot` is present in the project file, the behavior should be the same between CoreCLR and Native AOT. This allows you to use the standard Visual Studio managed debugging engine for development and testing. |
41 | 51 |
|
42 | | -Publishing your app as native AOT produces an app that has been ahead-of-time (AOT) compiled to native code. As mentioned above, this means that not all diagnostic tools will work seamlessly with published native AOT applications in .NET 8. However, all .NET diagnostic tools are available for developers during the application building stage. We recommend developing, debugging, and testing the applications as usual and publish the working app with native AOT as one of the last steps. |
| 52 | +After publishing, Native AOT applications are true native binaries. The managed debugger will not work on them. However, the Native AOT compiler generates fully native executable files that can be debugged by native debuggers on your platform of choice (for example, WinDbg or Visual Studio on Windows and gdb or lldb on Unix-like systems). |
43 | 53 |
|
44 | | -### Observability |
| 54 | +The Native AOT compiler generates information about line numbers, types, locals, and parameters. The native debugger lets you inspect stack trace and variables, step into or over source lines, or set line breakpoints. |
45 | 55 |
|
46 | | -The native AOT runtime supports [EventPipe](../../diagnostics/eventpipe.md), which allows native AOT apps to easily trace their applications. EventPipe support also allows most .NET diagnostic tools, like [dotnet-trace](../../diagnostics/dotnet-trace.md), [dotnet-counter](../../diagnostics/dotnet-counters.md), and [dotnet-monitor](../../diagnostics/dotnet-monitor.md), to work seamlessly with native AOT applications. EventPipe is an optional component in native AOT. To include EventPipe support, set the `EventSourceSupport` MSBuild property to `true`. |
| 56 | +To debug managed exceptions, set a breakpoint on the `RhThrowEx` method, which is called whenever a managed exception is thrown. The exception is stored in the `rcx` or `x0` register. If your debugger supports viewing C++ objects, you can cast |
| 57 | +the register to `S_P_CoreLib_System_Exception*` to see more information about the exception. |
47 | 58 |
|
48 | | -```xml |
49 | | -<PropertyGroup> |
50 | | - <EventSourceSupport>true</EventSourceSupport> |
51 | | -</PropertyGroup> |
52 | | -``` |
| 59 | +Collecting a [dump](../../diagnostics/dumps.md) file for a Native AOT application involves some manual steps in .NET 8. |
| 60 | + |
| 61 | +### Visual Studio-specific notes |
53 | 62 |
|
54 | | -[OpenTelemetry](../../diagnostics/observability-with-otel.md) is expected to support native AOT in the key three pillars of observability—logging, tracing, and metrics—in .NET 8. Native AOT provides partial support for some [well-known event providers](../../diagnostics/well-known-event-providers.md). Not all [runtime events](../../../fundamentals/diagnostics/runtime-events.md) are supported in native AOT. |
| 63 | +You can launch a Native AOT-compiled executable under the Visual Studio debugger by opening it in the Visual Studio IDE. You will need to [open the executable itself in Visual Studio](/visualstudio/debugger/how-to-debug-an-executable-not-part-of-a-visual-studio-solution). |
55 | 64 |
|
56 | | -### CPU profiling |
| 65 | +To set a breakpoint that breaks whenever an exception is thrown, choose the **Breakpoints** option from the **Debug > Windows** menu. In the new window, select **New > Function** breakpoint. Specify `RhThrowEx` as the Function Name and leave the Language option at **All Languages** (don't select C#). |
57 | 66 |
|
58 | | -Platform-specific tools like [PerfView](https://github.com/microsoft/perfview) and [Perf](https://perf.wiki.kernel.org/index.php/Main_Page) can be used to collect CPU samples of a native AOT application. |
| 67 | +To see what exception was thrown, start debugging (**Debug > Start Debugging** or <kbd>F5</kbd>), open the Watch window (**Debug > Windows > Watch**), and add following expression as one of the watches: `(S_P_CoreLib_System_Exception*)@rcx`. This mechanism leverages the fact that at the time `RhThrowEx` is called, the x64 CPU register RCX contains the thrown exception. You can also paste the expression into the Immediate window; the syntax is the same as for watches. |
| 68 | + |
| 69 | +### Importance of the symbol file |
59 | 70 |
|
60 | | -### Production debugging |
| 71 | +When publishing, the Native AOT compiler produces both an executable and a symbol file. Native debugging, and related activities like profiling, require access to the native symbol file. If this file is not present, you may have degraded or broken results. |
61 | 72 |
|
62 | | -Typical production debugging scenarios are done through logging and tracing and are [supported](#observability) in native AOT. Low-level debugging, using platform debuggers like WinDbg or Visual Studio on Windows, and gdb or lldb on Unix-like systems, can be used in native AOT. For this case, it's critical that the corresponding symbol file for the application is available. |
| 73 | +For information about the name and location of the symbol file, see [Native debug information](index.md#native-aot-deployment). |
63 | 74 |
|
64 | | -The native AOT compiler generates information about line numbers, types, locals, and parameters. The native debugger allows inspecting stack trace and variables, stepping into or over source lines, or setting line breakpoints. |
| 75 | +## CPU profiling |
65 | 76 |
|
66 | | -Collecting a [dump](../../diagnostics/dumps.md) file for a native AOT application involves some manual steps in .NET 8. |
| 77 | +Platform-specific tools like [PerfView](https://github.com/microsoft/perfview) and [Perf](https://perf.wiki.kernel.org/index.php/Main_Page) can be used to collect CPU samples of a Native AOT application. |
67 | 78 |
|
68 | | -### Heap analysis |
| 79 | +## Heap analysis |
69 | 80 |
|
70 | | -Managed heap analysis is not currently supported in native AOT. Heap analysis tools like [dotnet-gcdump](../../diagnostics/dotnet-gcdump.md), [PerfView](https://github.com/microsoft/perfview), and Visual Studio heap analysis tools don't work in native AOT in .NET 8. |
| 81 | +Managed heap analysis is not currently supported in Native AOT. Heap analysis tools like [dotnet-gcdump](../../diagnostics/dotnet-gcdump.md), [PerfView](https://github.com/microsoft/perfview), and Visual Studio heap analysis tools don't work in Native AOT in .NET 8. |
0 commit comments