Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -1694,3 +1694,4 @@ Full write-ups (root causes, measurements) for each entry are in
| 1.9.0 | 2026-08-15 | Adds **fluxsmooth** (unlocks havsfunc's STPresso), **bifrost** (temporal rainbow/dot-crawl removal), **retinex** (shadow-detail lift) — all pinned to the newest release with a published Windows binary |
| 1.10.0 | 2026-08-31 | **Issue #82**: zsmooth now ships one build per x86 CPU baseline (haswell, x86_64_v2), fixing an illegal-instruction crash on pre-2013 CPUs. **FFmpeg pinned to 9.0 on all four platforms** (they had silently diverged: Windows on an unpinned post-9.0 master, macOS on floating 9.0.1, Linux stuck at 7.1 after BtbN garbage-collected the pinned tag) |
| 1.11.0 | 2026-09 | **Issue #92**: every x86 bundle ships in two **CPU tiers** — `v3` (x86-64-v3; the plain asset names) and `v2` (`…-x64-v2`, anything older), chosen by the app from `vapourbox-worker --probe-cpu`. Each bundle carries one autoloaded zsmooth (replacing 1.10.0's two-builds-loaded-by-path). macOS v2 builds MVTools v24 from source without its AVX2 files, whose static initializers SIGILLed inside `dlopen` on pre-AVX Macs. v2 bundles are gated (SDE on Linux/Windows, static check on macOS) before publishing |
| 1.12.0 | 2026-10-04 | **Issue #101**: akarin 1.4.1 → **1.5.0** on every platform. The 1.4.1 Linux wheel put JIT code on the `brk` heap, where SELinux denies `PROT_EXEC`, so every job segfaulted on Fedora/RHEL from deps 1.8.0 on. `download-deps-linux.sh` now fails if `libakarin.so` lacks the mmap allocator |
19 changes: 18 additions & 1 deletion Scripts/download-deps-linux.sh
Original file line number Diff line number Diff line change
Expand Up @@ -1443,7 +1443,16 @@ fi
# wheel exists, the routing shim is arch-neutral, and keeping the two arches
# identical avoids the same job producing different output per platform.
# manylinux_2_35 is satisfied by our glibc 2.39 floor (ubuntu-24.04).
AKARIN_VERSION="1.4.1"
#
# 1.5.0 is the floor on Linux (issue #101). The 1.4.1 wheel allocated JIT code
# with new[] and then mprotect()ed it executable; a small allocation lands on
# the brk heap, where SELinux denies PROT_EXEC (execheap is off by default on
# Fedora/RHEL). The mprotect result was only ASSERTed, so a release build
# carried on and jumped into non-executable memory: SIGSEGV on the first
# akarin.Expr frame, in every job. 1.5.0 builds with
# REACTOR_ANONYMOUS_MMAP_NAME=akarin_jit, which takes the mmap path instead.
# No hosted runner enforces SELinux, so this is checked statically below.
AKARIN_VERSION="1.5.0"
echo ""
echo "=== Downloading akarin $AKARIN_VERSION (LLVM JIT for std.Expr) ==="
if [ "$FORCE" = true ] || [ ! -f "$PLUGINS_DIR/libakarin.so" ]; then
Expand Down Expand Up @@ -1486,6 +1495,14 @@ PYEOF
exit 1
fi
fi
# The mmap JIT allocator is a compile-time option whose only trace in
# the binary is the mapping's name. Without it the plugin works on the
# build machine and segfaults under SELinux (issue #101).
if ! LC_ALL=C grep -a -q "akarin_jit" "$PLUGINS_DIR/libakarin.so"; then
echo " ERROR: libakarin.so was not built with REACTOR_ANONYMOUS_MMAP_NAME;"
echo " it would allocate JIT code on the heap and crash under SELinux."
exit 1
fi
rm -rf "$BUILD_DIR/akarin" "$BUILD_DIR/akarin.whl"
BUILT_PLUGINS+=("akarin")
echo " Installed akarin -> libakarin.so"
Expand Down
2 changes: 1 addition & 1 deletion Scripts/download-deps-macos.sh
Original file line number Diff line number Diff line change
Expand Up @@ -1911,7 +1911,7 @@ download_prebuilt_plugin "LGhost" "liblghost.dylib" "$LGHOST_URL"
# targets $MACOS_MIN_VERSION (issue #39), so shipping it would raise the Intel
# floor to macOS 14 — and x86 already has the JIT, so it loses nothing. The
# routing shim falls back to std.Expr wherever core.akarin is absent.
AKARIN_VERSION="1.4.1"
AKARIN_VERSION="1.5.0"
echo ""
echo "=== Downloading akarin $AKARIN_VERSION (LLVM JIT for std.Expr) ==="
if [ "$ARCH" = "x86_64" ]; then
Expand Down
2 changes: 1 addition & 1 deletion Scripts/download-deps-windows.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -732,7 +732,7 @@ if (-not (Test-Path $DvdReadPath)) {
#
# akarin is bit-identical to std.Expr on 45 of the 46 expressions havsfunc
# generates; the one exception rounds a single .5 tie down instead of to even.
$AkarinVersion = "1.4.1"
$AkarinVersion = "1.5.0"
Write-Host ""
Write-Host "Downloading akarin $AkarinVersion (LLVM JIT for std.Expr)..." -ForegroundColor Yellow
if (-not (Test-Path "$PluginsDir\libakarin.dll")) {
Expand Down
6 changes: 3 additions & 3 deletions app/assets/deps-version.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"version": "1.11.0",
"releaseTag": "deps-v1.11.0",
"releaseDate": "2026-09-25",
"version": "1.12.0",
"releaseTag": "deps-v1.12.0",
"releaseDate": "2026-10-04",
"githubRepo": "StuartCameronCode/VapourBox"
}
41 changes: 40 additions & 1 deletion docs/ENGINEERING_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -1658,13 +1658,52 @@ the system one for ffmpeg. Linux's zstd carries a **per-arch build hash** in its
filename (`libzstd-5df4f4df…` on x64, `-a1561916…` on arm64), so glob it — and
the ELF `NEEDED` entry uses that exact hashed name.

akarin is **LGPL-3.0** and statically links **LLVM 22.1.2** (Apache-2.0 with LLVM
akarin is **LGPL-3.0** and statically links **LLVM 22.1.8** (Apache-2.0 with LLVM
exception); both are in `licenses/NOTICES.txt`. It adds ~61 MB uncompressed per
platform, but only about **21 MB to each deps zip** — the earlier "the zips
roughly double" estimate was wrong, because it compared uncompressed size against
compressed zips.


### akarin 1.4.1 segfaulted under SELinux (issue #101, 2026-10-04)

Every job crashed in `vspipe-bin` with `SIGSEGV` on Fedora from app 0.9.12 — the
first release on deps 1.8.0, which is where akarin arrived. The reporter's
`probe-plugin-compat` run isolated it: 22 plugins passed, `libakarin.so` crashed.

The 1.4.1 Linux wheel was built without `REACTOR_ANONYMOUS_MMAP_NAME`, so
`expr2/reactor/ExecutableMemory.cpp` took its generic fallback: allocate the JIT
buffer with `new[]`, then `mprotect` it `r-x`. A page-sized allocation comes off
the **`brk` heap**, and SELinux refuses `PROT_EXEC` there (`execheap`, off by
default for unconfined users on Fedora/RHEL — unlike `execmem`, which is on).
The `mprotect` result is checked only by an `ASSERT`, compiled out in release,
so the plugin jumped into non-executable memory. Upstream: akarin issue #38,
fixed in **1.5.0** by defining the macro (`meson.build`), which switches to an
anonymous `mmap`. macOS (`MAP_JIT`) and Windows (`VirtualProtect`) never took
the heap path.

Signatures worth recognising next time:

- **A one-frame backtrace at `0x55…` with no module.** That range is the PIE
executable and its `brk` heap; a JIT that used `mmap` would be at `0x7f…`.
A crash *at* a heap address means the program counter is in data.
- **It depends on allocator state**, so it need not reproduce in every host
process: a buffer over glibc's mmap threshold comes from `mmap` and works.
- **No hosted runner enforces SELinux** (Ubuntu ships AppArmor), so CI cannot
see it. `download-deps-linux.sh` instead fails the build if `libakarin.so`
lacks the `akarin_jit` mapping name, the only trace the option leaves.

The pin moved on all three platforms together to keep output identical per OS;
the Expr parity test passes unchanged against 1.5.0 (run on macos-arm64). 1.5.0
also repaired constant parsing (`0x…` hex and `0…` octal prefixes, which the
README always documented but 1.4.1's `from_chars` call mishandled) — none of
havsfunc's generated expressions are affected.

Workaround for an installed bundle that predates the fix: delete
`deps/linux-*/vapoursynth/plugins/libakarin.so`. Both the havsfunc shim and the
templates' `_expr()` fall back to `std.Expr`, which on x86 has its own JIT.


### Installing a deps bundle: staged, swapped, and version-directional

`DependencyManager` **replaces** a bundle rather than merging into one, which is
Expand Down
2 changes: 1 addition & 1 deletion licenses/NOTICES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ LLVM — Apache-2.0 WITH LLVM-exception
Copyright (c) the LLVM Project contributors
https://llvm.org
Licence text: Apache-2.0-LLVM-Exception.txt
LLVM 22.1.2 is statically linked into the akarin plugin above, which is where
LLVM 22.1.8 is statically linked into the akarin plugin above, which is where
its JIT comes from. Listed here because that binary carries LLVM code.

zsmooth — MIT
Expand Down
Loading