0

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;
}
omar.zhou
  • 23
  • 1
  • 7
  • Always check your error returns. If `pthread_create` fails it doesn't set your `fa[i]` to any valid value. I imagine you must set `k` very high because with just k = 2 there's no problem here. – Zan Lynx Feb 09 '21 at 00:48
  • I just set k = 2. And I can ensure that call to `pthread_create` success. – omar.zhou Feb 10 '21 at 03:18

1 Answers1

4

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.

Zan Lynx
  • 53,022
  • 10
  • 79
  • 131
  • The way I compile the code is `gcc -g demo_thread.c -lpthread -o demo_thread.out`. Maybe you miss the `-lpthread`. – omar.zhou Feb 10 '21 at 03:27
  • @omar.zhou No I didn't miss it. I have a lot of automated stuff in my editor and Makefiles so at first I didn't even see the header was missing, because my editor had automatically added it, and removed stdlib.h since it was never used. And `-pthread` gets automatically added to the compiler flags. – Zan Lynx Feb 10 '21 at 03:39