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

Popular posts from this blog

android - Gradle sync Error:Configuration with name 'default' not found -

java - Andrioid studio start fail: Fatal error initializing 'null' -

html - jQuery UI Sortable - Remove placeholder after item is dropped -