Skip to content

Commit af3107c

Browse files
authored
Document breaking change: Code coverage EnableDynamicNativeInstrumentation defaults to false in .NET 10 (#49620)
1 parent 8561836 commit af3107c

File tree

3 files changed

+69
-0
lines changed

3 files changed

+69
-0
lines changed

docs/core/compatibility/10.0.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ If you're migrating an app to .NET 10, the breaking changes listed here might af
117117
| [.NET CLI `--interactive` defaults to `true` in user scenarios](sdk/10.0/dotnet-cli-interactive.md) | Behavioral change | Preview 3 |
118118
| [`dotnet` CLI commands log non-command-relevant data to stderr](sdk/10.0/dotnet-cli-stderr-output.md) | Behavioral change | RC 2 |
119119
| [.NET tool packaging creates RuntimeIdentifier-specific tool packages](sdk/10.0/dotnet-tool-pack-publish.md) | Behavioral change | Preview 6 |
120+
| [Code coverage EnableDynamicNativeInstrumentation defaults to false](sdk/10.0/code-coverage-dynamic-native-instrumentation.md) | Behavioral change | GA |
120121
| [Default workload configuration from 'loose manifests' to 'workload sets' mode](sdk/10.0/default-workload-config.md) | Behavioral change | Preview 2 |
121122
| [dnx.ps1 file is no longer included in .NET SDK](sdk/10.0/dnx-ps1-removed.md) | Source incompatible | GA |
122123
| [Double quotes in file-level directives are disallowed](sdk/10.0/file-level-directive-double-quotes.md) | Source incompatible | GA |
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
---
2+
title: "Breaking change - Code coverage EnableDynamicNativeInstrumentation defaults to false"
3+
description: "Learn about the breaking change in .NET 10 where dynamic native instrumentation is disabled by default when collecting code coverage."
4+
ms.date: 11/05/2025
5+
ai-usage: ai-assisted
6+
ms.custom: https://github.com/dotnet/docs/issues/49376
7+
---
8+
9+
# Code coverage EnableDynamicNativeInstrumentation defaults to false
10+
11+
Running `dotnet test --collect:"Code Coverage"` now disables dynamic native instrumentation by default. This change affects how code coverage is collected from native code. It doesn't affect how code coverage is collected from managed code.
12+
13+
## Version introduced
14+
15+
.NET 10 GA
16+
17+
## Previous behavior
18+
19+
Previously, dynamic native instrumentation was enabled by default and used a fallback for native modules when static native instrumentation couldn't be used. This behavior is described in [Static and dynamic native instrumentation](/visualstudio/test/customizing-code-coverage-analysis?view=vs-2022#static-and-dynamic-native-instrumentation).
20+
21+
```bash
22+
dotnet test --collect:"Code Coverage"
23+
# Dynamic native instrumentation was enabled by default
24+
```
25+
26+
## New behavior
27+
28+
Starting in .NET 10, dynamic native instrumentation is disabled by default. The `<EnableDynamicNativeInstrumentation>false</EnableDynamicNativeInstrumentation>` option is set by default from `dotnet test` and `vstest`. If you explicitly set the option in a *runsettings* file, it isn't overridden.
29+
30+
```bash
31+
dotnet test --collect:"Code Coverage"
32+
# Dynamic native instrumentation is now disabled by default
33+
```
34+
35+
You can re-enable dynamic native instrumentation by setting `<EnableDynamicNativeInstrumentation>true</EnableDynamicNativeInstrumentation>` in your *runsettings* file. However, when you do so, it might fail with "The code execution cannot proceed because covrun64.dll was not found." This error can also happen for `covrun32.dll` in a 32-bit process.
36+
37+
## Type of breaking change
38+
39+
This change is a [behavioral change](../../categories.md#behavioral-change).
40+
41+
## Reason for change
42+
43+
Dynamic native instrumentation was enabled by default to maintain backwards compatibility in `dotnet test`. However, its way of injecting DLLs into the process isn't standard. With [security hardening changes](https://github.com/dotnet/runtime/pull/112359) in the .NET 10 runtime, it fails to find the linked DLL, causing the process to [crash with error](https://github.com/dotnet/sdk/issues/50950). The error might not be visible in non-interactive sessions or in the command line, but the process does crash.
44+
45+
Dynamic native instrumentation is already disabled by default by `dotnet-coverage`, which is an alternative way to collect code coverage using the same underlying tools. It's also disabled by default for solutions in Visual Studio that don't have native projects.
46+
47+
## Recommended action
48+
49+
If you collect coverage on solutions that don't have any native components, you shouldn't be affected. However, you might observe increased performance when collecting coverage.
50+
51+
If you collect coverage on solutions that include native components, such as C++ projects, you have the following options:
52+
53+
- Configure your projects to use [static native instrumentation](/visualstudio/test/customizing-code-coverage-analysis#static-and-dynamic-native-instrumentation)
54+
55+
OR
56+
57+
- Update to Microsoft.CodeCoverage 18.0.1 and enable dynamic native instrumentation:
58+
59+
- Add the setting `<EnableDynamicNativeInstrumentation>true</EnableDynamicNativeInstrumentation>` to your *runsettings* file.
60+
- Globally opt out from this new default by setting the `VSTEST_DISABLE_DYNAMICNATIVE_CODECOVERAGE_DEFAULT_SETTING=1` environment variable.
61+
62+
Similarly, when collecting code coverage with `vstest.console`, VSTest version 18.0.1 and newer is required to successfully collect dynamic native coverage on systems that have the .NET 10 SDK installed.
63+
64+
## Affected APIs
65+
66+
None.

docs/core/compatibility/toc.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,8 @@ items:
126126
href: reflection/10/makegeneric-signaturetype-validation.md
127127
- name: SDK and MSBuild
128128
items:
129+
- name: Code coverage EnableDynamicNativeInstrumentation defaults to false
130+
href: sdk/10.0/code-coverage-dynamic-native-instrumentation.md
129131
- name: .NET CLI `--interactive` defaults to `true` in user scenarios
130132
href: sdk/10.0/dotnet-cli-interactive.md
131133
- name: "`dotnet` CLI commands log non-command-relevant data to stderr"

0 commit comments

Comments
 (0)