Skip to content
Jōshin edited this page Jan 6, 2024 · 12 revisions

Issues

"I want to learn more about X program, but I can't find any documentation on it"

If the program has its own directory, check for the files README.md (original author's) and README.cosmo (Cosmo-specific changelog). If it's in third_party/, look for its help files online.

If that fails, check the source code for comments and documentation strings. If that's still not good enough, try reading the code -- understandable code is a priority for the developers.

"I'm troubleshooting and need more info about my program's execution"

All Cosmo binaries include two special flags: --strace which echoes system calls, and --ftrace which echoes function calls. This provides visibility into your program on a level that normally requires a debugger.

"My program won't execute in certain situations"

An example: the program runs fine when run straight from the command line, but usage from find -exec fails with the error ENOACCESS.

  • Running the program under a shell invocation, such as sh -c 'binary.com args...' may succeed.
  • Every Cosmopolitan binary can strip its own headers, to fit your native binary format with binary.com --assimilate. This is non-reversible and means that the program will no longer work on systems with different executable formats (the groups being Windows, Linux/BSD, and Mac). However, it may dodge this issue. Be sure to back up your programs before running.

"My program isn't behaving the way I expect"

There are a few differences between cosmopolitan binaries and normal C binaries. Some of these are platform-dependent. They mostly stem from the fact that cosmopolitan binaries run as interpreter scripts on unices, and therefore are mostly resolvable via --assimilate. Some are documented here.

"My argv[0] is getting clobbered"

This is usually how execve with interpreter scripts works. To quote from the execve(2) manpage:

If  the  pathname argument of execve() specifies an interpreter script,
then interpreter will be invoked with the following arguments:

    interpreter [optional-arg] pathname arg...

where pathname is the pathname of the file specified as the first argu‐
ment  of execve(), and arg...  is the series of words pointed to by the
argv argument of execve(), starting at argv[1].  Note that there is  no
way to get the argv[0] that was passed to the execve() call.

In spite of this, cosmopolitan libc does some work to preserve argv[0] where it can. If you have installed the binfmt_misc registrations with apeinstall.sh as of 15548b52, and your kernel is 5.12 or newer, then argv[0] should usually be preserved. It will also be preserved on any platform if the loader is called with ape -. If argv[0] is being clobbered anyway, and you are using a recent version of cosmopolitan, then it is your OS doing the clobbering.

If you are on Linux with a kernel older than 5.12 and still want to preserve argv[0], your options are to assimilate your binaries or to make a wrapper script, e.g. /usr/bin/ape- (or /usr/bin/ape\ - if you are feeling particularly BOFH-ish), that calls exec /usr/bin/ape - "$@", and configure your binfmt registrations to use that with the P flag.

"My setuid cosmopolitan binary isn’t working"

First of all, are you feeling okay? Second of all, it is commonly the case that the setuid/setgid bits are ignored on interpreter scripts. The two reasons generally given are:

  1. There is a TOCTOU problem between the kernel opening and reading the file to find the interpreter, and the invoked interpreter opening the file to execute it.
  2. Generally it is very difficult to secure a setuid interpreter under all possible modifications to things like the PATH and IFS variables, etc.

Cosmopolitan is not (or ought not be) particularly subject to 2; it is, however, subject to 1. (We also have a TOCTOU between the loader finding the program and the program opening itself to read its zip archive.)

On a few operating systems, secure setuid shebangs are supported via /dev/fd; details here. The Perl security documentation may be of use if you're trying to make this work.

"Zipping files into an executable breaks the executable"

Cosmo executables are usually also ZIP files, e.g. redbean.com, Lua.com, QuickJS, etc. You should be able to easily view their contents with any ZIP program, e.g. unzip -vl redbean.com. So support for reading files is universal. The issue is with modifying. Cosmo binaries are essentially what used to be called "self-extracting archives". Many modern ZIP tools don't understand this and will destroy the executable content when they rearrange files within the archive. It's particularly true of GUI programs on Windows. The best tool to use for changing your zip files is InfoZIP, which is available on nearly every Mac and UNIX install as the standard zip and unzip commands. Those tools work great and won't corrupt your executable. If you want a GUI, then the one that's known to work is PKZIP for Windows which costs $30. The Cosmopolitan mono-repo also has a third_party/zip/zip.com program that you can use, which is a port of InfoZIP.

Other ways to get APE binaries:

cosmocc always outputs APE binaries. Another option:

apecopy foo.elf foo.ape