GC heap initialization failed (0x8007000E) on ARM64 Linux (Ubuntu 24.04 via Termux/proot-distro)

Open
#116,431 5 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
5/5
Estimated time
Over a week
Newbie friendliness
20/100
Issue type
Bug
Clarity
Needs clarification
Activity status
Stale
Tech stack
android, linux

Research direction

Reproduce the failure in the documented Termux, proot-distro Ubuntu 24.04, ARM64 environment by running dotnet --info, then compare the result with a native Linux ARM64 environment. Use the reported memory, swap, SDK version, and GC initialization output to determine whether this is an environment limitation or a runtime defect; done requires a confirmed cause and an actionable workaround or fix direction.

Written by the indexing model from the issue text.

Description

area-GC-coreclr
Environment
  • .NET SDK Version: 10.0.100-preview.4.25258.110
  • Operating System: Android 15 (via Termux) running Ubuntu 24.04 (Noble Numbat) via proot-distro
  • Architecture: ARM64 (aarch64)
  • Host Device: Samsung SM-F956B (Galaxy Z Fold 6)
  • Termux Version: googleplay.2025.01.18
  • proot-distro Version: v4.25.0
  • Wasmtime Version: Not yet installed (N/A for this specific issue)
Description

I am attempting to set up a .NET development environment on my ARM64 Android device (Samsung SM-F956B, Galaxy Z Fold 6) using Termux and proot-distro (to host Ubuntu 24.04). My long-term goal is to explore the feasibility of running ASP.NET Core SignalR Hubs within a WebAssembly (WASM) / WebAssembly System Interface (WASI) environment, potentially for serverless or edge compute solutions.

After successfully downloading and extracting the .NET 10 Preview 4 SDK for linux-arm64 into the Ubuntu environment (which runs inside proot-distro), I consistently encounter a GC heap initialization failed with error 0x8007000E (E_OUTOFMEMORY) when running any dotnet command (e.g., dotnet --info, dotnet new console).

Steps to Reproduce
  1. Install Termux from F-Droid.
  2. Inside Termux, install proot-distro:
    pkg install proot-distro -y
    
  3. Install Ubuntu 24.04 LTS:
    proot-distro install ubuntu
    
  4. Log in to the Ubuntu environment:
    proot-distro login ubuntu
    
  5. Inside Ubuntu, update packages and install essential tools:
    apt update && apt upgrade -y
    apt install curl wget git -y
    
  6. Verify architecture (output was arm64):
    dpkg --print-architecture
    
  7. Download .NET 10.0.100-preview.4 SDK for Linux ARM64:
    mkdir -p ~/dotnet
    wget [https://builds.dotnet.microsoft.com/dotnet/Sdk/10.0.100-preview.4.25258.110/dotnet-sdk-10.0.100-preview.4.25258.110-linux-arm64.tar.gz](https://builds.dotnet.microsoft.com/dotnet/Sdk/10.0.100-preview.4.25258.110/dotnet-sdk-10.0.100-preview.4.25258.110-linux-arm64.tar.gz) -O dotnet-sdk.tar.gz
    
  8. Extract the SDK:
    tar -xzf dotnet-sdk.tar.gz -C ~/dotnet
    
  9. Add .NET to PATH:
    echo 'export DOTNET_ROOT=$HOME/dotnet' >> ~/.bashrc
    echo 'export PATH=$PATH:$HOME/dotnet' >> ~/.bashrc
    source ~/.bashrc
    
  10. Attempt to verify installation (this is where the error occurs):
    dotnet --info
    
Expected Behavior

dotnet --info should display the SDK information without any errors, indicating a successful initialization of the .NET CoreCLR runtime.

Actual Behavior

The command consistently fails with the following output:

GC heap initialization failed with error 0x8007000E
Failed to create CoreCLR, HRESULT: 0x8007000E
This error suggests an OutOfMemory condition or a failure to allocate necessary memory segments.

Troubleshooting Performed
  1. Verified sufficient storage: df -h /data/data/com.termux/files/home shows ample free space (291G available).
  2. Verified successful SDK download: The wget operation completed 100% with no errors.
  3. Attempted Termux/device restart: Performed a full restart of the Android device and the Termux app.
  4. Attempted to add swap space within the proot-distro Ubuntu environment:
    fallocate -l 8G /swapfile # or dd if=/dev/zero...
    chmod 600 /swapfile
    mkswap /swapfile
    swapon /swapfile # Fails with "swapon failed: Function not implemented"
    
    Despite swapon failing (due to proot-distro limitations for direct kernel interaction), free -h command's output shows significant available RAM (Mem: 10Gi total, 3.5Gi available) and active Swap space (Swap: 8.0Gi total, 4.7Gi used). This suggests that system-level swap is active (possibly via Android's ZRAM or similar mechanisms) and that the 0x8007000E error is likely not a simple total memory exhaustion, but rather a failure to allocate specific types of memory or to initialize the GC heap within the proot-distro's emulated environment, potentially due to underlying kernel/syscall compatibility issues or specific memory management semantics that CoreCLR expects.
Potential Root Cause (Hypothesis)

Given the ample memory resources reported by free -h and the swapon failure, it is hypothesized that the issue might be related to:

  1. CoreCLR's specific memory allocation requirements: The runtime may be trying to allocate memory segments (e.g., for its GC heap) in a way that is not fully compatible with the memory management layer provided by proot-distro or the Android Bionic linker's specific TLS segment alignment.
  2. proot-distro / Android kernel limitations: Despite proot-distro providing a Linux user-space environment, there might be underlying kernel-level syscalls or memory mapping features that are either not fully implemented or have different behaviors compared to a native Linux kernel.
  3. Preview build instability: As this is a preview version of .NET 10, it might contain bugs or new features that are less stable in highly specialized environments like Termux/proot-distro.
Request

I am seeking engineering guidance and insights into how to resolve this GC heap initialization failed issue. My primary goal is to establish a functional .NET development and execution environment on ARM64 Android devices to validate the feasibility of running complex .NET workloads (such as ASP.NET Core SignalR Hubs) in WASM/WASI for serverless or edge compute scenarios. Resolving this foundational issue is crucial for my research.

I am open to:

  • Trying specific environment variables for CoreCLR (COMPlus_ variables).
  • Exploring alternative proot-distro configurations or Linux distributions.
  • Any insights into CoreCLR's memory allocation patterns or requirements in such emulated/constrained environments.

Your expertise in this area would be highly appreciated. Thank you.

Dominant language
C#
Stars
18.3k
Forks
5.6k
PR merge metrics
PR metrics pending

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from dotnet/runtime

All issues in dotnet/runtime

Similar issues

More C# issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.