Files
DroidDeck/tools/tests/test_vrclient_loader.py
T
MaxsTechReview f27d0b006f perf: Wine's write watches stop costing a signal per page on arm64 (#1333)
Wine asks for userfaultfd with the i386 syscall number on arm64, so it
never gets one and falls back to mprotect and a SIGSEGV per first write,
which under proot is a ptrace stop each time. libblsession hands it the
real userfaultfd and, where Android refuses the PAGEMAP_SCAN ioctl, answers
it from /proc/self/pagemap and UFFDIO_WRITEPROTECT.
2026-10-22 19:53:12 +00:00

59 lines
2.2 KiB
Python

from pathlib import Path
import shutil
import subprocess
import tempfile
import unittest
@unittest.skipUnless(shutil.which("gcc"), "needs gcc on a Linux host")
class VrclientLoaderTest(unittest.TestCase):
def test_vrclient_keeps_syscall_interposition_without_changing_other_dsos(self):
with tempfile.TemporaryDirectory() as directory:
root = Path(directory)
module = root / "module.c"
module.write_text(r"""
#include <errno.h>
#include <stddef.h>
#include <unistd.h>
#include <sys/syscall.h>
long syscall(long number, ...) { (void)number; errno = ENOSYS; return -1; }
int probe(void) {
void *head = NULL; size_t length = 0;
return syscall(SYS_get_robust_list, 0L, &head, &length) == 0 && head && length > 0;
}
""")
subprocess.run(["gcc", "-shared", "-fPIC", "-O2", str(module), "-o",
str(root / "vrclient.so")], check=True)
shutil.copy(root / "vrclient.so", root / "ordinary.so")
robust = Path(__file__).resolve().parents[1] / "linuxfs/preload/robust.c"
harness = root / "loader.c"
harness.write_text(r"""
#define _GNU_SOURCE
#include <assert.h>
#include <dlfcn.h>
int bl_fsync_syscall(long n, const long *a, long *r) { (void)n; (void)a; (void)r; return 0; }
int bl_writewatch_syscall(long n, const long *a, long (*real)(long, ...), long *r) { (void)n; (void)a; (void)real; (void)r; return 0; }
#include """ + '"' + robust.as_posix() + '"' + r"""
int main(int argc, char **argv) {
assert(argc == 3);
void *ordinary = dlopen(argv[1], RTLD_NOW | RTLD_DEEPBIND);
assert(ordinary);
int (*probe)(void) = dlsym(ordinary, "probe");
assert(probe && probe() == 0);
dlclose(ordinary);
void *vr = dlopen(argv[2], RTLD_NOW | RTLD_DEEPBIND);
assert(vr);
probe = dlsym(vr, "probe");
assert(probe && probe() == 1);
dlclose(vr);
}
""")
subprocess.run(["gcc", "-O2", "-rdynamic", "-pthread", str(harness),
"-ldl", "-o", str(root / "loader")], check=True)
subprocess.run([str(root / "loader"), str(root / "ordinary.so"),
str(root / "vrclient.so")], check=True, timeout=10)
if __name__ == "__main__":
unittest.main()