Skip to content

.NET 7 JIT Crash when referencing struct of particular shape: Fatal error. Internal CLR error. (0x80131506) #80624

Closed
@RedworkDE

Description

@RedworkDE

Description

Referencing a ref struct with explicit layout, containing a ref struct, containing a struct, containing a value crashes the JIT in the importer phase when jitting the method containing that reference.

Reproduction Steps

using System.Runtime.InteropServices;

Console.WriteLine("Testing for crash.");
FailsToJit();
Console.WriteLine("Did not crash.");

static void FailsToJit()
{
	// any reference (direct or indirect) to godot_variant will crash in during JIT import when resolving the type token
	// loading a function pointer using the type, sizeof(), ... all crash in basically the same way
	void Test(godot_variant arg) { }
	Test(default);
}

[StructLayout(LayoutKind.Explicit)]
public ref struct godot_variant
{
	[FieldOffset(0)] // offset doesn't matter
	private godot_variant_data _data;

	private ref struct godot_variant_data
	{
		private godot_variant_data_mem _mem;

		public struct godot_variant_data_mem
		{
			private float _mem0; // also happens for int here
		}
	}
}

Expected behavior

Program runs to completion, printing two lines to console.

Actual behavior

The program crashes with the following output when trying to execute FailsToJit.

Fatal error. Internal CLR error. (0x80131506)
   at Program.<<Main>$>g__FailsToJit|0_0()
   at Program.<Main>$(System.String[])

Native Backtrace:

>	clrjit.dll!Compiler::lvaInitTypeRef() Line 280	C++
 	clrjit.dll!Compiler::compCompileHelper(CORINFO_MODULE_STRUCT_ * classPtr, ICorJitInfo * compHnd, CORINFO_METHOD_INFO * methodInfo, void * * methodCodePtr, unsigned int * methodCodeSize, JitFlags * compileFlags) Line 6509	C++
 	clrjit.dll!`Compiler::compCompile'[::M]::__Body::Run(Compiler::compCompile::__l2::__JITParam * __JITpParam) Line 5930	C++
 	clrjit.dll!Compiler::compCompile(CORINFO_MODULE_STRUCT_ * classPtr, void * * methodCodePtr, unsigned int * methodCodeSize, JitFlags * compileFlags) Line 5934	C++
 	clrjit.dll!``jitNativeCode'::`8'::__Body::Run'::`6'::__Body::Run(jitNativeCode::__l8::__Body::Run::__l5::__JITParam * __JITpParam) Line 7413	C++
 	clrjit.dll!`jitNativeCode'::`8'::__Body::Run(jitNativeCode::__l2::__JITParam * __JITpParam) Line 7416	C++
 	clrjit.dll!jitNativeCode(CORINFO_METHOD_STRUCT_ * methodHnd, CORINFO_MODULE_STRUCT_ * classPtr, ICorJitInfo * compHnd, CORINFO_METHOD_INFO * methodInfo, void * * methodCodePtr, unsigned int * methodCodeSize, JitFlags * compileFlags, void * inlineInfoPtr) Line 7440	C++
 	clrjit.dll!CILJit::compileMethod(ICorJitInfo * compHnd, CORINFO_METHOD_INFO * methodInfo, unsigned int flags, unsigned char * * entryAddress, unsigned int * nativeSizeOfCode) Line 261	C++
 	[Managed to Native Transition]	
 	test.dll!Program.<Main>$(string[] args) Line 5	C#
 	[Native to Managed Transition]	
 	[Inline Frame] hostpolicy.dll!coreclr_t::execute_assembly(int) Line 89	C++
 	hostpolicy.dll!run_app_for_context(const hostpolicy_context_t & context, int argc, const wchar_t * * argv) Line 255	C++
 	hostpolicy.dll!run_app(const int argc, const wchar_t * * argv) Line 284	C++
 	hostpolicy.dll!corehost_main(const int argc, const wchar_t * * argv) Line 430	C++
 	hostfxr.dll!execute_app(const std::wstring & impl_dll_dir, corehost_init_t * init, const int argc, const wchar_t * * argv) Line 146	C++
 	hostfxr.dll!`anonymous namespace'::read_config_and_execute(const std::wstring & host_command, const host_startup_info_t & host_info, const std::wstring & app_candidate, const std::unordered_map<enum known_options,std::vector<std::wstring,std::allocator<std::wstring>>,known_options_hash,std::equal_to<enum known_options>,std::allocator<std::pair<enum known_options const ,std::vector<std::wstring,std::allocator<std::wstring>>>>> & opts, int new_argc, const wchar_t * * new_argv, host_mode_t mode, const bool is_sdk_command, wchar_t * out_buffer, int buffer_size, int * required_buffer_size) Line 533	C++
 	hostfxr.dll!fx_muxer_t::handle_exec_host_command(const std::wstring & host_command, const host_startup_info_t & host_info, const std::wstring & app_candidate, const std::unordered_map<enum known_options,std::vector<std::wstring,std::allocator<std::wstring>>,known_options_hash,std::equal_to<enum known_options>,std::allocator<std::pair<enum known_options const ,std::vector<std::wstring,std::allocator<std::wstring>>>>> & opts, int argc, const wchar_t * * argv, int argoff, host_mode_t mode, const bool is_sdk_command, wchar_t * result_buffer, int buffer_size, int * required_buffer_size) Line 1018	C++
 	hostfxr.dll!fx_muxer_t::execute(const std::wstring host_command, const int argc, const wchar_t * * argv, const host_startup_info_t & host_info, wchar_t * result_buffer, int buffer_size, int * required_buffer_size) Line 579	C++
 	hostfxr.dll!hostfxr_main_startupinfo(const int argc, const wchar_t * * argv, const wchar_t * host_path, const wchar_t * dotnet_root, const wchar_t * app_path) Line 61	C++
 	test.exe!exe_start(const int argc, const wchar_t * * argv) Line 251	C++
 	test.exe!wmain(const int argc, const wchar_t * * argv) Line 322	C++
 	[Inline Frame] test.exe!invoke_main() Line 90	C++
 	test.exe!__scrt_common_main_seh() Line 288	C++
 	kernel32.dll!BaseThreadInitThunk�()	Unknown
 	ntdll.dll!RtlUserThreadStart�()	Unknown

Native debugging message:

Exception thrown: read access violation.
pSeries was 0x7FF7DB2478D8.

It varies depending on how the type is used, but it always ends at a call info.compCompHnd->xxx() with a type token as one of the arguments.
I think execution should continue in coreclr.dll at this point, but i am unable to get visual studio to step into that call, or to execute the program with a debug build of coreclr

Regression?

Yes, when changing the target framework to net6.0 the same code does not crash and executes successfully.

Known Workarounds

Removing about anything from the MRP makes the crash go away.

Configuration

On Windows 10 x64 versions:
.NET 7.0.2 - d099f07
.NET 7.0.0 - d037e07

On Linux Ubuntu 22.04.1 x64 version
.NET 7.0.2 - d037e07

Other information

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions