Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does this code fail without volatile declaration? [duplicate]

I have this code below from a book, compiled on Ubuntu 18.4, with Eclipse -O0 -g3

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

void *myThread( void *arg )
{
  printf( "Thread %d started\n", (int)arg );

  pthread_exit( arg );
}

#define MAX_THREADS 5

int main()
{
  volatile int  i;
  int status;
  int ret;
  pthread_t threadIds[MAX_THREADS];

  for (i = 0 ; i < MAX_THREADS ; i++) {
    ret = pthread_create( &threadIds[i], NULL, myThread, (void *)i );
    if (ret != 0) {
      printf( "Error creating thread %d\n", (int)threadIds[i] );
    }
  }

  for (i = 0 ; i < MAX_THREADS ; i++) {
    printf("-----------  i = %d\n",i);
    ret = pthread_join( threadIds[i], (void **)&status );
    if (ret != 0) {
      printf( "Error joining thread %d\n", (int)threadIds[i] );
    } else {
      printf( "Status = %d\n", status );
    }
  }

  return 0;
}

This code worked correctly and produced the output

-----------  i = 0
Thread 3 started
Thread 0 started
Status = 0
-----------  i = 1
Thread 2 started
Thread 1 started
Status = 1
-----------  i = 2
Status = 2
-----------  i = 3
Status = 3
-----------  i = 4
Thread 4 started
Status = 4

However, if volatile keyword at variable i declaration is ignored, the following output is produced:

Thread 1 started
Thread 0 started
Thread 2 started
Thread 3 started
-----------  i = 0
Status = 0
-----------  i = 1
Status = 1
-----------  i = 1
Error joining thread -947054848
-----------  i = 2
Status = 2
-----------  i = 1
Error joining thread -947054848
-----------  i = 2
Error joining thread -955447552
-----------  i = 3
Status = 3
-----------  i = 1
Error joining thread -947054848
-----------  i = 2
Error joining thread -955447552
-----------  i = 3
Error joining thread -963840256
-----------  i = 4
Thread 4 started
Status = 4
-----------  i = 1
Error joining thread -947054848
-----------  i = 2
Error joining thread -955447552
-----------  i = 3
Error joining thread -963840256
-----------  i = 4
Error joining thread -1073744128

Please help me identify what the problem could be that led to this issue.

like image 365
user1502776 Avatar asked Dec 18 '25 13:12

user1502776


1 Answers

In your code:

int status;

// ...

pthread_join( threadIds[i], (void **)&status );

this is a strict aliasing violation. The pthread_join writes a value of type void * to the location, however you provided the location of an int. This causes undefined behaviour, meaning anything can happen.

Possibly what happened on your system would be a write out of bounds (int = 4 bytes, void * = 8 bytes), scrambling the stack leading to a mess.

You can fix this with:

void *status;
// ...
pthread_join( threadIds[i], &status );

and later on, if you want to print status with %d, use (int)status for the argument.

like image 97
M.M Avatar answered Dec 20 '25 07:12

M.M



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!