Skip to content

Fix DllImportResolver#27397

Merged
tianleiwu merged 2 commits intomainfrom
tlwu/fix_dll_import_resolver
Feb 24, 2026
Merged

Fix DllImportResolver#27397
tianleiwu merged 2 commits intomainfrom
tlwu/fix_dll_import_resolver

Conversation

@tianleiwu
Copy link
Copy Markdown
Contributor

@tianleiwu tianleiwu commented Feb 20, 2026

Description

This PR addresses two issues related to the newly added DllImportResolver for .NET native library loading:

  1. Fix IL3000 Warning during Native AOT / Single-File Publish
    When publishing projects that reference Microsoft.ML.OnnxRuntime as a single file or using Native AOT in .NET 9, the compiler reports an IL3000 warning/error because DllImportResolver accesses Assembly.Location. In these deployment models, Assembly.Location always returns an empty string or throws.
    Since DllImportResolver already correctly handles the empty string failure and falls back to AppContext.BaseDirectory (which is fully supported), this PR adds the [UnconditionalSuppressMessage] attribute to suppress the build warning statically.

  2. Fix TypeInitializationException in NativeMethods Static Constructor
    Users reported a System.TypeInitializationException: The type initializer for 'Microsoft.ML.OnnxRuntime.NativeMethods' threw an exception. when initializing the ONNX Runtime environment.
    This occurs because the DllImportResolver (registered in the static constructor) is invoked on the first P/Invoke (OrtGetApiBase). If any API within the resolver throws an unhandled exception (for instance, AppContext.BaseDirectory throwing AppDomainUnloadedException in sandboxed AppDomains or Environment.GetEnvironmentVariable throwing SecurityException), the exception bubbles up and crashes the application with a type initialization failure.
    This PR wraps the DllImportResolver logic in a try-catch block (specifically handling AppContext.BaseDirectory edge cases) so that any resolution failure safely swallows the error and falls back to IntPtr.Zero, allowing the default .NET Platform Invoke mechanism to take over and throw a standard DllNotFoundException instead of a fatal type initialization crash.
    A unit test (TestDllImportResolverDoesNotThrow) has been added to OrtEnvTests.cs to verify that DllImportResolver successfully swallows internal exceptions without crashing the initialization process.

Motivation and Context

These changes ensure that .NET developers can safely compile Native AOT/Single-File applications without build errors and prevent hard application crashes in environments with restricted permissions.

@eserscor
Copy link
Copy Markdown
Contributor

Is it possible to add a test so we don't regress again?

@tianleiwu tianleiwu merged commit 426b006 into main Feb 24, 2026
153 checks passed
@tianleiwu tianleiwu deleted the tlwu/fix_dll_import_resolver branch February 24, 2026 00:43
tianleiwu added a commit that referenced this pull request Feb 26, 2026
### Description
This PR addresses two issues related to the newly added
`DllImportResolver` for `.NET` native library loading:

1. **Fix IL3000 Warning during Native AOT / Single-File Publish**
When publishing projects that reference `Microsoft.ML.OnnxRuntime` as a
single file or using Native AOT in .NET 9, the compiler reports an
`IL3000` warning/error because `DllImportResolver` accesses
`Assembly.Location`. In these deployment models, `Assembly.Location`
always returns an empty string or throws.
Since `DllImportResolver` already correctly handles the empty string
failure and falls back to `AppContext.BaseDirectory` (which is fully
supported), this PR adds the `[UnconditionalSuppressMessage]` attribute
to suppress the build warning statically.

2. **Fix `TypeInitializationException` in `NativeMethods` Static
Constructor**
Users reported a `System.TypeInitializationException: The type
initializer for 'Microsoft.ML.OnnxRuntime.NativeMethods' threw an
exception.` when initializing the ONNX Runtime environment.
This occurs because the `DllImportResolver` (registered in the static
constructor) is invoked on the first P/Invoke (`OrtGetApiBase`). If any
API within the resolver throws an unhandled exception (for instance,
`AppContext.BaseDirectory` throwing `AppDomainUnloadedException` in
sandboxed AppDomains or `Environment.GetEnvironmentVariable` throwing
`SecurityException`), the exception bubbles up and crashes the
application with a type initialization failure.
This PR wraps the `DllImportResolver` logic in a `try-catch` block
(specifically handling `AppContext.BaseDirectory` edge cases) so that
any resolution failure safely swallows the error and falls back to
`IntPtr.Zero`, allowing the default .NET Platform Invoke mechanism to
take over and throw a standard `DllNotFoundException` instead of a fatal
type initialization crash.
A unit test (`TestDllImportResolverDoesNotThrow`) has been added to
`OrtEnvTests.cs` to verify that `DllImportResolver` successfully
swallows internal exceptions without crashing the initialization
process.

### Motivation and Context
These changes ensure that .NET developers can safely compile Native
AOT/Single-File applications without build errors and prevent hard
application crashes in environments with restricted permissions.
tianleiwu added a commit that referenced this pull request Feb 27, 2026
This cherry-picks the following commits for the release:

| Commit ID | PR Number | Commit Title |
|-----------|-----------|-------------|
| decd177 | #27090 | Fix GatherND division by zero when batch
dimensions mismatch |
| 55f8234 | #27360 | Fix QMoE CPU Operator |
| df9146f | #27403 | [MLAS] Adding DynamicQGemm function pointers and
ukernel interface |
| 0f93853 | #27318 | [js/web] Use embedded WASM module in Blob URL
workers when wasmBinary is provided |
| b2a6e69 | #27364 | QMoE CPU Performance Update (Up to 4x on 4-bit)
|
| f501e1d | #27413 | Fix refcount bug in map input conversion that
caused shutdown segfault |
| b32b205 | #27421 | Fix error where bytes is not assigned for
dynamic qgemm pack b size |
| 426b006 | #27397 | Fix DllImportResolver |
| 0982844 | #27412 | MatmulNBits prepacking scales fix |
| 9afb0d2 | #27430 | Fix validation for external data paths for
models loaded from bytes |
| 71d2cd0 | #27401 | Enable Python 3.14 CI and Upgrade Dependencies |
| 79e0676 | #27419 | fix: out of bounds access for resize operation |
| 82eb99c | #27459 | Fix SkipLayerNorm fusion incorrectly applied
when gamma/beta are not 1D |
| 355278a | #27444 | Fix GatherCopyData Integer Truncation Leading to
Heap Out-of-Bounds Read/Write |
| cf96123 | #27411 | [web] fix usage of wasmBinary together with a
blob URL for .mjs |
| 1131a86 | #27399 | [web] remove the unhelpful "Unknown CPU vendor"
warning. |
| ffbbc4f | #27316 | Build Windows ARM64X binaries as part of
packaging pipeline |

---------

Signed-off-by: Jonathan Clohessy <Jonathan.Clohessy@arm.com>
Co-authored-by: patryk-kaiser-ARM <patryk.kaiser@arm.com>
Co-authored-by: don <70039285+0-don@users.noreply.github.com>
Co-authored-by: Jonathan Clohessy <jonathan.clohessy@arm.com>
Co-authored-by: Hariharan Seshadri <shariharan91@gmail.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Adrian Lizarraga <adlizarraga@microsoft.com>
Co-authored-by: Lukas Folle <126877803+lukas-folle-snkeos@users.noreply.github.com>
Co-authored-by: Chi Lo <54722500+chilo-ms@users.noreply.github.com>
Co-authored-by: Yulong Wang <7679871+fs-eire@users.noreply.github.com>
Co-authored-by: Chaya <cha182350@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Erik <erscor@microsoft.com>
Co-authored-by: Edward Chen <18449977+edgchen1@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants