Repository navigation
Netcore3.0 app aborts in release configuration on a Linux machine #2409
Description
Possibly related to this previous issue: https://github.com/dotnet/coreclr/issues/27734
Running the attached app (which targets netcoreapp3.0) in release configuration on our Linux machines aborts with one of the following errors:
- System.AccessViolationException: 'Attempted to read or write protected memory. This is often an indication that other memory is corrupt.'
- Segmentation fault
Although unlike the previous bug, the occurrence is not 100% deterministic. It does however, usually occur on the first run of the program at some point and has been observed to occur more frequently when the following environment variables were set for debugging purposes.
- COMPlus_DbgEnableMiniDump=1
- COMPlus_StressLog=1
- COMPlus_DbgMiniDumpType=4 (we found that our symbols weren't loading properly without this)
The program is reasonably simple, contains no unmanaged code, no third party dependencies, and has some fairly simple logic intended to use some memory (but not anywhere close to all of it) and stress the cpu in a manner similar to the way our full program does.
Operating system: CentOS Linux 7 (Core)
Kernel: Linux 3.10.0-862.11.6.el7.x86_64
dotnet --info
.NET Core SDK (reflecting any global.json):
Version: 3.0.100
Commit: 04339c3a26
Runtime Environment:
OS Name: centos
OS Version: 7
OS Platform: Linux
RID: centos.7-x64
Base Path: /usr/share/dotnet/sdk/3.0.100/
Host (useful for support):
Version: 3.0.0
Commit: 95a0a61858
.NET Core SDKs installed:
2.2.402 [/usr/share/dotnet/sdk]
3.0.100 [/usr/share/dotnet/sdk]
.NET Core runtimes installed:
Microsoft.AspNetCore.All 2.2.7 [/usr/share/dotnet/shared/Microsoft.AspNetCore.All]
Microsoft.AspNetCore.App 2.2.7 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.0.0 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.NETCore.App 2.2.7 [/usr/share/dotnet/shared/Microsoft.NETCore.App]
Microsoft.NETCore.App 3.0.0 [/usr/share/dotnet/shared/Microsoft.NETCore.App]
category:correctness
theme:tail-call
skill-level:intermediate
cost:medium
Activity
janvorli commentedon Nov 20, 2019
I can confirm that it repros on my Linux box as well. I will look into it.
janvorli commentedon Nov 21, 2019
I've found the culprit. It is a bug in fast tailcall argument shuffling order where we end up overwriting lower 32 bits of an incoming argument stack slot before we actually extract that stack slot to a new parameter register. The problem is in the generated code for the FailingLinuxTestApp.Thing1.DoWork1 method. See the disass below with my comment on what happens.
cc: @dotnet/jit-contrib - this issue is in the .NET Core 3.0 release.
janvorli commentedon Nov 21, 2019
I've forgotten to mention - setting
COMPlus_TieredCompilation=0results in reproing the issue almost instantly.jashook commentedon Nov 21, 2019
I will take this, thank you @janvorli for doing the triage.
jashook commentedon Nov 21, 2019
There have been a bunch of fixes in this area that are in 5.0.
dotnet/coreclr#20643
dotnet/coreclr#26255
dotnet/coreclr#26158
jashook commentedon Nov 21, 2019
The test passes on master.
jashook commentedon Nov 21, 2019
/cc @jakobbotsch
jakobbotsch commentedon Nov 21, 2019
Seems likely this was fixed in dotnet/coreclr#26255.
rossgurbutt commentedon Nov 22, 2019
@jashook
Is it possible / likely for these fixes to make it into the 3.1 release? It's currently preventing us from running an important chunk of our software on Linux machines and waiting for 5.0 in November doesn't seem like an option.
Alternatively, if this won't make it into 3.1, is there any guaranteed way of working around it and if there is, is it likely to have any negative effect on performance?
jashook commentedon Nov 22, 2019
@jakobbotsch is correct, this is an instance of https://github.com/dotnet/coreclr/issues/12468, dotnet/coreclr#26255 fixes this. I have a pr out into 3.1, the change is to turn of fast tail calls when the callee has stack space. Note I am not porting dotnet/coreclr#26255 back into 3.1, that will go out with 5.0.
rossgurbutt commentedon Dec 4, 2019
@jashook I note that 3.1 was released yesterday and your pull request temporarily fixing this issue didn't appear to be merged into the release. Is there any plan for when this will be fixed moving forward?
jashook commentedon Dec 6, 2019
@rossgurbutt the change is targeting a servicing release that will happen potentially a few months from now. That assumes that the change is approved, which currently does not look like it meets the bar to make it into release/3.1.
That being said there are workarounds to this issue.
The last method on the call stack can be marked as Optimization Sensitive. You can use
[MethodImplAttribute(MethodImplOptions.NoOptimization)]to compile the method without optimizations.This specific optimization is tail call related. The JIT does not require are recursive method to do a tail call optimization. It is sometimes pretty easy to avoid doing an opportunistic tail call. Off the top of my head the following can avoid this:
MethodImplOptions.NoInliningdisables Fast Tail Calls.Changing to use the result will invalidate the ability to tail call.
I understand that these workarounds may not work for everyone. Please let me know if I can help out further.
jashook commentedon Dec 6, 2019
Also please note that another possibility is to set the following environment variable:
COMPlus_TailCallOpt=0rossgurbutt commentedon Jan 7, 2020
Thanks for all of your help on this @jashook and @janvorli and apologies for the delay in replying.
We have tried several of the options and the one that worked easiest / best for us was MethodImplOptions.NoInlining.