Skip to content

[Regression] iOS workload 10.0.105: NativeReference symbols no longer globally exported, breaking runtime-resolved P/Invoke #25008

@hubaksis

Description

@hubaksis

Apple platform

iOS

Framework version

net10.0-*

Affected platform version

.NET 10.0.201, iOS workload 10.0.105 (iOS SDK 26.2.10217), VS 2026 Insiders v18

Description

Note: This iOS app is on .NET 10 MAUI and uses Microsoft.ML.OnnxRuntime. After updating VS and workloads, ONNX Runtime started throwing EntryPointNotFoundException: OrtGetApiBase on iOS. After extensive debugging, rolling back the workload from 10.0.105 to 10.0.103 resolved the issue. I'm not 100% certain the workload is the sole cause (multiple variables changed during investigation), but the evidence below points to a symbol export regression. Please verify. Claude's analysis is below.

Description

Native symbols from statically linked xcframeworks (via NativeReference) are no longer globally exported in iOS workload 10.0.105 (iOS SDK 26.2.10217). They were correctly exported in workload 10.0.103 (iOS SDK 26.2.10197).

Specifically, _OrtGetApiBase from the Microsoft.ML.OnnxRuntime NuGet package (1.24.3) is linked into the binary (confirmed via nm) but marked as local (t) instead of global (T). This makes it invisible to dlsym(), causing EntryPointNotFoundException at runtime when P/Invoke tries to resolve it.

Steps to Reproduce

  1. Create a .NET MAUI iOS app referencing Microsoft.ML.OnnxRuntime 1.24.3
  2. Build for ios-arm64 (Release) with iOS workload 10.0.105 (SDK 26.2.10217)
  3. Check symbol visibility: nm -g MyApp.app/MyApp | grep OrtGetApiBase -- empty (not exported)
  4. At runtime: EntryPointNotFoundException: OrtGetApiBase

Expected Behavior

_OrtGetApiBase should be a global symbol (T) in the binary, as it is with workload 10.0.103 (SDK 26.2.10197):

nm -g MyApp.app/MyApp | grep OrtGetApiBase 0000000100ba0954 T _OrtGetApiBase 

Actual Behavior

With workload 10.0.105 (SDK 26.2.10217):

nm MyApp.app/MyApp | grep OrtGetApiBase 0000000100b8ffac t _OrtGetApiBase <-- local, not exported 
nm -g MyApp.app/MyApp | grep OrtGetApiBase <-- empty, invisible to dlsym 

Runtime error:

System.TypeInitializationException: The type initializer for 'Microsoft.ML.OnnxRuntime.NativeMethods' threw an exception. ---> System.EntryPointNotFoundException: OrtGetApiBase 

Root Cause Analysis

The -exported_symbols_list mtouch-symbols.list mechanism controls which symbols are globally visible. The ListExportedSymbols IL linker step only adds symbols referenced by DllImport("__Internal") declarations.

Microsoft.ML.OnnxRuntime.Managed uses DllImport("onnxruntime") with a runtime NativeLibrary.SetDllImportResolver to redirect to the main binary. Since the build-time scanner doesn't know about runtime-resolved P/Invoke, _OrtGetApiBase is never added to the export list.

This worked in 10.0.103 -- the symbol was exported. Something in 10.0.105 changed the export list generation or the linker flag handling.

Workarounds Attempted (None Worked with 10.0.105)

  • <ReferenceNativeSymbol Include="_OrtGetApiBase" SymbolType="Function" SymbolMode="Default" /> -- this item type appears to be removed from .NET 10 iOS SDK (only exists in .NET 9 SDK packs)
  • <_ExtraTrimmerArgs>--custom-data "ReferenceNativeSymbol=Function:Default:_OrtGetApiBase"</_ExtraTrimmerArgs> -- not processed
  • -Wl,-exported_symbol,_OrtGetApiBase in NativeReference LinkerFlags -- overridden by -exported_symbols_list
  • [DllImport("__Internal")] static extern IntPtr OrtGetApiBase() in app code -- trimmer removes it
  • <MtouchNoSymbolStrip>true</MtouchNoSymbolStrip> -- controls strip, not the export list
  • Manually appending to mtouch-symbols.list on Mac -- overwritten or not used as -exported_symbols_list

Working Workaround

Downgrade to workload 10.0.103: dotnet workload update --version 10.0.103

Environment

  • .NET SDK: 10.0.200 and 10.0.201 (both affected)
  • iOS workload 10.0.105 (iOS SDK 26.2.10217) -- BROKEN
  • iOS workload 10.0.103 (iOS SDK 26.2.10197) -- WORKS
  • Xcode 26.2
  • Mac: Apple Silicon (M-series)
  • NuGet: Microsoft.ML.OnnxRuntime 1.24.3
  • Build via Pair to Mac from Visual Studio 2026 Insiders (v18)

Impact

This regression affects any NuGet package that:

  1. Provides a static xcframework via NativeReference
  2. Uses DllImport("library-name") (not "__Internal")
  3. Resolves the library at runtime via NativeLibrary.SetDllImportResolver

This is a common pattern for native ML libraries on iOS.

Steps to Reproduce

  1. Create a .NET MAUI iOS app referencing Microsoft.ML.OnnxRuntime 1.24.3
  2. Build for ios-arm64 (Release) with iOS workload 10.0.105 (SDK 26.2.10217)
  3. Check symbol visibility: nm -g MyApp.app/MyApp | grep OrtGetApiBase -- empty (not exported)
  4. At runtime: EntryPointNotFoundException: OrtGetApiBase

Did you find any workaround?

Downgrade to workload 10.0.103: dotnet workload update --version 10.0.103

Build logs

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions