Acroyear
Acroyear

Reputation: 1460

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?

Upvotes: 1

Views: 2485

Answers (2)

sujin
sujin

Reputation: 2853

Error in

  1. Calling function pointer

  2. passing parameter to thread handler

In pthread prototype of pthread_create below

int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
                      void *(*start_routine) (void *), void *arg);

1st argument - pthread_variable

2nd argument - thread attrubutes

3rd argument - thread handler(function pointer name)

4th argument - variable need to pass thread handler.

In 4th argument - if two thread want to share single variable, then create global variable, and the pass this variable when creating thread.

sample program:

#include <pthread.h>
#include <stdio.h>
#define NUM_THREADS     5

void *PrintHello(void *threadid)
{
    long tid;
    tid = (long)threadid;
    printf("Hello World! It's me, thread #%ld!\n", tid);
    pthread_exit(NULL);
}

int main (int argc, char *argv[])
{
    pthread_t threads[NUM_THREADS];
    int rc;
    long t;

    for(t=0; t<NUM_THREADS; t++){
        printf("In main: creating thread %ld\n", t);
        rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t);
        if (rc){
             printf("ERROR; return code from pthread_create() is %d\n", rc);
             exit(-1);
        }
    }

    pthread_exit(NULL);

}

further details here

Upvotes: 0

Michael Anderson
Michael Anderson

Reputation: 73480

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

Upvotes: 3

Related Questions