Browse Source

Fix: Don't call locking CRT functions after fork(), as it can deadlock in musl

default_compile_flags
vector-of-bool 4 years ago
parent
commit
3678ff8dbe
1 changed files with 11 additions and 8 deletions
  1. +11
    -8
      src/dds/proc.nix.cpp

+ 11
- 8
src/dds/proc.nix.cpp View File

@@ -27,6 +27,15 @@ void check_rc(bool b, std::string_view s) {

::pid_t
spawn_child(const std::vector<std::string>& command, int stdout_pipe, int close_me) noexcept {
// We must allocate BEFORE fork(), since the CRT might stumble with malloc()-related locks that
// are held during the fork().
std::vector<const char*> strings;
strings.reserve(command.size() + 1);
for (auto& s : command) {
strings.push_back(s.data());
}
strings.push_back(nullptr);

auto child_pid = ::fork();
if (child_pid != 0) {
return child_pid;
@@ -38,25 +47,19 @@ spawn_child(const std::vector<std::string>& command, int stdout_pipe, int close_
rc = dup2(stdout_pipe, STDERR_FILENO);
check_rc(rc != -1, "Failed to dup2 stderr");

std::vector<const char*> strings;
strings.reserve(command.size() + 1);
for (auto& s : command) {
strings.push_back(s.data());
}
strings.push_back(nullptr);
::execvp(strings[0], (char* const*)strings.data());

if (errno == ENOENT) {
std::cerr
<< fmt::format("[dds child executor] The requested executable ({}) could not be found.",
strings[0]);
std::exit(-1);
std::quick_exit(-1);
}

std::cerr << "[dds child executor] execvp returned! This is a fatal error: "
<< std::system_category().message(errno) << '\n';

std::terminate();
std::quick_exit(-1);
}

} // namespace

Loading…
Cancel
Save