-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Migration from .NET Framework 4.7.2 to .NET 8 results in StackOverflowException due to reduced stack size #96347
Comments
cc @janvorli |
AFAIR .NET 8 mostly defaults to the OS default stack sizes today, but I recall there being some talks in the past about having a guaranteed size for all platforms. If you control the thread creation, you can change the stack limit in the managed code with the Thread constructor. |
1.5MB is not a Windows OS default and you can't control it for the main thread (only via env vars). |
Sure, it might, but I hope you're not really trying to |
it's not the only way to get an SO. We still have an open issue somwhere where Roslyn runs out of stack compiling a C# program. I think bumping main thread's default stack size AND/OR exposing DefaultStackSize option as a runtime-config/msbuild property does make sense. |
@jkotas do you happen to remember why we have opted for 1.5MB large main thread stack size for both 32 and 64 bit code instead of the 1MB / 4MB that .NET framework was using? |
That would not work for the main thread - the main thread gets its stack size from the app .exe file header (Windows OS reads it from the PE file and sets it accordingly) and it is embedded in that header when we compile the dotnet.exe / apphost.exe. |
Ah, good point |
I still think that .NET should share a minimum of like 2MB or 4MB for all platforms. |
|
Seems like it was the result of this suggestion: |
@janvorli any news?
If there is no silver bullet, please give us the option to configure this via app.config/runtime.config/etc. per application because now this is the regression and there is no way to fix it in prod. :( |
You can workaround this for now by running
|
@jkotas unfortunately, this works in a very limited way:
This isn't quite the stack size control we expect. :)
Therefore, the ability to explicitly specify the stack size of the main thread and threads in the thread pool is really necessary so that the application works the same, and we can use the AnyCPU platform (at least for now it is the default for all created projects in the IDE). |
If we enable the main thread stack size to be configurable, it will require your app to be launched via platform-specific apphost (ie
The current default for most projects is Framework-dependent Executable. The build will produce the yourapp.exe on Windows, the Visual Studio debugger is going to use yourapp.exe to start you app, etc. (There is still yourapp.dll in the bin directory, but it is not meant to be the primary entrypoint for your app.) |
It is also worth noting that the editbin works for Windows binaries only. On Linux, you can influence the main thread stack size using the "ulimit -s" command before launching your executable. |
In this case, I hope that you can return the 4MB stack and make it the default for all configurations in Windows.
Well, we haven't had to reduce the stack size yet, and 8 MB on Linux is definitely enough for us. |
Maintaining bug-for-bug .NET Framework compatibility is not a strong argument at this point. There are number of scenarios where the stack consumption can be very different from how .NET Framework behaved. Also, we have 1.5MB default in .NET Core/5+ on Windows for close to 10 years and it worked fine so far. Could you please tell us more about what your app does that it is hitting the 1.5MB limit? Why is the launching your app via platform specific |
@jkotas, as I said at the beginning:
We've stopped using
Create platform-specific wrappers with hard-wired limits to return the old behavior. Expectations: after changing the old version of the framework to a new one, and fixing the compatibility problems mentioned in the guides, we get a solution that works no worse than before. Now our expectations are different from reality. :( |
Description
In the process of migrating a huge Enterprise solution to .NET8, we encountered an unexpected regression:
The default stack size for the main and secondary threads has been reduced from
4 MB
(x64) to1.5 MB
.This resulted in a
StackOverflowException
in a RestAPI service usingAutoMapper
, custom serialization logic, and building dynamic methods.The
DefaultStackSize
environment variable is internal and cannot be configured from an external .json config file.Configuration
Prefer 32-bit
is disabled)Regression?
Yes, this is regression from .NET Framework where the default stack size was 4 MB for 64-bit applications.
I expect 4 MB and this to work the same for the .NET Framework and .NET8+ on any OS, when building for x64 and AnyCPU platforms.
Data
Analysis
An article about internals of threads:
https://learn.microsoft.com/en-us/archive/blogs/markrussinovich/pushing-the-limits-of-windows-processes-and-threads
Current .NET stack sizes:
The text was updated successfully, but these errors were encountered: