Skip to content

GetCommandLineArgsNative fallback used for hosted libraries is not implemented on non-Windows #128545

Description

@CasualPokePlayer

Description

Under NativeAOT, it is possible create a native library which can be consumed by a native executable (e.g. a .so shared library on Linux). On such a setup, Environment.GetCommandLineArgs() returns an empty array on Linux. It does not do this under Windows (instead functioning completely as "expected"). This means Environment.GetCommandLineArgs()[0] will throw under Linux in this type of setup.

Reproduction Steps

using System;
using System.Runtime.InteropServices;

namespace Program;

internal static class Program
{
	[UnmanagedCallersOnly(EntryPoint = "Test")]
	public static void Test()
	{
		try
		{
			Console.WriteLine($"Environment.GetCommandLineArgs()[0]: {Environment.GetCommandLineArgs()[0]}");
		}
		catch (Exception ex)
		{
			Console.WriteLine($"Exception: {ex}");
		}
	}
}
<Project Sdk="Microsoft.NET.Sdk">
	<PropertyGroup>
		<TargetFramework>net10.0</TargetFramework>
		<OutputType>Library</OutputType>
		<NativeLib>Shared</NativeLib>
		<PublishAot>true</PublishAot>
		<TargetName>libProgram</TargetName>
	</PropertyGroup>
</Project>

dotnet publish -r linux-x64

#include <dlfcn.h>
#include <stdio.h>

typedef void (*TestFunc)(void);

int main(void)
{
	void* handle = dlopen("./libProgram.so", RTLD_NOW | RTLD_LOCAL);
	TestFunc testFunc = (TestFunc)dlsym(handle, "Test");
	testFunc();
}

Expected behavior

Environment.GetCommandLineArgs docs states:

The first element in the array contains the file name of the executing program. If the file name is not available, the first element is equal to String.Empty.

This implies that the array returned should have at least 1 element. As such, an empty array should not be returned (at the best least it should have 1 element with an empty string, so Environment.GetCommandLineArgs()[0] will not throw).

Actual behavior

Environment.GetCommandLineArgs()[0] throws.

Regression?

No response

Known Workarounds

Do not assume Environment.GetCommandLineArgs() has at least 1 element. try/catch for third party code that makes such assumptions.

Configuration

This was originally encountered on Android with linux-bionic (as such under NativeAOT practically means you would be making a shared library anyways). On standard Linux (Ubuntu), this issue also occurs. On Windows, this issue does not occur (it's even able to provide command line args for the host exe just fine).

Other information

This was originally encountered with System.CommandLine as the RootCommand ctor triggers this exception.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    • Status
      No status

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions