Sort locks by their guestaddr to make the error output independent
of the dynamically allocated Lock addresses.
This restores helgrind/tests/locked_vs_unlocked2.stderr.exp
from r14931.

While regtesting the patch I've observed intermittent failures
of helgrind/tests/hg05_race2 like so:

--- ../../helgrind/tests/hg05_race2.stderr.exp  (revision 15001)
+++ ../../helgrind/tests/hg05_race2.stderr.exp  (working copy)
@@ -26,8 +26,7 @@
    at 0x........: th (hg05_race2.c:17)
    by 0x........: mythread_wrapper (hg_intercepts.c:...)
    ...
- Location 0x........ is 0 bytes inside foo.poot[5].plop[11],
- declared at hg05_race2.c:24, in frame #x of thread x
+ Address 0x........ is on thread #x's stack
 
 ----------------------------------------------------------------
 
@@ -42,8 +41,7 @@
    at 0x........: th (hg05_race2.c:17)
    by 0x........: mythread_wrapper (hg_intercepts.c:...)
    ...
- Location 0x........ is 0 bytes inside foo.poot[5].plop[11],
- declared at hg05_race2.c:24, in frame #x of thread x
+ Address 0x........ is on thread #x's stack

Surely, that's something else.


git-svn-id: svn://svn.valgrind.org/valgrind/trunk@15009 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/NEWS b/NEWS
index 7bcbd54..4a57638 100644
--- a/NEWS
+++ b/NEWS
@@ -111,6 +111,7 @@
 343335  unhandled instruction 0x1E638400 (fccmp) aarch64
 343523  OS X mach_ports_register: UNKNOWN task message [id 3403, to 
         mach_task_self(), reply 0x30f]
+343597  ppc64le: incorrect use of offseof macro
 343732  Unhandled syscall 144 (setgid) on aarch64
 343733  Unhandled syscall 187 (msgctl and related) on aarch64
 343802  s390x: Fix false positives "conditional jump or move depends on
@@ -137,12 +138,12 @@
 344686  Fix suppression for pthread_rwlock_init on OS X 10.10
 344702  Fix missing libobjc suppressions on OS X 10.10
 344939  Fix memcheck/tests/xml1 on OS X 10.10
+345016  helgrind/tests/locked_vs_unlocked2 is failing sometimes
 n-i-bz  Provide implementations of certain compiler builtins to support
         compilers who may not provide those
 n-i-bz  Old STABS code is still being compiled, but never used. Remove it.
 n-i-bz  Fix compilation on distros with glibc < 2.5
 n-i-bz  (vex 3098) Avoid generation of Neon insns on non-Neon hosts
-343597  ppc64le: incorrect use of offseof macro
 
 
 Release 3.10.1 (25 November 2014)
diff --git a/helgrind/hg_errors.c b/helgrind/hg_errors.c
index 87c5bbd..d0fac40 100644
--- a/helgrind/hg_errors.c
+++ b/helgrind/hg_errors.c
@@ -184,6 +184,18 @@
    return lkp;
 }
 
+static Int sort_by_guestaddr(const void* n1, const void* n2)
+{
+   const Lock* l1 = *(const Lock *const *)n1;
+   const Lock* l2 = *(const Lock *const *)n2;
+
+   Addr a1 = l1 == Lock_INVALID ? 0 : l1->guestaddr;
+   Addr a2 = l2 == Lock_INVALID ? 0 : l2->guestaddr;
+   if (a1 < a2) return -1;
+   if (a1 > a2) return 1;
+   return 0;
+}
+
 /* Expand a WordSet of LockN*'s into a NULL-terminated vector of
    LockP*'s.  Any LockN's that can't be converted into a LockP
    (because they have been freed, see comment on mk_LockP_from_LockN)
@@ -215,6 +227,10 @@
       lockPs[i] = mk_LockP_from_LockN( (Lock*)lockNs[i],
                                        allowed_to_be_invalid );
    }
+   /* Sort the locks by increasing Lock::guestaddr to avoid jitters
+      in the output. */
+   VG_(ssort)(lockPs, nLockNs, sizeof lockPs[0], sort_by_guestaddr);
+
    return lockPs;
 }
 
diff --git a/helgrind/tests/locked_vs_unlocked2.stderr.exp b/helgrind/tests/locked_vs_unlocked2.stderr.exp
index d80f32d..3463b54 100644
--- a/helgrind/tests/locked_vs_unlocked2.stderr.exp
+++ b/helgrind/tests/locked_vs_unlocked2.stderr.exp
@@ -16,13 +16,13 @@
 
  Lock at 0x........ was first observed
    at 0x........: pthread_mutex_init (hg_intercepts.c:...)
-   by 0x........: main (locked_vs_unlocked2.c:59)
- Address 0x........ is 0 bytes inside data symbol "mx2b"
+   by 0x........: main (locked_vs_unlocked2.c:58)
+ Address 0x........ is 0 bytes inside data symbol "mx2a"
 
  Lock at 0x........ was first observed
    at 0x........: pthread_mutex_init (hg_intercepts.c:...)
-   by 0x........: main (locked_vs_unlocked2.c:58)
- Address 0x........ is 0 bytes inside data symbol "mx2a"
+   by 0x........: main (locked_vs_unlocked2.c:59)
+ Address 0x........ is 0 bytes inside data symbol "mx2b"
 
  Lock at 0x........ was first observed
    at 0x........: pthread_mutex_init (hg_intercepts.c:...)