jart / cosmopolitan

build-once run-anywhere c library
ISC License
18.35k stars 630 forks source link

redbean ape error: prog mmap failed on android #940

Closed orlovushek closed 3 months ago

orlovushek commented 12 months ago

Tried to run redbean from Cosmopolitan v3.0.2 release on Android. As I understood it should now support ARM, in contrast to official readbean-2.2 release.

Here is the error, called from Termux:

$ ./redbean
ape error: ./redbean: prog mmap failed w/ errno 12
$ file redbean
redbean: DOS/MBR boot sector; partition 1 : ID=0x7f, active, start-CHS (0x0,0,1), end-CHS (0x3ff,255,63), startsector 0, 4294967295 sectors
$ ls -l redbean
-rwxrwxrwx 1 u0_a320 u0_a320 5409969 Nov 10 04:00 redbean
$ uname -a
Linux localhost 5.10.157-android13-4-00001-g5c7ff5dc7aac-ab10381520 #1 SMP PREEMPT Fri Jun 23 18:30:49 UTC 2023 aarch64 Android

In case this is expected and not supported yet, please tell where I can track it if it's planned. Thank you for your work.

pkulchenko commented 12 months ago

It may be helpful to run redbean with --strace to see what exact call it fails on.

orlovushek commented 12 months ago

It may be helpful to run redbean with --strace to see what exact call it fails on.

With --strace there are no additional messages, just the same error.

thuibr commented 11 months ago

I'm getting the same running linux on my chromebook

$ strace  $SHELL ./redbean 
execve("/bin/bash", ["/bin/bash", "./redbean"], 0x7fcf7894b8 /* 35 vars */) = 0
brk(NULL)                               = 0x574883e000
faccessat(AT_FDCWD, "/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=29865, ...}) = 0
mmap(NULL, 29865, PROT_READ, MAP_PRIVATE, 3, 0) = 0x75b04b6000
close(3)                                = 0
openat(AT_FDCWD, "/lib/aarch64-linux-gnu/libtinfo.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0\267\0\1\0\0\0 \351\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0644, st_size=187704, ...}) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x75b04b4000
mmap(NULL, 252176, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x75b0452000
mprotect(0x75b047c000, 61440, PROT_NONE) = 0
mmap(0x75b048b000, 20480, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x29000) = 0x75b048b000
close(3)                                = 0
openat(AT_FDCWD, "/lib/aarch64-linux-gnu/libdl.so.2", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0\267\0\1\0\0\0P\17\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0644, st_size=14560, ...}) = 0
mmap(NULL, 78080, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x75b043e000
mprotect(0x75b0441000, 61440, PROT_NONE) = 0
mmap(0x75b0450000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x2000) = 0x75b0450000
close(3)                                = 0
openat(AT_FDCWD, "/lib/aarch64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0\267\0\1\0\0\0`\17\2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1451024, ...}) = 0
mmap(NULL, 1523656, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x75b02ca000
mprotect(0x75b0426000, 61440, PROT_NONE) = 0
mmap(0x75b0435000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x15b000) = 0x75b0435000
mmap(0x75b043b000, 12232, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x75b043b000
close(3)                                = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x75b04b2000
mprotect(0x75b0435000, 16384, PROT_READ) = 0
mprotect(0x75b0450000, 4096, PROT_READ) = 0
mprotect(0x75b048b000, 16384, PROT_READ) = 0
mprotect(0x572119c000, 16384, PROT_READ) = 0
mprotect(0x75b04c1000, 4096, PROT_READ) = 0
munmap(0x75b04b6000, 29865)             = 0
openat(AT_FDCWD, "/dev/tty", O_RDWR|O_NONBLOCK) = 3
close(3)                                = 0
brk(NULL)                               = 0x574883e000
brk(0x574885f000)                       = 0x574885f000
openat(AT_FDCWD, "/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=3041456, ...}) = 0
mmap(NULL, 3041456, PROT_READ, MAP_PRIVATE, 3, 0) = 0x75affe3000
close(3)                                = 0
openat(AT_FDCWD, "/usr/lib/aarch64-linux-gnu/gconv/gconv-modules.cache", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=27004, ...}) = 0
mmap(NULL, 27004, PROT_READ, MAP_SHARED, 3, 0) = 0x75b04b7000
close(3)                                = 0
getuid()                                = 1000
getgid()                                = 1000
geteuid()                               = 1000
getegid()                               = 1000
rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
ioctl(-1, TIOCGPGRP, 0x7fe5184db4)      = -1 EBADF (Bad file descriptor)
sysinfo({uptime=618, loads=[64, 4512, 4384], totalram=2938392576, freeram=1186770944, sharedram=204800, bufferram=2424832, totalswap=0, freeswap=0, procs=204, totalhigh=0, freehigh=0, mem_unit=1}) = 0
rt_sigaction(SIGCHLD, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTART}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGCHLD, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTART}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTART}, 8) = 0
rt_sigaction(SIGINT, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGINT, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGQUIT, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGQUIT, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGTSTP, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGTSTP, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGTTIN, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGTTIN, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGTTOU, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGTTOU, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
rt_sigaction(SIGQUIT, {sa_handler=SIG_IGN, sa_mask=[], sa_flags=0}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
uname({sysname="Linux", nodename="penguin", ...}) = 0
newfstatat(AT_FDCWD, "/home/thuibr", {st_mode=S_IFDIR|0755, st_size=266, ...}, 0) = 0
newfstatat(AT_FDCWD, ".", {st_mode=S_IFDIR|0755, st_size=266, ...}, 0) = 0
newfstatat(AT_FDCWD, "/home", {st_mode=S_IFDIR|0755, st_size=12, ...}, 0) = 0
newfstatat(AT_FDCWD, "/home/thuibr", {st_mode=S_IFDIR|0755, st_size=266, ...}, 0) = 0
getpid()                                = 1306
getppid()                               = 1303
getpid()                                = 1306
getppid()                               = 1303
getpid()                                = 1306
getppid()                               = 1303
getpgid(0)                              = 1303
ioctl(2, TIOCGPGRP, [1303])             = 0
rt_sigaction(SIGCHLD, {sa_handler=0x57210c1c64, sa_mask=[], sa_flags=SA_RESTART}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTART}, 8) = 0
prlimit64(0, RLIMIT_NPROC, NULL, {rlim_cur=11207, rlim_max=11207}) = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
openat(AT_FDCWD, "./redbean", O_RDONLY) = 3
newfstatat(AT_FDCWD, "./redbean", {st_mode=S_IFREG|0755, st_size=5405759, ...}, 0) = 0
ioctl(3, TCGETS, 0x7fe5184d60)          = -1 ENOTTY (Inappropriate ioctl for device)
lseek(3, 0, SEEK_CUR)                   = 0
read(3, "MZqFpD='\n\n\0\20\0\370\0\0\0\0\0\0\0\1\0\10@\0\0\0\0\0\0\0"..., 80) = 80
lseek(3, 0, SEEK_SET)                   = 0
prlimit64(0, RLIMIT_NOFILE, NULL, {rlim_cur=1024, rlim_max=1024*1024}) = 0
fcntl(255, F_GETFD)                     = -1 EBADF (Bad file descriptor)
dup3(3, 255, 0)                         = 255
close(3)                                = 0
fcntl(255, F_SETFD, FD_CLOEXEC)         = 0
fcntl(255, F_GETFL)                     = 0x20000 (flags O_RDONLY|O_LARGEFILE)
fstat(255, {st_mode=S_IFREG|0755, st_size=5405759, ...}) = 0
lseek(255, 0, SEEK_CUR)                 = 0
read(255, "MZqFpD='\n\n\0\20\0\370\0\0\0\0\0\0\0\1\0\10@\0\0\0\0\0\0\0"..., 8192) = 8192
pipe2([3, 4], 0)                        = 0
fcntl(4, F_GETPIPE_SZ)                  = 65536
write(4, "X\16\1\262@\353\353\24\220\220\353\6H\203\354\0101\322\275\353\5\351%E\374\17\37\207>\340\277p"..., 358) = 358
close(4)                                = 0
fcntl(0, F_GETFD)                       = 0
fcntl(0, F_DUPFD, 10)                   = 10
fcntl(0, F_GETFD)                       = 0
fcntl(10, F_SETFD, FD_CLOEXEC)          = 0
dup3(3, 0, 0)                           = 0
close(3)                                = 0
dup3(10, 0, 0)                          = 0
fcntl(10, F_GETFD)                      = 0x1 (flags FD_CLOEXEC)
close(10)                               = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
pipe2([3, 4], 0)                        = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
rt_sigprocmask(SIG_BLOCK, [INT TERM CHLD], [], 8) = 0
lseek(255, -7639, SEEK_CUR)             = 553
clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x75b04b20e0) = 1307
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigaction(SIGCHLD, {sa_handler=0x57210c1c64, sa_mask=[], sa_flags=SA_RESTART}, {sa_handler=0x57210c1c64, sa_mask=[], sa_flags=SA_RESTART}, 8) = 0
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=1307, si_uid=1000, si_status=0, si_utime=0, si_stime=0} ---
wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], WNOHANG, NULL) = 1307
wait4(-1, 0x7fe5182fa0, WNOHANG, NULL)  = -1 ECHILD (No child processes)
rt_sigreturn({mask=[]})                 = 0
close(4)                                = 0
rt_sigprocmask(SIG_BLOCK, [INT], [], 8) = 0
read(3, "./redbean\n", 512)             = 10
read(3, "", 512)                        = 0
close(3)                                = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigaction(SIGINT, {sa_handler=0x57210bee64, sa_mask=[], sa_flags=0}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGINT, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, {sa_handler=0x57210bee64, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
read(255, "[ x\"$1\" != x--assimilate ] && ty"..., 8192) = 8192
openat(AT_FDCWD, "/dev/null", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
fcntl(1, F_GETFD)                       = 0
fcntl(1, F_DUPFD, 10)                   = 10
fcntl(1, F_GETFD)                       = 0
fcntl(10, F_SETFD, FD_CLOEXEC)          = 0
dup3(3, 1, 0)                           = 1
close(3)                                = 0
fcntl(2, F_GETFD)                       = 0
fcntl(2, F_DUPFD, 10)                   = 11
fcntl(2, F_GETFD)                       = 0
fcntl(11, F_SETFD, FD_CLOEXEC)          = 0
dup3(1, 2, 0)                           = 2
fcntl(1, F_GETFD)                       = 0
newfstatat(AT_FDCWD, ".", {st_mode=S_IFDIR|0755, st_size=266, ...}, 0) = 0
newfstatat(AT_FDCWD, "/usr/local/bin/ape", 0x7fe5184568, 0) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/bin/ape", 0x7fe5184568, 0) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/bin/ape", 0x7fe5184568, 0) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/local/games/ape", 0x7fe5184568, 0) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/games/ape", 0x7fe5184568, 0) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/share/locale/locale.alias", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=2996, ...}) = 0
read(3, "# Locale name alias data base.\n#"..., 4096) = 2996
read(3, "", 4096)                       = 0
close(3)                                = 0
openat(AT_FDCWD, "/usr/share/locale/en_US.UTF-8/LC_MESSAGES/bash.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/share/locale/en_US.utf8/LC_MESSAGES/bash.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/share/locale/en_US/LC_MESSAGES/bash.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/share/locale/en.UTF-8/LC_MESSAGES/bash.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/share/locale/en.utf8/LC_MESSAGES/bash.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/share/locale/en/LC_MESSAGES/bash.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
fstat(2, {st_mode=S_IFCHR|0666, st_rdev=makedev(0x1, 0x3), ...}) = 0
ioctl(2, TCGETS, 0x7fe5183d60)          = -1 ENOTTY (Inappropriate ioctl for device)
write(2, "./redbean: line 9: type: ape: no"..., 40) = 40
dup3(11, 2, 0)                          = 2
fcntl(11, F_GETFD)                      = 0x1 (flags FD_CLOEXEC)
close(11)                               = 0
dup3(10, 1, 0)                          = 1
fcntl(10, F_GETFD)                      = 0x1 (flags FD_CLOEXEC)
close(10)                               = 0
faccessat(AT_FDCWD, "/home/thuibr/.ape-1.9", X_OK) = 0
rt_sigaction(SIGINT, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGQUIT, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, {sa_handler=SIG_IGN, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGCHLD, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTART}, {sa_handler=0x57210c1c64, sa_mask=[], sa_flags=SA_RESTART}, 8) = 0
lseek(255, -8015, SEEK_CUR)             = 730
execve("/home/thuibr/.ape-1.9", ["/home/thuibr/.ape-1.9", "./redbean"], 0x5748852d10 /* 34 vars */) = 0
faccessat(AT_FDCWD, "./redbean", X_OK)  = 0
openat(AT_FDCWD, "./redbean", O_RDONLY) = 3
pread64(3, "MZqFpD='\n\n\0\20\0\370\0\0\0\0\0\0\0\1\0\10@\0\0\0\0\0\0\0"..., 8192, 0) = 8192
pread64(3, "\1\0\0\0\5\0\0\0\0\200'\0\0\0\0\0\0\0\0\0\0\1\0\0\0\0\0\0\0\1\0\0"..., 280, 3880) = 280
mmap(0x10000000000, 2417136, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED, 3, 0x278000) = -1 ENOMEM (Cannot allocate memory)
write(2, "ape error: ./redbean: prog mmap "..., 51ape error: ./redbean: prog mmap failed w/ errno 12
) = 51
exit_group(127)                         = ?
+++ exited with 127 +++
hak8or commented 11 months ago

For both of you with issues (@thuibr and @orlovushek), can you do the following to gather more information;

I am hoping it's some system configuration issue that can be adjusted via either sysfs/procfs, or worst case a kernel recompile. In a perfect world, we would just the executable dump the contents of /proc/self/maps after the failed mmap to see what the address space is looking like, but that might be tough. I am wondering if there is some odd ASLR interaction here, or the NDK is jumping in between and doing something interesting here.

thuibr commented 11 months ago

Hi, @hak8or , thank you for looking into this. I have two Chromebooks. The first is a Samsung Galaxy Chromebook with an Intel i5 and 8GB RAM. I am able to execute redbean from https://cosmo.zip/pub/cosmos/bin/ with no issues.

The second Chromebook is a Lenovo Chromebook 100e 2nd Gen with a MediaTek CPU and 4GB RAM. Here is the information that I was able to capture:

thuibr@penguin:~$ cat /proc/meminfo
MemTotal:        2869524 kB
MemFree:         2418608 kB
MemAvailable:    2786620 kB
Buffers:               0 kB
Cached:           368012 kB
SwapCached:            0 kB
Active:           221844 kB
Inactive:         206668 kB
Active(anon):      60432 kB
Inactive(anon):      232 kB
Active(file):     161412 kB
Inactive(file):   206436 kB
Unevictable:           0 kB
Mlocked:               0 kB
SwapTotal:             0 kB
SwapFree:              0 kB
Dirty:               176 kB
Writeback:             0 kB
AnonPages:         60500 kB
Mapped:            75192 kB
Shmem:               164 kB
KReclaimable:      21108 kB
Slab:                  0 kB
SReclaimable:          0 kB
SUnreclaim:            0 kB
KernelStack:        3312 kB
PageTables:         3396 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:     1434760 kB
Committed_AS:    1025788 kB
VmallocTotal:   259653632 kB
VmallocUsed:        4356 kB
VmallocChunk:          0 kB
Percpu:              992 kB
AnonHugePages:         0 kB
ShmemHugePages:        0 kB
ShmemPmdMapped:        0 kB
FileHugePages:         0 kB
FilePmdMapped:         0 kB
HugePages_Total:       0
HugePages_Free:        0
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB
Hugetlb:               0 kB
thuibr@penguin:~$ free -m
               total        used        free      shared  buff/cache   available
Mem:            2802          80        2361           0         359        2721
Swap:              0           0           0
thuibr@penguin:~$ cat /proc/sys/vm/nr_hugepages 
0
thuibr@penguin:~$ uname -a
Linux penguin 5.15.130-20472-g682e24dd583b #1 SMP PREEMPT Wed Oct 25 18:25:04 PDT 2023 aarch64 GNU/Linux
thuibr@penguin:~$ dmesg | grep mmap
thuibr@penguin:~$ dmesg | grep redbean
thuibr@penguin:~$ 

It didn't seem anything was added to dmesg when I attempted to execute redbean.

Here's /proc/config.gz: config.gz

ashleemikeyoung commented 11 months ago

This looks like it might be related to my error, as well, which is not running on Android. I am seeing the following:

ash@B020111-648c752:~/Developement/cosmocc$ bin/make --version ape error: bin/make: prog mmap failed w/ errno 12

This comes from following the steps up to the Sanity Test here: https://justine.lol/cosmopolitan/index.html. If I follow the steps for installing the APE Loader, the same error persists.

2023-12-03 23:00:31 (9.32 MB/s) - '/usr/bin/ape' saved [8936/8936] ash@B020111-648c752:~/Developement/cosmocc$ sudo chmod +x /usr/bin/ape ash@B020111-648c752:~/Developement/cosmocc$ sudo sh -c "echo ':APE:M::MZqFpD::/usr/bin/ape:' >/proc/sys/fs/binfmt_misc/register" ash@B020111-648c752:~/Developement/cosmocc$ sudo sh -c "echo ':APE-jart:M::jartsr::/usr/bin/ape:' >/proc/sys/fs/binfmt_misc/register" ash@B020111-648c752:~/Developement/cosmocc$ bin/make --version ape error: bin/make: prog mmap failed w/ errno 12

If I instead try to install APE via the ape/apeinstall.sh, after first running the uninstall script, I get the following:

ash@B020111-648c752:~/Developement/cosmocc$ bin/make --version bin/make: line 9: /usr/bin/ape: cannot execute binary file: Exec format error bin/make: line 9: /usr/bin/ape: Success

Maybe it's unrelated. It looks like the same problem that folks on Android and on Chromebooks are seeing. It's not your normal hardware. This is on a Rockchip 3588 with 16GB of RAM and running Ubuntu 22.04.

ash@B020111-648c752:~/Developement/cosmocc$ hostnamectl Static hostname: B020111-648c752 Icon name: computer Machine ID: 281cb6d7477544bbbc9961d16296af48 Boot ID: e8ad9e043fcf4ac48adbd9b3858a0a61 Operating System: Ubuntu 22.04 LTS
Kernel: Linux 5.10.66-1-rockchip-g856bdc53aa57 Architecture: arm64

hakanrw commented 8 months ago

i have the same issue. tested on termux and alpine-proot.

i suspect this might be related to limited available memory?

fat-tire commented 7 months ago

raspberry pi 4 (8gb) gets the same error. See here.

kedorlaomer commented 6 months ago

The same on a Xiaomi Mi 11 Lite. There, free -m reports

               total        used        free      shared  buff/cache   available
Mem:            7368        5983         189          42        1196         907
Swap:           4095        1579        2516

It's unlikely that insufficient memory is to be blamed

kedorlaomer commented 6 months ago

To debug this a bit further, consider the following replica of the ape's behaviour:

#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>

int main(int argc, char **argv) {
    int fd = openat(AT_FDCWD, *argv, O_RDONLY);
    void *res = mmap((void*) 0x10000000000, 2824540, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED, fd, 0x310000);
    return 0;
}

When running this under a sane environment, we expect the mmap to return the 0x10000000000 unchanged. This happens under a Linux environment that I chose. Under Android, however, we receive a -1. I don't know why. Understanding/mitigating this should yield the resolution of this bug.

randomtwdude commented 5 months ago

I believe this is caused by the Android kernel being built with only 39 bits of virtual address space (try cat /proc/xxx/maps). In the example from the last comment, 0x10000000000 is 44 bits and so doesn't fit.

kedorlaomer commented 5 months ago

You're right, @randomtwdude, decreasing the the address to 0x80000000 (which is 31 bits) yields a good result on my Android machine. Anything higher yields 0x0, though. I'm not sufficiently deep into cosmopolitan, but can we learn something for a possible fix?

randomtwdude commented 5 months ago

I think the Vista branch retains support for reduced VA space (Windows 7 and before only had 43 bits instead of 47). I wasn't able to build it on my machine though (one of the include files said permission denied even if I set 777), so maybe someone can test if it works.

mrdomino commented 5 months ago

Regarding Raspberry Pi: this is a known issue with the weird kernels that ship with Raspberry Pi OS, and the recommended resolution is to either use a real distro (like raspi.debian.net) or to custom compile a kernel with the right address space configuration.

Regarding Android: I don't know how widespread this is. Are there any Android builds that it doesn't crash this way on? At any rate, leaving this open for now in case there is ever more of a push for Android support in the future.

fat-tire commented 5 months ago

Regarding Raspberry Pi: this is a known issue with the weird kernels that ship with Raspberry Pi OS, and the recommended resolution is to either use a real distro (like raspi.debian.net) or to custom compile a kernel with the right address space configuration.

fwiw the distro is debian 12 bookworm. The kernel is 6.6.28+rpt-rpi-v8 . And the cigarette is Parliament.

mrdomino commented 5 months ago

Really? Like you installed it from that URL?

Raspberry Pi OS sort of pretends to be Debian, but it's not maintained by them. Like my kernel package on my raspberry pi 4 8GB is just linux-image-arm64. uname is 6.1.0-21-arm64.

fat-tire commented 5 months ago

I installed it quite a while ago when the raspi 4 was 1st introduced- maybe early 2020 or even late 2019 (?). At the time https://raspi.debian.net didn't exist or at least didn't have a pi 4 image yet, I know that. It was really early. I feel like it was pre-covid early.

I do remember having to use a custom kernel because there was no support for direct boot-from-usb and maybe other hardware support missing in Raspbian at the time- so I either had to build the kernel myself with some stuff turned on or maybe there was some experimental build on rpi's site. Checking, I now have deb http://archive.raspberrypi.org/debian/ bookworm main in /sources.list.d. I recall there were userspace issues when the 4 first came out, so I think I was using some generic debian arm64 bullseye w/the custom raspi kernel and maybe a few raspi pkgs too. This was 4 or 5 years ago, so I don't quite remember. (I've since updated to bookworm from bullseye, so it probably updated packages from that repo above.)

/etc/os-release reports:

PRETTY_NAME="Debian GNU/Linux 12 (bookworm)"
NAME="Debian GNU/Linux"

hostnamectl says:

Operating System: Debian GNU/Linux 12 (bookworm)  
          Kernel: Linux 6.6.28+rpt-rpi-v8
    Architecture: arm64

I would think one of these might mention "raspberry os" or something. But maybe not. Pretty sure at least the kernel is not mainline debian as you say.

Anyhoo, yeah, I guess I can just switch kernels to fix the issue or rebuild. :grin:

mrdomino commented 5 months ago

Cool, sounds good. Yeah, for some reason the "raspi" kernel flips the 39-bit config flag even though it doesn't need to.

jart commented 5 months ago

Just buy a RasPi v5. Even RPI OS uses the larger address space on those.

randomtwdude commented 5 months ago

After some prodding around and not understanding how to build cosmopolitan from source, I was able to have my ape run on Android (12, Linux 4.14) by changing the addresses in ape/aarch64.lds and libc/runtime/memtrack.internal.h I have no idea if this would break anything else.

jart commented 5 months ago

Really? Could you give a diff?

randomtwdude commented 5 months ago

Compiled without errors means we're good, I think.

diff --git a/ape/aarch64.lds b/ape/aarch64.lds
index 57b22b4b5..98af27346 100644
--- a/ape/aarch64.lds
+++ b/ape/aarch64.lds
@@ -11,7 +11,7 @@ OUTPUT_FORMAT("elf64-littleaarch64",

 SECTIONS {

-  . = SEGMENT_START("text-segment", 0x010000000000);
+  . = SEGMENT_START("text-segment", 0x000100000000);
   __executable_start = .;
   . += SIZEOF_HEADERS;

@@ -283,7 +283,7 @@ SECTIONS {
   }
 }

-ape_stack_vaddr = DEFINED(ape_stack_vaddr) ? ape_stack_vaddr : 0x700000000000;
+ape_stack_vaddr = DEFINED(ape_stack_vaddr) ? ape_stack_vaddr : 0x007000000000;
 ape_stack_memsz = DEFINED(ape_stack_memsz) ? ape_stack_memsz : 8 * 1024 * 1024;
 ape_stack_align = DEFINED(ape_stack_align) ? ape_stack_align : 16;
 ape_stack_round = -ape_stack_align;
diff --git a/libc/runtime/memtrack.internal.h b/libc/runtime/memtrack.internal.h
index 120cf5939..9efd4eedc 100644
--- a/libc/runtime/memtrack.internal.h
+++ b/libc/runtime/memtrack.internal.h
@@ -9,18 +9,28 @@
 #include "libc/thread/tls.h"
 COSMOPOLITAN_C_START_

-#define kAutomapStart       0x100080040000
+/*
+ * All the addresses here have been scaled down 256x along with the
+ * .text and stack to accomodate a 39-bit vaspace on Android.
+ * 
+ * The addresses below are calculated (shifted down) to satisfy the
+ * requirements of _extend() (libc/intrin/extend.c).
+ * 
+ * The kMemtrack* addresses (bottom six) have been shifted even more,
+ * otherwise they overlap.
+ */
+#define kAutomapStart       0x0010007c0000
 #define kAutomapSize        (kMemtrackStart - kAutomapStart)
-#define kMemtrackStart      0x1fe7fffc0000
-#define kMemtrackSize       (0x1ffffffc0000 - kMemtrackStart)
-#define kFixedmapStart      0x300000040000
-#define kFixedmapSize       (0x400000040000 - kFixedmapStart)
-#define kMemtrackNsyncStart 0x6fc000040000
-#define kMemtrackNsyncSize  (0x6fcffffc0000 - kMemtrackNsyncStart)
-#define kMemtrackFdsStart   0x6fe000040000
-#define kMemtrackFdsSize    (0x6feffffc0000 - kMemtrackFdsStart)
-#define kMemtrackZiposStart 0x6fd000040000
-#define kMemtrackZiposSize  (0x6fdffffc0000 - kMemtrackZiposStart)
+#define kMemtrackStart      0x001fe7fc0000
+#define kMemtrackSize       (0x001ffffc0000 - kMemtrackStart)
+#define kFixedmapStart      0x002ffffc0000
+#define kFixedmapSize       (0x003ffffc0000 - kFixedmapStart)
+#define kMemtrackNsyncStart 0x006f9ffc0000
+#define kMemtrackNsyncSize  (0x006faffc0000 - kMemtrackNsyncStart)
+#define kMemtrackFdsStart   0x006fdffc0000
+#define kMemtrackFdsSize    (0x006feffc0000 - kMemtrackFdsStart)
+#define kMemtrackZiposStart 0x006fbffc0000
+#define kMemtrackZiposSize  (0x006fcffc0000 - kMemtrackZiposStart)
 #define kMemtrackGran       (!IsAsan() ? FRAMESIZE : FRAMESIZE * 8)

 struct MemoryInterval {
@@ -124,8 +134,11 @@ forceinline pureconst bool IsZiposFrame(int x) {
          x <= (int)((kMemtrackZiposStart + kMemtrackZiposSize - 1) >> 16);
 }

+/*
+ * These are divided 256x as well.
+ */
 forceinline pureconst bool IsShadowFrame(int x) {
-  return 0x7fff <= x && x < 0x10008000;
+  return 0x7f <= x && x < 0x100080;
 }

 forceinline pureconst bool IsStaticStackFrame(int x) {
@@ -172,13 +185,16 @@ forceinline pureconst bool OverlapsImageSpace(const void *p, size_t n) {
   }
 }

+/*
+ * EndB here 1/256x'd too.
+ */
 forceinline pureconst bool OverlapsShadowSpace(const void *p, size_t n) {
   intptr_t BegA, EndA, BegB, EndB;
   if (n) {
     BegA = (intptr_t)p;
     EndA = BegA + n;
     BegB = 0x7fff0000;
-    EndB = 0x100080000000;
+    EndB = 0x001000800000;
     return MAX(BegA, BegB) < MIN(EndA, EndB);
   } else {
     return 0;
randomtwdude commented 5 months ago

I should clarify that I got my silly cowsay clone to work on Android. I just tried Redbean with no success.

I hope I'm not just building it wrong, but running the result in qemu fails the assertion in GenerateHardRandom(). (note: make m=aarch64 only compiled redbean.o, so I manually invoked the linker with the arguments from the x86 make, with the aarch64 version of every file)

In addition, it crashes even sooner on Android with SIGSYS, Google says that the landlock_create_ruleset syscall is not allowed on Android for security reasons.

jart commented 3 months ago

Cosmopolitan now supports Android. The mmap error has been fixed since 78d3b86ec74012e0a2b5e2d2778077b0ab44e4f8. Enjoy!

thuibr commented 3 months ago

Nice! I can confirm that it now works on my Samsung Galaxy Chromebook. Thank you and good work!

jart commented 3 months ago

Glad to hear it. I had to rewrite the entire memory manager to fix this one. We have a much nicer project as a result. All the technical debt from the early days of the project has been paid off. Enjoy Android!