Description
Found on ARM64 Alpine Linux.
Only tested with .NET 6 but I would expect the bug to affect the rest of the Alpine Linux runtimes too.
Steps to reproduce
Use gcc to compile a C DLL which exports a function. Place the compiled DLL into different folder, such as linux-musl-arm64
subfolder.
Use the following code to load it from absolute path:
[DllImport( "libdl" )]
static extern IntPtr dlopen( [In, MarshalAs( UnmanagedType.LPUTF8Str )] string fileName, int flags );
const int RTLD_NOW = 0x002;
string iLoadLibrary.fileName( string dll ) => $"lib{ dll }.so";
void iLoadLibrary.load( string dll )
{
IntPtr handle = dlopen( dll, RTLD_NOW );
if( handle != IntPtr.Zero )
return;
throw new ApplicationException( $"dlopen failed to load { Path.GetFileName( dll ) }" );
}
In another class, consume the function exported from the DLL with [DllImport]
attribute.
In the main function, call iLoadLibrary.load
with absolute path to the *.so
file, then call the imported function.
Compile and run the .NET app.
Expected Behavior
Should work like on the rest of the platforms (Windows, non-Alpine Linux including ARM)
Actual Behavior
Exception saying it’s unable to find my DLL, despite already loaded into the current process with dlopen
.
Couple more notes.
I did try to copy the DLL into the same location where the C# DLL is, worked fine that way. Can’t do that in production because I support multiple architectures, and for security reasons the process does not have permissions to write its own binaries.
If you don’t know how to enumerate loaded native DLLs on Linux, read this. BTW, that’s how I’m detecting musl libc on Linux, by looking for the loaded ld-musl-*
DLL.
Metadata
Metadata
Assignees
Type
Projects
Status