Skip to content

RegisterExecutionProviderLibrary leaks one loader ref on plugin-EP DLLs (ProviderLibrary::Load early-return after LoadDynamicLibrary) #28395

@BoarQing

Description

@BoarQing

Describe the issue

OrtApi::RegisterExecutionProviderLibrary leaks one Win32 / dlopen reference on the EP DLL when the registered DLL does not export GetProvider (i.e. plugin EPs, e.g. onnxruntime_vitisai_ep.dll).

After a single Register + Unregister + ReleaseEnv cycle the EP DLL is still mapped (refcount = 1). On Windows this often surfaces as a STATUS_STACK_BUFFER_OVERRUN (0xC0000409) fast-fail during process teardown because the EP DLL outlives Unregister.

Root cause: ProviderLibrary::Load() (in onnxruntime/core/session/provider_bridge_ort.cc) calls LoadDynamicLibrary and then GetSymbolFromLibrary("GetProvider", ...). When the symbol lookup fails, ORT_RETURN_IF_ERROR returns early without calling Unload(). ~ProviderLibrary() is empty, so the temporary provider_library constructed by LoadPluginOrProviderBridge (in utils.cc) silently leaks its handle. EpLibraryPlugin::Load() then LoadDynamicLibrarys the same DLL again — refcount = 2 — and UnregisterExecutionProviderLibrary only releases one reference.

To reproduce

Standalone Win32 reproducer (no model, no inference, no link against onnxruntime.lib):

https://github.com/BoarQing/ep_double_load_repro

loaded onnxruntime.dll (runtime ORT version: 1.25.0)
ep dll leaked refcount after Unregister+ReleaseEnv = 1   <-- expected 0

Fix

PR #28396 — call Unload() in ProviderLibrary::Load() when the GetProvider symbol lookup fails. With the patch, the repro reports = 0.

Platform

Windows

OS Version

Windows 10.0.26100 (24H2), x64

ONNX Runtime Installation

Built from Source

ONNX Runtime Version or Commit ID

1.25.0 (also reproduces on main at e3c34da)

ONNX Runtime API

C

Architecture

X64

Execution Provider

Vitis AI

Execution Provider Library Version

onnxruntime_vitisai_ep.dll (registered via RegisterExecutionProviderLibrary("VitisAIExecutionProvider", ...)). The bug is in generic loader code, so it should reproduce with any plugin EP DLL that does not export GetProvider.

Metadata

Metadata

Assignees

No one assigned

    Labels

    ep:VitisAIissues related to Vitis AI execution provider

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions