Repository navigation
Fatal CLR error when XML serializing ImmutableArray, related to reflection #66163
Description
Description
When running the fairly simple program in the reproduction below, the CLR crashes and so asp.net stops receiving requests.
It only happens when using the XML response type to serialize a non-empty ImmutableArray of reference types.
The stack trace is:
Fatal error. Internal CLR error. (0x80131506)
at System.RuntimeMethodHandle.InvokeMethod(System.Object, System.Span1<System.Object> ByRef, System.Signature, Boolean, Boolean) at System.Reflection.RuntimeMethodInfo.Invoke(System.Object, System.Reflection.BindingFlags, System.Reflection.Binder, System.Object[], System.Global ization.CultureInfo) at System.Reflection.MethodBase.Invoke(System.Object, System.Object[]) at System.Xml.Serialization.TempAssembly.InvokeWriter(System.Xml.Serialization.XmlMapping, System.Xml.XmlWriter, System.Object, System.Xml.Serializat ion.XmlSerializerNamespaces, System.String, System.String) at System.Xml.Serialization.XmlSerializer.Serialize(System.Xml.XmlWriter, System.Object, System.Xml.Serialization.XmlSerializerNamespaces, System.Str ing, System.String) at System.Xml.Serialization.XmlSerializer.Serialize(System.Xml.XmlWriter, System.Object) at Microsoft.AspNetCore.Mvc.Formatters.XmlSerializerOutputFormatter.Serialize(System.Xml.Serialization.XmlSerializer, System.Xml.XmlWriter, System.Ob ject) at Microsoft.AspNetCore.Mvc.Formatters.XmlSerializerOutputFormatter+<WriteResponseBodyAsync>d__19.MoveNext() at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[Microsoft.AspNetCore.Mvc.Formatters.XmlSerializerOutputFormatter+<WriteResponseBodyA sync>d__19, Microsoft.AspNetCore.Mvc.Formatters.Xml, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]](<WriteResponseBodyAsync>d__19 B yRef) at System.Runtime.CompilerServices.AsyncTaskMethodBuilder.Start[[Microsoft.AspNetCore.Mvc.Formatters.XmlSerializerOutputFormatter+<WriteResponseBodyA sync>d__19, Microsoft.AspNetCore.Mvc.Formatters.Xml, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]](<WriteResponseBodyAsync>d__19 B yRef) at Microsoft.AspNetCore.Mvc.Formatters.XmlSerializerOutputFormatter.WriteResponseBodyAsync(Microsoft.AspNetCore.Mvc.Formatters.OutputFormatterWriteCo ntext, System.Text.Encoding) at Microsoft.AspNetCore.Mvc.Formatters.TextOutputFormatter.WriteAsync(Microsoft.AspNetCore.Mvc.Formatters.OutputFormatterWriteContext) at Microsoft.AspNetCore.Mvc.Infrastructure.ObjectResultExecutor.ExecuteAsyncCore(Microsoft.AspNetCore.Mvc.ActionContext, Microsoft.AspNetCore.Mvc.Obj ectResult, System.Type, System.Object) at Microsoft.AspNetCore.Mvc.Infrastructure.ObjectResultExecutor.ExecuteAsync(Microsoft.AspNetCore.Mvc.ActionContext, Microsoft.AspNetCore.Mvc.ObjectR esult) at Microsoft.AspNetCore.Mvc.ObjectResult.ExecuteResultAsync(Microsoft.AspNetCore.Mvc.ActionContext) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeResultAsync(Microsoft.AspNetCore.Mvc.IActionResult) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultNext[[System.__Canon, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, Publ icKeyToken=7cec85d7bea7798e],[System.__Canon, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]](State ByRef, S cope ByRef, System.Object ByRef, Boolean ByRef) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeResultFilters() at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State ByRef, Scope ByRef, System.Object ByRef, Boolean ByRef) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeFilterPipelineAsync() at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeAsync() at Microsoft.AspNetCore.Mvc.Routing.ControllerRequestDelegateFactory+<>c__DisplayClass10_0.<CreateRequestDelegate>b__0(Microsoft.AspNetCore.Http.Http Context) at Microsoft.AspNetCore.Routing.EndpointMiddleware.Invoke(Microsoft.AspNetCore.Http.HttpContext) at Microsoft.AspNetCore.Routing.EndpointRoutingMiddleware.Invoke(Microsoft.AspNetCore.Http.HttpContext) at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware+<Invoke>d__9.MoveNext() at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware+<Invoke>d__9, Micr osoft.AspNetCore.Diagnostics, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]](<Invoke>d__9 ByRef) at System.Runtime.CompilerServices.AsyncTaskMethodBuilder.Start[[Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware+<Invoke>d__9, Micr osoft.AspNetCore.Diagnostics, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]](<Invoke>d__9 ByRef) at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(Microsoft.AspNetCore.Http.HttpContext) at Microsoft.AspNetCore.HostFiltering.HostFilteringMiddleware.Invoke(Microsoft.AspNetCore.Http.HttpContext) at Microsoft.AspNetCore.Hosting.HostingApplication.ProcessRequestAsync(Context) at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol+<ProcessRequests>d__2231[[System.__Canon, System.Private.CoreLib, Version=6.0
.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].MoveNext()
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol+<ProcessRequestsd__223
1[[System.__Canon, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], Microsoft.AspNetCore.Server.Kest rel.Core, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]](<ProcessRequests>d__2231<System.__Canon> ByRef)
at System.Runtime.CompilerServices.AsyncTaskMethodBuilder.Start[[Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol+<ProcessRequests
d__2231[[System.__Canon, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], Microsoft.AspNetCore.Server.Kest rel.Core, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]](<ProcessRequests>d__2231<System.__Canon> ByRef)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[System.__Canon, System.Private.CoreLib, Version=6.0.0.0, Cult
ure=neutral, PublicKeyToken=7cec85d7bea7798e]
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol+d__2221[[System.__Canon, System.Private.CoreLib, Versio n=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].MoveNext() at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol+<ProcessRequests Async>d__2221[[System.__Canon, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], Microsoft.AspNetCore.Server
.Kestrel.Core, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]](d__2221<System.__Canon> ByRef) at System.Runtime.CompilerServices.AsyncTaskMethodBuilder.Start[[Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol+<ProcessRequests Async>d__2221[[System.__Canon, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], Microsoft.AspNetCore.Server
.Kestrel.Core, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]](d__2221<System.__Canon> ByRef) at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequestsAsync[[System.__Canon, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]](Microsoft.AspNetCore.Hosting.Server.IHttpApplication1<System.__Canon>)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.Http2Stream`1[[System.__Canon, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, P
ublicKeyToken=7cec85d7bea7798e]].Execute()
at System.Threading.ThreadPoolWorkQueue.Dispatch()
at System.Threading.PortableThreadPool+WorkerThread.WorkerThreadStart()
at System.Threading.Thread.StartCallback()Process finished with exit code -1,073,741,819.
Reproduction Steps
Run the following program
using System.Collections.Immutable;
using Microsoft.AspNetCore.Mvc;
var builder = WebApplication.CreateBuilder(args);
builder.Services
.AddControllers(x => x.OutputFormatters.Clear()) //clear the json formatter as only the XML one crashes
.AddXmlSerializerFormatters();
var app = builder.Build();
app.MapControllers();
var serverTask = app.RunAsync();
var crashTask = CrashServerClr();
await serverTask;
await crashTask;
async Task CrashServerClr()
{
await Task.Delay(TimeSpan.FromSeconds(5)); //wait for server to be up
var rootUri = app.Urls.First(x => x.StartsWith("http://"));
await new HttpClient().GetAsync(rootUri);
}
[Route("/")]
public class HomeController
{
[HttpGet]
public ImmutableArray<object> Index() => ImmutableArray.Create(new object());
}
Expected behavior
The CLR presumably shouldn't be crashable in this way. It seems different to a regular exception that would suggest just a bug in the SDK (which there could also be). For one thing, it doesn't return a 5xx error but just hangs the connection.
Actual behavior
The CLR appears to crash with the error given and asp.net never responds to the request.
Regression?
It didn't work in 6.0.1xx either.
Known Workarounds
Switch to ImmutableList which works fine
Configuration
SDK 6.0.200 with associated runtime
At least Windows 10 and 11 x64, haven't tried linux yet.
Other information
No response
Activity
KeterSCP commentedon Mar 3, 2022
Here is a shorter console app repro:
Btw on .NET5 this code produces System.AccessViolationException
jkotas commentedon Mar 4, 2022
This is crashing in the code ref.emited code by the Xml serializer.
mungojam commentedon Mar 6, 2022
Does my original reproduction count as a security flaw in asp.net since it could feasibly be used to crash a production asp.net server? It's not too obscure a setup and the serialisation works for JSON so could be in a live service that just had XML as an option
GrabYourPitchforks commentedon Mar 6, 2022
Hi @mungojam - hard to say right now. We'll send it around to the larger team for review. But your mixed JSON/XML web service scenario is compelling.
BTW, thank you for the very clear repro. Much appreciated. :)
StephenMolloy commentedon Mar 17, 2022
If you try to serialize as an IEnumerable which is backed by the ImmutableArray... would this work then? That might be a way to unblock until this can be addressed.
mungojam commentedon Mar 17, 2022
Do you mean as a workaround? The easiest one I found was to convert things to immutablelist. I only had a handful of classes in my case.
The real issue is the crash, not the lack of support for ImmutableArray as there are plenty of other common types that aren't supported either.