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

Greg Clayton via lldb-commits lldb-commits at lists.llvm.org
Tue Feb 13 12:53:47 PST 2024


================
@@ -0,0 +1,45 @@
+#include <iostream>
+#include <thread>
+#include <unistd.h>
+#include <vector>
+
+int call_vfork() {
+  printf("Before vfork\n");
+
+  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
+    printf("Child process\n");
+    _exit(0); // Exit the child process
+  } else {
+    // This code is executed by the parent process
+    printf("Parent process\n");
+  }
+
+  printf("After vfork\n");
+  return 0;
+}
+
+void worker_thread() { call_vfork(); }
+
+void create_threads(int num_threads) {
+  std::vector<std::thread> threads;
+  for (int i = 0; i < num_threads; ++i) {
+    threads.emplace_back(std::thread(worker_thread));
+  }
+  printf("Created %d threads, joining...\n",
+         num_threads); // end_of_create_threads
+  for (auto &thread : threads) {
+    thread.join();
+  }
+}
+
+int main() {
+  int num_threads = 5; // break here
+  create_threads(num_threads);
+}
----------------
clayborg wrote:

Now reap the children you spawned:
```
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)
    _exit(1); // This will let our program know that some child processes didn't exist with a zero exit status.
  if (pid !=  child_pid)
    _exit(2); // This will let our program know it didn't succeed
}
```
This will ensure that if we stayed with the parent, then we successfully resumed all of the child processes and that they didn't crash and that they exited. If we don't resume the child processes correctly, they can get caught in limbo if they weren't resumed and this test will deadlock waiting for the child process to exit. There are some options you can do that allows you to not hang where instead of zero passed as the last parameter of `waitpid()`, you can specify `WNOHANG`, but that will get racy. We would poll for a few seconds. We will want to make sure that the test doesn't just deadlock and cause the test suite to never complete.


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


More information about the lldb-commits mailing list