[Lldb-commits] [lldb] Fix lldb crash while handling concurrent vfork() (PR #81564)

Greg Clayton via lldb-commits lldb-commits at lists.llvm.org
Fri Feb 23 09:57:28 PST 2024


================
@@ -0,0 +1,70 @@
+#include <iostream>
+#include <mutex>
+#include <sys/wait.h>
+#include <thread>
+#include <unistd.h>
+#include <vector>
+
+pid_t g_pid = 0;
+std::mutex g_child_pids_mutex;
+std::vector<pid_t> g_child_pids;
+
+int call_vfork(int index) {
+  pid_t child_pid = vfork();
+
+  if (child_pid == -1) {
+    // Error handling
+    perror("vfork");
+    return 1;
+  } else if (child_pid == 0) {
+    // This code is executed by the child process
+    g_pid = getpid();
+    printf("Child process: %d\n", g_pid);
+    _exit(index + 10); // Exit the child process
+  } else {
+    // This code is executed by the parent process
+    printf("[Parent] Forked process id: %d\n", child_pid);
+  }
+  return 0;
+}
+
+void wait_all_children_to_exit() {
+  std::lock_guard<std::mutex> Lock(g_child_pids_mutex);
+  for (pid_t child_pid : g_child_pids) {
+    int child_status = 0;
+    pid_t pid = waitpid(child_pid, &child_status, 0);
+    if (child_status != 0) {
+      int exit_code = WEXITSTATUS(child_status);
+      if (exit_code > 15 || exit_code < 10) {
+        printf("Error: child process exits with unexpected code %d\n",
+               exit_code);
+        _exit(1); // This will let our program know that some child processes
+                  // didn't exist with an expected exit status.
+      }
+    }
+    if (pid != child_pid)
+      _exit(2); // This will let our program know it didn't succeed
+  }
+}
+
+void create_threads(int num_threads) {
+  std::vector<std::thread> threads;
+  for (int i = 0; i < num_threads; ++i) {
+    threads.emplace_back(std::thread(call_vfork, i));
+  }
+  printf("Created %d threads, joining...\n",
+         num_threads); // end_of_create_threads
+  for (auto &thread : threads) {
+    thread.join();
+  }
+  wait_all_children_to_exit();
+}
+
+int main() {
+  g_pid = getpid();
+  printf("Entering main() pid: %d\n", g_pid);
+
----------------
clayborg wrote:

parse args manually to check if we should use `fork` or `vfork` and if we should exec:
```
bool use_vfork = true;
bool call_exec = false;
for (int i=1; i<argc; ++i) {
  if (strcmp(argv[i], "--fork") == 0)
    use_vfork = false;
  else if (strcmp(argv[i], "--exec") == 0)
    call_exec = true;
}
```


https://github.com/llvm/llvm-project/pull/81564


More information about the lldb-commits mailing list