clinuxfaultcontinuouspthread-join

Calling pthread_join with one argument causes a segmentation fault?


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;
}

Solution

  • 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.