Skip to content

Commit dc76612

Browse files
authored
fix(mobile): _pyrepl pruning + mimalloc seccomp open() on 3.13/3.14 (#29)
Two distinct on-device runtime bugs that only surface on a genuine 3.13/3.14 mobile run (3.12 unaffected), found via mobile-forge genuine multi-Python mobile tests (fork run 27439192170): 1. _pyrepl was pruned from the iOS + Android stdlib excludes as a "dev-only / interactive-REPL" module. But CPython 3.14 pdb.py imports _pyrepl at module load, so any on-device code importing pdb (incl. pytest) dies with "ModuleNotFoundError: No module named _pyrepl". 3.13 pdb does not import it, which is why 3.13 iOS was unaffected. Un-prune _pyrepl in darwin/python-darwin-stdlib.exclude + android/python-android-dart.exclude. 2. mimalloc (bundled in CPython since 3.13) issues a bare open(2) syscall from its load-time constructor (mi_process_load -> unix_detect_overcommit reading /proc/sys/vm/overcommit_memory) where SYS_open is defined (x86_64). Android bionic seccomp forbids open(2) -> SIGSYS at dlopen of libpython, before the interpreter starts. arm64 is unaffected (no SYS_open; mimalloc falls back to libc open() -> openat). Patch mi_prim_open to use SYS_openat (android/patches/mimalloc_seccomp_openat.patch, gated >=3.13 in build.sh).
1 parent ecbd1a0 commit dc76612

4 files changed

Lines changed: 33 additions & 4 deletions

File tree

android/build.sh

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,12 @@ if [ $version_int -eq 312 ]; then
5757
# Android tooling; this 3.12-only patch matches that behavior at link time.
5858
patches+=" soname_linktime bldlibrary grp"
5959
fi
60+
if [ $version_int -ge 313 ]; then
61+
# mimalloc (bundled since 3.13) issues a bare SYS_open at load on x86_64,
62+
# which Android seccomp kills (SIGSYS) at dlopen of libpython. Switch it to
63+
# SYS_openat. See patches/mimalloc_seccomp_openat.patch.
64+
patches+=" mimalloc_seccomp_openat"
65+
fi
6066
for name in $patches; do
6167
patch_file="$script_dir/patches/$name.patch"
6268
echo "$patch_file"
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
mimalloc: use SYS_openat instead of SYS_open (Android seccomp).
2+
3+
CPython bundles mimalloc since 3.13. On Android, mimalloc's load-time constructor
4+
(mi_process_load -> unix_detect_overcommit, Objects/mimalloc/init.c) reads
5+
/proc/sys/vm/overcommit_memory through mi_prim_open. On platforms where SYS_open
6+
is defined (x86_64) mi_prim_open issues the bare open(2) syscall directly (to
7+
avoid recursion while mimalloc is still initializing). Android's bionic seccomp
8+
policy forbids open(2) -- only openat(2) is permitted -- so the kernel raises
9+
SIGSYS (SYS_SECCOMP) and the process is killed at dlopen() of libpython, before
10+
the interpreter starts. 3.12 has no mimalloc; arm64 is unaffected (it has no
11+
SYS_open, so mimalloc falls back to libc open(), which bionic routes through
12+
openat). SYS_openat(AT_FDCWD, ...) is semantically identical and allowed.
13+
14+
--- a/Objects/mimalloc/prim/unix/prim.c
15+
+++ b/Objects/mimalloc/prim/unix/prim.c
16+
@@ -67,5 +67,5 @@
17+
static int mi_prim_open(const char* fpath, int open_flags) {
18+
- return syscall(SYS_open,fpath,open_flags,0);
19+
+ return syscall(SYS_openat,AT_FDCWD,fpath,open_flags,0);
20+
}
21+
static ssize_t mi_prim_read(int fd, void* buf, size_t bufsize) {
22+
return syscall(SYS_read,fd,buf,bufsize);

android/python-android-dart.exclude

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ lib/python*/tkinter
2020
lib/python*/turtle*
2121
lib/python*/wsgiref
2222
# Interactive-REPL / dev-only modules + easter eggs / frozen demos (never imported when
23-
# running a script in embedded mode).
24-
lib/python*/_pyrepl
23+
# running a script in embedded mode). _pyrepl is intentionally NOT pruned: CPython 3.14's
24+
# pdb imports it at module load, so dropping it breaks pdb / pytest / anything that imports it.
2525
lib/python*/rlcompleter*
2626
lib/python*/tabnanny*
2727
lib/python*/antigravity*

darwin/python-darwin-stdlib.exclude

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,9 @@ tkinter
1919
turtle*
2020
wsgiref
2121
# Interactive-REPL / dev-only modules — never imported when running a script (embedded
22-
# mode); plus easter eggs and frozen demo modules.
23-
_pyrepl
22+
# mode); plus easter eggs and frozen demo modules. _pyrepl is intentionally NOT pruned:
23+
# CPython 3.14's pdb imports it at module load, so dropping it breaks pdb / pytest /
24+
# anything that imports it on-device.
2425
rlcompleter*
2526
tabnanny*
2627
antigravity*

0 commit comments

Comments
 (0)