Getting `Attempt to execute managed code after the .NET runtime thread state has been destroyed` when a native method holds a `static std::string`?

Open
#118,741 26 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
5/5
Estimated time
Over a week
Newbie friendliness
35/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Stale
Tech stack
cpp, csharp

Research direction

Start by building and running the minimal C++/CLI reproducer on Windows with .NET 9.0.8, then inspect the assertion at src/coreclr/vm/ceemain.cpp:1818 and the static std::string destruction at application shutdown. Done means the sample exits without the assertion while retaining the reported behavior across the stated runtime versions.

Written by the indexing model from the issue text.

Description

area-Interop-coreclr
Description

Since updating our C++/CLI application to dotnet 9.0.8 we are affected by a new issue, where the below message is printed always at application end:

CLR: Assert failure(PID 19224 [0x00004b18], Thread: 7056 [0x1b90]): !"Attempt to execute managed code after the .NET runtime thread state has been destroyed."
    File: D:\a\_work\1\s\src\coreclr\vm\ceemain.cpp:1818

Note: This is a follow-up on my discussion at the end of https://github.com/dotnet/runtime/issues/117538.

Reproduction Steps

I have created a minimal reproducer, but the behavior is very strange. The following code will trigger the issue.

// The C++/CLI header:

public ref class Test {
public:
    static void testMethod();
};

// The C++/CLI source file:

#include <Test.hh>

#pragma managed(push, off)
#include <string>
void haveString() {
    static const std::string cString = "MyClass";
}
#pragma managed(pop)

#include <msclr/lock.h>

void Test::testMethod() {
    haveString();
}

When a corresponding C# executable now calls Test::testMethod() then the above error will be triggered at program end (after the end of main, probably during destruction of static memory). The problem is 100% reproducible for me.

Expected behavior

No assertion should be raised.

Actual behavior

An assertion is raised at program end.

Regression?

This worked successfully in .NET 9.0.4, however it is possible that the older .NET did not have the same thorough checks (so maybe the issue was just hidden there).

Known Workarounds

No response

Configuration

This is on Microsoft Windows 11 x64.

Dotnet installed with Visual Studio:

.NET SDK:
 Version:           9.0.304
 Commit:            f12f5f689e
 Workload version:  9.0.300-manifests.ad61bb1c
 MSBuild version:   17.14.16+5d8159c5f

Runtime Environment:
 OS Name:     Windows
 OS Version:  10.0.26100
 OS Platform: Windows
 RID:         win-x64
 Base Path:   C:\Program Files\dotnet\sdk\9.0.304\

.NET workloads installed:
There are no installed workloads to display.
Configured to use loose manifests when installing new manifests.

Host:
  Version:      9.0.8
  Architecture: x64
  Commit:       aae90fa090

.NET SDKs installed:
  9.0.304 [C:\Program Files\dotnet\sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.App 8.0.19 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 9.0.8 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 8.0.19 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 9.0.8 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.WindowsDesktop.App 8.0.19 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 9.0.8 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

Other architectures found:
  x86   [C:\Program Files (x86)\dotnet]
    registered at [HKLM\SOFTWARE\dotnet\Setup\InstalledVersions\x86\InstallLocation]

Visual Studio is current latest:

Microsoft Visual Studio Professional 2022
Version 17.14.12
VisualStudio.17.Release/17.14.12+36408.4
Microsoft .NET Framework
Version 4.8.09032

Installed Version: Professional

Visual C++ 2022   00483-10100-14247-AA184
Microsoft Visual C++ 2022

ASP.NET and Web Tools   17.14.122.59099
ASP.NET and Web Tools

Azure App Service Tools v3.0.0   17.14.122.59099
Azure App Service Tools v3.0.0

C# Tools   4.14.0-3.25359.3+6dbcfd2f553ef1ef0ac48878ab17d18c1360735d
C# components used in the IDE. Depending on your project type and settings, a different version of the compiler may be used.

GitHub Copilot   17.14.995.13737
GitHub Copilot is an AI pair programmer that helps you write code faster and with less work.

Microsoft JVM Debugger   1.0
Provides support for connecting the Visual Studio debugger to JDWP compatible Java Virtual Machines

NuGet Package Manager   6.14.1
NuGet Package Manager in Visual Studio. For more information about NuGet, visit https://docs.nuget.org/

TypeScript Tools   17.0.40502.2001
TypeScript Tools for Microsoft Visual Studio

Visual Basic Tools   4.14.0-3.25359.3+6dbcfd2f553ef1ef0ac48878ab17d18c1360735d
Visual Basic components used in the IDE. Depending on your project type and settings, a different version of the compiler may be used.

Visual F# Tools   17.14.0-beta.25230.7+c1a9d78ad4a474a716ccffb4367ed5151e3f7c9f
Microsoft Visual F# Tools

Visual Studio IntelliCode   2.2
AI-assisted development for Visual Studio.
Other information

No response

Dominant language
C#
Stars
18.3k
Forks
5.6k
PR merge metrics
PR metrics pending

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from dotnet/runtime

All issues in dotnet/runtime

Similar issues

More C# issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.