frankenphp amd64 images ship x86-64-v3/v4 binaries and SIGILL on older CPUs #19

Closed
opened 2026-08-04 09:43:04 +00:00 by geusebio · 0 comments
Owner

Split out of #16, where it turned up
while re-enabling the FrankenPHP tests.

What

The php-zts packages we install from
pkg.henderkes.com are built with x86-64-v3 and
x86-64-v4 code. On an amd64 image:

$ readelf -n /usr/bin/php
Properties: x86 feature used: x86, XMM, YMM, ZMM, XSAVE, MASK
  x86 ISA used: x86-64-baseline, x86-64-v2, x86-64-v3, x86-64-v4

ZMM/MASK means AVX-512 code paths. On a CPU without them the process dies
with Illegal instruction — which is exactly what our CI runner does, and why
the FrankenPHP tests have been commented out of the test suite since the images
were added.

Why it matters beyond the tests

The same binaries go into the images we publish:
matthewbaggett/frankenphp:{latest,8.5,8.4,8.3,8.2}, linux/amd64.

Those builds pass CI only because buildx builds amd64 under QEMU, which
emulates the instructions happily. Nothing in the pipeline ever executes the
amd64 artefact on a real amd64 CPU, so we have no signal on whether what we
push actually runs. Anyone pulling the amd64 tag onto a host without AVX-512
plausibly gets a container that dies on the first request.

The arm64 images are unaffected, and no other image family uses this repo —
php, php-ubuntu and magento all use distro PHP packages.

Options, roughly in order of appeal

  1. Ask upstream to target baseline x86-64 (or publish a baseline variant).
    Cheapest if they are willing; everything else follows from it.
  2. Build static-php ourselves for amd64 with a baseline -march.
  3. Drop linux/amd64 from the frankenphp bake target, so we stop publishing
    something we cannot test. Honest, but narrows the image's usefulness.
  4. Keep publishing but gate on a native amd64 smoke test — needs a runner that
    is not QEMU, which we do not currently have.

Worth doing either way

Whatever we pick, a build-time assertion on the ISA level (parse readelf -n,
fail if x86-64-v3/v4 shows up in a binary we ship) would turn this from
"discovered by a user" into "discovered by the build".

Related: the same repo's php-zts-igbinary / php-zts-redis packages are
already omitted for crashing with Illegal instruction on native aarch64
(see the note in FrankenPHP.Dockerfile) — likely the same class of problem
from the other direction.

Split out of https://git.grey.ooo/Grey.ooo/docker/pulls/16, where it turned up while re-enabling the FrankenPHP tests. ### What The `php-zts` packages we install from [pkg.henderkes.com](https://pkg.henderkes.com) are built with x86-64-v3 and x86-64-v4 code. On an amd64 image: ``` $ readelf -n /usr/bin/php Properties: x86 feature used: x86, XMM, YMM, ZMM, XSAVE, MASK x86 ISA used: x86-64-baseline, x86-64-v2, x86-64-v3, x86-64-v4 ``` `ZMM`/`MASK` means AVX-512 code paths. On a CPU without them the process dies with `Illegal instruction` — which is exactly what our CI runner does, and why the FrankenPHP tests have been commented out of the test suite since the images were added. ### Why it matters beyond the tests The same binaries go into the images we publish: `matthewbaggett/frankenphp:{latest,8.5,8.4,8.3,8.2}`, `linux/amd64`. Those builds pass CI only because buildx builds amd64 under QEMU, which emulates the instructions happily. Nothing in the pipeline ever executes the amd64 artefact on a real amd64 CPU, so we have no signal on whether what we push actually runs. Anyone pulling the amd64 tag onto a host without AVX-512 plausibly gets a container that dies on the first request. The arm64 images are unaffected, and no other image family uses this repo — `php`, `php-ubuntu` and `magento` all use distro PHP packages. ### Options, roughly in order of appeal 1. Ask upstream to target baseline x86-64 (or publish a baseline variant). Cheapest if they are willing; everything else follows from it. 2. Build static-php ourselves for amd64 with a baseline `-march`. 3. Drop `linux/amd64` from the `frankenphp` bake target, so we stop publishing something we cannot test. Honest, but narrows the image's usefulness. 4. Keep publishing but gate on a native amd64 smoke test — needs a runner that is not QEMU, which we do not currently have. ### Worth doing either way Whatever we pick, a build-time assertion on the ISA level (parse `readelf -n`, fail if `x86-64-v3`/`v4` shows up in a binary we ship) would turn this from "discovered by a user" into "discovered by the build". Related: the same repo's `php-zts-igbinary` / `php-zts-redis` packages are already omitted for crashing with `Illegal instruction` on native aarch64 (see the note in FrankenPHP.Dockerfile) — likely the same class of problem from the other direction.
Sign in to join this conversation.
No labels
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
Grey.ooo/docker#19
No description provided.