MG_ Difference with FreeBSD:
mkdir /tmp/a
cp /bin/ls /tmp/a
chroot /tmp/a /ls
result: ELF interpreter /libexec/ld-elf.so.1 not found, error 2
Abort trap
Oh, that's just a convenience the FreeBSD kernel provides:
https://github.com/freebsd/freebsd-src/blob/main/sys/kern/imgact_elf.c#L1092
OpenBSD, however's, just recently removed this from theirs:
https://github.com/openbsd/src/commit/7db5826dada7d33c09da396a91ea673ce2e93737
One obvious problem with the kernel printing directly to userspace is this:
$ uname -a
FreeBSD CoreBook.local 15.0-RELEASE-p4 FreeBSD 15.0-RELEASE-p4 GENERIC amd64
$ mkdir a
$ cp /bin/sh a
$ sudo chroot -u rvp /tmp/a ./sh >log.txt 2>&1
ELF interpreter /libexec/ld-elf.so.1 not found, error 2
Abort trap sudo chroot -u rvp /tmp/a ./sh > log.txt 2>&1
$ ls -l log.txt
-rw------- 1 rvp wheel 0 20 Mar 22:41 log.txt
# ^^^
# where's my log, dude!?
$
redirections don't work; which is very confusing too.
Anyway, as I said before, this isn't much of a hassle to figure out if you've seen it before. The real headache is for shared objects loaded withdlopen()--like PAM modules, or i18n support objects. With those, one has to run strings(1) on the binaries (and the libraries, as well as any config. files!) to get a clue as to what modules are missing.