Skip to content

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

Open
@sultanaalyami

Description

@sultanaalyami

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.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions