[Telemetry] Prevent crashes in shell-less containers (#32226)
## Description
Fixes #32173.
ONNX Runtime 1.29.0 crashes during `OrtEnv` initialization in
chiseled/distroless Linux images when POSIX telemetry is enabled. These
images omit both `/etc/machine-id` and `/bin/sh`, so
`cpp_client_telemetry` reaches its device-ID fallback and `popen()`
fails.
The SDK currently constructs `std::shared_ptr<FILE>(nullptr, pclose)`. A
`shared_ptr` created with a custom deleter invokes that deleter even for
a null pointer, so teardown calls `pclose(nullptr)` and segfaults in
`_IO_new_fclose`.
Own the `FILE*` with a lambda-deleter `unique_ptr`. `Exec()` has sole
ownership of the pipe, and `unique_ptr` naturally skips its deleter when
`popen()` returns null, allowing the empty-result fallback to work as
intended when no shell is available.
## Validation
- Reproduced the issue with the released `Microsoft.ML.OnnxRuntime`
1.29.0 package in the filesystem from
`mcr.microsoft.com/dotnet/aspnet:10.0-noble-chiseled` under its default
UID.
- Telemetry enabled: deterministic SIGSEGV at `OrtEnv.Instance()`.
- `ORT_DISABLE_TELEMETRY=1`: initialization succeeds.
- Captured the failing native backtrace: `pclose(nullptr)` enters
`_IO_new_fclose(fp=0x0)` immediately after the failed `popen()`
fallback.
- Built the telemetry-enabled Linux shared library with this
unique-ownership implementation and warnings treated as errors.
- Replaced the native library in the same managed repro and chiseled
filesystem.
- Telemetry enabled: initialization succeeds.
- `ORT_DISABLE_TELEMETRY=1`: initialization succeeds.
## Upstream
The SDK fix is proposed in microsoft/cpp_client_telemetry#1523. ORT
should retain this compatibility patch until it pins an SDK release
containing that change.
`Exec()` is used only by the non-Apple legacy device-ID fallback when
`/etc/machine-id` is unavailable. ORT replaces the SDK-generated ID with
its own persistent hashed device ID after `LogManager` initialization,
but the SDK probe currently runs before that override. A future SDK
option to suppress automatic device-ID discovery would let ORT avoid
this unnecessary shell probe entirely; the null-safe cleanup is still
required for existing SDK consumers and versions.
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: d7d2f27a-7339-4585-ad02-9f89ce20ef40