-
Notifications
You must be signed in to change notification settings - Fork 847
Description
Please, read the first comment for more details and TL;DR
When compiling assembly with one namespace, which contains 3 types, and each type contains 40_000 instance methods, running the assembly fails with:
Fatal error. System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
at Program+Main.main(System.String[])
NativeCommandExitException: Program "dotnet.exe" ended with non-zero exit code: -1073741819.
Script to generate Program.fs (which then can be just built using normal .NET):
open System.Text
open System.IO
#nowarn "20"
let generateTypes (x:int) (y:int) =
let sb = StringBuilder()
for i in 1..x do
sb.Append("[<NoComparison; NoEquality>]\n")
sb.Append(sprintf "type Type%d() =\n" i)
for j in 1..y do
sb.Append(sprintf " member _.Method%d() = printfn \"Type%d Method%d\"\n" j i j)
sb.Append('\n')
sb
let generatedCode = generateTypes 1 (65533)
generatedCode.Append("module Main =\n")
generatedCode.Append(" [<EntryPoint>]\n")
generatedCode.Append(" let main _ =\n")
generatedCode.Append(" printfn \"Fin\"\n")
generatedCode.Append(" 0\n")
File.WriteAllText("Program.fs", generatedCode.ToString())Update: so, 1 type with 65532 methods causes no issues 65533 methods (+1 more) shows the issue.
It seems we overflow somewhere above 65535 (65532 + main + .ctor(s)), MethodDef table shows 65535 in both cases, however in the second case (case of failure) it seems all the methods' type is the same (AssemblyAttribute), meaning when we have more than 65k methods in total, all of them go to one type int the table.
Update 2: if we have much more methods (70k) we get AccessViolation, if we have exactly 65535/65536 - we get te initial issue:
Update 3: My initial testing methodology is incorrect - it is obvious that the limitation for one type is 65k (known CLR limitation), however if you will generate 2 types with 32766 methods each, it will still fail,
Codegen for 2 types:
open System.Text
open System.IO
#nowarn "20"
let generateTypes (x:int) (y:int) =
let sb = StringBuilder()
for i in 1..x do
sb.Append("[<NoComparison; NoEquality>]\n")
sb.Append(sprintf "type Type%d() =\n" i)
for j in 1..y do
sb.Append(sprintf " member _.Method%d() = printfn \"Type%d Method%d\"\n" j i j)
sb.Append('\n')
sb
let generatedCode = generateTypes 2 (32766)
generatedCode.Append("module Main =\n")
generatedCode.Append(" [<EntryPoint>]\n")
generatedCode.Append(" let main _ =\n")
generatedCode.Append(" printfn \"Fin\"\n")
generatedCode.Append(" 0\n")
File.WriteAllText("Program.fs", generatedCode.ToString())
Unhandled exception. System.TypeLoadException: Type '<StartupCode$helloworld>.$.NETCoreApp,Version=v7.0.AssemblyAttributes' from assembly 'helloworld, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' contains more methods than the current implementation allows.
Provide any related information (optional):
- Win 11, latest .NET8 RC
Metadata
Metadata
Assignees
Labels
Type
Projects
Status