title: Segmentation Fault when using Threads and Semaphores, Mac Vs Linux
body: <p>My problem deals with a segmentation fault that I get when I run this program on a linux machine versus my own mac computer. This program runs how I believe it should on my own mac computer, yet when I try to run it on my school's linux computers, I get a segmentation fault that doesn't appear on my mac computer. I'll give a brief background on the assignment and then go over the problem in more detail.</p>
  
  <p>So I have this program which basically simulates baboons crossing a ravine with a single rope. Only one baboon can cross at a time and there are certain restraints on the number of baboons that can cross at a time, as well as how many baboons can cross from one direction before baboons from the other direction are allowed to cross. The implementation of the code.    </p>
  
  <p>I have searched for segmentation fault questions already here on stackoverflow, yet most of them deal with multiple processes whereas I am merely using different threads. The segmentation fault ends up coming from waiting on a semaphore that doesn't exist, yet when I checked to see whether it was initialized, it was successfully initialized. Again, this program works on my mac but then doesn't work when I try to run it on my Mac. Any help at all understanding why it can't run on the linux machines but can run on the mac. If any more information is needed, I would be happy to provide it. I did error check at one point but that code was deleted off the school computers. My error checking, as far as I remember, didn't show any errors. </p>
  
  <pre><code>#include &lt;stdlib.h&gt;
  #include &lt;stdio.h&gt;
  #include &lt;string.h&gt;
  #include &lt;sys/types.h&gt;
  #include &lt;unistd.h&gt;
  #include &lt;sys/time.h&gt;
  #include &lt;time.h&gt;
  #include &lt;pthread.h&gt;
  
  #include &lt;semaphore.h&gt;
  #include &lt;fcntl.h&gt;
  #include &lt;sys/stat.h&gt; //for mode flags, if needed for future use
  
  #define ATOB_COUNT 20
  #define BTOA_COUNT 20
  #define RANDOM_SEED 2123
  
  //semaphore names
  #define MUTEX_SEM "/mutex"
  #define TOB_SEM "/toB"
  #define TOA_SEM "/toA"
  
  //define methods here if needed
  void *toAThread(void *threadId);
  void *toBThread(void *threadId);
  void my_sleep(int limit);
  void sem_open_errorCheck(char *name, unsigned int startingValue, sem_t *result);
  
  //defining semaphores and shared variables
  sem_t *mutex, *toB, *toA;
  int xingCount = 0;
  int xedCount = 0;
  int toBWaitCount = 0;
  int toAWaitCount = 0;
  enum xingDirectionTypes {
      none,
      aToB,
      bToA
  };
  enum xingDirectionTypes xingDirection = none;
  
  char orderLeaving[100];
  
  
  struct threadInfo {
      int threadId;
  };
  
  struct threadInfo atobIDs[ATOB_COUNT];
  struct threadInfo btoaIDs[BTOA_COUNT];
  
  int main(void) {
  
      pthread_t atobPTHREADS[ATOB_COUNT];
      pthread_t btoaPTHREADS[BTOA_COUNT];
      pthread_attr_t attr;
      void *status;
  
      srandom(RANDOM_SEED);
  
      //call helper method which creates semaphore and errorchecks
      sem_open_errorCheck(MUTEX_SEM, (unsigned int)1, mutex);
      sem_open_errorCheck(TOA_SEM, (unsigned int)0, toA);
      sem_open_errorCheck(TOB_SEM, (unsigned int)0, toB);
  
  
      //Creating a set of attributes to send to the threads
      pthread_attr_init(&amp;attr);
      pthread_attr_setdetachstate(&amp;attr, PTHREAD_CREATE_JOINABLE);
  
      //spawn toB baboons
      int counter;
      for (counter = 0; counter &lt; BTOA_COUNT; counter++) {
          atobIDs[counter].threadId = counter;
          int result;
          if ((result = pthread_create(&amp;atobPTHREADS[counter], &amp;attr, toBThread, (void*) &amp;atobIDs[counter])) == -1) {
              perror("Thread Creation Error: atob baboon");
              exit(EXIT_FAILURE);
          }
      }
  
      //spawn toA baboons
      for (counter = 0; counter &lt; ATOB_COUNT; counter++) {
          btoaIDs[counter].threadId = counter + 20;
          int result;
          if ((result = pthread_create(&amp;btoaPTHREADS[counter], &amp;attr, toAThread, (void*) &amp;btoaIDs[counter])) == -1) {
              perror("Thread Creation Error: btoa baboon");
              exit(EXIT_FAILURE);
          }
      }
  
      //Wait for all the threads to finish
      for(counter = 0; counter &lt; ATOB_COUNT; counter++)
      {
          int result = pthread_join(atobPTHREADS[counter], &amp;status);
          if(result == -1)
          {
              perror("Thread Join: AtoB");
              exit(EXIT_FAILURE);
          }
      }
  
      for(counter = 0; counter &lt; BTOA_COUNT; counter++)
      {
          int result = pthread_join(btoaPTHREADS[counter], &amp;status);
          if(result == -1)
          {
              perror("Thread Join: BtoA");
              exit(EXIT_FAILURE);
          }
      }
      printf("The order leaving %s", orderLeaving);
      exit(EXIT_SUCCESS);
  }
  
  void *toBThread(void *threadId) {
  
      struct threadInfo *info;
      info = (struct threadInfo *)threadId;
      int id = info-&gt;threadId;
  
      my_sleep(100); //simulate being idle for 1-100ms
      //for order checking
      char *baboonOrder;
      baboonOrder = "B ";
      strcat(orderLeaving, baboonOrder);
  
      sem_wait(mutex);
      if ((xingDirection == aToB || xingDirection == none) &amp;&amp; xingCount &lt; 5 &amp;&amp; (xedCount + xingCount) &lt; 10) { //there is an extra parenthesis here in the solutions
          xingDirection = aToB;
          xingCount++;
          printf("AtoB baboon (thread %d) got on the rope\n", id);
          sem_post(mutex);
      }
      else {
          toBWaitCount++;
          sem_post(mutex);
          sem_wait(toB);
          toBWaitCount--;
          xingCount++;
          xingDirection = aToB;
          printf("AtoB baboon (thread %d) got on the rope\n", id);
          sem_post(mutex);
      }
      //CROSSING
  
  
      sem_wait(mutex);
      printf("AtoB baboon (thread %d) got off the rope\n", id);
      xedCount++;
      xingCount--;
      if (toBWaitCount != 0 &amp;&amp; (((xedCount+xingCount)&lt;10) || ((xedCount+xingCount) &gt;= 10 &amp;&amp; toAWaitCount == 0))) {
          sem_post(toB);
      }
      else {
          if (xingCount == 0 &amp;&amp; toAWaitCount != 0 &amp;&amp; (toBWaitCount == 0 || (xedCount + xingCount)&gt;=10)) {
              xingDirection = bToA;
              xedCount = 0;
              sem_post(toA);
          }
          else {
              if (xingCount == 0 &amp;&amp; toBWaitCount == 0 &amp;&amp; toAWaitCount == 0) {
                  xingDirection = none;
                  xedCount = 0;
                  sem_post(mutex);
              }
              else {
                  sem_post(mutex);
              }
          }
      }
  }
  
  /*
   baboons going from side a to side b
   */
  void *toAThread(void *threadId) {
  
      struct threadInfo *info;
      info = (struct threadInfo *)threadId;
      int id = info-&gt;threadId;
  
      my_sleep(100);
  
      //for order checking
      char *baboonOrder;
      baboonOrder = "A ";
      strcat(orderLeaving, baboonOrder);
  
      sem_wait(mutex);
      if ((xingDirection == bToA || xingDirection == none) &amp;&amp; xingCount &lt; 5 &amp;&amp; (xedCount + xingCount) &lt; 10) { //there is an extra parenthesis here in the solutions
          xingDirection = bToA;
          xingCount++;
          printf("BtoA baboon (thread %d) got on the rope\n", id);
          sem_post(mutex);
      }
      else {
          toAWaitCount++;
          sem_post(mutex);
          sem_wait(toA);
          toAWaitCount--;
          xingCount++;
          xingDirection = bToA;
          printf("BtoA baboon (thread %d) got on the rope\n", id);
          sem_post(mutex);
      }
      //CROSSING
  
  
      sem_wait(mutex);
      printf("BtoA baboon (thread %d) got off the rope\n", id);
      xedCount++;
      xingCount--;
      if (toAWaitCount != 0 &amp;&amp; (((xedCount+xingCount)&lt;10) || ((xedCount+xingCount) &gt;= 10 &amp;&amp; toBWaitCount == 0))) {
          sem_post(toA);
      }
      else {
          if (xingCount == 0 &amp;&amp; toBWaitCount != 0 &amp;&amp; (toAWaitCount == 0 || (xedCount + xingCount)&gt;=10)) {
              xingDirection = aToB;
              xedCount = 0;
              sem_post(toB);
          }
          else {
              if (xingCount == 0 &amp;&amp; toAWaitCount == 0 &amp;&amp; toBWaitCount == 0) {
                  xingDirection = none;
                  xedCount = 0;
                  sem_post(mutex);
              }
              else {
                  sem_post(mutex);
              }
          }
      }
  }
  
  //taken with permission from readers/writers problem
  //Puts the calling thread to sleep to simulate both random start times and random workloads
  void my_sleep(int limit) {
      struct timespec time_ns;
      int duration = random() % limit + 1;
      time_ns.tv_sec = 0;
      time_ns.tv_nsec = duration * 1000000;
      int result = nanosleep(&amp;time_ns, NULL);
      if (result != 0)
      {
          perror("Nanosleep");
          exit(EXIT_FAILURE);
      }
  }
  
  void sem_open_errorCheck(char *name, unsigned int startingValue, sem_t *result) {
  
      sem_unlink(name);
      result = sem_open(name, O_CREAT, 0600, startingValue);
      if (result == -1) {
          perror("sem_open error: semaphore failed to open correctly");
          exit(EXIT_FAILURE);
      }
  }
  </code></pre>