Previously, we were just using Linux's passwd, which caused inconsistencies, e.g., with home directory lookups.
Now, we also add the user to /etc/master.passwd so programs running as fake root within the prefix can still look our user up (since libinfo checks /etc/master.passwd when running as root instead of /etc/passwd).
O_NONBLOCK is a "file status flag", which means it is set on the underlying file, not individual file descriptors. This means that, when we pass our stdin to the child directly, they will see it as O_NONBLOCK (but that's not supposed to happen).
The workaround is to leave it as a blocking file but instead use FIONREAD to determine exactly how many bytes we can read without blocking.
Additional flavors are implemented: PIDTASKINFO, PIDTASKALLINFO, PIDLISTTHREADS.
Furthermore, PIDTBSDINFO gets a valid pbi_start_tvsec and pbi_start_tvusec
The biggest improvement is the ability to log xtrace's output to a separate file for each thread. Jumbled output has been a big reason why xtrace is hard to use with multi-threaded programs, but this provides a nice optional solution to that problem. It doesn't come without its drawbacks, however: because xtrace has to open descriptors for the logfiles, it can affect program behavior, especially if the program sees the descriptors and decides to do something with them (like close them, which some programs do).
xtrace no longer buffers output on the stack (which could lead to stack overflows or truncated output). Actually, it doesn't buffer output at all anymore, which might be an issue (it means more potentially jumbled output when using the normal output method). If turns out to be a signifcant issue, we can re-add buffering in xtrace_log using a per-thread buffer rather than an on-stack one.
The kevent family of syscalls is now properly described! This means that those calls will now print much more useful output.
Also, to work around a stack overflow issue when running within signal handlers, xtrace now overrides the default sigstack with its own larger one. It's not apparent why xtrace is using so much stack space, but it seems like 16KiB is enough for now (rather than the default of 8KiB).
Executing the xtrace command with no arguments now produces a help message describing the various environment variables that can be used to modify xtrace's behavior.
Also, the simple printf family of functions in libsystem_kernel now support various argument sizes.
Finally, there's no reason to call the wrapper for `semaphore_signal_trap` in `bsdthread_terminate` (causing unnecessary xtrace output), so call our implementation directly instead.
Yes, special-casing is ugly, but we already do it in other cases, and we DO want to keep resolving most absolute symlinks relative to the prefix root, so special-casing `/proc` seems to me like the best way to go.
Instead of using the `inherit` action, LLDB uses `dup2` with both FDs being the same number. This is supported by XNU, so we have to support it as well. The solution is to see if each descriptor we want to set CLOEXEC on is present in the file actions list. If it is, then we *don't* set CLOEXEC on it.
Also, implement octal formatting in `__simple_vsnprintf`.
This makes xtrace print more useful debugging information for posix_spawn. There are other syscalls that could definitely benefit from having more detailed output (e.g. `kevent` and friends).
Also, I was noticing segfaults when processes exited with pthread_terminate; they were due to xtrace using pthread keys after pthread_terminate had been called, which cleans up pthread keys. This new static key approach should be fault free, if only at the expense of leaking some memory per-thread. TODO: add a death hook in libsystem_kernel to notify xtrace when a thread is *actually* going to die.