Continuous cross-architecture testing of strace on rarely-tested CPU architectures.
GitHub Actions build a cross toolchain and a minimal root filesystem with
Buildroot, cross-compile strace and its test suite
against that toolchain, then boot the target architecture under QEMU system
emulation and run make check inside the guest. The point is to exercise
strace's per-architecture support -- syscall decoders, register/ABI handling,
struct layouts -- on platforms that rarely get tested elsewhere.
| Arch | QEMU machine | Notes |
|---|---|---|
m68k |
virt |
no dedicated TP register, 2-byte int alignment |
s390x |
(default) | z15 target |
sparc64 |
sun4u |
64-bit, VA hole in the address space |
mips64el |
malta |
64-bit little-endian, n64 ABI |
Per-architecture QEMU and guest settings (machine, emulator binary, memory,
kernel image, virtio transport, console) live in ci/lib.sh.
Each architecture has a Buildroot defconfig under
ci/buildroot-config-<arch>.
| Patches | m68k |
s390x |
sparc64 |
mips64el |
|---|---|---|---|---|
| strace | -- (4) | -- | -- (1) | 2 |
| gcc | 1 | -- | -- | -- |
| elfutils | -- | -- | -- | 1 |
A plain number is patches currently carried; a number in parentheses is patches since accepted upstream and no longer carried. These are bugs found by the cross-testing itself -- in the strace tests on these architectures, and one m68k compiler miscompile -- and are reported upstream.
The workflow (.github/workflows/cross.yml) has
two jobs, run as a matrix over the architectures:
-
build
ci/build-buildroot <arch>-- runs Buildroot with the per-arch config to produce the cross toolchain, kernel, and an initramfs (busybox + the host QEMU build).ci/build-strace <arch>-- checks out upstream strace, applies the patches inci/strace-patches/, and cross-compiles strace plus everytests*/directory with the toolchain.- The Buildroot output and the strace build tree are cached (and uploaded as artifacts) keyed on the Buildroot version, arch config, strace commit, and patch set, so the test job reuses them without rebuilding.
-
test (sharded across many parallel jobs per architecture)
ci/run-qemu <arch>packs the freshly built strace tree into an ext2 image, boots the guest kernel under QEMU, and shares the source tree and toolchain over virtio-9p.- On boot the guest runs
ci/rootfs-overlay/etc/init.d/S99strace-check, which runsmake checkfor this shard's tests, records the exit status, and powers off. ci/shard-testssplits each test directory's$(TESTS)list into shards so the suite runs in parallel across many jobs per arch.
Failures uncovered on these architectures are tracked as patches and reported upstream.
strace (ci/strace-patches/, applied by
ci/build-strace):
- mips64el --
ioctl_pidfd_get_info: the test hardcoded theSIGABRTname forcoredump_signal, but MIPS names signal 6SIGIOT; decode it throughsignal2name()so the expected output matches. - mips64el --
restart_syscall-p: on MIPS the syscall number shares thev0register with the syscall return value, so on attach strace misread an interrupted syscall's return value as a syscall number; skipv0whenPTRACE_GET_SYSCALL_INFOreports no syscall entry.
GCC (ci/patches/gcc/):
- m68k --
fold-mem-offsets: the pass folds a constant offset into a base register still used by a memory-to-memory move, miscompiling code at-O2.
elfutils (ci/patches/elfutils/):
- mips64el -- MIPS unwinding: the MIPS backend omits a
same_valuedefault rule for the return-address registerra(r31), so libdwfl stops after one frame andstrace -kat a syscall site shows only the libc entry; add the missing rule.
These strace test fixes were found by the cross-testing and have since been
accepted upstream, so they are no longer carried in
ci/strace-patches/:
- m68k --
restart_syscall-p(824c818b0),prctl-seccomp-filter-v,seccomp-filter-v(both folded intoc9ea4e35c): on m68k libc reads the thread pointer viaget_thread_area, which polluted attach traces and tripped the seccomp filters. - m68k --
net-sockaddr(090b1be72):struct sockaddr_ax25is 14 bytes on m68k (2-byteintalignment) vs 16 elsewhere. - sparc64 --
mmap(bc4934e36): the hardcoded mmap hint address the test passes fell inside the sparc64 VA hole.
The ci/ scripts are plain POSIX shell and can be run outside CI, given a host
with Buildroot's dependencies and the right paths. For example:
export STRACE_SRC=$PWD/strace BUILDROOT_SRC=$PWD/buildroot OUTPUT_BASE=$PWD/output
./ci/build-buildroot s390x # toolchain, kernel, rootfs (slow, first time)
./ci/build-strace s390x # cross-compile strace + tests
./ci/run-qemu s390x # boot under QEMU and run make checkHonored environment variables are documented at the top of each script
(STRACE_TESTS, STRACE_SHARD/STRACE_SHARDS, QEMU_TIMEOUT, QEMU_SMP, ...).
GPL-2.0-or-later. See LICENSE.