Search code examples
cunixpthreadspthread-join

Seg fault (core dumped) after pthread_join in C


I keep getting a seg fault (core dump) after pthread_join in my program. It prints out the expected result just fine, but seg faults when joining the thread. I have looked at several other discussions on this topic, but none of the suggested solutions seem to work in my case. Here is what my compile command looks like (no compile warnings or errors):

$ gcc -Wall -pthread test.c -o test

Here is the output:

$ ./test
1 2 3 4 5 6 7 8 9 10 
Segmentation fault (core dumped)

And here is the code:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

int array[10];

void *fillArray(int *size) {
  int i;

  for (i = 0; i < *size; i++) {
    array[i] = i+1;
  }

  return NULL;
}

int main (int argc, char *argv[])
{
  int i, rc;
  int size = 10;
  pthread_t thread;
  void *res, *end;

  //initialize the array
  for (i = 0; i < size; i++) {
    array[i] = 0;
  }

  rc = pthread_create(&thread, NULL, fillArray(&size), &res);
  if (rc != 0) {
    perror("Cannot create thread");
    exit(EXIT_FAILURE);
  }

  //print the array
  for (i = 0; i < size; i++) {
    if (array[i] != -1) 
      printf("%d ", array[i]);
  }
  printf("\n");

  rc = pthread_join(thread, &end);
  if (rc != 0) {
    perror("Cannot join thread");
    exit(EXIT_FAILURE);
  }

  return 0;
}

Any ideas what could be the cause?


Solution

  • This doesn't compile for me: It fails with

    dummy.cpp: In function ‘int main(int, char**)’:
    dummy.cpp:29: error: invalid conversion from ‘void*’ to ‘void* (*)(void*)’
    dummy.cpp:29: error:   initializing argument 3 of ‘int pthread_create(_opaque_pthread_t**, const pthread_attr_t*, void* (*)(void*), void*)’
    

    Which is because you're actually calling fillArray and passing its result to pthread_create, rather than passing the function pointer. I expect your code will need to look more like this (UNTESTED!) : (Note I changed signature of fillArray, created data struct type to pass to fillArray, changed how pthread_create is called)

    #include <stdio.h>
    #include <stdlib.h>
    #include <pthread.h>
    
    int array[10];
    
    struct fillArrayData {
      int * array;
      int size;
      int * result;
    };
    
    void *fillArray(void *void_data) {
      fillArrayData * data = (fillArray*)void_data;
    
      for (int i = 0; i < data.size; i++) {
        data.array[i] = i+1;
      }
    
      //You could fill in some return info into data.result here if you wanted.
    
      return NULL;
    }
    
    int main (int argc, char *argv[])
    {
      int i, rc;
      int size = 10;
      pthread_t thread;
      void *res, *end;
    
    
      //initialize the array
      for (i = 0; i < size; i++) {
        array[i] = 0;
      }
    
      fillArrayData data;
      data.array = array;
      data.size = 10;
    
      rc = pthread_create(&thread, NULL, fillArray, &data);
      if (rc != 0) {
        perror("Cannot create thread");
        exit(EXIT_FAILURE);
      }
    
      //print the array
      for (i = 0; i < size; i++) {
        if (array[i] != -1) 
          printf("%d ", array[i]);
      }
      printf("\n");
    
      rc = pthread_join(thread, &end);
      if (rc != 0) {
        perror("Cannot join thread");
        exit(EXIT_FAILURE);
      }
    
      return 0;
    }