2
votes

I'm getting a segmentation fault when trying to acess the 4th argument of pthread_join. Here is my code:

void* threadHandler(void* arg)
{
  printf("arg: %c\n", *(char *) arg);
  pthread_exit(0);
}

int main()
{
  pthread_t threadA;
  pthread_create(&threadA, NULL, threadHandler, "N");

  void *retval;
  pthread_join(threadA, &retval);

  printf("retval: %d\n", *(int *) retval);

  return 0;
}

Any idea as to why the last printf causes a segmentation fault error? How do i fix it? (it's my understanding that retval should contain the return value of the threadHandler, so in this case, it should be 0 right?)

Thanks in advance!

1
pthread_exit takes a pointer-to-void as the return value. You're returning (void *)0, which is a null pointer. Then you're dereferencing null pointer, which leads to undefined behaviour (crash in this case). - Antti Haapala
Instead of returning an int, usually you're expected to pthread_exit with a pointer to the result of calculation in your thread, or NULL on error, or something like that. - Antti Haapala
First of all, you say the return value of threadHandler() but it is not returning anythin which will invoke undefined behavior. Most importantly, you should return a pointer instead and 0 is probably the NULL pointer. Then you dereference it invoking in theory UB and ultimately causing a crash. - Iharob Al Asimi
facepalm Thank you all :) - Tirafesi

1 Answers

5
votes

If you understand that pthread_join() will pick the return value of the thread callback then you should return from it like this

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

void *
threadHandler(void *data)
{
    printf("arg: %s\n", (char *) data);
    return (void *) 0;
}

int 
main(void)
{
    pthread_t thread;
    const char *string;
    void *number;

    string = "N";
    if (pthread_create(&thread, NULL, threadHandler, (void *) string) != 0)
        return -1;
    pthread_join(thread, &number);
    printf("%d\n", ((int) (intptr_t) number));
    return 0;
}

Note however, that the returned address 0x00 is probably not a valid address — usually it's the NULL pointer (void *) 0x00 — so you should only do this as long as youre interested in using the value of the pointer as the integer you want to return.

Dereferencing the pointer is Undefined Behavior but, using the value is not.