microsoft / microsoft/onnxruntime

XNNPACK EP on Android arm64 aborts the process (Abort message: 'terminating') instead of returning an error — Resize with empty scales, still in 1.26.0

Open
#32,298 0 comments 0 reactions 0 assignees View on GitHub
.NET api:CSharp ep:Xnnpack platform:mobile
Dominant language
C++
Stars
21.9k
Forks
4.2k
Avg merge
4d 11h
Merged PRs (30d)
184

Description

### Describe the issue

Creating an `InferenceSession` with the XNNPACK EP on Android arm64 **aborts the whole process** (`SIGABRT`, `Abort message: 'terminating'`) instead of returning an error. Because the C++ exception escapes through `std::terminate`, a managed `try/catch` around session creation cannot intercept it, so an application has no way to probe for XNNPACK support and fall back to CPU.

This is the same failure mode reported in #23826 (closed as a documentation issue). That reporter tracked the root cause down to `Resize` nodes whose `scales` input is an **empty tensor**, and worked around it by patching their own copy of the XNNPACK wrapper. The underlying crash is still present in **1.26.0**, and it reproduces with a widely used public model.

Two separable problems:

1. XNNPACK cannot handle `Resize` with an empty `roi`/`scales` initializer (opset 11 style, produced by `tf2onnx`).
2. Regardless of (1) — an unsupported node should not terminate the process. Session creation should fail with a catchable status so callers can fall back to the CPU EP.

### To reproduce

**Model:** MoveNet SinglePose Lightning v4, `tf2onnx` conversion — public and directly downloadable:

```
https://raw.githubusercontent.com/Kazuhito00/MoveNet-Python-Example/515743a113e49b4f31677b1f6252c0041f237e30/onnx/movenet_singlepose_lightning_4.onnx
```

Input `1x192x192x3` int32 NHWC, output `1x1x17x3`, `opset_import: ai.onnx v11`.

The model contains three `Resize` nodes, each with `roi` and `scales` bound to the same zero-length initializer:

```
Resize__347 inputs = [ ...conv2d/BiasAdd:0, const_empty_float__341, const_empty_float__341, Concat__346:0 ]
Resize__368 inputs = [ ...re_lu/Relu:0, const_empty_float__341, const_empty_float__341, Concat__367:0 ]
Resize__389 inputs = [ ...re_lu_1/Relu:0, const_empty_float__341, const_empty_float__341, Concat__388:0 ]

const_empty_float__341: initializer, dims = [0] # empty tensor
```

**Code** (C#, `Microsoft.ML.OnnxRuntime` 1.26.0, .NET 10 Android):

```csharp
using var options = new SessionOptions();
options.AppendExecutionProvider(
"XNNPACK",
new Dictionary { ["intra_op_num_threads"] = "2" });

// Never returns. The process aborts here; the surrounding try/catch never runs.
using var session = new InferenceSession(modelBytes, options);
```

The same model loads and runs correctly with default session options (CPU EP) on the same device.

### Urgency

Not blocking — we fall back to the CPU EP. But it costs us the ability to even *probe* for XNNPACK at runtime: a process-level abort cannot be guarded, so the only safe option is never to request the EP at all.

### Platform

Android

### OS Version

Android 15 (`realme/RMX3771RU/RE58B8L1:15/AP3A.240617.008`), arm64-v8a, MediaTek Dimensity 7050

### ONNX Runtime Installation

Released Package

### ONNX Runtime Version or Commit ID

1.26.0 (`Microsoft.ML.OnnxRuntime` NuGet; native library from `runtimes/android/native/onnxruntime.aar`, `jni/arm64-v8a/libonnxruntime.so`)

### ONNX Runtime API

C#

### Architecture

ARM64

### Execution Provider

Other / Unknown (XNNPACK)

### Execution Provider Library Version

XNNPACK as shipped inside the 1.26.0 Android AAR (`XnnpackExecutionProvider` symbols are present in `jni/arm64-v8a/libonnxruntime.so`, so the EP is compiled in).

### Actual behaviour

```
F libc : Fatal signal 6 (SIGABRT), code -1 (SI_QUEUE) in tid 32022 (.NET TP Worker)
F DEBUG : Build fingerprint: 'realme/RMX3771RU/RE58B8L1:15/AP3A.240617.008/T.231124a_d5daf:user/release-keys'
F DEBUG : ABI: 'arm64'
F DEBUG : pid: 31996, tid: 32022, name: .NET TP Worker
F DEBUG : signal 6 (SIGABRT), code -1 (SI_QUEUE), fault addr --------
F DEBUG : Abort message: 'terminating'
F DEBUG : backtrace:
F DEBUG : #00 pc 0000000000093dc8 /apex/com.android.runtime/lib64/bionic/libc.so (abort+168)
F DEBUG : #01 pc 00000000009c32a8 /lib/arm64/libonnxruntime.so
F DEBUG : #02 pc 00000000009c2d04 /lib/arm64/libonnxruntime.so
F DEBUG : #03 pc 00000000009c2ca0 /lib/arm64/libonnxruntime.so
F DEBUG : #04 pc 00000000009c2c64 /lib/arm64/libonnxruntime.so
F DEBUG : #05 pc 00000000009ff2a8 /lib/arm64/libonnxruntime.so
F DEBUG : #06 pc 0000000000b6ace4 /lib/arm64/libonnxruntime.so
F DEBUG : #07 pc 0000000000b79f04 /lib/arm64/libonnxruntime.so
F DEBUG : #08 pc 0000000000b53d94 /lib/arm64/libonnxruntime.so
F DEBUG : #09 pc 00000000013d810c /lib/arm64/libonnxruntime.so
F DEBUG : #10 pc 00000000013dad94 /lib/arm64/libonnxruntime.so
F DEBUG : #11 pc 00000000013d85d4 /lib/arm64/libonnxruntime.so
F DEBUG : #12 pc 00000000013d49d8 /lib/arm64/libonnxruntime.so
F DEBUG : #13 pc 0000000000a2223c /lib/arm64/libonnxruntime.so
F DEBUG : #14 pc 0000000000a26d60 /lib/arm64/libonnxruntime.so
F DEBUG : #15 pc 0000000000acdd5c /lib/arm64/libonnxruntime.so
F DEBUG : #16 pc 00000000009e89f4 /lib/arm64/libonnxruntime.so
F DEBUG : #17 pc 00000000001abc08 /lib/arm64/libmonosgen-2.0.so
...
F DEBUG : #21 pc 000000000025acc8 /lib/arm64/libmonosgen-2.0.so (mono_runtime_invoke_checked+140)
```

(`libonnxruntime.so` BuildId `de83f9cb47b2efdf4d6ddb222f4ac169dec0542e`. The library is unstripped only to the extent shipped in the AAR, hence the bare addresses.)

### Expected behaviour

Session creation with an unsupported model should fail with an `OrtStatus` / `OnnxRuntimeException` that the caller can catch and handle — for example by falling back to the CPU EP — rather than calling `std::terminate` and taking the process down.

Additionally, `Resize` with an empty `roi`/`scales` initializer is valid ONNX (both inputs are optional and this is what `tf2onnx` emits for opset 11); XNNPACK should either handle it or decline to take the node during partitioning.

Contributor guide

Open the contributing guide

Research direction

Start with the C# InferenceSession reproduction using the MoveNet model and the XNNPACK execution provider, then trace the Resize nodes with empty roi/scales inputs through the native XNNPACK path. Done means unsupported models return a catchable OrtStatus or OnnxRuntimeException without terminating the Android process, and valid empty Resize inputs are handled or declined during partitioning.

Written by the indexing model from the issue text.

Assessment

Tech stack
android, cpp, csharp
Domain
machine-learning, mobile-dev
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.