Fix session logger use-after-free during EP teardown under VERBOSE logging (#28274)
### Description
Move `owned_session_logger_` declaration before `execution_providers_`
in `InferenceSession` so the logger outlives EPs during member
destruction.
C++ destroys members in reverse declaration order. Previously:
```
~owned_session_logger_ (L905) // logger freed
↓
~execution_providers_ (L745) // EP teardown logs via dangling pointer → crash
```
After this change:
```
~execution_providers_ (L750) // EP teardown logs safely ✅
↓
~owned_session_logger_ (L744) // logger freed, no remaining users
```
### Motivation and Context
Plugin EPs receive an `OrtLogger*` via `OrtEpFactory::CreateEp()`.
During session destruction, EP teardown callbacks (e.g.,
`ReleaseNodeComputeInfos`) may log through this pointer. Because
`owned_session_logger_` was declared after `execution_providers_`, the
logger was already freed when EPs destructed — a use-after-free that
crashes deterministically under VERBOSE logging.
Affects all Plugin EPs that log in any teardown path. Reproduced with
OpenVINO Plugin EP via `webnn_graph_impl_fuzzer` at VERBOSE level.
Fixes https://github.com/microsoft/onnxruntime/issues/28234
### Tests Added
Added regression tests in
`onnxruntime/test/framework/inference_session_test.cc`:
- **`LoggingOnDestroyExecutionProvider`** — A mock EP that logs via its
stored logger pointer in its destructor. If the logger has been freed,
this triggers a use-after-free (detected by ASan or as a segfault).
- **`SessionLoggerOutlivesEPsOnDestruction`** — Creates a session with
VERBOSE logging and the mock EP, then destroys the session. Verifies
that the logger was valid during EP teardown and that the teardown log
message was captured.
- **`SessionLoggerOutlivesEPsWithMultipleEPs`** — Same scenario with two
mock EPs (distinct type names) to confirm all registered EPs can safely
log during teardown.
### Verification
Confirmed the tests are effective regression tests:
| Scenario | Result |
|----------|--------|
| **With fix** (logger declared before EPs) | Both tests pass ✅ |
| **Without fix** (logger declared after EPs, original bug) |
`SessionLoggerOutlivesEPsOnDestruction` crashes with **Segmentation
fault** (exit code 139) — use-after-free ❌ |
This proves the member declaration order is the critical factor, and the
tests will catch any future regression that reorders these members.
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: tianleiwu <30328909+tianleiwu@users.noreply.github.com>