From 07c8d8b737ad2e1c449580319d63feebca1421cb Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 5 Nov 2025 01:39:08 +0000 Subject: [PATCH 1/6] Initial plan From a04e4e633a250b3dbf0550db7d1f06af44b510b0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 5 Nov 2025 01:45:57 +0000 Subject: [PATCH 2/6] Add breaking change documentation for code coverage EnableDynamicNativeInstrumentation Co-authored-by: gewarren <24882762+gewarren@users.noreply.github.com> --- docs/core/compatibility/10.0.md | 1 + ...coverage-dynamic-native-instrumentation.md | 59 +++++++++++++++++++ docs/core/compatibility/toc.yml | 2 + 3 files changed, 62 insertions(+) create mode 100644 docs/core/compatibility/sdk/10.0/code-coverage-dynamic-native-instrumentation.md diff --git a/docs/core/compatibility/10.0.md b/docs/core/compatibility/10.0.md index 07d6f374888e2..1db9ccf2bcb2b 100644 --- a/docs/core/compatibility/10.0.md +++ b/docs/core/compatibility/10.0.md @@ -111,6 +111,7 @@ If you're migrating an app to .NET 10, the breaking changes listed here might af | [.NET CLI `--interactive` defaults to `true` in user scenarios](sdk/10.0/dotnet-cli-interactive.md) | Behavioral change | Preview 3 | | [`dotnet` CLI commands log non-command-relevant data to stderr](sdk/10.0/dotnet-cli-stderr-output.md) | Behavioral change | RC 2 | | [.NET tool packaging creates RuntimeIdentifier-specific tool packages](sdk/10.0/dotnet-tool-pack-publish.md) | Behavioral change | Preview 6 | +| [Code coverage EnableDynamicNativeInstrumentation defaults to false](sdk/10.0/code-coverage-dynamic-native-instrumentation.md) | Behavioral change | GA | | [Default workload configuration from 'loose manifests' to 'workload sets' mode](sdk/10.0/default-workload-config.md) | Behavioral change | Preview 2 | | [dnx.ps1 file is no longer included in .NET SDK](sdk/10.0/dnx-ps1-removed.md) | Source incompatible | GA | | [`dotnet new sln` defaults to SLNX file format](sdk/10.0/dotnet-new-sln-slnx-default.md) | Behavioral change | RC 1 | diff --git a/docs/core/compatibility/sdk/10.0/code-coverage-dynamic-native-instrumentation.md b/docs/core/compatibility/sdk/10.0/code-coverage-dynamic-native-instrumentation.md new file mode 100644 index 0000000000000..2183427d240c1 --- /dev/null +++ b/docs/core/compatibility/sdk/10.0/code-coverage-dynamic-native-instrumentation.md @@ -0,0 +1,59 @@ +--- +title: "Breaking change - Code coverage EnableDynamicNativeInstrumentation defaults to false" +description: "Learn about the breaking change in .NET 10 where dynamic native instrumentation is disabled by default when collecting code coverage." +ms.date: 11/05/2025 +ai-usage: ai-assisted +ms.custom: https://github.com/dotnet/docs/issues/50950 +--- + +# Code coverage EnableDynamicNativeInstrumentation defaults to false + +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. + +## Version introduced + +.NET 10 GA + +## Previous behavior + +Dynamic native instrumentation was enabled by default, and used a fallback for native modules when static native instrumentation couldn't be used. As described in [Static and dynamic native instrumentation](/visualstudio/test/customizing-code-coverage-analysis?view=vs-2022#static-and-dynamic-native-instrumentation). + +```bash +dotnet test --collect:"Code Coverage" +# Dynamic native instrumentation was enabled by default +``` + +## New behavior + +Dynamic native instrumentation is disabled by default. The `false` option is set by default from `dotnet test` and `vstest`. If you explicitly set the option in a runsettings file, it won't be overridden. + +```bash +dotnet test --collect:"Code Coverage" +# Dynamic native instrumentation is now disabled by default +``` + +When you re-enable dynamic native instrumentation, 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. + +## Type of breaking change + +This is a [behavioral change](../../categories.md#behavioral-change). + +## Reason for change + +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 .NET 10 runtime, it fails to find the linked DLL, causing process crash with error [dotnet/sdk#50950](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 crash happens. + +Dynamic native instrumentation is already disabled by default by `dotnet-coverage`, 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. + +## Recommended action + +Users who collect coverage on solutions that don't have any native components shouldn't be affected. They might observe increased performance when collecting coverage. + +Users who collect coverage on solutions that include native components, such as C++ projects, and wish to re-enable dynamic native instrumentation should remain on .NET 9, or disable collecting code coverage until the problem is resolved. + +Users who wish to globally opt out from this new default can set the `VSTEST_DISABLE_DYNAMICNATIVE_CODECOVERAGE_DEFAULT_SETTING=1` environment variable. + +## Affected APIs + +None. diff --git a/docs/core/compatibility/toc.yml b/docs/core/compatibility/toc.yml index 084502fd419de..b0e745d69e789 100644 --- a/docs/core/compatibility/toc.yml +++ b/docs/core/compatibility/toc.yml @@ -124,6 +124,8 @@ items: items: - name: .NET CLI `--interactive` defaults to `true` in user scenarios href: sdk/10.0/dotnet-cli-interactive.md + - name: Code coverage EnableDynamicNativeInstrumentation defaults to false + href: sdk/10.0/code-coverage-dynamic-native-instrumentation.md - name: "`dotnet` CLI commands log non-command-relevant data to stderr" href: sdk/10.0/dotnet-cli-stderr-output.md - name: .NET tool packaging creates RuntimeIdentifier-specific tool packages From 5162e84975e048bdac52ee2074e2a309c7c50d99 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 5 Nov 2025 01:48:31 +0000 Subject: [PATCH 3/6] Improve recommended actions and clarify re-enabling instructions Co-authored-by: gewarren <24882762+gewarren@users.noreply.github.com> --- .../10.0/code-coverage-dynamic-native-instrumentation.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/core/compatibility/sdk/10.0/code-coverage-dynamic-native-instrumentation.md b/docs/core/compatibility/sdk/10.0/code-coverage-dynamic-native-instrumentation.md index 2183427d240c1..4014dd2623f9c 100644 --- a/docs/core/compatibility/sdk/10.0/code-coverage-dynamic-native-instrumentation.md +++ b/docs/core/compatibility/sdk/10.0/code-coverage-dynamic-native-instrumentation.md @@ -32,7 +32,7 @@ dotnet test --collect:"Code Coverage" # Dynamic native instrumentation is now disabled by default ``` -When you re-enable dynamic native instrumentation, 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. +You can re-enable dynamic native instrumentation by setting `true` 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. ## Type of breaking change @@ -50,9 +50,11 @@ Dynamic native instrumentation is already disabled by default by `dotnet-coverag Users who collect coverage on solutions that don't have any native components shouldn't be affected. They might observe increased performance when collecting coverage. -Users who collect coverage on solutions that include native components, such as C++ projects, and wish to re-enable dynamic native instrumentation should remain on .NET 9, or disable collecting code coverage until the problem is resolved. +Users who collect coverage on solutions that include native components, such as C++ projects, have the following options: -Users who wish to globally opt out from this new default can set the `VSTEST_DISABLE_DYNAMICNATIVE_CODECOVERAGE_DEFAULT_SETTING=1` environment variable. +- **Globally opt out from this new default** by setting the `VSTEST_DISABLE_DYNAMICNATIVE_CODECOVERAGE_DEFAULT_SETTING=1` environment variable. +- **Remain on .NET 9** until the problem with dynamic native instrumentation is resolved. +- **Disable code coverage collection** temporarily until a solution is available. ## Affected APIs From 81c6af50de79862ac226fb07a0db7031629b0ece Mon Sep 17 00:00:00 2001 From: Genevieve Warren <24882762+gewarren@users.noreply.github.com> Date: Tue, 4 Nov 2025 18:21:24 -0800 Subject: [PATCH 4/6] Apply suggestions from code review --- ...code-coverage-dynamic-native-instrumentation.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/core/compatibility/sdk/10.0/code-coverage-dynamic-native-instrumentation.md b/docs/core/compatibility/sdk/10.0/code-coverage-dynamic-native-instrumentation.md index 4014dd2623f9c..624bba77d3ebf 100644 --- a/docs/core/compatibility/sdk/10.0/code-coverage-dynamic-native-instrumentation.md +++ b/docs/core/compatibility/sdk/10.0/code-coverage-dynamic-native-instrumentation.md @@ -3,7 +3,7 @@ title: "Breaking change - Code coverage EnableDynamicNativeInstrumentation defau description: "Learn about the breaking change in .NET 10 where dynamic native instrumentation is disabled by default when collecting code coverage." ms.date: 11/05/2025 ai-usage: ai-assisted -ms.custom: https://github.com/dotnet/docs/issues/50950 +ms.custom: https://github.com/dotnet/docs/issues/49376 --- # Code coverage EnableDynamicNativeInstrumentation defaults to false @@ -16,7 +16,7 @@ Running `dotnet test --collect:"Code Coverage"` now disables dynamic native inst ## Previous behavior -Dynamic native instrumentation was enabled by default, and used a fallback for native modules when static native instrumentation couldn't be used. As described in [Static and dynamic native instrumentation](/visualstudio/test/customizing-code-coverage-analysis?view=vs-2022#static-and-dynamic-native-instrumentation). +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). ```bash dotnet test --collect:"Code Coverage" @@ -25,18 +25,18 @@ dotnet test --collect:"Code Coverage" ## New behavior -Dynamic native instrumentation is disabled by default. The `false` option is set by default from `dotnet test` and `vstest`. If you explicitly set the option in a runsettings file, it won't be overridden. +Starting in .NET 10, dynamic native instrumentation is disabled by default. The `false` option is set by default from `dotnet test` and `vstest`. If you explicitly set the option in a *runsettings* file, it isn't overridden. ```bash dotnet test --collect:"Code Coverage" # Dynamic native instrumentation is now disabled by default ``` -You can re-enable dynamic native instrumentation by setting `true` 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. +You can re-enable dynamic native instrumentation by setting `true` 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. ## Type of breaking change -This is a [behavioral change](../../categories.md#behavioral-change). +This change is a [behavioral change](../../categories.md#behavioral-change). ## Reason for change @@ -48,9 +48,9 @@ Dynamic native instrumentation is already disabled by default by `dotnet-coverag ## Recommended action -Users who collect coverage on solutions that don't have any native components shouldn't be affected. They might observe increased performance when collecting coverage. +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. -Users who collect coverage on solutions that include native components, such as C++ projects, have the following options: +If you collect coverage on solutions that include native components, such as C++ projects, you have the following options: - **Globally opt out from this new default** by setting the `VSTEST_DISABLE_DYNAMICNATIVE_CODECOVERAGE_DEFAULT_SETTING=1` environment variable. - **Remain on .NET 9** until the problem with dynamic native instrumentation is resolved. From 67517278f546a13416871cc7b90ebbb774ae5e3f Mon Sep 17 00:00:00 2001 From: Genevieve Warren <24882762+gewarren@users.noreply.github.com> Date: Wed, 5 Nov 2025 11:10:34 -0800 Subject: [PATCH 5/6] Apply suggestions from code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- ...ode-coverage-dynamic-native-instrumentation.md | 15 +++++++++++---- docs/core/compatibility/toc.yml | 4 ++-- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/docs/core/compatibility/sdk/10.0/code-coverage-dynamic-native-instrumentation.md b/docs/core/compatibility/sdk/10.0/code-coverage-dynamic-native-instrumentation.md index 624bba77d3ebf..10a1afa3b575c 100644 --- a/docs/core/compatibility/sdk/10.0/code-coverage-dynamic-native-instrumentation.md +++ b/docs/core/compatibility/sdk/10.0/code-coverage-dynamic-native-instrumentation.md @@ -40,7 +40,7 @@ This change is a [behavioral change](../../categories.md#behavioral-change). ## Reason for change -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 .NET 10 runtime, it fails to find the linked DLL, causing process crash with error [dotnet/sdk#50950](https://github.com/dotnet/sdk/issues/50950). +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 crash happens. @@ -52,9 +52,16 @@ If you collect coverage on solutions that don't have any native components, you If you collect coverage on solutions that include native components, such as C++ projects, you have the following options: -- **Globally opt out from this new default** by setting the `VSTEST_DISABLE_DYNAMICNATIVE_CODECOVERAGE_DEFAULT_SETTING=1` environment variable. -- **Remain on .NET 9** until the problem with dynamic native instrumentation is resolved. -- **Disable code coverage collection** temporarily until a solution is available. +- Configure your projects to use [static native instrumentation](/visualstudio/test/customizing-code-coverage-analysis#static-and-dynamic-native-instrumentation) + +OR + +- Update to Microsoft.CodeCoverage 18.0.1 and enable dynamic native instrumentation: + + - Add the MSBuild property `true` to your project file. + - Globally opt out from this new default by setting the `VSTEST_DISABLE_DYNAMICNATIVE_CODECOVERAGE_DEFAULT_SETTING=1` environment variable. + +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. ## Affected APIs diff --git a/docs/core/compatibility/toc.yml b/docs/core/compatibility/toc.yml index b0e745d69e789..a2c6899095893 100644 --- a/docs/core/compatibility/toc.yml +++ b/docs/core/compatibility/toc.yml @@ -122,10 +122,10 @@ items: href: reflection/10/makegeneric-signaturetype-validation.md - name: SDK and MSBuild items: - - name: .NET CLI `--interactive` defaults to `true` in user scenarios - href: sdk/10.0/dotnet-cli-interactive.md - name: Code coverage EnableDynamicNativeInstrumentation defaults to false href: sdk/10.0/code-coverage-dynamic-native-instrumentation.md + - name: .NET CLI `--interactive` defaults to `true` in user scenarios + href: sdk/10.0/dotnet-cli-interactive.md - name: "`dotnet` CLI commands log non-command-relevant data to stderr" href: sdk/10.0/dotnet-cli-stderr-output.md - name: .NET tool packaging creates RuntimeIdentifier-specific tool packages From 38e8e1166f1c259e14ff043a26d6a44e74db7f93 Mon Sep 17 00:00:00 2001 From: Genevieve Warren <24882762+gewarren@users.noreply.github.com> Date: Wed, 5 Nov 2025 11:21:28 -0800 Subject: [PATCH 6/6] Update documentation on dynamic native instrumentation Clarified the impact of dynamic native instrumentation on process crashes and mentioned that it is disabled by default in certain scenarios. Updated recommendations for handling code coverage with native components. --- .../code-coverage-dynamic-native-instrumentation.md | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/docs/core/compatibility/sdk/10.0/code-coverage-dynamic-native-instrumentation.md b/docs/core/compatibility/sdk/10.0/code-coverage-dynamic-native-instrumentation.md index 10a1afa3b575c..42357703a88c5 100644 --- a/docs/core/compatibility/sdk/10.0/code-coverage-dynamic-native-instrumentation.md +++ b/docs/core/compatibility/sdk/10.0/code-coverage-dynamic-native-instrumentation.md @@ -40,11 +40,9 @@ This change is a [behavioral change](../../categories.md#behavioral-change). ## Reason for change -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). +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. -The error might not be visible in non-interactive sessions or in the command line, but the process crash happens. - -Dynamic native instrumentation is already disabled by default by `dotnet-coverage`, 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. +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. ## Recommended action @@ -54,14 +52,14 @@ If you collect coverage on solutions that include native components, such as C++ - Configure your projects to use [static native instrumentation](/visualstudio/test/customizing-code-coverage-analysis#static-and-dynamic-native-instrumentation) -OR + OR - Update to Microsoft.CodeCoverage 18.0.1 and enable dynamic native instrumentation: - - Add the MSBuild property `true` to your project file. + - Add the setting `true` to your *runsettings* file. - Globally opt out from this new default by setting the `VSTEST_DISABLE_DYNAMICNATIVE_CODECOVERAGE_DEFAULT_SETTING=1` environment variable. -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. + 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. ## Affected APIs