Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.

Add NativeLibrary Resolve Event #21929

Merged
merged 1 commit into from
Jan 13, 2019
Merged

Conversation

swaroop-sridhar
Copy link

This change adds the Native library resolving event, to be raised as the last attempt to resolve a native DLL in an AssemblyLoadContext.

With this change, the DllImport resolution sequence is as follows (stopping at any step with successful resolution):

  • If the invoking-assembly is not in the default load context, call AssemblyLoadContext.LoadUnmanagedDll()
  • Run the default load logic, try loading from:
    • AppDomain cache
    • NATIVE_DLL_SEARCH_DIRECTORIES
    • Invoking-assembly directory, System32, etc. based on DllImportSearchPaths
  • Raise the ResolvingUnmanagedDll event

API Review: https://github.com/dotnet/corefx/issues/32850


if (dllResolveHandler != null)
{
// Loop through the event subscribers and return the first non-null Assembly instance
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return the first non-null Assembly instance

Copy&paste. This is not returning Assembly instances...

@@ -509,7 +540,22 @@ internal static void OnProcessExit()
}
}

/// Event handler for resolving native libraries.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you want to use /// comments, you have to make them a valid XML.

src/vm/dllimport.cpp Outdated Show resolved Hide resolved
src/vm/dllimport.cpp Show resolved Hide resolved
src/vm/dllimport.cpp Show resolved Hide resolved
src/vm/dllimport.h Outdated Show resolved Hide resolved
tests/src/Interop/CMakeLists.txt Outdated Show resolved Hide resolved
tests/src/Interop/ResolveEvent/ResolveEventTests.cs Outdated Show resolved Hide resolved
@AaronRobinsonMSFT
Copy link
Member

I do have a quick questions about the ordering here. What is the expectation of there being an app local native library that is the wrong version, but the user wants a different version with the same name. In the current algorithm, the app local version would be found first and the defined callback wouldn't be found. Is this what we want? In the below directory layout, would the application ever get the chance to load v1/foo.dll?

App/
  foo.dll
  v1/
    foo.dll

@jkotas
Copy link
Member

jkotas commented Jan 10, 2019

he expectation of there being an app local native library that is the wrong version, but the user wants a different version with the same name

This fallback does not help you with that.

You have to use other ways to solve this - the NativeLibrary APIs, do not deploy bad applocal library, etc. No different from how would you solve the same situation for C/C++ code.

@AaronRobinsonMSFT
Copy link
Member

No different from how would you solve the same situation for C/C++ code.

Other than the fact that if the user defined a P/Invoke that is now no longer valid and it isn't obvious that the wrong library was loaded until the extension library or app developer gets a very unexpected bug.

Not arguing if this is or isn't the wrong approach, just wanted to clarify this is the intent. So our expectation here is that the events are for P/Invokes with a well structured app layout that is known to app and potential plugin developers. In the event there is a situation where non-versioned libraries can pollute the loader paths, using the NativeLibrary API directly is our recommendation right?

@swaroop-sridhar
Copy link
Author

So our expectation here is that the events are for P/Invokes with a well structured app layout that is known to app and potential plugin developers.

Yes the primary motivation for the native library resolve event is resolution for plugins. The app and it components have to agree on native-library versions to avoid problems with native libraries in the app-global scope.

@swaroop-sridhar
Copy link
Author

Thanks @AaronRobinsonMSFT I've made the additional changes.

@swaroop-sridhar
Copy link
Author

@dotnet-bot test Windows_NT arm Cross Checked Innerloop Build and Test
@dotnet-bot test Windows_NT arm64 Cross Checked Innerloop Build and Test

@swaroop-sridhar
Copy link
Author

swaroop-sridhar commented Jan 11, 2019

@adityamandaleeka and I Iooked at the failure on ARM64. The ResolveEventTests triggered a pre-existing bug in the exception handling code. So, I filed #21964 for it.

Until this is fixed, I'll disable the test on ARM64 Windows.

@adityamandaleeka
Copy link
Member

adityamandaleeka commented Jan 12, 2019

@swaroop-sridhar The assertion is familiar, but of course it could be getting triggered in this case for a completely different reason than previous occurrences. I'll investigate what's going on with EH in this situation. Thanks for reporting it!

@@ -6656,27 +6736,37 @@ HINSTANCE NDirect::LoadLibraryModule(NDirectMethodDesc * pMD, LoadLibErrorTracke
if (SString::_wcsicmp(wszLibName, MAIN_CLR_MODULE_NAME_W) == 0)
{
hmod = GetCLRModule();
if (hmod == NULL)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this condition rather be if (hmod != NULL) ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, do we need the check for NULL at all? This should never be NULL.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am surprised that this is not causing things to fail. It looks like that this special path that checks for MAIN_CLR_MODULE_NAME_W is probably just dead code and can be just deleted.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, sorry, fixed it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please rather just delete it?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've fixed the comparison for now. I'll remove the check along with the PAL registration cleanup in another upcoming PR.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this is defunct. The few places that PInvoke into coreclr in CoreLib use the proper name (libcoreclr) and I expect we will get rid of those few places too at some point.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the explanation, I deleted the code.

@swaroop-sridhar swaroop-sridhar force-pushed the Event branch 2 times, most recently from e78519f to 678c6dd Compare January 12, 2019 00:48
@swaroop-sridhar
Copy link
Author

@dotnet-bot test Windows_NT arm Cross Checked Innerloop Build and Test

This change adds the Native library resolving event, to be raised as the last attempt to resolve a native DLL in an AssemblyLoadContext.

With this change, the DllImport resolution sequence is as follows (stopping at any step with successful resolution):

* If the invoking-assembly is not in the default load context, call AssemblyLoadContext.LoadUnmanagedDll()
* Run the default load logic, try loading from:
    * AppDomain cache
    * NATIVE_DLL_SEARCH_DIRECTORIES
    * Invoking-assembly directory, System32, etc. based on DllImportSearchPaths
* Raise the ResolvingUnmanagedDll event

API Review: https://github.com/dotnet/corefx/issues/32850

The ResolveEventTests triggered a pre-existing bug in the exception handling code (#21964).
Disabling the test on ARM64 Windows until the issue is fixed.
@swaroop-sridhar
Copy link
Author

The "Tizen armel Cross Checked Innerloop Build and Test" leg is failing in every build, and looks unrelated. So will merge the change.

@swaroop-sridhar swaroop-sridhar merged commit 8b7d300 into dotnet:master Jan 13, 2019
picenka21 pushed a commit to picenka21/runtime that referenced this pull request Feb 18, 2022
This change adds the Native library resolving event, to be raised as the last attempt to resolve a native DLL in an AssemblyLoadContext.

With this change, the DllImport resolution sequence is as follows (stopping at any step with successful resolution):

* If the invoking-assembly is not in the default load context, call AssemblyLoadContext.LoadUnmanagedDll()
* Run the default load logic, try loading from:
    * AppDomain cache
    * NATIVE_DLL_SEARCH_DIRECTORIES
    * Invoking-assembly directory, System32, etc. based on DllImportSearchPaths
* Raise the ResolvingUnmanagedDll event

API Review: https://github.com/dotnet/corefx/issues/32850

The ResolveEventTests triggered a pre-existing bug in the exception handling code (dotnet/coreclr#21964).
Disabling the test on ARM64 Windows until the issue is fixed.

Commit migrated from dotnet/coreclr@8b7d300
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants