Issue 166059
Summary EXPECT_EXIT timeouts on darwin
Labels new issue
Assignees
Reporter bojle
    Running the `EXPECT_EXIT` macro (by running `_Exit_test` for example) on darwin (macos) causes 
the test to suspend for a while and later timeout.

The likely cause of this is in the file
[ExecuteFunctionUnix.cpp](https://github.com/llvm/llvm-project/blob/138e0ff87c5855d4d78ab27f59dfbd9191e81872/libc/test/UnitTest/ExecuteFunctionUnix.cpp#L61).

The poll struct is populated with a zero `.event` field. This is fine on linux
but hangs on macos. To test this in isolation, here's a small indepent snippet
recreating the condition just like the `invoke_in_subprocess` fucntion:

```
#include <assert.h>
#include <errno.h>
#include <poll.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>

int main() {
  int pipe_fds[2];
  if (pipe(pipe_fds) == -1) {
    perror("pipe failed");
 return EXIT_FAILURE;
  }

  pid_t pid = fork();
  if (pid == -1) {
 perror("fork failed");
    close(pipe_fds[0]);
    close(pipe_fds[1]);
 return EXIT_FAILURE;
  }

  if (pid == 0) {
    // child
 close(pipe_fds[0]); // Close read end
    // Short delay to ensure the parent has time to enter poll()
    usleep(100000); // 100ms
 printf("Child process exiting, closing pipe write end...\n");
 close(pipe_fds[1]);
    _exit(0);
  }

  // Parent
  close(pipe_fds[1]); // Close write end in parent

  printf("Parent process (PID: %d): Waiting for child (PID: %d) exit via "
         "poll(2) for 5000ms...\n",
 getpid(), pid);

  // LIKELY CAUSE OF ERROR
  // Chage .events to POLLIN and it should work
  struct pollfd poll_fd = {.fd = pipe_fds[0], .events = 0, .revents = 0};

  int timeout_ms = 5000;
  int ret = poll(&poll_fd, 1, timeout_ms);
  if (ret == -1) {
    printf("POLL RESULT: FAILED (-1). errno: %d (%s)\n", errno,
           strerror(errno));
  } else if (ret == 0) {
    printf("POLL RESULT: TIMED OUT (0).\n");
  } else {
    printf(
        "POLL RESULT: SUCCEEDED (%d). revents: 0x%x (Expected POLLHUP 0x%x)\n",
        ret, poll_fd.revents, POLLHUP);
 assert(poll_fd.revents & POLLHUP);
  }

  close(pipe_fds[0]);
  int wstatus;
  if (waitpid(pid, &wstatus, 0) == -1) {
    perror("waitpid failed");
  }
  printf("Parent process finished.\n");
  return 0;
}
```

Compile this and run: `clang file.c -o a; ./a`. It hangs and exits via a
timeout. Change the events to be POLLIN and it should succeed.

Note: This is not an issue on linux

I couldn't find why this happens precisely. My gut feeling is that macos just
doesn't like an empty events field.

_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to