| 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