Skip to content

MLComputePlan.load_from_path() aborts the whole process (uncatchable SIGABRT) when given an .mlpackage path #2757

Description

@robertopernisco

🐞 Bug

MLComputePlan.load_from_path() hard-crashes the whole host process (SIGABRT, uncatchable from Python) when given an .mlpackage path instead of a compiled .mlmodelc. A wrong-path-type mistake should raise a Python exception, not kill the process.

To Reproduce (100% deterministic)

from coremltools.models.compute_plan import MLComputePlan
from coremltools import ComputeUnit

# any UNCOMPILED .mlpackage path (the API expects a compiled .mlmodelc)
MLComputePlan.load_from_path(path="Any.mlpackage", compute_units=ComputeUnit.ALL)
# → libc++abi: terminating due to uncaught exception of type
#   std::__1::ios_base::failure: Failed to open file: .../coremldata.bin.
#   It is not a valid .mlmodelc file.
# → SIGABRT (whole process, no Python exception possible)

What happens (from the .ips crash report)

The abort happens on CoreML's internal dispatch queue, so the Python caller (blocked on a semaphore waiting for the completion handler) can never catch it:

Triggered by Thread: 10, Dispatch Queue: com.apple.coreml.MLModelAssetResourceFactory.structureLoadQueue

Thread 10 Crashed:
  8  libc++abi  __cxa_throw
  9  CoreML     Archiver::_IArchiveDiskImpl::_IArchiveDiskImpl(std::string const&, Archiver::FileFormat) + 1324
  10 CoreML     IArchive::IArchive(...) + 104
  11 CoreML     -[MLModelAssetResourceFactoryOnDiskImpl modelStructureWithError:] + 228
  12 CoreML     __67-[MLModelAssetResourceFactory modelStructureWithCompletionHandler:]_block_invoke + 60
  ... _dispatch_call_block_and_release / _dispatch_lane_serial_drain ...

Thread 0 (main):
  0  libsystem_kernel  semaphore_wait_trap
  3  libcoremlpython.so ...

The C++ exception thrown by IArchive's constructor escapes -[MLModelAssetResourceFactoryOnDiskImpl modelStructureWithError:] (which has an NSError** out-param that should carry this error) on the structureLoadQueue, where nothing catches it → std::terminateabort().

Expected behavior

load_from_path should either (a) accept .mlpackage and compile it internally, or (b) validate the path and raise a normal Python ValueError before calling into the native API. (The framework-side issue — the C++ exception crossing a dispatch queue instead of honoring the NSError contract — has been reported to Apple via Feedback Assistant separately.)

System environment

  • coremltools version: 9.0
  • OS: macOS 26.5.2 (25F84), MacBook Pro M2 Pro 16 GB (Mac14,9)
  • Python 3.12.10 (python.org framework build)
  • CoreML.framework CFBundleVersion 3520.5.1

Additional context

Found while using MLComputePlan to enumerate per-op compute-device support for a large mlprogram. Workaround: always pre-compile via coremltools.models.utils.compile_model() and pass the resulting .mlmodelc — and run any MLComputePlan probing in a sacrificial subprocess.

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