CSharpRepl
CSharpRepl copied to clipboard
Void async method can crash whole CSharRepl
Version
last
What happened?
The following code is able (there is a race condition) to crash CSharpRepl: (EDIT: not sure about race condition now, but I believe I saw non-crashing evaluations of this)
async Task Method1() => await Method2(async () => await File.ReadAllTextAsync(""));
async Task Method2(Action action) => /*missing await*/ action();
await Method1()

Exception Info: System.ArgumentException: The value cannot be an empty string. (Parameter 'path')
at System.ArgumentException.ThrowNullOrEmptyException(String argument, String paramName)
at System.IO.File.Validate(String path, Encoding encoding)
at System.IO.File.ReadAllTextAsync(String path, Encoding encoding, CancellationToken cancellationToken)
at Submission#1.<>c.<<Method1>b__1_0>d.MoveNext()
--- End of stack trace from previous location ---
at System.Threading.Tasks.Task.<>c.<ThrowAsync>b__128_1(Object state)
at System.Threading.ThreadPoolWorkQueue.Dispatch()
at System.Threading.PortableThreadPool.WorkerThread.WorkerThreadStart()
Simpler crashing code:
async void M() => throw null;
M()
I believe the root cause (and why it crashes CSharpRepl and cannot be prevented) is summarized here: https://codeblog.jonskeet.uk/2022/02/20/diagnosing-an-asp-net-core-hard-crash/
Ideally we should move the execution engine outside into separate process. There are another problems aside from crashes that would be solved by that. E.g. some of my scripts loads different versions of Microsoft.CodeAnalysis.* and analyze it. This is problematic now inside CSharpRepl because it also has loaded these assemblies for itself.