Created
March 18, 2017 18:11
-
-
Save a3f/0fe444521feca3096fc91e0bfddc1a2c to your computer and use it in GitHub Desktop.
Possible pthreads race bug on macOS Sierra
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
for i in `seq 100000`; do ./a.out $i ; done && echo ' All is well!' | |
*/ | |
#include <assert.h> | |
#include <unistd.h> | |
#include <stdio.h> | |
#include <pthread.h> | |
void *interp(void *param) { | |
(void)param; | |
char ch; | |
while (read(0, &ch, sizeof ch) > 0) | |
; | |
puts("Should never be reached"); | |
return NULL; | |
} | |
int main(int argc, char *argv[]) { | |
int ret; | |
pthread_t pthread; | |
ret = pthread_create(&pthread, NULL, interp, NULL); | |
assert(ret == 0); | |
ret = pthread_cancel(pthread); | |
assert(ret == 0); | |
ret = pthread_join(pthread, NULL); | |
assert(ret == 0); | |
printf("\r%s", argv[argc-1]); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Compile the code and run
for i in `seq 100000`; do ./a.out $i ; done && echo ' All is well!'
.After a short while (Usually before reaching 1000), the command will hang.
LLDB inspection shows that the thread is blocking on
read
as expected. If the usercall pthread_cancel(pthread)
manually onmain
's frame, the thread is cancelled.So it seems, there's a race between
pthread_create
andpthread_cancel
, which leads to the cancellation request to be lost. Inspection of the libc source didn't show any problems however. Maybe the issue is with the pthread trampoline? Regardless, this violates POSIX, as apthread_t
handle ought to be usable as soon aspthread_create
returns.The expected behavior, seen on other Unices, e.g. Linux is the command terminating at
100000 All is well!
.