diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2024-06-28 13:20:29 +0200 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2024-06-28 12:16:25 +0000 |
| commit | 2081f66ad07722ba9a808fa4f0d2ced2822950f7 (patch) | |
| tree | 4c2f74ff1ee6ba546efbb9dd98f416ed2760cf44 | |
| parent | 30bd3f741301a9ad137b62a686ba1ed2284388c8 (diff) | |
executor: fix max signal/cover filter mapping into subprocesses
There is a quirk related to posix_spawn_file_actions_adddup2:
it just executes the specified dup's in order in the child process.
In our case we do dups as follows:
20 -> 4 (output region)
4 -> 5 (max signal)
So we dup the output region onto 4 first, and then dup the same output region
(fd 4 becomes the output region) onto 5 (max signal).
So we have output region as both output region and max signal.
| -rw-r--r-- | executor/executor_runner.h | 6 | ||||
| -rw-r--r-- | executor/subprocess.h | 10 |
2 files changed, 15 insertions, 1 deletions
diff --git a/executor/executor_runner.h b/executor/executor_runner.h index 57d63f6a7..766669dda 100644 --- a/executor/executor_runner.h +++ b/executor/executor_runner.h @@ -797,5 +797,11 @@ static void runner(char** argv, int argc) fail("signal(SIGBUS) failed"); Connection conn(manager_addr, manager_port); + + // This is required to make Subprocess fd remapping logic work. + // kCoverFilterFd is the largest fd we set in the child processes. + for (int fd = conn.FD(); fd < kCoverFilterFd;) + fd = dup(fd); + Runner(conn, name, argv[0]); } diff --git a/executor/subprocess.h b/executor/subprocess.h index 4477cc482..2553422a9 100644 --- a/executor/subprocess.h +++ b/executor/subprocess.h @@ -17,9 +17,17 @@ public: if (posix_spawn_file_actions_init(&actions)) fail("posix_spawn_file_actions_init failed"); int max_fd = 0; - for (auto pair : fds) { + for (auto pair : fds) max_fd = std::max(max_fd, pair.second); + for (auto pair : fds) { if (pair.first != -1) { + // Remapping won't work if fd's overlap with the target range: + // we can dup something onto fd we need to dup later, in such case the later fd + // will be wrong. Resolving this would require some tricky multi-pass remapping. + // So we just require the caller to not do that. + if (pair.first <= max_fd) + failmsg("bad subprocess fd", "%d->%d max_fd=%d", + pair.first, pair.second, max_fd); if (posix_spawn_file_actions_adddup2(&actions, pair.first, pair.second)) fail("posix_spawn_file_actions_adddup2 failed"); } else { |
