-
Notifications
You must be signed in to change notification settings - Fork 4.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implementation of AppContext.BaseDirectory and DllImportSearchPath.AssemblyDirectory handling on NativeAOT in the SharedLibrary scenario is unintuitive #112290
Comments
Tagging subscribers to this area: @agocke, @MichalStrehovsky, @jkotas |
Previously: #90131 If we can find a mechanism that reliably works crossplatform, it would certainly be an improvement over the current state. Note that shared libraries could also take advantage of the DirectPInvoke mechanism and have the OS deal with binding (and use OS-level overrides). |
As mentioned, I think it’s reasonable to have a different behavior for Native aot libraries vs applications. Only complication is determining which one we’re compiling for, so we can use a different implementation. I suppose we could use a feature switch for this. |
We have mechanisms in the bootstrapper and the NativeAOT runtime initialization to know whether or not we're running from an Exe or Library scenario. We could use that to differentiate. |
That mechanism is a hack added for #91715. I think building native AOT into a static library will make it think we're in a DLL when in fact we don't know. For the hack purposes, it's fine, since event pipe is already unsupported in OutputType!=EXE scenarios and the hack just makes it sort of work. I think this will need run time probing; we don't know if we're a shared library at compile time. |
/cc @lateralusX |
We use something similar for Mono components where we have logic to find other runtime component shared libraries that is side by side with the runtime using this logic: runtime/src/mono/mono/metadata/components.c Line 147 in 9b77dd4
The runtime doesn't know how it will be linked, so it uses a runtime check to get hold of the module owning some symbol at link time in order to get hold of the module owning that address. This scenario doesn't support the case where runtime is static linked into application and the components end up as shared library, but the probing could be extended with a fallback on unix if dladdr didn't find the address, since that would mean we should fallback to use the application path (like we currently do). We use this implementation on all platforms that support dynamic loadable components, so it works on at least on Windows, Linux, OSX, iOS, tvOS and Android. |
The fix was reverted in #113211 |
On NativeAOT today,
DllImportSearchPath.AssemblyDirectory
tells the runtime to load the requested library fromPath.Combine(AppContext.BaseDirectory, libName)
. On NativeAOT,AppContext.BaseDirectory
is always defined as the directory of the process executable. As a result, trying to load a native shared library from a NativeAOT application will always look next to the process entry module.This makes sense for NativeAOT applications that produce executables, but this behavior becomes unintuitive for SharedLibrary-based NativeAOT applications. In that scenario, using
DllImportSearchPath.AssemblyDirectory
will look next to the entry executable of the process, not next to the NativeAOT shared library.This makes it extremely difficult to load any native shared libraries that are shipped alongside a NativeAOT shared library. Users are forced to manually use P/Invokes to
GetModuleFileName
anddladdr
to determine their path (or, if loaded by another native library, passed these values) and manually callNativeLibrary.Load(string)
with the full path to load, losing all of the niceties ofLibraryImport/DllImport
or theNativeLibrary.Load
overload that takesDllImportSearchPath
(like prependinglib
and appending.so
/.dylib
on different platforms).I propose that on NativeAOT SharedLibrary scenarios, the "Assembly directory" that's used is the directory that the NativeAOT shared library is installed in, not the directory where the executable that loads the library is located.
@agocke has also expressed that we should continue to have AppContext.BaseDirectory and the "Assembly directory" be the same, and if we decide to do this to change the AppContext.BaseDirectory path to always be the path to the NativeAOT-produced library or exe that is calling
AppContext.BaseDirectory
, not always the process executable path.@max-charlamb hit this while working on the native unwinder work for the cDAC.
The text was updated successfully, but these errors were encountered: