Description
Sometimes when execve fails it doesn't return with an error. Quoting from the blog EWONTFIX here:
For common reasons it might fail, the execve syscall returns failure in the original process image, allowing the program to handle the error. However, failure of execve is not entirely atomic:
The kernel may fail setting up the VM for the new process image after the original VM has already been destroyed; the main situation under which this would happen is resource exhaustion.
Even after the kernel successfully sets up the new VM and transfers execution to the new process image, it's possible to have failures prior to the transfer of control to the actual application program. This could happen in the dynamic linker (resource exhaustion or other transient failures mapping required libraries or loading configuration files) or libc startup code. Using musl libc with static linking or even dynamic linking with no additional libraries eliminates these failure cases, but systemd is intended to be used with glibc.
This means that using a pipe to report errors is incorrect or at least does not cover all cases.
My personal hack to get around the issue is here.
In order to check for execve aborts I wait for exits or stops and arrange for a stop signal to be delivered atomically after execve and then continue. Currently, in my own code I do not actually check for the specific exit status that is generated when execve aborts but that will be easy to add in later.