If I call pthread_join continuously (without using other functions) it will cause a segmentation fault.
I can solve the problem by inserting a sleep();
, printf()
or anything else between two calls of pthread_join.
OS & GCC Version:
gcc --version
gcc (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Complie command:
gcc demo_thread.c -lpthread -o demo_thread.out
Source code (demo_thread.c):
#include <stdio.h>
#include <stdlib.h>
void *f1(void *);
int main() {
int k = 2;
pthread_t fa[k];
for(int i=0; i<k; i++) {
pthread_create(&fa[i], NULL, f1, NULL);
}
for(int i=0; i<k; i++) {
// printf("%ul\n", fa[i]); // uncomment this line, problem disapper.
pthread_join(fa[i]);
}
}
void *f1(void *arg) {
for(int i=0; i<4;i++) {
printf("%d\n",i );
}
return 0;
}
How did you even make that compile? I just now realized you did not use #include <pthread.h>
and you used one argument instead of two for pthread_join
.
If I leave out the include I get
error: unknown type name ‘pthread_t’
And if I do include it then I get
error: too few arguments to function ‘pthread_join’
Oh I see that if I include #include <stdlib.h>
and leave out <pthread.h>
then it will have a definition for pthread_t
but nothing for pthread_join
. There are still plenty of warnings though:
warning: implicit declaration of function ‘pthread_join’
You should always build programs with the -Wall -W -pedantic
arguments to the compiler. And fix the warnings.
And to explain the crash: Since you don't pass NULL as the second argument to pthread_join
it will be receiving a "random" value and then writing into it as if it was a pointer. Which it isn't. So it will either write a value into your allocated memory where it shouldn't, or it will get a segmentation fault.
And to explain how printf
or sleep
fixes the problem: Making those function calls must change the value of the RSI
register (RSI is used for the second function argument) enough that it is either a valid pointer or NULL.