Fixes: https://github.com/google/sanitizers/issues/979
Note that I can't seem to get the tests running locally, so I haven't been able to properly verify this!
Differential D48451
[sanitizers_common] when spawning a subprocess for symbolizers, use posix_spawn instead of fork() alex on Jun 21 2018, 12:51 PM. Authored by
Details
Fixes: https://github.com/google/sanitizers/issues/979 Note that I can't seem to get the tests running locally, so I haven't been able to properly verify this!
Diff Detail
Event TimelineComment Actions It appears that Android plans to support posix_spawn in P release: https://android.googlesource.com/platform/bionic/+/master/libc/libc.map.txt#1385 This code needs to work in M, at least. Sorry I did not notice this before. Try vfork? Comment Actions Simply using vfork instead of fork is probably a no-go: the vfork's man page (on macOS, I haven't verified the panoply of other BSDs) says that EINVAL is returned when "A system call other than _exit() or execve() (or libc functions that make no system calls other than those) is called following calling a vfork() call." That is, on platforms with this constraint using vfork where we currently use fork will fail, because we use other syscalls to do things like setup the file descriptor table.
Do you have a preference between these two? Comment Actions Really? Is that actually the case in practice, or is the man page too cautious? Cloning file descriptor tables should not make vfork any more expensive, and without that it is kinda useless. That's a pity. I'd prefer to go with the smallest diff for now. Comment Actions Good call actually checking the manpage... both dup2 and close seem to work perfectly fine in the child after vfork. I'll update the patch accordingly. Comment Actions
Comment Actions Fantastic, thanks for the review. (As an FYI I'm not an llvm committer, so I can't land this myself). Comment Actions Tests are crashing with corrupted stack.
Comment Actions I've talked to our runtime and kernel folks and we should not be using vfork on Darwin. Even when the behavior you tested seems to work today, it might break tomorrow. Please opt out Darwin from vfork. Also, it seems best to use posix_spawn wherever it's available. If Android doesn't have it, we should only fallback to fork/vfork on Android. Comment Actions OK. It looks like internal_vfork has to be implemented in platform-specific assembly, which is was to much hassle. Comment Actions Also, FYI, this is a related attempt of using posix_spawn on Darwin: https://reviews.llvm.org/D40032. Comment Actions Thanks! As a suggestion (perhaps for a future patch, not required to fix now): Could we detect the Android version at runtime and call posix_spawn on newer Android versions (where we know it's available)? Comment Actions Yes, I imagine such a thing is possible. It may also be detect at compile time which version of the SDK it's targetting, but I don't know the Android SDK (NDK?) well enough to say how.
Comment Actions
Comment Actions These are pointers to opaque structs, aka void *. On the other hand, no one else has complained about fork() so far. Comment Actions Would you be ok landing this with the current approach (+/- any other feedback of course), and filing a follow-up bug to switch it to a runtime check? Comment Actions OK, sounds fine.
Comment Actions Tests hang with this change when output is redirected to a pipe. The test binary exits OK, but it looks like the process on the receiving end never gets an EOF. |
You can't return from a function that calls vfork() in the child process. It will destroy the stack frame in the parent process.