Skip to content

Commit 6ff474a

Browse files
agockesbomerelinor-funggewarren
authored
Reword and rearrange Native AOT docs (#36885)
This change mostly moves sections in the AOT docs around to put our recommended features near the top, and the rarer options near the bottom. Co-authored-by: Sven Boemer <[email protected]> Co-authored-by: Elinor Fung <[email protected]> Co-authored-by: Genevieve Warren <[email protected]>
1 parent 44ed085 commit 6ff474a

File tree

15 files changed

+115
-104
lines changed

15 files changed

+115
-104
lines changed
Lines changed: 50 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,70 +1,81 @@
11
---
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
44
author: lakshanf
55
ms.author: lakshanf
66
ms.date: 08/07/2023
77
---
8-
# Diagnostics in native AOT applications
98

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
1110

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.
1312

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
1514

16-
### Trimming as a first-class feature
15+
The following table summarizes diagnostic features supported for Native AOT deployments:
1716

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> |
1924

20-
### Importance of the symbol file
25+
## Observability and telemetry
2126

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`.
2328

24-
### Application type
29+
```xml
30+
<PropertyGroup>
31+
<EventSourceSupport>true</EventSourceSupport>
32+
</PropertyGroup>
33+
```
2534

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.
2736

28-
## .NET 8 native AOT diagnostic support
37+
## Development-time diagnostics
2938

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.
3147

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
3949

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.
4151

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).
4353

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.
4555

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.
4758

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
5362

54-
[OpenTelemetry](../../diagnostics/observability-with-otel.md) is expected to support native AOT in the key three pillars of observability&mdash;logging, tracing, and metrics&mdash;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).
5564

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#).
5766

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
5970

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.
6172

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).
6374

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
6576

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.
6778

68-
### Heap analysis
79+
## Heap analysis
6980

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.

docs/core/deploying/native-aot/fixing-warnings.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
---
22
title: Introduction to AOT warnings
3-
description: Learn why warnings might be produced when publishing an application as native AOT, how to address them, and how to make the application "AOT compatible."
3+
description: Learn why warnings might be produced when publishing an application as Native AOT, how to address them, and how to make the application "AOT compatible."
44
author: MichalStrehovsky
55
ms.author: michals
66
ms.date: 09/06/2022
77
---
88
# Introduction to AOT warnings
99

10-
When publishing your application as native AOT, the build process produces all the native code and data structures required to support the application at run time. This is different from non-native deployments, which execute the application from formats that describe the application in abstract terms (a program for a virtual machine) and create native representations on demand at run time.
10+
When publishing your application as Native AOT, the build process produces all the native code and data structures required to support the application at run time. This is different from non-native deployments, which execute the application from formats that describe the application in abstract terms (a program for a virtual machine) and create native representations on demand at run time.
1111

1212
The abstract representations of program parts don't have a one-to-one mapping to native representation. For example, the abstract description of the generic `List<T>.Add` method maps to potentially infinite native method bodies that need to be specialized for the given `T` (for example, `List<int>.Add` and `List<double>.Add`).
1313

1414
Because the relationship of abstract code to native code is not one-to-one, the build process needs to create a complete list of native code bodies and data structures at build time. It can be difficult to create this list at build time for some of the .NET APIs. If the API is used in a way that wasn't anticipated at build time, an exception will be thrown at run time.
1515

16-
To prevent changes in behavior when deploying as native AOT, the .NET SDK provides static analysis of AOT compatibility through "AOT warnings." AOT warnings are produced when the build finds code that may not be compatible with AOT. Code that's not AOT-compatible may produce behavioral changes or even crashes in an application after it's been built as native AOT. Ideally, all applications that use native AOT should have no AOT warnings. If there are any AOT warnings, ensure there are no behavior changes by thoroughly testing your app after building as native AOT.
16+
To prevent changes in behavior when deploying as Native AOT, the .NET SDK provides static analysis of AOT compatibility through "AOT warnings." AOT warnings are produced when the build finds code that may not be compatible with AOT. Code that's not AOT-compatible may produce behavioral changes or even crashes in an application after it's been built as Native AOT. Ideally, all applications that use Native AOT should have no AOT warnings. If there are any AOT warnings, ensure there are no behavior changes by thoroughly testing your app after building as Native AOT.
1717

1818
## Examples of AOT warnings
1919

@@ -30,9 +30,9 @@ while (true)
3030
struct GenericType<T> { }
3131
```
3232

33-
While the above program is not very useful, it represents an extreme case that requires an infinite number of generic types to be created when building the application as native AOT. Without native AOT, the program would run until it runs out of memory. With native AOT, we would not be able to even build it if we were to generate all the necessary types (the infinite number of them).
33+
While the above program is not very useful, it represents an extreme case that requires an infinite number of generic types to be created when building the application as Native AOT. Without Native AOT, the program would run until it runs out of memory. With Native AOT, we would not be able to even build it if we were to generate all the necessary types (the infinite number of them).
3434

35-
In this case, native AOT build issues the following warning on the `MakeGenericType` line:
35+
In this case, Native AOT build issues the following warning on the `MakeGenericType` line:
3636

3737
```
3838
AOT analysis warning IL3050: Program.<Main>$(String[]): Using member 'System.Type.MakeGenericType(Type[])' which has 'RequiresDynamicCodeAttribute' can break functionality when AOT compiling. The native code for this instantiation might not be available at runtime.
@@ -42,7 +42,7 @@ At run time, the application will indeed throw an exception from the `MakeGeneri
4242

4343
## React to AOT warnings
4444

45-
The AOT warnings are meant to bring predictability to native AOT builds. A majority of AOT warnings are about possible run-time exception in situations when native code wasn't generated to support the scenario. The broadest category is `RequiresDynamicCodeAttribute`.
45+
The AOT warnings are meant to bring predictability to Native AOT builds. A majority of AOT warnings are about possible run-time exception in situations when native code wasn't generated to support the scenario. The broadest category is `RequiresDynamicCodeAttribute`.
4646

4747
### RequiresDynamicCode
4848

@@ -60,7 +60,7 @@ void TestMethod()
6060
}
6161
```
6262

63-
There aren't many workarounds for `RequiresDynamicCode`. The best fix is to avoid calling the method at all when building as native AOT and use something else that's AOT compatible. If you're writing a library and it's not in your control whether or not to call the method, you can also add `RequiresDynamicCode` to your own method. This will annotate your method as not AOT compatible. Adding `RequiresDynamicCode` silences all AOT warnings in the annotated method but will produce a warning whenever someone else calls it. For this reason, it's mostly useful to library authors to "bubble up" the warning to a public API.
63+
There aren't many workarounds for `RequiresDynamicCode`. The best fix is to avoid calling the method at all when building as Native AOT and use something else that's AOT compatible. If you're writing a library and it's not in your control whether or not to call the method, you can also add `RequiresDynamicCode` to your own method. This will annotate your method as not AOT compatible. Adding `RequiresDynamicCode` silences all AOT warnings in the annotated method but will produce a warning whenever someone else calls it. For this reason, it's mostly useful to library authors to "bubble up" the warning to a public API.
6464

6565
If you can somehow determine that the call is safe, and all native code will be available at run time, you can also suppress the warning using <xref:System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute>. For example:
6666

0 commit comments

Comments
 (0)