title: Why does Helgrind show "lock order violated" error message?
body: <p>Please see the following code</p>
  
  <pre><code>    #include &lt;stdio.h&gt;
      #include &lt;pthread.h&gt;
      #include &lt;assert.h&gt;
      #include &lt;stdlib.h&gt;
  
      pthread_mutex_t g = PTHREAD_MUTEX_INITIALIZER;
      pthread_mutex_t m1 = PTHREAD_MUTEX_INITIALIZER;
      pthread_mutex_t m2 = PTHREAD_MUTEX_INITIALIZER;
  
      void* worker(void* arg) 
      {
          pthread_mutex_lock(&amp;g);
  
          if ((long long) arg == 0) {
          pthread_mutex_lock(&amp;m1);
          pthread_mutex_lock(&amp;m2);
          } else {
          pthread_mutex_lock(&amp;m2);
          pthread_mutex_lock(&amp;m1);
          }
          pthread_mutex_unlock(&amp;m1);
          pthread_mutex_unlock(&amp;m2);
  
          pthread_mutex_unlock(&amp;g);
          return NULL;
      }
  
      int main(int argc, char *argv[]) {
          pthread_t p1, p2;
          pthread_create(&amp;p1, NULL, worker, (void *) (long long) 0);
          pthread_create(&amp;p2, NULL, worker, (void *) (long long) 1);
          pthread_join(p1, NULL);
          pthread_join(p2, NULL);
          return 0;
      }
  </code></pre>
  
  <p>Helgrind throws the following error:</p>
  
  <pre><code>==10035== Helgrind, a thread error detector
  ==10035== Copyright (C) 2007-2017, and GNU GPL'd, by OpenWorks LLP et al.
  ==10035== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
  ==10035== Command: ./Hw5
  ==10035== 
  ==10035== ---Thread-Announcement------------------------------------------
  ==10035== 
  ==10035== Thread #3 was created
  ==10035==    at 0x538987E: clone (clone.S:71)
  ==10035==    by 0x5050EC4: create_thread (createthread.c:100)
  ==10035==    by 0x5050EC4: pthread_create@@GLIBC_2.2.5 (pthread_create.c:797)
  ==10035==    by 0x4C36A27: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
  ==10035==    by 0x1088BD: main (Hw5.c:28)
  ==10035== 
  ==10035== ----------------------------------------------------------------
  ==10035== 
  ==10035== Thread #3: lock order "0x309080 before 0x3090C0" violated
  ==10035== 
  ==10035== Observed (incorrect) order is: acquisition of lock at 0x3090C0
  ==10035==    at 0x4C3403C: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
  ==10035==    by 0x10882E: worker (Hw5.c:16)
  ==10035==    by 0x4C36C26: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
  ==10035==    by 0x50506DA: start_thread (pthread_create.c:463)
  ==10035==    by 0x538988E: clone (clone.S:95)
  ==10035== 
  ==10035==  followed by a later acquisition of lock at 0x309080
  ==10035==    at 0x4C3403C: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
  ==10035==    by 0x10883A: worker (Hw5.c:17)
  ==10035==    by 0x4C36C26: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
  ==10035==    by 0x50506DA: start_thread (pthread_create.c:463)
  ==10035==    by 0x538988E: clone (clone.S:95)
  ==10035== 
  ==10035== Required order was established by acquisition of lock at 0x309080
  ==10035==    at 0x4C3403C: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
  ==10035==    by 0x108814: worker (Hw5.c:13)
  ==10035==    by 0x4C36C26: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
  ==10035==    by 0x50506DA: start_thread (pthread_create.c:463)
  ==10035==    by 0x538988E: clone (clone.S:95)
  ==10035== 
  ==10035==  followed by a later acquisition of lock at 0x3090C0
  ==10035==    at 0x4C3403C: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
  ==10035==    by 0x108820: worker (Hw5.c:14)
  ==10035==    by 0x4C36C26: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
  ==10035==    by 0x50506DA: start_thread (pthread_create.c:463)
  ==10035==    by 0x538988E: clone (clone.S:95)
  ==10035== 
  ==10035==  Lock at 0x309080 was first observed
  ==10035==    at 0x4C3403C: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
  ==10035==    by 0x108814: worker (Hw5.c:13)
  ==10035==    by 0x4C36C26: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
  ==10035==    by 0x50506DA: start_thread (pthread_create.c:463)
  ==10035==    by 0x538988E: clone (clone.S:95)
  ==10035==  Address 0x309080 is 0 bytes inside data symbol "m1"
  ==10035== 
  ==10035==  Lock at 0x3090C0 was first observed
  ==10035==    at 0x4C3403C: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
  ==10035==    by 0x108820: worker (Hw5.c:14)
  ==10035==    by 0x4C36C26: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
  ==10035==    by 0x50506DA: start_thread (pthread_create.c:463)
  ==10035==    by 0x538988E: clone (clone.S:95)
  ==10035==  Address 0x3090c0 is 0 bytes inside data symbol "m2"
  ==10035== 
  ==10035== 
  ==10035== 
  ==10035== For counts of detected and suppressed errors, rerun with: -v
  ==10035== Use --history-level=approx or =none to gain increased speed, at
  ==10035== the cost of reduced accuracy of conflicting-access information
  ==10035== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 7 from 7)
  </code></pre>
  
  <p>I think the outer lock <code>g</code> will not allow two threads to enter the critical section at same time.
  Only one thread can acquire the lock <code>g</code> at a given time. So I think there is no possibility for a deadlock. Am I worng? Why helgrind is throwing this error? Please explain.</p>