linux - Wrong exit value from pthread_exit -
below code creates 2 threads , tries return values of them.
i've compiled , run on 32-bit glibc-2.15 system , went right (output: r1: 1, r2: 2). when did same thing on 64-bit glibc-2.17 system, output wrong (output: r1: 0, r2: 2). why same code behaves differently on different systems?
note: if types of r1 , r2 changed void*
or int*
commented below, code works on both systems.
#include <stdio.h> #include <pthread.h> #include <unistd.h> #include <string.h> void* worker(void* arg) { int = (int) arg; pthread_exit((void*)i); } int main(int argc, char** argv) { pthread_t tid[2]; int err = 0; err = pthread_create(&tid[0], null, worker, (void*) 1); if(err != 0) printf("error: %s\n", strerror(err)); err = pthread_create(&tid[1], null, worker, (void*) 2); if(err != 0) printf("error: %s\n", strerror(err)); ///* int r1 = 0, r2 = 0; // <-- wrong: r1: 0, r2: 2 //void *r1, *r2; // <-- ok: r1: 1, r2: 2 pthread_join(tid[0], (void**) &r1); pthread_join(tid[1], (void**) &r2); printf("r1: %d, r2: %d\n", (int) r1, (int) r2); //*/ // make comment above snippet , uncomment below snippet: // <-- ok: r1: 1, r2: 2 /* int *r1 = (int*) malloc(sizeof(int)); int *r2 = (int*) malloc(sizeof(int)); pthread_join(tid[0], (void**) r1); pthread_join(tid[1], (void**) r2); printf("r1: %d, r2: %d\n", (int)(*r1), (int)(*r2)); */ return 0; }
short answer: on 64-bit system, sizeof(void*) != sizeof(int)
, , passing &int
pthread_join
invoking undefined behavior (and corrupting stack; running variant of program under address sanitizer should detect error).
in case pass &int
, int
heap-allocated, corrupting heap instead, don't notice yet (your program crash later on subsequent malloc
or free
). running variant of program under valgrind or address sanitizer should trivially prove heap corruption you.
longer answer: pthread_join(tid, &x)
performs this:
memcpy(&x, previosly_used_pthread_exit_value, sizeof(void*));
it should clear passing in address of variable sizeof(x) < sizeof(void*)
invokes undefined behavior.
Comments
Post a Comment