dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
15.25k stars 4.73k forks source link

[Linux] Failed to initialize CoreCLR, HRESULT: 0x8007000E #13027

Open htdag opened 5 years ago

htdag commented 5 years ago

Just test a hello world console application on linux x64. log.txt: https://gist.github.com/htdag/86d3974c2602d565a81805849cb2755c

.NET Core 2.2

Edit: same as https://givemeans.wordpress.com/2018/05/21/php-exec-running-dotnet-new-mvc-out-of-memory/

janvorli commented 5 years ago

This error code means "out of memory". How much memory does your Linux device have? And if it is running in a container, does it have a memory limit set? Also, can you please check if .NET Core 3.0 has the same issue?

htdag commented 5 years ago

LiteSpeed, shared hosting 768MB RAM, 500MB Storage. memory_limit=768MB, still 0x8007000E. Tested, .NET Core 3.0 have same issue.

I create a small C program to test memory_limit. Execute from php excec, It's can alloc >750MB memory without error.

On blog, author tried many way but:

When running the command from ssh it works fine, and finishes quickly with root user

Root require?

janvorli commented 5 years ago

This is very strange. Looking at the strace log, something keeps trying to allocate 128MB, it fails, then 64MB and it succeeds and releases the memory immediately. This occurs 17 times in the log. Based on the fact that it passes MAP_NORESERVE to mmap, it is not coreclr code. We never pass in such flag. However this may be completely benign. CoreCLR initialization fails when it tries to reserve 256MB of virtual address space (with PROT_NONE, so no physical memory is mapped) and it fails with ENOMEM. I wonder if it is possible that in your environment, the amount of available virtual memory is limited e.g. by the ulimit -v command or something similar. What does ulimit -v print on that system? dotnet reserves slightly under 2GB of virtual memory space at startup for its executable allocator, so if there is a virtual memory limit set say to or a bit over 2GB, then this could cause the trouble. It might also explain the reason why the blog post you've linked mentions that running as root worked. My guess is that root would have different or no virtual memory limit set.

htdag commented 5 years ago

ulimit -v

2096128

Is it valid?

janvorli commented 5 years ago

So that's the problem. Your limit is slightly below 2GB (2146435072 bytes). So after .NET core reserves 1908342784 bytes of virtual address space, there is only about 227MB of that address space left. So when we try to reserve another 256MB (that would be virtual address space space for the GC heap), we fail. Please note that this is just reserving virtual address space, not allocating physical memory. I am not sure why the virtual address space is limited in your environment. Linux on x64 has 128TB of virtual address space available. This space is not shared between processes, so each process can reserve that amount of virtual address space if no ulimit -v is set. Would you be able to at least enlarge if not remove the limit? 2GB + the size of your physical memory should be sufficient. Please note that the ulimit values are in kilobytes, so if you want to set the limit to e.g. 2.75GB - which looks like a sufficient value given you have 768MB of RAM, you set the limit to 2883584.

Const-me commented 5 years ago

Same error. ulimit -v prints unlimited. Running on WSL, my Linux device has 16GB RAM. Any other ideas?

janvorli commented 5 years ago

@Const-me when you say "same error", do you mean the same error code or also that you hit this problem with vanilla app created using "dotnet create console"? And could you please also share strace log using gist like @htdag did?

Const-me commented 5 years ago

@janvorli Same message and same error code. My app is only slightly more complex than hello world.

I’ve already found the reason, apparently .NET core doesn’t like WSL’s mounted file system. It works fine when I copy the binaries to Linux native portion of the file system, e.g. to ~/

janvorli commented 5 years ago

@Const-me interesting, I'll take a look into why the different file system results in an OOM.

SecH0us3 commented 5 years ago

@Const-me, Thanks! I turned off WSL and dotnet new passed )

htdag commented 4 years ago

@janvorli Thank you for your explain.

Would you be able to at least enlarge if not remove the limit?

No, my hosting provider does not allow to change any system settings.

Just test on another hosting with ulimit -v unlimited, and it works fine. Any other solution to deal with limited ulimit?

janvorli commented 4 years ago

We cannot do anything with it at the moment, however it seems it would make sense to make .NET Core aware of the virtual memory limit and reduce the initial virtual memory range reservation based on that. It currently doesn't expect any virtual memory limits.

Thiago-PC889 commented 1 year ago

Comigo ta Este Codigo De Problema Tambem, Eu Tento Adicionar O Negocio Do Terminal.GUI Mais Da Nisso:

C:\Users\cLiEnTe\Documents\Csharp-Projects\Terminal-01>dotnet add package Terminal.GUI Determinando os projetos a serem restaurados... Writing C:\Users\cLiEnTe\AppData\Local\Temp\tmp1DD3.tmp Failed to create CoreCLR, HRESULT: 0x8007000E

Detalhes Do Meu Notebook: Notebook: Emachines Modelo: emd732 (D732-6643) Memoria: 3 GB DRR3 Memory (Windows: 2,00 GB (utilizavel: 1,74 GB) Bios: Atuallizada OS: Windows 7 Professional 64-bit

perlun commented 1 day ago

We cannot do anything with it at the moment, however it seems it would make sense to make .NET Core aware of the virtual memory limit and reduce the initial virtual memory range reservation based on that. It currently doesn't expect any virtual memory limits.

@janvorli, I'm under the impression that you fixed this in https://github.com/dotnet/runtime/issues/79612, so perhaps this issue could be closed now?