You can subscribe to this list here.
| 2002 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(1) |
Oct
(122) |
Nov
(152) |
Dec
(69) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2003 |
Jan
(6) |
Feb
(25) |
Mar
(73) |
Apr
(82) |
May
(24) |
Jun
(25) |
Jul
(10) |
Aug
(11) |
Sep
(10) |
Oct
(54) |
Nov
(203) |
Dec
(182) |
| 2004 |
Jan
(307) |
Feb
(305) |
Mar
(430) |
Apr
(312) |
May
(187) |
Jun
(342) |
Jul
(487) |
Aug
(637) |
Sep
(336) |
Oct
(373) |
Nov
(441) |
Dec
(210) |
| 2005 |
Jan
(385) |
Feb
(480) |
Mar
(636) |
Apr
(544) |
May
(679) |
Jun
(625) |
Jul
(810) |
Aug
(838) |
Sep
(634) |
Oct
(521) |
Nov
(965) |
Dec
(543) |
| 2006 |
Jan
(494) |
Feb
(431) |
Mar
(546) |
Apr
(411) |
May
(406) |
Jun
(322) |
Jul
(256) |
Aug
(401) |
Sep
(345) |
Oct
(542) |
Nov
(308) |
Dec
(481) |
| 2007 |
Jan
(427) |
Feb
(326) |
Mar
(367) |
Apr
(255) |
May
(244) |
Jun
(204) |
Jul
(223) |
Aug
(231) |
Sep
(354) |
Oct
(374) |
Nov
(497) |
Dec
(362) |
| 2008 |
Jan
(322) |
Feb
(482) |
Mar
(658) |
Apr
(422) |
May
(476) |
Jun
(396) |
Jul
(455) |
Aug
(267) |
Sep
(280) |
Oct
(253) |
Nov
(232) |
Dec
(304) |
| 2009 |
Jan
(486) |
Feb
(470) |
Mar
(458) |
Apr
(423) |
May
(696) |
Jun
(461) |
Jul
(551) |
Aug
(575) |
Sep
(134) |
Oct
(110) |
Nov
(157) |
Dec
(102) |
| 2010 |
Jan
(226) |
Feb
(86) |
Mar
(147) |
Apr
(117) |
May
(107) |
Jun
(203) |
Jul
(193) |
Aug
(238) |
Sep
(300) |
Oct
(246) |
Nov
(23) |
Dec
(75) |
| 2011 |
Jan
(133) |
Feb
(195) |
Mar
(315) |
Apr
(200) |
May
(267) |
Jun
(293) |
Jul
(353) |
Aug
(237) |
Sep
(278) |
Oct
(611) |
Nov
(274) |
Dec
(260) |
| 2012 |
Jan
(303) |
Feb
(391) |
Mar
(417) |
Apr
(441) |
May
(488) |
Jun
(655) |
Jul
(590) |
Aug
(610) |
Sep
(526) |
Oct
(478) |
Nov
(359) |
Dec
(372) |
| 2013 |
Jan
(467) |
Feb
(226) |
Mar
(391) |
Apr
(281) |
May
(299) |
Jun
(252) |
Jul
(311) |
Aug
(352) |
Sep
(481) |
Oct
(571) |
Nov
(222) |
Dec
(231) |
| 2014 |
Jan
(185) |
Feb
(329) |
Mar
(245) |
Apr
(238) |
May
(281) |
Jun
(399) |
Jul
(382) |
Aug
(500) |
Sep
(579) |
Oct
(435) |
Nov
(487) |
Dec
(256) |
| 2015 |
Jan
(338) |
Feb
(357) |
Mar
(330) |
Apr
(294) |
May
(191) |
Jun
(108) |
Jul
(142) |
Aug
(261) |
Sep
(190) |
Oct
(54) |
Nov
(83) |
Dec
(22) |
| 2016 |
Jan
(49) |
Feb
(89) |
Mar
(33) |
Apr
(50) |
May
(27) |
Jun
(34) |
Jul
(53) |
Aug
(53) |
Sep
(98) |
Oct
(206) |
Nov
(93) |
Dec
(53) |
| 2017 |
Jan
(65) |
Feb
(82) |
Mar
(102) |
Apr
(86) |
May
(187) |
Jun
(67) |
Jul
(23) |
Aug
(93) |
Sep
(65) |
Oct
(45) |
Nov
(35) |
Dec
(17) |
| 2018 |
Jan
(26) |
Feb
(35) |
Mar
(38) |
Apr
(32) |
May
(8) |
Jun
(43) |
Jul
(27) |
Aug
(30) |
Sep
(43) |
Oct
(42) |
Nov
(38) |
Dec
(67) |
| 2019 |
Jan
(32) |
Feb
(37) |
Mar
(53) |
Apr
(64) |
May
(49) |
Jun
(18) |
Jul
(14) |
Aug
(53) |
Sep
(25) |
Oct
(30) |
Nov
(49) |
Dec
(31) |
| 2020 |
Jan
(87) |
Feb
(45) |
Mar
(37) |
Apr
(51) |
May
(99) |
Jun
(36) |
Jul
(11) |
Aug
(14) |
Sep
(20) |
Oct
(24) |
Nov
(40) |
Dec
(23) |
| 2021 |
Jan
(14) |
Feb
(53) |
Mar
(85) |
Apr
(15) |
May
(19) |
Jun
(3) |
Jul
(14) |
Aug
(1) |
Sep
(57) |
Oct
(73) |
Nov
(56) |
Dec
(22) |
| 2022 |
Jan
(3) |
Feb
(22) |
Mar
(6) |
Apr
(55) |
May
(46) |
Jun
(39) |
Jul
(15) |
Aug
(9) |
Sep
(11) |
Oct
(34) |
Nov
(20) |
Dec
(36) |
| 2023 |
Jan
(79) |
Feb
(41) |
Mar
(99) |
Apr
(169) |
May
(48) |
Jun
(16) |
Jul
(16) |
Aug
(57) |
Sep
(19) |
Oct
|
Nov
|
Dec
|
| S | M | T | W | T | F | S |
|---|---|---|---|---|---|---|
|
|
1
(10) |
2
(8) |
3
(17) |
4
(28) |
5
(22) |
6
(8) |
|
7
(8) |
8
(22) |
9
(12) |
10
(17) |
11
(14) |
12
(15) |
13
(6) |
|
14
(9) |
15
(9) |
16
(16) |
17
(13) |
18
(18) |
19
(7) |
20
(5) |
|
21
(6) |
22
(5) |
23
(11) |
24
(5) |
25
(11) |
26
(7) |
27
(15) |
|
28
(11) |
29
(12) |
30
(12) |
31
(15) |
|
|
|
|
From: <sv...@va...> - 2007-10-30 01:18:25
|
Author: sewardj
Date: 2007-10-30 01:18:24 +0000 (Tue, 30 Oct 2007)
New Revision: 7054
Log:
Make "Unlocking a totally bogus lock" fail more reliably.
Modified:
branches/THRCHECK/thrcheck/tests/tc09_bad_unlock.c
Modified: branches/THRCHECK/thrcheck/tests/tc09_bad_unlock.c
===================================================================
--- branches/THRCHECK/thrcheck/tests/tc09_bad_unlock.c 2007-10-29 21:04:42 UTC (rev 7053)
+++ branches/THRCHECK/thrcheck/tests/tc09_bad_unlock.c 2007-10-30 01:18:24 UTC (rev 7054)
@@ -16,10 +16,10 @@
{
pthread_t child;
pthread_mutex_t mx1, mx2;
- int bogus[100];
-
+ int bogus[100], i;
+ /* fill bogus with values which will cause glibc's pth_mx_unlock to fail */
+ for (i = 0; i < 100; i++) bogus[i] = 0xFFFFFFFF;
/* Unlocking a lock that is already unlocked */
-
pthread_mutex_init( &mx1, NULL );
pthread_mutex_lock( &mx1 );
pthread_mutex_unlock( &mx1 );
|
|
From: <js...@ac...> - 2007-10-30 01:16:57
|
Nightly build on g5 ( SuSE 10.1, ppc970 ) started at 2007-10-30 02:00:01 CET Results unchanged from 24 hours ago Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 228 tests, 6 stderr failures, 2 stdout failures, 0 posttest failures == memcheck/tests/deep_templates (stdout) memcheck/tests/leak-cycle (stderr) memcheck/tests/leak-tree (stderr) memcheck/tests/pointer-trace (stderr) none/tests/faultstatus (stderr) none/tests/fdleak_cmsg (stderr) none/tests/mremap (stderr) none/tests/mremap2 (stdout) |
|
From: <sv...@va...> - 2007-10-29 21:04:41
|
Author: sewardj
Date: 2007-10-29 21:04:42 +0000 (Mon, 29 Oct 2007)
New Revision: 7053
Log:
Duh. r7051 was bogus; tc14_laog_dinphils.stderr.exp was renamed to
tc14_laog_dinphils.stderr.exp-glibc25-amd64 some time after r7051.
Fix it.
Removed:
branches/THRCHECK/thrcheck/tests/tc14_laog_dinphils.stderr.exp
Modified:
branches/THRCHECK/thrcheck/tests/tc14_laog_dinphils.stderr.exp-glibc25-amd64
Deleted: branches/THRCHECK/thrcheck/tests/tc14_laog_dinphils.stderr.exp
===================================================================
--- branches/THRCHECK/thrcheck/tests/tc14_laog_dinphils.stderr.exp 2007-10-29 20:49:31 UTC (rev 7052)
+++ branches/THRCHECK/thrcheck/tests/tc14_laog_dinphils.stderr.exp 2007-10-29 21:04:42 UTC (rev 7053)
@@ -1,16 +0,0 @@
-
-Thread #6 was created
- at 0x........: clone (in /...libc...)
- by 0x........: ...
- by 0x........: pthread_create@GLIBC_ (in /lib/libpthread...)
- by 0x........: pthread_create@* (tc_intercepts.c:...)
- by 0x........: main (tc14_laog_dinphils.c:34)
-
-Thread #6: lock order "0x........ before 0x........" violated
- at 0x........: pthread_mutex_lock (tc_intercepts.c:...)
- by 0x........: dine (tc14_laog_dinphils.c:19)
- by 0x........: mythread_wrapper (tc_intercepts.c:...)
- by 0x........: ...
- by 0x........: ...
-
-ERROR SUMMARY: 1000 errors from 1 contexts (suppressed: 0 from 0)
Modified: branches/THRCHECK/thrcheck/tests/tc14_laog_dinphils.stderr.exp-glibc25-amd64
===================================================================
--- branches/THRCHECK/thrcheck/tests/tc14_laog_dinphils.stderr.exp-glibc25-amd64 2007-10-29 20:49:31 UTC (rev 7052)
+++ branches/THRCHECK/thrcheck/tests/tc14_laog_dinphils.stderr.exp-glibc25-amd64 2007-10-29 21:04:42 UTC (rev 7053)
@@ -12,17 +12,5 @@
by 0x........: mythread_wrapper (tc_intercepts.c:...)
by 0x........: ...
by 0x........: ...
- Required order was established by acquisition of lock at 0x........
- at 0x........: pthread_mutex_lock (tc_intercepts.c:...)
- by 0x........: dine (tc14_laog_dinphils.c:18)
- by 0x........: mythread_wrapper (tc_intercepts.c:...)
- by 0x........: ...
- by 0x........: ...
- followed by a later acquisition of lock at 0x........
- at 0x........: pthread_mutex_lock (tc_intercepts.c:...)
- by 0x........: dine (tc14_laog_dinphils.c:19)
- by 0x........: mythread_wrapper (tc_intercepts.c:...)
- by 0x........: ...
- by 0x........: ...
ERROR SUMMARY: 1000 errors from 1 contexts (suppressed: 0 from 0)
|
|
From: <sv...@va...> - 2007-10-29 20:49:30
|
Author: sewardj
Date: 2007-10-29 20:49:31 +0000 (Mon, 29 Oct 2007)
New Revision: 7052
Log:
Update expected output following r7050.
Modified:
branches/THRCHECK/thrcheck/tests/tc19_shadowmem.stderr.exp-glibc25-amd64
Modified: branches/THRCHECK/thrcheck/tests/tc19_shadowmem.stderr.exp-glibc25-amd64
===================================================================
--- branches/THRCHECK/thrcheck/tests/tc19_shadowmem.stderr.exp-glibc25-amd64 2007-10-29 20:48:01 UTC (rev 7051)
+++ branches/THRCHECK/thrcheck/tests/tc19_shadowmem.stderr.exp-glibc25-amd64 2007-10-29 20:49:31 UTC (rev 7052)
@@ -155,19 +155,19 @@
Reason: this thread, #13, holds no locks at all
---------- char gran, 0 .. 99, skip 6 ----------
-Thread #15 was created
+Thread #14 was created
at 0x........: clone (in /...libc...)
by 0x........: ...
by 0x........: pthread_create@GLIBC_ (in /lib/libpthread...)
by 0x........: pthread_create@* (tc_intercepts.c:...)
- by 0x........: main (tc19_shadowmem.c:173)
+ by 0x........: main (tc19_shadowmem.c:172)
-Thread #14 was created
+Thread #15 was created
at 0x........: clone (in /...libc...)
by 0x........: ...
by 0x........: pthread_create@GLIBC_ (in /lib/libpthread...)
by 0x........: pthread_create@* (tc_intercepts.c:...)
- by 0x........: main (tc19_shadowmem.c:172)
+ by 0x........: main (tc19_shadowmem.c:173)
Possible data race during write of size 1 at 0x........
at 0x........: child8 (tc19_shadowmem.c:35)
@@ -176,7 +176,7 @@
by 0x........: ...
by 0x........: ...
Old state: owned exclusively by thread #14
- New state: shared-modified by threads #15, #14
+ New state: shared-modified by threads #14, #15
Reason: this thread, #15, holds no locks at all
---------- char gran, 0 .. 99, skip 7 ----------
@@ -1655,19 +1655,19 @@
Reason: this thread, #133, holds no locks at all
---------- char gran, 0 .. 99, skip 66 ----------
-Thread #135 was created
+Thread #134 was created
at 0x........: clone (in /...libc...)
by 0x........: ...
by 0x........: pthread_create@GLIBC_ (in /lib/libpthread...)
by 0x........: pthread_create@* (tc_intercepts.c:...)
- by 0x........: main (tc19_shadowmem.c:173)
+ by 0x........: main (tc19_shadowmem.c:172)
-Thread #134 was created
+Thread #135 was created
at 0x........: clone (in /...libc...)
by 0x........: ...
by 0x........: pthread_create@GLIBC_ (in /lib/libpthread...)
by 0x........: pthread_create@* (tc_intercepts.c:...)
- by 0x........: main (tc19_shadowmem.c:172)
+ by 0x........: main (tc19_shadowmem.c:173)
Possible data race during write of size 1 at 0x........
at 0x........: child8 (tc19_shadowmem.c:35)
@@ -1676,7 +1676,7 @@
by 0x........: ...
by 0x........: ...
Old state: owned exclusively by thread #134
- New state: shared-modified by threads #135, #134
+ New state: shared-modified by threads #134, #135
Reason: this thread, #135, holds no locks at all
---------- char gran, 0 .. 99, skip 67 ----------
@@ -1780,19 +1780,19 @@
Reason: this thread, #143, holds no locks at all
---------- char gran, 0 .. 99, skip 71 ----------
-Thread #145 was created
+Thread #144 was created
at 0x........: clone (in /...libc...)
by 0x........: ...
by 0x........: pthread_create@GLIBC_ (in /lib/libpthread...)
by 0x........: pthread_create@* (tc_intercepts.c:...)
- by 0x........: main (tc19_shadowmem.c:173)
+ by 0x........: main (tc19_shadowmem.c:172)
-Thread #144 was created
+Thread #145 was created
at 0x........: clone (in /...libc...)
by 0x........: ...
by 0x........: pthread_create@GLIBC_ (in /lib/libpthread...)
by 0x........: pthread_create@* (tc_intercepts.c:...)
- by 0x........: main (tc19_shadowmem.c:172)
+ by 0x........: main (tc19_shadowmem.c:173)
Possible data race during write of size 1 at 0x........
at 0x........: child8 (tc19_shadowmem.c:35)
@@ -1801,7 +1801,7 @@
by 0x........: ...
by 0x........: ...
Old state: owned exclusively by thread #144
- New state: shared-modified by threads #145, #144
+ New state: shared-modified by threads #144, #145
Reason: this thread, #145, holds no locks at all
---------- char gran, 0 .. 99, skip 72 ----------
@@ -2055,19 +2055,19 @@
Reason: this thread, #165, holds no locks at all
---------- char gran, 0 .. 99, skip 82 ----------
-Thread #167 was created
+Thread #166 was created
at 0x........: clone (in /...libc...)
by 0x........: ...
by 0x........: pthread_create@GLIBC_ (in /lib/libpthread...)
by 0x........: pthread_create@* (tc_intercepts.c:...)
- by 0x........: main (tc19_shadowmem.c:173)
+ by 0x........: main (tc19_shadowmem.c:172)
-Thread #166 was created
+Thread #167 was created
at 0x........: clone (in /...libc...)
by 0x........: ...
by 0x........: pthread_create@GLIBC_ (in /lib/libpthread...)
by 0x........: pthread_create@* (tc_intercepts.c:...)
- by 0x........: main (tc19_shadowmem.c:172)
+ by 0x........: main (tc19_shadowmem.c:173)
Possible data race during write of size 1 at 0x........
at 0x........: child8 (tc19_shadowmem.c:35)
@@ -2076,7 +2076,7 @@
by 0x........: ...
by 0x........: ...
Old state: owned exclusively by thread #166
- New state: shared-modified by threads #167, #166
+ New state: shared-modified by threads #166, #167
Reason: this thread, #167, holds no locks at all
---------- char gran, 0 .. 99, skip 83 ----------
@@ -2105,19 +2105,19 @@
Reason: this thread, #169, holds no locks at all
---------- char gran, 0 .. 99, skip 84 ----------
-Thread #171 was created
+Thread #170 was created
at 0x........: clone (in /...libc...)
by 0x........: ...
by 0x........: pthread_create@GLIBC_ (in /lib/libpthread...)
by 0x........: pthread_create@* (tc_intercepts.c:...)
- by 0x........: main (tc19_shadowmem.c:173)
+ by 0x........: main (tc19_shadowmem.c:172)
-Thread #170 was created
+Thread #171 was created
at 0x........: clone (in /...libc...)
by 0x........: ...
by 0x........: pthread_create@GLIBC_ (in /lib/libpthread...)
by 0x........: pthread_create@* (tc_intercepts.c:...)
- by 0x........: main (tc19_shadowmem.c:172)
+ by 0x........: main (tc19_shadowmem.c:173)
Possible data race during write of size 1 at 0x........
at 0x........: child8 (tc19_shadowmem.c:35)
@@ -2126,7 +2126,7 @@
by 0x........: ...
by 0x........: ...
Old state: owned exclusively by thread #170
- New state: shared-modified by threads #171, #170
+ New state: shared-modified by threads #170, #171
Reason: this thread, #171, holds no locks at all
---------- char gran, 0 .. 99, skip 85 ----------
@@ -2230,19 +2230,19 @@
Reason: this thread, #179, holds no locks at all
---------- char gran, 0 .. 99, skip 89 ----------
-Thread #181 was created
+Thread #180 was created
at 0x........: clone (in /...libc...)
by 0x........: ...
by 0x........: pthread_create@GLIBC_ (in /lib/libpthread...)
by 0x........: pthread_create@* (tc_intercepts.c:...)
- by 0x........: main (tc19_shadowmem.c:173)
+ by 0x........: main (tc19_shadowmem.c:172)
-Thread #180 was created
+Thread #181 was created
at 0x........: clone (in /...libc...)
by 0x........: ...
by 0x........: pthread_create@GLIBC_ (in /lib/libpthread...)
by 0x........: pthread_create@* (tc_intercepts.c:...)
- by 0x........: main (tc19_shadowmem.c:172)
+ by 0x........: main (tc19_shadowmem.c:173)
Possible data race during write of size 1 at 0x........
at 0x........: child8 (tc19_shadowmem.c:35)
@@ -2251,7 +2251,7 @@
by 0x........: ...
by 0x........: ...
Old state: owned exclusively by thread #180
- New state: shared-modified by threads #181, #180
+ New state: shared-modified by threads #180, #181
Reason: this thread, #181, holds no locks at all
---------- char gran, 0 .. 99, skip 90 ----------
|
|
From: <sv...@va...> - 2007-10-29 20:48:01
|
Author: sewardj Date: 2007-10-29 20:48:01 +0000 (Mon, 29 Oct 2007) New Revision: 7051 Log: Hmm, I thought this had been committed in r6933. Strange. Added: branches/THRCHECK/thrcheck/tests/tc14_laog_dinphils.stderr.exp Added: branches/THRCHECK/thrcheck/tests/tc14_laog_dinphils.stderr.exp =================================================================== --- branches/THRCHECK/thrcheck/tests/tc14_laog_dinphils.stderr.exp (rev 0) +++ branches/THRCHECK/thrcheck/tests/tc14_laog_dinphils.stderr.exp 2007-10-29 20:48:01 UTC (rev 7051) @@ -0,0 +1,16 @@ + +Thread #6 was created + at 0x........: clone (in /...libc...) + by 0x........: ... + by 0x........: pthread_create@GLIBC_ (in /lib/libpthread...) + by 0x........: pthread_create@* (tc_intercepts.c:...) + by 0x........: main (tc14_laog_dinphils.c:34) + +Thread #6: lock order "0x........ before 0x........" violated + at 0x........: pthread_mutex_lock (tc_intercepts.c:...) + by 0x........: dine (tc14_laog_dinphils.c:19) + by 0x........: mythread_wrapper (tc_intercepts.c:...) + by 0x........: ... + by 0x........: ... + +ERROR SUMMARY: 1000 errors from 1 contexts (suppressed: 0 from 0) |
|
From: <sv...@va...> - 2007-10-29 20:38:48
|
Author: sewardj
Date: 2007-10-29 20:38:44 +0000 (Mon, 29 Oct 2007)
New Revision: 7050
Log:
Changes to make error message printing more repeatable. This is
important for reliable regression testing. Specifically, sort thread
sets by their constituent errmsg_index fields before showing them in
summarise_threadset() and announce_threadset().
Modified:
branches/THRCHECK/thrcheck/tc_main.c
Modified: branches/THRCHECK/thrcheck/tc_main.c
===================================================================
--- branches/THRCHECK/thrcheck/tc_main.c 2007-10-29 17:40:09 UTC (rev 7049)
+++ branches/THRCHECK/thrcheck/tc_main.c 2007-10-29 20:38:44 UTC (rev 7050)
@@ -106,6 +106,11 @@
#define TC_CLI__MALLOC_REDZONE_SZB 16 /* let's say */
+/* This has to do with printing error messages. See comments on
+ announce_threadset() and summarise_threadset(). */
+#define N_THREADS_TO_ANNOUNCE 5
+
+
// FIXME: don't hardwire initial entries for root thread.
// Instead, let the pre_thread_ll_create handler do this.
@@ -7823,23 +7828,66 @@
tl_assert(0);
}
-/* Announce (that is, print the point-of-creation) of the threads in
- 'tset'. Only do this once, as we only want to see these
- announcements once each. */
-
-static void announce_threadset ( WordSetID tset )
+/* Given a WordSetID in univ_tsets (that is, a Thread set ID), produce
+ an XArray* with the corresponding Thread*'s sorted by their
+ errmsg_index fields. This is for printing out thread sets in
+ repeatable orders, which is important for for repeatable regression
+ testing. The returned XArray* is dynamically allocated (of course)
+ and so must be tc_freed by the caller. */
+static Int cmp_Thread_by_errmsg_index ( void* thr1V, void* thr2V ) {
+ Thread* thr1 = *(Thread**)thr1V;
+ Thread* thr2 = *(Thread**)thr2V;
+ if (thr1->errmsg_index < thr2->errmsg_index) return -1;
+ if (thr1->errmsg_index > thr2->errmsg_index) return 1;
+ return 0;
+}
+static XArray* /* of Thread* */ get_sorted_thread_set ( WordSetID tset )
{
- Thread* thr;
+ XArray* xa;
Word* ts_words;
Word ts_size, i;
+ xa = VG_(newXA)( tc_zalloc, tc_free, sizeof(Thread*) );
+ tl_assert(xa);
TC_(getPayloadWS)( &ts_words, &ts_size, univ_tsets, tset );
tl_assert(ts_words);
tl_assert(ts_size >= 0);
- // FIXME: announce the threads in order of their errmsg_index
- // fields
+ /* This isn't a very clever scheme, but we don't expect this to be
+ called very often. */
for (i = 0; i < ts_size; i++) {
- thr = (Thread*)ts_words[i];
+ Thread* thr = (Thread*)ts_words[i];
tl_assert(is_sane_Thread(thr));
+ VG_(addToXA)( xa, (void*)&thr );
+ }
+ tl_assert(ts_size == VG_(sizeXA)( xa ));
+ VG_(setCmpFnXA)( xa, cmp_Thread_by_errmsg_index );
+ VG_(sortXA)( xa );
+ return xa;
+}
+
+
+/* Announce (that is, print the point-of-creation) of the threads in
+ 'tset'. Only do this once, as we only want to see these
+ announcements once each. Also, first sort the threads by their
+ errmsg_index fields, and show only the first N_THREADS_TO_ANNOUNCE.
+ That's because we only want to bother to announce threads
+ enumerated by summarise_threadset() below, and that in turn does
+ the same: it sorts them and then only shows the first
+ N_THREADS_TO_ANNOUNCE. */
+
+static void announce_threadset ( WordSetID tset )
+{
+ const Word limit = N_THREADS_TO_ANNOUNCE;
+ Thread* thr;
+ XArray* sorted;
+ Word ts_size, i, loopmax;
+ sorted = get_sorted_thread_set( tset );
+ ts_size = VG_(sizeXA)( sorted );
+ tl_assert(ts_size >= 0);
+ loopmax = limit < ts_size ? limit : ts_size; /* min(limit, ts_size) */
+ tl_assert(loopmax >= 0 && loopmax <= limit);
+ for (i = 0; i < loopmax; i++) {
+ thr = *(Thread**)VG_(indexXA)( sorted, i );
+ tl_assert(is_sane_Thread(thr));
tl_assert(thr->errmsg_index >= 1);
if (thr->announced)
continue;
@@ -7858,34 +7906,35 @@
VG_(message)(Vg_UserMsg, "");
thr->announced = True;
}
+ VG_(deleteXA)( sorted );
}
-
static void announce_one_thread ( Thread* thr ) {
announce_threadset( TC_(singletonWS)(univ_tsets, (Word)thr ));
}
+/* Generate into buf[0 .. nBuf-1] a 1-line summary of a thread set, of
+ the form "#1, #3, #77, #78, #79 and 42 others". The first
+ N_THREADS_TO_ANNOUNCE are listed explicitly (as '#n') and the
+ leftovers lumped into the 'and n others' bit. */
+
static void summarise_threadset ( WordSetID tset, Char* buf, UInt nBuf )
{
- const Word limit = 5;
+ const Word limit = N_THREADS_TO_ANNOUNCE;
Thread* thr;
- Word* ts_words;
- Word ts_size, i;
+ XArray* sorted;
+ Word ts_size, i, loopmax;
UInt off = 0;
- Word loopmax;
tl_assert(nBuf > 0);
tl_assert(nBuf >= 40 + 20*limit);
tl_assert(buf);
- TC_(getPayloadWS)( &ts_words, &ts_size, univ_tsets, tset );
- tl_assert(ts_words);
+ sorted = get_sorted_thread_set( tset );
+ ts_size = VG_(sizeXA)( sorted );
tl_assert(ts_size >= 0);
loopmax = limit < ts_size ? limit : ts_size; /* min(limit, ts_size) */
tl_assert(loopmax >= 0 && loopmax <= limit);
-
VG_(memset)(buf, 0, nBuf);
- // FIXME: list the threads in order of their errmsg_index
- // fields
for (i = 0; i < loopmax; i++) {
- thr = (Thread*)ts_words[i];
+ thr = *(Thread**)VG_(indexXA)( sorted, i );
tl_assert(is_sane_Thread(thr));
tl_assert(thr->errmsg_index >= 1);
off += VG_(sprintf)(&buf[off], "#%d", (Int)thr->errmsg_index);
@@ -7899,6 +7948,7 @@
}
tl_assert(off < nBuf);
tl_assert(buf[nBuf-1] == 0);
+ VG_(deleteXA)( sorted );
}
static void tc_pp_Error ( Error* err )
|
|
From: <sv...@va...> - 2007-10-29 17:40:08
|
Author: sewardj
Date: 2007-10-29 17:40:09 +0000 (Mon, 29 Oct 2007)
New Revision: 7049
Log:
Try to fix the wretched lock-acquisition-order-graph machinery so that
it doesn't produce such bogus claims about where the required lock
ordering was initially established.
Modified:
branches/THRCHECK/thrcheck/tc_main.c
Modified: branches/THRCHECK/thrcheck/tc_main.c
===================================================================
--- branches/THRCHECK/thrcheck/tc_main.c 2007-10-29 14:11:58 UTC (rev 7048)
+++ branches/THRCHECK/thrcheck/tc_main.c 2007-10-29 17:40:09 UTC (rev 7049)
@@ -269,9 +269,9 @@
/* EXPOSITION */
/* Place where lock first came to the attention of Thrcheck. */
ExeContext* appeared_at;
- /* Place where the lock was first locked. */
+ /* Place where the lock most recently made an unlocked->locked
+ transition. */
ExeContext* acquired_at;
- ExeContext* acquired_at_laog;
/* USEFUL-STATIC */
Addr guestaddr; /* Guest address of lock */
LockKind kind; /* what kind of lock this is */
@@ -568,7 +568,6 @@
lock->magic = LockN_MAGIC;
lock->appeared_at = NULL;
lock->acquired_at = NULL;
- lock->acquired_at_laog = NULL;
lock->guestaddr = guestaddr;
lock->kind = kind;
lock->heldW = False;
@@ -621,8 +620,11 @@
default: return False;
}
if (lock->heldBy == NULL) {
+ if (lock->acquired_at != NULL) return False;
/* Unheld. We arbitrarily require heldW to be False. */
return !lock->heldW;
+ } else {
+ if (lock->acquired_at == NULL) return False;
}
/* If heldBy is non-NULL, we require it to contain at least one
@@ -681,18 +683,15 @@
/* EXPOSITION only */
/* We need to keep recording snapshots of where the lock was
- acquired, up till the point that the lock gets incorporated into
- LAOG. Before that point, .acquired_at_laog is NULL. When the
- lock is incorporated into LAOG, .acquired_at is copied into
- .acquired_at_laog and we stop snapshotting it after that.
- This is so as to produce better lock-order error messages. */
- if (lk->acquired_at_laog == NULL) {
- ThreadId tid = map_threads_maybe_reverse_lookup_SLOW(thr);
- if (tid != VG_INVALID_THREADID) {
- stats__lockN_acquires_w_ExeContext++;
- lk->acquired_at
- = VG_(record_ExeContext(tid, 0/*first_ip_delta*/));
- }
+ acquired, so as to produce better lock-order error messages. */
+ if (lk->acquired_at == NULL) {
+ ThreadId tid;
+ tl_assert(lk->heldBy == NULL);
+ tid = map_threads_maybe_reverse_lookup_SLOW(thr);
+ lk->acquired_at
+ = VG_(record_ExeContext(tid, 0/*first_ip_delta*/));
+ } else {
+ tl_assert(lk->heldBy != NULL);
}
/* end EXPOSITION only */
@@ -740,18 +739,15 @@
/* EXPOSITION only */
/* We need to keep recording snapshots of where the lock was
- acquired, up till the point that the lock gets incorporated into
- LAOG. Before that point, .acquired_at_laog is NULL. When the
- lock is incorporated into LAOG, .acquired_at is copied into
- .acquired_at_laog and we stop snapshotting it after that.
- This is so as to produce better lock-order error messages. */
- if (lk->acquired_at_laog == NULL) {
- ThreadId tid = map_threads_maybe_reverse_lookup_SLOW(thr);
- if (tid != VG_INVALID_THREADID) {
- stats__lockN_acquires_w_ExeContext++;
- lk->acquired_at
- = VG_(record_ExeContext(tid, 0/*first_ip_delta*/));
- }
+ acquired, so as to produce better lock-order error messages. */
+ if (lk->acquired_at == NULL) {
+ ThreadId tid;
+ tl_assert(lk->heldBy == NULL);
+ tid = map_threads_maybe_reverse_lookup_SLOW(thr);
+ lk->acquired_at
+ = VG_(record_ExeContext(tid, 0/*first_ip_delta*/));
+ } else {
+ tl_assert(lk->heldBy != NULL);
}
/* end EXPOSITION only */
@@ -783,10 +779,12 @@
/* thr must actually have been a holder of lk */
tl_assert(b);
/* normalise */
+ tl_assert(lk->acquired_at);
if (TC_(isEmptyBag)(lk->heldBy)) {
TC_(deleteBag)(lk->heldBy);
- lk->heldBy = NULL;
- lk->heldW = False;
+ lk->heldBy = NULL;
+ lk->heldW = False;
+ lk->acquired_at = NULL;
}
tl_assert(is_sane_LockN(lk));
}
@@ -6399,6 +6397,33 @@
/* lock order acquisition graph */
static WordFM* laog = NULL; /* WordFM Lock* LAOGLinks* */
+/* EXPOSITION ONLY: for each edge in 'laog', record the two places
+ where that edge was created, so that we can show the user later if
+ we need to. */
+typedef
+ struct {
+ Addr src_ga; /* Lock guest addresses for */
+ Addr dst_ga; /* src/dst of the edge */
+ ExeContext* src_ec; /* And corresponding places where that */
+ ExeContext* dst_ec; /* ordering was established */
+ }
+ LAOGLinkExposition;
+
+static Word cmp_LAOGLinkExposition ( Word llx1W, Word llx2W ) {
+ /* Compare LAOGLinkExposition*s by (src_ga,dst_ga) field pair. */
+ LAOGLinkExposition* llx1 = (LAOGLinkExposition*)llx1W;
+ LAOGLinkExposition* llx2 = (LAOGLinkExposition*)llx2W;
+ if (llx1->src_ga < llx2->src_ga) return -1;
+ if (llx1->src_ga > llx2->src_ga) return 1;
+ if (llx1->dst_ga < llx2->dst_ga) return -1;
+ if (llx1->dst_ga > llx2->dst_ga) return 1;
+ return 0;
+}
+
+static WordFM* laog_exposition = NULL; /* WordFM LAOGLinkExposition* NULL */
+/* end EXPOSITION ONLY */
+
+
static void laog__show ( void ) {
Word i, ws_size;
Word* ws_words;
@@ -6429,26 +6454,29 @@
static void laog__add_edge ( Lock* src, Lock* dst ) {
Word keyW;
LAOGLinks* links;
+ Bool presentF, presentR;
if (0) VG_(printf)("laog__add_edge %p %p\n", src, dst);
- /* EXPOSITION only: update the execontext snapshots */
- if (src->acquired_at_laog == NULL) {
- src->acquired_at_laog = src->acquired_at;
- src->acquired_at = NULL;
- }
- if (dst->acquired_at_laog == NULL) {
- dst->acquired_at_laog = dst->acquired_at;
- dst->acquired_at = NULL;
- }
- /* end EXPOSITION only */
+ /* Take the opportunity to sanity check the graph. Record in
+ presentF if there is already a src->dst mapping in this node's
+ forwards links, and presentR if there is already a src->dst
+ mapping in this node's backwards links. They should agree!
+ Also, we need to know whether the edge was already present so as
+ to decide whether or not to update the link details mapping. We
+ can compute presentF and presentR essentially for free, so may
+ as well do this always. */
+ presentF = presentR = False;
/* Update the out edges for src */
keyW = 0;
links = NULL;
if (TC_(lookupFM)( laog, &keyW, (Word*)&links, (Word)src )) {
+ WordSetID outs_new;
tl_assert(links);
tl_assert(keyW == (Word)src);
- links->outs = TC_(addToWS)( univ_laog, links->outs, (Word)dst );
+ outs_new = TC_(addToWS)( univ_laog, links->outs, (Word)dst );
+ presentF = outs_new == links->outs;
+ links->outs = outs_new;
} else {
links = tc_zalloc(sizeof(LAOGLinks));
links->inns = TC_(emptyWS)( univ_laog );
@@ -6459,15 +6487,46 @@
keyW = 0;
links = NULL;
if (TC_(lookupFM)( laog, &keyW, (Word*)&links, (Word)dst )) {
+ WordSetID inns_new;
tl_assert(links);
tl_assert(keyW == (Word)dst);
- links->inns = TC_(addToWS)( univ_laog, links->inns, (Word)src );
+ inns_new = TC_(addToWS)( univ_laog, links->inns, (Word)src );
+ presentR = inns_new == links->inns;
+ links->inns = inns_new;
} else {
links = tc_zalloc(sizeof(LAOGLinks));
links->inns = TC_(singletonWS)( univ_laog, (Word)src );
links->outs = TC_(emptyWS)( univ_laog );
TC_(addToFM)( laog, (Word)dst, (Word)links );
}
+
+ tl_assert( (presentF && presentR) || (!presentF && !presentR) );
+
+ if (!presentF && src->acquired_at && dst->acquired_at) {
+ LAOGLinkExposition expo;
+ /* If this edge is entering the graph, and we have acquired_at
+ information for both src and dst, record those acquisition
+ points. Hence, if there is later a violation of this
+ ordering, we can show the user the two places in which the
+ required src-dst ordering was previously established. */
+ if (0) VG_(printf)("acquire edge %p %p\n",
+ src->guestaddr, dst->guestaddr);
+ expo.src_ga = src->guestaddr;
+ expo.dst_ga = dst->guestaddr;
+ expo.src_ec = NULL;
+ expo.dst_ec = NULL;
+ tl_assert(laog_exposition);
+ if (TC_(lookupFM)( laog_exposition, NULL, NULL, (Word)&expo )) {
+ /* we already have it; do nothing */
+ } else {
+ LAOGLinkExposition* expo2 = tc_zalloc(sizeof(LAOGLinkExposition));
+ expo2->src_ga = src->guestaddr;
+ expo2->dst_ga = dst->guestaddr;
+ expo2->src_ec = src->acquired_at;
+ expo2->dst_ec = dst->acquired_at;
+ TC_(addToFM)( laog_exposition, (Word)expo2, (Word)NULL );
+ }
+ }
}
__attribute__((noinline))
@@ -6640,6 +6699,9 @@
if (!laog)
laog = TC_(newFM)( tc_zalloc, tc_free, NULL/*unboxedcmp*/ );
+ if (!laog_exposition)
+ laog_exposition = TC_(newFM)( tc_zalloc, tc_free,
+ cmp_LAOGLinkExposition );
/* First, the check. Complain if there is any path in laog from lk
to any of the locks already held by thr, since if any such path
@@ -6649,22 +6711,48 @@
*/
other = laog__do_dfs_from_to(lk, thr->locksetA);
if (other) {
+ LAOGLinkExposition key, *found;
/* So we managed to find a path lk --*--> other in the graph,
which implies that 'lk' should have been acquired before
'other' but is in fact being acquired afterwards. We present
the lk/other arguments to record_error_LockOrder in the order
- in which they should have been acquired. */
- record_error_LockOrder( thr,
- lk->guestaddr, other->guestaddr,
- lk->acquired_at_laog, other->acquired_at_laog );
+ in which they should have been acquired. */
+ /* Go look in the laog_exposition mapping, to find the allocation
+ points for this edge, so we can show the user. */
+ key.src_ga = lk->guestaddr;
+ key.dst_ga = other->guestaddr;
+ key.src_ec = NULL;
+ key.dst_ec = NULL;
+ found = NULL;
+ if (TC_(lookupFM)( laog_exposition, (Word*)&found, NULL, (Word)&key )) {
+ tl_assert(found != &key);
+ tl_assert(found->src_ga == key.src_ga);
+ tl_assert(found->dst_ga == key.dst_ga);
+ tl_assert(found->src_ec);
+ tl_assert(found->dst_ec);
+ record_error_LockOrder( thr,
+ lk->guestaddr, other->guestaddr,
+ found->src_ec, found->dst_ec );
+ } else {
+ /* Hmm. This can't happen (can it?) */
+ record_error_LockOrder( thr,
+ lk->guestaddr, other->guestaddr,
+ NULL, NULL );
+ }
}
/* Second, add to laog the pairs
(old, lk) | old <- locks already held by thr
+ Since both old and lk are currently held by thr, their acquired_at
+ fields must be non-NULL.
*/
+ tl_assert(lk->acquired_at);
TC_(getPayloadWS)( &ls_words, &ls_size, univ_lsets, thr->locksetA );
- for (i = 0; i < ls_size; i++)
- laog__add_edge( (Lock*)ls_words[i], lk );
+ for (i = 0; i < ls_size; i++) {
+ Lock* old = (Lock*)ls_words[i];
+ tl_assert(old->acquired_at);
+ laog__add_edge( old, lk );
+ }
}
@@ -6690,8 +6778,12 @@
for (i = 0; i < preds_size; i++) {
for (j = 0; j < succs_size; j++) {
- if (preds_words[i] != succs_words[j])
+ if (preds_words[i] != succs_words[j]) {
+ /* This can pass unlocked locks to laog__add_edge, since
+ we're deleting stuff. So their acquired_at fields may
+ be NULL. */
laog__add_edge( (Lock*)preds_words[i], (Lock*)succs_words[j] );
+ }
}
}
}
@@ -6704,6 +6796,12 @@
Word i, ws_size;
Word* ws_words;
+ if (!laog)
+ laog = TC_(newFM)( tc_zalloc, tc_free, NULL/*unboxedcmp*/ );
+ if (!laog_exposition)
+ laog_exposition = TC_(newFM)( tc_zalloc, tc_free,
+ cmp_LAOGLinkExposition );
+
TC_(getPayloadWS)( &ws_words, &ws_size, univ_lsets, locksToDelete );
for (i = 0; i < ws_size; i++)
laog__handle_one_lock_deletion( (Lock*)ws_words[i] );
@@ -7425,9 +7523,12 @@
*lkp = *lkn;
lkp->admin = NULL;
lkp->magic = LockP_MAGIC;
- /* Forget about the bag of lock holders - don't copy that. */
+ /* Forget about the bag of lock holders - don't copy that.
+ Also, acquired_at should be NULL whenever heldBy is, and vice
+ versa. */
lkp->heldW = False;
lkp->heldBy = NULL;
+ lkp->acquired_at = NULL;
TC_(addToFM)( yaWFM, (Word)lkp, (Word)lkp );
}
tl_assert( is_sane_LockP(lkp) );
|
|
From: <sv...@va...> - 2007-10-29 14:17:13
|
Author: sewardj
Date: 2007-10-29 14:11:58 +0000 (Mon, 29 Oct 2007)
New Revision: 7048
Log:
Pretty up --trace-addr= --trace-level=2 output.
Modified:
branches/THRCHECK/thrcheck/tc_main.c
Modified: branches/THRCHECK/thrcheck/tc_main.c
===================================================================
--- branches/THRCHECK/thrcheck/tc_main.c 2007-10-28 14:54:49 UTC (rev 7047)
+++ branches/THRCHECK/thrcheck/tc_main.c 2007-10-29 14:11:58 UTC (rev 7048)
@@ -2902,6 +2902,7 @@
txt_new[sizeof(txt_new)-1] = 0;
if (clo_trace_level == 2) {
/* show everything */
+ VG_(message)(Vg_UserMsg, "");
announce_one_thread( thr_acc );
VG_(message)(Vg_UserMsg,
"TRACE: %p %s %d thr#%d :: %s --> %s",
@@ -2910,7 +2911,6 @@
if (tid != VG_INVALID_THREADID) {
VG_(get_and_pp_StackTrace)( tid, 8 );
}
- VG_(message)(Vg_UserMsg, "");
} else {
/* Just print one line */
VG_(message)(Vg_UserMsg,
|
|
From: Julian S. <js...@ac...> - 2007-10-29 11:32:57
|
Here is a completely "fixed" version of your program (I hope).
By using semaphores, Thrcheck can reliably see all synchronisation
events. It should give the same results on all runs.
The false positives in Jump::run exist for the following reason.
1. You create NUM_THREADS Loop jobs. These access the counter
array, some with shared locks, some without.
2. You call wait_for_jobs(). This is like a barrier: all the
Loop jobs must finish before it returns.
3. You create NUM_THREADS Jump jobs. These modify the counter
array again.
Unfortunately, in (3), Thrcheck has no way to know that the Jump
jobs are logically unrelated to the Loop jobs that happened before.
So (for example) vec[0].ptr is accessed by multiple threads in the
Loop jobs. And so Thrcheck expects that it should continue to be
protected by a lock in the Jump jobs, but it is not.
This is a classic problem with thread checkers: "memory recycling".
My solution is a standard one. You must tell Thrcheck, after the
Loop jobs have finished, to "forget" what it knows about
vec[..].counter. This is done using the calls to VALGRIND_TC_CLEAN_MEMORY.
One final detail. If you write the program in a more simple way
then Thrcheck can give correct results without using VALGRIND_TC_CLEAN_MEMORY.
The more simple way is: create a new worker thread for each task, then
wait for it to exit. Thrcheck understands that when a thread joins with
its parent, then the parent "inherits" ownership of the child's memory
locations. So in this case, after all the threads for the Loop jobs
had exited, then the whole memory state would be clean, and ready for
you to start new threads for the Jump jobs.
I hope that makes some sense. Thanks again for the feedback.
J
----------------------------------------------------------------------
g++ -g -O -o thread thread.C -lpthread -I$prefix/include
#include <iostream>
#include <vector>
extern "C" {
#include <pthread.h>
#include <semaphore.h>
#include <assert.h>
#include "valgrind/thrcheck.h"
}
pthread_mutex_t odd_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t even_mutex = PTHREAD_MUTEX_INITIALIZER;
static int const NUM_THREADS = 8;
class Job {
public:
virtual void run() = 0;
};
/* Used to tell workers to look in the work[] array. */
sem_t jobs_available;
/* Used to tell the controller that a job is done. */
sem_t jobs_completed;
/* Work array. Must be locked using this lock whenever anyone
accesses it. */
pthread_mutex_t work_mutex = PTHREAD_MUTEX_INITIALIZER;
Job* work[NUM_THREADS] = {NULL, NULL};
extern "C" void * start(void *) {
while (true) {
/* First, wait for the controller to tell me there is some
work available. */
int r = sem_wait( &jobs_available ); assert(r==0);
/* Now scan the work[] array to find out what I should do. */
pthread_mutex_lock(&work_mutex);
Job * job = NULL;
for (int i = 0; i < NUM_THREADS; ++i) {
if (work[i] != NULL) {
job = work[i];
work[i] = NULL;
break;
}
}
pthread_mutex_unlock(&work_mutex);
/* If there is no work found, I should quit. */
if (job == NULL)
return NULL;
/* else do it, then post to the controller that I am done. */
job->run();
r = sem_post(&jobs_completed); assert(r==0);
}
/*NOTREACHED*/
}
struct Data {
Data() : counter(0) {}
int counter;
};
class Loop : public Job {
public:
Loop(std::vector<Data *> & vec) : vec(vec) {}
virtual void run() {
for (std::size_t i = 0; i < vec.size(); ++i) {
if (i % 2 == 0) {
pthread_mutex_lock(&even_mutex);
vec[i]->counter++;
pthread_mutex_unlock(&even_mutex);
} else {
// pthread_mutex_lock(&odd_mutex);
vec[i]->counter++;
// pthread_mutex_unlock(&odd_mutex);
}
}
}
private:
std::vector<Data *> & vec;
};
class Jump : public Job {
public:
Jump(std::vector<Data *> & vec, std::size_t my_indices)
: vec(vec), my_indices(my_indices) {}
virtual void run() {
for (std::size_t i = 0; i < vec.size(); ++i) {
if (i % NUM_THREADS == my_indices) {
vec[i]->counter++;
}
}
}
private:
std::vector<Data *> & vec;
std::size_t my_indices;
};
void wait_for_jobs(int num) {
int i, r;
for (i = 0; i < num; i++) {
std::cout << "waitf_j " << i << std::endl;
r = sem_wait( &jobs_completed ); assert(r==0);
}
}
void start_jobs(int num) {
int i, r;
for (i = 0; i < num; i++) {
std::cout << "start_j " << i << std::endl;
r = sem_post( &jobs_available ); assert(r==0);
}
}
int main() {
int r;
int* counter_ptrs[NUM_THREADS];
r = sem_init( &jobs_available, 0/*pshared*/, 0/*initial_value*/ );
assert(r==0);
r = sem_init( &jobs_completed, 0/*pshared*/, 0/*initial_value*/ );
assert(r==0);
std::cout << "Starting main programm" << std::endl;
pthread_t tid[NUM_THREADS];
for (int i = 0; i < NUM_THREADS; ++i) {
pthread_create(&tid[i], NULL, start, NULL);
}
std::cout << "Threads created" << std::endl;
std::vector<Data *> vec;
for (std::size_t i = 0; i < NUM_THREADS; ++i) {
vec.push_back(new Data());
std::cout << "Created counter at address: "
<< &vec.back()->counter << std::endl;
counter_ptrs[i] = &vec.back()->counter;
}
std::cout << "Vector initialized" << std::endl;
Loop l(vec);
pthread_mutex_lock(&work_mutex);
for (std::size_t i = 0; i < NUM_THREADS; ++i) {
work[i] = &l;
}
pthread_mutex_unlock(&work_mutex);
std::cout << "Added loop jobs" << std::endl;
start_jobs(NUM_THREADS);
wait_for_jobs(NUM_THREADS);
/* Create new jobs and clean up the memory used by the old jobs. */
std::vector<Jump *> jump_vec;
for (std::size_t i = 0; i < NUM_THREADS; ++i) {
jump_vec.push_back(new Jump(vec, i));
VALGRIND_TC_CLEAN_MEMORY( counter_ptrs[i], sizeof(int) );
}
pthread_mutex_lock(&work_mutex);
for (std::size_t i = 0; i < NUM_THREADS; ++i) {
assert(work[i] == NULL);
work[i] = jump_vec[i];
}
pthread_mutex_unlock(&work_mutex);
std::cout << "Added jump jobs" << std::endl;
start_jobs(NUM_THREADS);
wait_for_jobs(NUM_THREADS);
/* Cause all the threads to exit, by ensuring work[] is completely
NULL (which it should already be), then doing start_jobs. All
threads will fail to find any work, and exit. */
pthread_mutex_lock(&work_mutex);
for (std::size_t i = 0; i < NUM_THREADS; ++i) {
assert(work[i] == NULL);
}
pthread_mutex_unlock(&work_mutex);
start_jobs(NUM_THREADS);
/* And collect up all the threads. */
for (std::size_t i = 0; i < NUM_THREADS; ++i) {
pthread_join(tid[i], NULL);
}
}
|
|
From: Tom H. <th...@cy...> - 2007-10-29 03:31:13
|
Nightly build on alvis ( i686, Red Hat 7.3 ) started at 2007-10-29 03:15:02 GMT Results unchanged from 24 hours ago Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 260 tests, 27 stderr failures, 1 stdout failure, 0 posttest failures == memcheck/tests/addressable (stderr) memcheck/tests/badjump (stderr) memcheck/tests/describe-block (stderr) memcheck/tests/erringfds (stderr) memcheck/tests/leak-0 (stderr) memcheck/tests/leak-cycle (stderr) memcheck/tests/leak-pool-0 (stderr) memcheck/tests/leak-pool-1 (stderr) memcheck/tests/leak-pool-2 (stderr) memcheck/tests/leak-pool-3 (stderr) memcheck/tests/leak-pool-4 (stderr) memcheck/tests/leak-pool-5 (stderr) memcheck/tests/leak-regroot (stderr) memcheck/tests/leak-tree (stderr) memcheck/tests/long_namespace_xml (stderr) memcheck/tests/match-overrun (stderr) memcheck/tests/partial_load_dflt (stderr) memcheck/tests/partial_load_ok (stderr) memcheck/tests/partiallydefinedeq (stderr) memcheck/tests/pointer-trace (stderr) memcheck/tests/sigkill (stderr) memcheck/tests/stack_changes (stderr) memcheck/tests/x86/scalar (stderr) memcheck/tests/x86/scalar_supp (stderr) memcheck/tests/x86/xor-undef-x86 (stderr) memcheck/tests/xml1 (stderr) none/tests/mremap (stderr) none/tests/mremap2 (stdout) |
|
From: Tom H. <th...@cy...> - 2007-10-29 03:23:49
|
Nightly build on lloyd ( x86_64, Fedora 7 ) started at 2007-10-29 03:05:06 GMT Results unchanged from 24 hours ago Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 293 tests, 4 stderr failures, 2 stdout failures, 0 posttest failures == memcheck/tests/pointer-trace (stderr) memcheck/tests/vcpu_fnfns (stdout) memcheck/tests/x86/scalar (stderr) memcheck/tests/xml1 (stderr) none/tests/mremap (stderr) none/tests/mremap2 (stdout) |
|
From: Tom H. <th...@cy...> - 2007-10-29 03:23:20
|
Nightly build on dellow ( x86_64, Fedora 7 ) started at 2007-10-29 03:10:04 GMT Results unchanged from 24 hours ago Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 293 tests, 4 stderr failures, 3 stdout failures, 0 posttest failures == memcheck/tests/pointer-trace (stderr) memcheck/tests/vcpu_fnfns (stdout) memcheck/tests/x86/scalar (stderr) memcheck/tests/xml1 (stderr) none/tests/mremap (stderr) none/tests/mremap2 (stdout) none/tests/pth_detached (stdout) |
|
From: Tom H. <th...@cy...> - 2007-10-29 03:15:35
|
Nightly build on gill ( x86_64, Fedora Core 2 ) started at 2007-10-29 03:00:03 GMT Results unchanged from 24 hours ago Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 295 tests, 6 stderr failures, 1 stdout failure, 0 posttest failures == memcheck/tests/pointer-trace (stderr) memcheck/tests/stack_switch (stderr) memcheck/tests/x86/scalar (stderr) memcheck/tests/x86/scalar_supp (stderr) none/tests/fdleak_fcntl (stderr) none/tests/mremap (stderr) none/tests/mremap2 (stdout) |
|
From: <js...@ac...> - 2007-10-29 01:17:18
|
Nightly build on g5 ( SuSE 10.1, ppc970 ) started at 2007-10-29 02:00:01 CET Results unchanged from 24 hours ago Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 228 tests, 6 stderr failures, 2 stdout failures, 0 posttest failures == memcheck/tests/deep_templates (stdout) memcheck/tests/leak-cycle (stderr) memcheck/tests/leak-tree (stderr) memcheck/tests/pointer-trace (stderr) none/tests/faultstatus (stderr) none/tests/fdleak_cmsg (stderr) none/tests/mremap (stderr) none/tests/mremap2 (stdout) |
|
From: Julian S. <js...@ac...> - 2007-10-28 15:00:03
|
You might want to svn up to >= r7047 and try the new flags shown below. They may help make sense of the reports (or not, just cause confusion and slow the tool down :-( J Add new flags --trace-addr and --trace-level, which cause all state changes for a given address to be logged. Intended to help track down the root causes of races. At --trace-level=2, a complete stack trace is printed every time the location specified with --trace-addr changes state. At --trace-level=1 (the default) just a 1-line summary for each state change is printed. |
|
From: <sv...@va...> - 2007-10-28 14:54:47
|
Author: sewardj
Date: 2007-10-28 14:54:49 +0000 (Sun, 28 Oct 2007)
New Revision: 7047
Log:
Add new flags --trace-addr and --trace-level, which cause all state
changes for a given address to be logged. Intended to help track down
the root causes of races.
At --trace-level=2, a complete stack trace is printed every time the
location specified with --trace-addr changes state.
At --trace-level=1 (the default) just a 1-line summary for each state
change is printed.
Also a bit of comment-tidying and variable renaming.
Modified:
branches/THRCHECK/thrcheck/tc_main.c
Modified: branches/THRCHECK/thrcheck/tc_main.c
===================================================================
--- branches/THRCHECK/thrcheck/tc_main.c 2007-10-28 14:51:23 UTC (rev 7046)
+++ branches/THRCHECK/thrcheck/tc_main.c 2007-10-28 14:54:49 UTC (rev 7047)
@@ -47,6 +47,7 @@
#include "pub_tool_machine.h"
#include "pub_tool_options.h"
#include "pub_tool_xarray.h"
+#include "pub_tool_stacktrace.h"
#include "thrcheck.h"
@@ -126,6 +127,12 @@
(regtesting) this is sometimes important. */
static Bool clo_cmp_race_err_addrs = False;
+/* Tracing memory accesses, so we can see what's going on.
+ clo_trace_addr is the address to monitor. clo_trace_level = 0 for
+ no tracing, 1 for summary, 2 for detailed. */
+static Addr clo_trace_addr = 0;
+static Int clo_trace_level = 0;
+
// FIXME: when a SecMap is completely set via and address range
// setting operation to a non-ShR/M state, clear its .mbHasShared
// bit
@@ -675,9 +682,9 @@
/* EXPOSITION only */
/* We need to keep recording snapshots of where the lock was
acquired, up till the point that the lock gets incorporated into
- LAOG. Before that point, .first_locked_laog is NULL. When the
- lock is incorporated into LAOG, .first_locked is copied into
- .first_locked_laog and we stop snapshotting it after that.
+ LAOG. Before that point, .acquired_at_laog is NULL. When the
+ lock is incorporated into LAOG, .acquired_at is copied into
+ .acquired_at_laog and we stop snapshotting it after that.
This is so as to produce better lock-order error messages. */
if (lk->acquired_at_laog == NULL) {
ThreadId tid = map_threads_maybe_reverse_lookup_SLOW(thr);
@@ -734,9 +741,9 @@
/* EXPOSITION only */
/* We need to keep recording snapshots of where the lock was
acquired, up till the point that the lock gets incorporated into
- LAOG. Before that point, .first_locked_laog is NULL. When the
- lock is incorporated into LAOG, .first_locked is copied into
- .first_locked_laog and we stop snapshotting it after that.
+ LAOG. Before that point, .acquired_at_laog is NULL. When the
+ lock is incorporated into LAOG, .acquired_at is copied into
+ .acquired_at_laog and we stop snapshotting it after that.
This is so as to produce better lock-order error messages. */
if (lk->acquired_at_laog == NULL) {
ThreadId tid = map_threads_maybe_reverse_lookup_SLOW(thr);
@@ -969,8 +976,12 @@
/*--- Print out the primary data structures ---*/
/*----------------------------------------------------------------*/
-static void get_ZF_by_index ( /*OUT*/CacheLineZ** zp, /*OUT*/CacheLineF** fp,
- SecMap* sm, Int zix ); /* fwds */
+static WordSetID del_BHL ( WordSetID lockset ); /* fwds */
+static
+void get_ZF_by_index ( /*OUT*/CacheLineZ** zp, /*OUT*/CacheLineF** fp,
+ SecMap* sm, Int zix ); /* fwds */
+static
+Segment* map_segments_maybe_lookup ( SegmentID segid ); /* fwds */
#define PP_THREADS (1<<1)
#define PP_LOCKS (1<<2)
@@ -1190,6 +1201,49 @@
}
}
+static
+void show_shadow_w32_for_user ( /*OUT*/Char* buf, Int nBuf, UInt w32 )
+{
+ tl_assert(nBuf-1 >= 99);
+ VG_(memset)(buf, 0, nBuf);
+ if (is_SHVAL_ShM(w32)) {
+ WordSetID tset = un_SHVAL_ShM_tset(w32);
+ WordSetID lset = del_BHL( un_SHVAL_ShM_lset(w32) );
+ VG_(sprintf)(buf, "ShMod(#Tset=%d,#Lset=%d)",
+ TC_(cardinalityWS)(univ_tsets, tset),
+ TC_(cardinalityWS)(univ_lsets, lset));
+ }
+ else
+ if (is_SHVAL_ShR(w32)) {
+ WordSetID tset = un_SHVAL_ShR_tset(w32);
+ WordSetID lset = del_BHL( un_SHVAL_ShR_lset(w32) );
+ VG_(sprintf)(buf, "ShRO(#Tset=%d,#Lset=%d)",
+ TC_(cardinalityWS)(univ_tsets, tset),
+ TC_(cardinalityWS)(univ_lsets, lset));
+ }
+ else
+ if (is_SHVAL_Excl(w32)) {
+ SegmentID segid = un_SHVAL_Excl(w32);
+ Segment* mb_seg = map_segments_maybe_lookup(segid);
+ if (mb_seg && mb_seg->thr && is_sane_Thread(mb_seg->thr)) {
+ VG_(sprintf)(buf, "Exclusive(thr#%d)", mb_seg->thr->errmsg_index);
+ } else {
+ VG_(sprintf)(buf, "Exclusive(segid=%u)", un_SHVAL_Excl(w32));
+ }
+ }
+ else
+ if (is_SHVAL_New(w32)) {
+ VG_(sprintf)(buf, "%s", "New");
+ }
+ else
+ if (is_SHVAL_NoAccess(w32)) {
+ VG_(sprintf)(buf, "%s", "NoAccess");
+ }
+ else {
+ VG_(sprintf)(buf, "Invalid-shadow-word(%u)", w32);
+ }
+}
+
static void pp_SecMap_shared ( Int d, SecMap* sm, Addr ga )
{
Int i;
@@ -2668,26 +2722,26 @@
/*--- the core memory state machine (msm__* functions) ---*/
/*----------------------------------------------------------------*/
-static UWord stats__msm_r32_Excl_nochange = 0;
-static UWord stats__msm_r32_Excl_transfer = 0;
-static UWord stats__msm_r32_Excl_to_ShR = 0;
-static UWord stats__msm_r32_ShR_to_ShR = 0;
-static UWord stats__msm_r32_ShM_to_ShM = 0;
-static UWord stats__msm_r32_New_to_Excl = 0;
-static UWord stats__msm_r32_NoAccess = 0;
+static UWord stats__msm_read_Excl_nochange = 0;
+static UWord stats__msm_read_Excl_transfer = 0;
+static UWord stats__msm_read_Excl_to_ShR = 0;
+static UWord stats__msm_read_ShR_to_ShR = 0;
+static UWord stats__msm_read_ShM_to_ShM = 0;
+static UWord stats__msm_read_New_to_Excl = 0;
+static UWord stats__msm_read_NoAccess = 0;
-static UWord stats__msm_w32_Excl_nochange = 0;
-static UWord stats__msm_w32_Excl_transfer = 0;
-static UWord stats__msm_w32_Excl_to_ShM = 0;
-static UWord stats__msm_w32_ShR_to_ShM = 0;
-static UWord stats__msm_w32_ShM_to_ShM = 0;
-static UWord stats__msm_w32_New_to_Excl = 0;
-static UWord stats__msm_w32_NoAccess = 0;
+static UWord stats__msm_write_Excl_nochange = 0;
+static UWord stats__msm_write_Excl_transfer = 0;
+static UWord stats__msm_write_Excl_to_ShM = 0;
+static UWord stats__msm_write_ShR_to_ShM = 0;
+static UWord stats__msm_write_ShM_to_ShM = 0;
+static UWord stats__msm_write_New_to_Excl = 0;
+static UWord stats__msm_write_NoAccess = 0;
/* fwds */
static void record_error_Race ( Thread* thr,
Addr data_addr, Bool isWrite, Int szB,
- UInt old_w32, UInt new_w32,
+ UInt old_sv, UInt new_sv,
ExeContext* mb_lastlock );
static void record_error_FreeMemLock ( Thread* thr, Lock* lk );
@@ -2700,12 +2754,16 @@
ExeContext*, ExeContext* );
static void record_error_Misc ( Thread*, HChar* );
+static void announce_one_thread ( Thread* thr ); /* fwds */
-static WordSetID add_BHL ( WordSetID lockset )
-{
+static WordSetID add_BHL ( WordSetID lockset ) {
return TC_(addToWS)( univ_lsets, lockset, (Word)__bus_lock_Lock );
}
+static WordSetID del_BHL ( WordSetID lockset ) {
+ return TC_(delFromWS)( univ_lsets, lockset, (Word)__bus_lock_Lock );
+}
+
/* Last-lock-lossage records. This mechanism exists to help explain
to programmers why we are complaining about a race. The idea is to
monitor all lockset transitions. When a previously nonempty
@@ -2761,7 +2819,7 @@
/* This is slow, but at least it's simple. The bus hardware lock
just confuses the logic, so remove it from the locksets we're
considering before doing anything else. */
- lset_new = TC_(delFromWS)( univ_lsets, lset_new, (Word)__bus_lock_Lock );
+ lset_new = del_BHL( lset_new );
if (!TC_(isEmptyWS)( univ_lsets, lset_new )) {
/* The post-transition lock set is not empty. So we are not
@@ -2774,7 +2832,7 @@
card_new = TC_(cardinalityWS)( univ_lsets, lset_new );
tl_assert(card_new == 0);
- lset_old = TC_(delFromWS)( univ_lsets, lset_old, (Word)__bus_lock_Lock );
+ lset_old = del_BHL( lset_old );
card_old = TC_(cardinalityWS)( univ_lsets, lset_old );
if (0) VG_(printf)(" X2: %d (card %d) -> %d (card %d)\n",
@@ -2823,6 +2881,68 @@
}
+static void msm__show_state_change ( Thread* thr_acc, Addr a, Int szB,
+ Char howC,
+ UInt sv_old, UInt sv_new )
+{
+ ThreadId tid;
+ UChar txt_old[100], txt_new[100];
+ Char* how = "";
+ tl_assert(is_sane_Thread(thr_acc));
+ tl_assert(clo_trace_level == 1 || clo_trace_level == 2);
+ switch (howC) {
+ case 'r': how = "rd"; break;
+ case 'w': how = "wr"; break;
+ case 'p': how = "pa"; break;
+ default: tl_assert(0);
+ }
+ show_shadow_w32_for_user(txt_old, sizeof(txt_old), sv_old);
+ show_shadow_w32_for_user(txt_new, sizeof(txt_new), sv_new);
+ txt_old[sizeof(txt_old)-1] = 0;
+ txt_new[sizeof(txt_new)-1] = 0;
+ if (clo_trace_level == 2) {
+ /* show everything */
+ announce_one_thread( thr_acc );
+ VG_(message)(Vg_UserMsg,
+ "TRACE: %p %s %d thr#%d :: %s --> %s",
+ a, how, szB, thr_acc->errmsg_index, txt_old, txt_new );
+ tid = map_threads_maybe_reverse_lookup_SLOW(thr_acc);
+ if (tid != VG_INVALID_THREADID) {
+ VG_(get_and_pp_StackTrace)( tid, 8 );
+ }
+ VG_(message)(Vg_UserMsg, "");
+ } else {
+ /* Just print one line */
+ VG_(message)(Vg_UserMsg,
+ "TRACE: %p %s %d thr#%d :: %22s --> %22s",
+ a, how, szB, thr_acc->errmsg_index, txt_old, txt_new );
+ }
+}
+
+
+/* Here are some MSM stats from startup/shutdown of OpenOffice.
+
+ msm: 489,734,723 80,278,862 rd/wr_Excl_nochange
+ msm: 3,171,542 93,738 rd/wr_Excl_transfer
+ msm: 45,036 167 rd/wr_Excl_to_ShR/ShM
+ msm: 13,352,594 285 rd/wr_ShR_to_ShR/ShM
+ msm: 1,125,879 815,779 rd/wr_ShM_to_ShM
+ msm: 7,561,842 250,629,935 rd/wr_New_to_Excl
+ msm: 17,778 0 rd/wr_NoAccess
+
+ This says how the clauses should be ordered for greatest speed:
+
+ * the vast majority of memory reads (490 million out of a total of
+ 515 million) are of memory in an exclusive state, and the state
+ is unchanged. All other read accesses are insignificant by
+ comparison.
+
+ * 75% (251 million out of a total of 332 million) writes are 'first
+ time' writes, which take New memory into exclusive ownership.
+ Almost all the rest (80 million) are accesses to exclusive state,
+ which remains unchanged. All other write accesses are
+ insignificant. */
+
/* The core MSM. If 'wold' is the old 32-bit shadow word for a
location, return the new shadow word that would result for a read
of the location, and report any errors necessary on the way. This
@@ -2832,12 +2952,14 @@
static
UInt msm__handle_read ( Thread* thr_acc, Addr a, UInt wold, Int szB )
{
+ UInt wnew = SHVAL_Invalid;
+
tl_assert(is_sane_Thread(thr_acc));
if (0) VG_(printf)("read thr=%p %p\n", thr_acc, a);
/* Exclusive */
- if (is_SHVAL_Excl(wold)) {
+ if (LIKELY(is_SHVAL_Excl(wold))) {
/* read Excl(segid)
| segid_old == segid-of-thread
-> no change
@@ -2848,20 +2970,19 @@
*/
SegmentID segid_old = un_SHVAL_Excl(wold);
tl_assert(is_sane_SegmentID(segid_old));
- if (segid_old == thr_acc->csegid) {
+ if (LIKELY(segid_old == thr_acc->csegid)) {
/* no change */
- stats__msm_r32_Excl_nochange++;
- return wold;
+ stats__msm_read_Excl_nochange++;
+ /*NOCHANGE*/return wold;
}
if (happens_before(segid_old, thr_acc->csegid)) {
/* -> Excl(segid-of-this-thread) */
- UInt wnew = mk_SHVAL_Excl(thr_acc->csegid);
- stats__msm_r32_Excl_transfer++;
- return wnew;
+ wnew = mk_SHVAL_Excl(thr_acc->csegid);
+ stats__msm_read_Excl_transfer++;
+ goto changed;
}
/* else */ {
/* Enter the shared-readonly (ShR) state. */
- UInt wnew;
WordSetID tset, lset;
/* This location has been accessed by precisely two threads.
Make an appropriate tset. */
@@ -2872,8 +2993,8 @@
tset = TC_(doubletonWS)( univ_tsets, (Word)thr_old, (Word)thr_acc );
lset = add_BHL( thr_acc->locksetA ); /* read ==> use all locks */
wnew = mk_SHVAL_ShR( tset, lset );
- stats__msm_r32_Excl_to_ShR++;
- return wnew;
+ stats__msm_read_Excl_to_ShR++;
+ goto changed;
}
/*NOTREACHED*/
}
@@ -2892,11 +3013,11 @@
lset_old,
add_BHL(thr_acc->locksetA)
/* read ==> use all locks */ );
- UInt wnew = mk_SHVAL_ShR( tset_new, lset_new );
+ /*UInt*/ wnew = mk_SHVAL_ShR( tset_new, lset_new );
if (lset_old != lset_new)
record_last_lock_lossage(a,lset_old,lset_new);
- stats__msm_r32_ShR_to_ShR++;
- return wnew;
+ stats__msm_read_ShR_to_ShR++;
+ goto changed;
}
/* Shared-Modified */
@@ -2913,7 +3034,7 @@
lset_old,
add_BHL(thr_acc->locksetA)
/* read ==> use all locks */ );
- UInt wnew = mk_SHVAL_ShM( tset_new, lset_new );
+ /*UInt*/ wnew = mk_SHVAL_ShM( tset_new, lset_new );
if (lset_old != lset_new)
record_last_lock_lossage(a,lset_old,lset_new);
if (TC_(isEmptyWS)(univ_lsets, lset_new)
@@ -2922,16 +3043,16 @@
False/*isWrite*/, szB, wold, wnew,
maybe_get_lastlock_initpoint(a) );
}
- stats__msm_r32_ShM_to_ShM++;
- return wnew;
+ stats__msm_read_ShM_to_ShM++;
+ goto changed;
}
/* New */
if (is_SHVAL_New(wold)) {
/* read New -> Excl(segid) */
- UInt wnew = mk_SHVAL_Excl( thr_acc->csegid );
- stats__msm_r32_New_to_Excl++;
- return wnew;
+ wnew = mk_SHVAL_Excl( thr_acc->csegid );
+ stats__msm_read_New_to_Excl++;
+ goto changed;
}
/* NoAccess */
@@ -2942,12 +3063,21 @@
VG_(printf)(
"msm__handle_read_aligned_32(thr=%p, addr=%p): NoAccess\n",
thr_acc, (void*)a );
- stats__msm_r32_NoAccess++;
- return wold; /* no change */
+ stats__msm_read_NoAccess++;
+ /*NOCHANGE*/return wold; /* no change */
}
/* hmm, bogus state */
tl_assert(0);
+
+ changed:
+ if (UNLIKELY(clo_trace_level > 0)) {
+ if (a <= clo_trace_addr && clo_trace_addr < a+szB
+ && wold != wnew) {
+ msm__show_state_change( thr_acc, a, szB, 'r', wold, wnew );
+ }
+ }
+ return wnew;
}
/* Similar to msm__handle_read, compute a new 32-bit shadow word
@@ -2956,17 +3086,21 @@
static
UInt msm__handle_write ( Thread* thr_acc, Addr a, UInt wold, Int szB )
{
+ UInt wnew = SHVAL_Invalid;
+
tl_assert(is_sane_Thread(thr_acc));
if (0) VG_(printf)("write32 thr=%p %p\n", thr_acc, a);
/* New */
- if (is_SHVAL_New(wold)) {
+ if (LIKELY(is_SHVAL_New(wold))) {
/* write New -> Excl(segid) */
- UInt wnew = mk_SHVAL_Excl( thr_acc->csegid );
- stats__msm_w32_New_to_Excl++;
- return wnew;
+ wnew = mk_SHVAL_Excl( thr_acc->csegid );
+ stats__msm_write_New_to_Excl++;
+ goto changed;
}
+
+ /* Exclusive */
if (is_SHVAL_Excl(wold)) {
// I believe is identical to case for read Excl
// apart from enters ShM rather than ShR
@@ -2982,18 +3116,17 @@
tl_assert(is_sane_SegmentID(segid_old));
if (segid_old == thr_acc->csegid) {
/* no change */
- stats__msm_w32_Excl_nochange++;
- return wold;
+ stats__msm_write_Excl_nochange++;
+ /*NOCHANGE*/return wold;
}
if (happens_before(segid_old, thr_acc->csegid)) {
/* -> Excl(segid-of-this-thread) */
- UInt wnew = mk_SHVAL_Excl(thr_acc->csegid);
- stats__msm_w32_Excl_transfer++;
- return wnew;
+ wnew = mk_SHVAL_Excl(thr_acc->csegid);
+ stats__msm_write_Excl_transfer++;
+ goto changed;
}
/* else */ {
/* Enter the shared-modified (ShM) state. */
- UInt wnew;
WordSetID tset, lset;
/* This location has been accessed by precisely two threads.
Make an appropriate tset. */
@@ -3009,8 +3142,8 @@
a, True/*isWrite*/, szB, wold, wnew,
maybe_get_lastlock_initpoint(a) );
}
- stats__msm_w32_Excl_to_ShM++;
- return wnew;
+ stats__msm_write_Excl_to_ShM++;
+ goto changed;
}
/*NOTREACHED*/
}
@@ -3031,7 +3164,7 @@
thr_acc->locksetW
/* write ==> use only w-held locks */
);
- UInt wnew = mk_SHVAL_ShM( tset_new, lset_new );
+ /*UInt*/ wnew = mk_SHVAL_ShM( tset_new, lset_new );
if (lset_old != lset_new)
record_last_lock_lossage(a,lset_old,lset_new);
if (TC_(isEmptyWS)(univ_lsets, lset_new)) {
@@ -3039,8 +3172,8 @@
True/*isWrite*/, szB, wold, wnew,
maybe_get_lastlock_initpoint(a) );
}
- stats__msm_w32_ShR_to_ShM++;
- return wnew;
+ stats__msm_write_ShR_to_ShM++;
+ goto changed;
}
/* Shared-Modified */
@@ -3059,7 +3192,7 @@
thr_acc->locksetW
/* write ==> use only w-held locks */
);
- UInt wnew = mk_SHVAL_ShM( tset_new, lset_new );
+ /*UInt*/ wnew = mk_SHVAL_ShM( tset_new, lset_new );
if (lset_old != lset_new)
record_last_lock_lossage(a,lset_old,lset_new);
if (TC_(isEmptyWS)(univ_lsets, lset_new)
@@ -3068,8 +3201,8 @@
True/*isWrite*/, szB, wold, wnew,
maybe_get_lastlock_initpoint(a) );
}
- stats__msm_w32_ShM_to_ShM++;
- return wnew;
+ stats__msm_write_ShM_to_ShM++;
+ goto changed;
}
/* NoAccess */
@@ -3080,14 +3213,23 @@
VG_(printf)(
"msm__handle_write_aligned_32(thr=%p, addr=%p): NoAccess\n",
thr_acc, (void*)a );
- stats__msm_w32_NoAccess++;
- return wold;
+ stats__msm_write_NoAccess++;
+ /*NOCHANGE*/return wold;
}
/* hmm, bogus state */
VG_(printf)("msm__handle_write_aligned_32: bogus old state 0x%x\n",
wold);
tl_assert(0);
+
+ changed:
+ if (UNLIKELY(clo_trace_level > 0)) {
+ if (a <= clo_trace_addr && clo_trace_addr < a+szB
+ && wold != wnew) {
+ msm__show_state_change( thr_acc, a, szB, 'w', wold, wnew );
+ }
+ }
+ return wnew;
}
@@ -3097,8 +3239,8 @@
static void laog__pre_thread_acquires_lock ( Thread*, Lock* ); /* fwds */
static void laog__handle_lock_deletions ( WordSetID ); /* fwds */
+static inline Thread* get_current_Thread ( void ); /* fwds */
-
/* ------------ CacheLineF and CacheLineZ related ------------ */
static void write_twobit_array ( UChar* arr, UWord ix, UWord b2 ) {
@@ -4435,6 +4577,15 @@
UInt sv;
stats__cline_copy8s++;
sv = shadow_mem_get8( src );
+
+ if (UNLIKELY(clo_trace_level > 0)) {
+ if (dst == clo_trace_addr) {
+ Thread* thr = get_current_Thread();
+ UInt sv_old = shadow_mem_get8( dst );
+ msm__show_state_change( thr, dst, 1, 'w', sv_old, sv );
+ }
+ }
+
shadow_mem_set8( NULL/*unused*/, dst, sv );
}
@@ -4565,6 +4716,12 @@
static void shadow_mem_make_New ( Thread* thr, Addr a, SizeT len )
{
+ if (UNLIKELY(clo_trace_level > 0)) {
+ if (len > 0 && a <= clo_trace_addr && clo_trace_addr < a+len) {
+ UInt sv_old = shadow_mem_get8( clo_trace_addr );
+ msm__show_state_change( thr, a, (Int)len, 'p', sv_old, SHVAL_New );
+ }
+ }
shadow_mem_modify_range( thr, a, len,
shadow_mem_set8,
shadow_mem_set16,
@@ -4675,6 +4832,13 @@
/* --- Step 2 --- */
+ if (UNLIKELY(clo_trace_level > 0)) {
+ if (len > 0 && firstA <= clo_trace_addr && clo_trace_addr <= lastA) {
+ UInt sv_old = shadow_mem_get8( clo_trace_addr );
+ msm__show_state_change( thr, firstA, (Int)len, 'p',
+ sv_old, SHVAL_NoAccess );
+ }
+ }
shadow_mem_modify_range( thr, firstA, len,
shadow_mem_set8,
shadow_mem_set16,
@@ -5135,7 +5299,7 @@
- for uses definitely within client code, use
get_current_Thread_in_C_C.
- - for all other uses, use get_current_Thread_general.
+ - for all other uses, use get_current_Thread.
*/
static Thread* current_Thread = NULL;
@@ -7387,7 +7551,7 @@
static void record_error_Race ( Thread* thr,
Addr data_addr, Bool isWrite, Int szB,
- UInt old_w32, UInt new_w32,
+ UInt old_sv, UInt new_sv,
ExeContext* mb_lastlock ) {
XError xe;
tl_assert( is_sane_Thread(thr) );
@@ -7396,8 +7560,8 @@
xe.XE.Race.data_addr = data_addr;
xe.XE.Race.szB = szB;
xe.XE.Race.isWrite = isWrite;
- xe.XE.Race.new_state = new_w32;
- xe.XE.Race.old_state = old_w32;
+ xe.XE.Race.new_state = new_sv;
+ xe.XE.Race.old_state = old_sv;
xe.XE.Race.mb_lastlock = mb_lastlock;
xe.XE.Race.thr = thr;
// FIXME: tid vs thr
@@ -7990,6 +8154,13 @@
else if (VG_CLO_STREQ(arg, "--cmp-race-err-addrs=yes"))
clo_cmp_race_err_addrs = True;
+ else if (VG_CLO_STREQN(13, arg, "--trace-addr=")) {
+ clo_trace_addr = VG_(atoll16)(&arg[13]);
+ if (clo_trace_level == 0)
+ clo_trace_level = 1;
+ }
+ else VG_BNUM_CLO(arg, "--trace-level", clo_trace_level, 0, 2)
+
else
return VG_(replacement_malloc_process_cmd_line_option)(arg);
@@ -8001,6 +8172,8 @@
VG_(printf)(
" --happens-before=none|threads|condvars [condvars] consider no events,\n"
" thread create/join, thread create/join/cvsignal/cvwait as sync points\n"
+" --trace-addr=0xXXYYZZ show all state changes for address 0xXXYYZZ\n"
+" --trace-level=0|1|2 verbosity level of --trace-addr [1]\n"
);
VG_(replacement_malloc_print_usage)();
}
@@ -8082,19 +8255,19 @@
VG_(printf)("\n");
VG_(printf)(" msm: %,12lu %,12lu rd/wr_Excl_nochange\n",
- stats__msm_r32_Excl_nochange, stats__msm_w32_Excl_nochange);
+ stats__msm_read_Excl_nochange, stats__msm_write_Excl_nochange);
VG_(printf)(" msm: %,12lu %,12lu rd/wr_Excl_transfer\n",
- stats__msm_r32_Excl_transfer, stats__msm_w32_Excl_transfer);
+ stats__msm_read_Excl_transfer, stats__msm_write_Excl_transfer);
VG_(printf)(" msm: %,12lu %,12lu rd/wr_Excl_to_ShR/ShM\n",
- stats__msm_r32_Excl_to_ShR, stats__msm_w32_Excl_to_ShM);
+ stats__msm_read_Excl_to_ShR, stats__msm_write_Excl_to_ShM);
VG_(printf)(" msm: %,12lu %,12lu rd/wr_ShR_to_ShR/ShM\n",
- stats__msm_r32_ShR_to_ShR, stats__msm_w32_ShR_to_ShM);
+ stats__msm_read_ShR_to_ShR, stats__msm_write_ShR_to_ShM);
VG_(printf)(" msm: %,12lu %,12lu rd/wr_ShM_to_ShM\n",
- stats__msm_r32_ShM_to_ShM, stats__msm_w32_ShM_to_ShM);
+ stats__msm_read_ShM_to_ShM, stats__msm_write_ShM_to_ShM);
VG_(printf)(" msm: %,12lu %,12lu rd/wr_New_to_Excl\n",
- stats__msm_r32_New_to_Excl, stats__msm_w32_New_to_Excl);
+ stats__msm_read_New_to_Excl, stats__msm_write_New_to_Excl);
VG_(printf)(" msm: %,12lu %,12lu rd/wr_NoAccess\n",
- stats__msm_r32_NoAccess, stats__msm_w32_NoAccess);
+ stats__msm_read_NoAccess, stats__msm_write_NoAccess);
VG_(printf)("\n");
VG_(printf)(" secmaps: %,10lu allocd (%,12lu g-a-range)\n",
|
|
From: <sv...@va...> - 2007-10-28 14:51:23
|
Author: sewardj
Date: 2007-10-28 14:51:23 +0000 (Sun, 28 Oct 2007)
New Revision: 7046
Log:
Add VG_(atoll16) for ascii-hex to signed Long conversions.
Modified:
branches/THRCHECK/coregrind/m_libcbase.c
branches/THRCHECK/include/pub_tool_libcbase.h
Modified: branches/THRCHECK/coregrind/m_libcbase.c
===================================================================
--- branches/THRCHECK/coregrind/m_libcbase.c 2007-10-28 01:46:12 UTC (rev 7045)
+++ branches/THRCHECK/coregrind/m_libcbase.c 2007-10-28 14:51:23 UTC (rev 7046)
@@ -63,6 +63,36 @@
return n;
}
+Long VG_(atoll16) ( Char* str )
+{
+ Bool neg = False;
+ Long n = 0;
+ if (*str == '-') { str++; neg = True; };
+ if (*str == '0' && (*(str+1) == 'x' || *(str+1) == 'X')) {
+ str += 2;
+ }
+ while (True) {
+ Char c = *str;
+ if (c >= '0' && c <= (Char)'9') {
+ n = 16*n + (Long)(c - '0');
+ }
+ else
+ if (c >= 'A' && c <= (Char)'F') {
+ n = 16*n + (Long)((c - 'A') + 10);
+ }
+ else
+ if (c >= 'a' && c <= (Char)'f') {
+ n = 16*n + (Long)((c - 'a') + 10);
+ }
+ else {
+ break;
+ }
+ str++;
+ }
+ if (neg) n = -n;
+ return n;
+}
+
Long VG_(atoll36) ( Char* str )
{
Bool neg = False;
Modified: branches/THRCHECK/include/pub_tool_libcbase.h
===================================================================
--- branches/THRCHECK/include/pub_tool_libcbase.h 2007-10-28 01:46:12 UTC (rev 7045)
+++ branches/THRCHECK/include/pub_tool_libcbase.h 2007-10-28 14:51:23 UTC (rev 7046)
@@ -42,8 +42,9 @@
Converting strings to numbers
------------------------------------------------------------------ */
-extern Long VG_(atoll) ( Char* str ); // base 10
-extern Long VG_(atoll36) ( Char* str ); // base 36
+extern Long VG_(atoll) ( Char* str ); // base 10
+extern Long VG_(atoll16) ( Char* str ); // base 16; leading 0x accepted
+extern Long VG_(atoll36) ( Char* str ); // base 36
/* ---------------------------------------------------------------------
String functions and macros
|
|
From: Julian S. <js...@ac...> - 2007-10-28 10:56:07
|
On Thursday 25 October 2007 12:03, Bart Van Assche wrote: > Welcome to the world of vector clocks ... > > Do you see an opportunity of sharing the vector clock / vector > timestamp code between thrcheck and drd ? I don't know - I didn't look at the drd implementation. I just have a very simple implementation of tick, join and compare - nothing fancy. J |
|
From: Tom H. <th...@cy...> - 2007-10-28 03:31:45
|
Nightly build on alvis ( i686, Red Hat 7.3 ) started at 2007-10-28 03:14:57 GMT Results unchanged from 24 hours ago Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 260 tests, 27 stderr failures, 1 stdout failure, 0 posttest failures == memcheck/tests/addressable (stderr) memcheck/tests/badjump (stderr) memcheck/tests/describe-block (stderr) memcheck/tests/erringfds (stderr) memcheck/tests/leak-0 (stderr) memcheck/tests/leak-cycle (stderr) memcheck/tests/leak-pool-0 (stderr) memcheck/tests/leak-pool-1 (stderr) memcheck/tests/leak-pool-2 (stderr) memcheck/tests/leak-pool-3 (stderr) memcheck/tests/leak-pool-4 (stderr) memcheck/tests/leak-pool-5 (stderr) memcheck/tests/leak-regroot (stderr) memcheck/tests/leak-tree (stderr) memcheck/tests/long_namespace_xml (stderr) memcheck/tests/match-overrun (stderr) memcheck/tests/partial_load_dflt (stderr) memcheck/tests/partial_load_ok (stderr) memcheck/tests/partiallydefinedeq (stderr) memcheck/tests/pointer-trace (stderr) memcheck/tests/sigkill (stderr) memcheck/tests/stack_changes (stderr) memcheck/tests/x86/scalar (stderr) memcheck/tests/x86/scalar_supp (stderr) memcheck/tests/x86/xor-undef-x86 (stderr) memcheck/tests/xml1 (stderr) none/tests/mremap (stderr) none/tests/mremap2 (stdout) |
|
From: Tom H. <th...@cy...> - 2007-10-28 03:23:47
|
Nightly build on lloyd ( x86_64, Fedora 7 ) started at 2007-10-28 03:05:08 GMT Results unchanged from 24 hours ago Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 293 tests, 4 stderr failures, 2 stdout failures, 0 posttest failures == memcheck/tests/pointer-trace (stderr) memcheck/tests/vcpu_fnfns (stdout) memcheck/tests/x86/scalar (stderr) memcheck/tests/xml1 (stderr) none/tests/mremap (stderr) none/tests/mremap2 (stdout) |
|
From: Tom H. <th...@cy...> - 2007-10-28 03:23:27
|
Nightly build on dellow ( x86_64, Fedora 7 ) started at 2007-10-28 03:10:04 GMT Results differ from 24 hours ago Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 293 tests, 4 stderr failures, 3 stdout failures, 0 posttest failures == memcheck/tests/pointer-trace (stderr) memcheck/tests/vcpu_fnfns (stdout) memcheck/tests/x86/scalar (stderr) memcheck/tests/xml1 (stderr) none/tests/mremap (stderr) none/tests/mremap2 (stdout) none/tests/pth_detached (stdout) ================================================= == Results from 24 hours ago == ================================================= Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 293 tests, 4 stderr failures, 2 stdout failures, 0 posttest failures == memcheck/tests/pointer-trace (stderr) memcheck/tests/vcpu_fnfns (stdout) memcheck/tests/x86/scalar (stderr) memcheck/tests/xml1 (stderr) none/tests/mremap (stderr) none/tests/mremap2 (stdout) ================================================= == Difference between 24 hours ago and now == ================================================= *** old.short Sun Oct 28 03:16:52 2007 --- new.short Sun Oct 28 03:23:30 2007 *************** *** 8,10 **** ! == 293 tests, 4 stderr failures, 2 stdout failures, 0 posttest failures == memcheck/tests/pointer-trace (stderr) --- 8,10 ---- ! == 293 tests, 4 stderr failures, 3 stdout failures, 0 posttest failures == memcheck/tests/pointer-trace (stderr) *************** *** 15,16 **** --- 15,17 ---- none/tests/mremap2 (stdout) + none/tests/pth_detached (stdout) |
|
From: Tom H. <th...@cy...> - 2007-10-28 03:11:07
|
Nightly build on gill ( x86_64, Fedora Core 2 ) started at 2007-10-28 03:00:03 GMT Results unchanged from 24 hours ago Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 295 tests, 6 stderr failures, 1 stdout failure, 0 posttest failures == memcheck/tests/pointer-trace (stderr) memcheck/tests/stack_switch (stderr) memcheck/tests/x86/scalar (stderr) memcheck/tests/x86/scalar_supp (stderr) none/tests/fdleak_fcntl (stderr) none/tests/mremap (stderr) none/tests/mremap2 (stdout) |
|
From: Julian S. <js...@ac...> - 2007-10-28 02:04:44
|
> Is there some documentation on the algorithm that thrcheck uses? See http://bugs.kde.org/show_bug.cgi?id=137396 for other user feedback and a description of how to build the documentation. J |
|
From: <sv...@va...> - 2007-10-28 01:46:14
|
Author: sewardj
Date: 2007-10-28 01:46:12 +0000 (Sun, 28 Oct 2007)
New Revision: 7045
Log:
Redo suppressions based on object names, for the most part, rather
than function names. The latter approach is preferable but was
getting out of hand. The new approach is unfortunately rather a
blunt-instrument scheme, but at least it's concise.
Modified:
branches/THRCHECK/glibc-2.X-thrcheck.supp
Modified: branches/THRCHECK/glibc-2.X-thrcheck.supp
===================================================================
--- branches/THRCHECK/glibc-2.X-thrcheck.supp 2007-10-27 02:24:52 UTC (rev 7044)
+++ branches/THRCHECK/glibc-2.X-thrcheck.supp 2007-10-28 01:46:12 UTC (rev 7045)
@@ -3,400 +3,116 @@
# Suppressions for the Thrcheck tool when using
# a glibc-2.{2,3,4,5,6} system
-#z###--- ld.so stuff ---###
-#z{
-#z thrcheck-glibc2X-ldso-1
-#z Thrcheck:Race
-#z fun:_dl_lookup_symbol_x
-#z fun:_dl_fixup
-#z fun:_dl_runtime_resolve
-#z}
-#z{
-#z thrcheck-glibc2X-ldso-2
-#z Thrcheck:Race
-#z fun:do_lookup_x
-#z fun:_dl_lookup_symbol_x
-#z fun:_dl_fixup
-#z}
-#z{
-#z thrcheck-glibc2X-ldso-3
-#z Thrcheck:Race
-#z fun:_dl_map_object_deps
-#z fun:dl_open_worker
-#z fun:_dl_catch_error
-#z}
-#z{
-#z thrcheck-glibc2X-ldso-4
-#z Thrcheck:Race
-#z fun:setup_direct
-#z fun:_dl_map_object_deps
-#z fun:dl_open_worker
-#z}
-#z{
-#z thrcheck-glibc2X-ldso-5
-#z Thrcheck:Race
-#z fun:_dl_map_object_from_fd
-#z fun:_dl_map_object
-#z fun:dl_open_worker
-#z}
-#z{
-#z thrcheck-glibc2X-ldso-6
-#z Thrcheck:Race
-#z fun:_dl_map_object
-#z fun:dl_open_worker
-#z fun:_dl_catch_error
-#z}
-
-###--- pthread_join ---###
+######------ glibc-2.5 specific ------######
{
- thrcheck-glibc2X-pthjoin-1
+ thrcheck-glibc25-01
Thrcheck:Race
- fun:pthread_join
- fun:pthread_join
+ obj:/lib*/ld-2.5.so
+ obj:/lib*/ld-2.5.so
+ obj:/lib*/ld-2.5.so
}
{
- thrcheck-glibc2X-pthjoin-2
+ thrcheck-glibc25-02
Thrcheck:Race
- fun:__deallocate_stack
- fun:pthread_join
- fun:pthread_join
+ obj:/lib*/ld-2.5.so
+ obj:/lib*/libc-2.5.so
+ obj:/lib*/ld-2.5.so
}
{
- thrcheck-glibc2X-pthjoin-3
+ thrcheck-glibc25-03
Thrcheck:Race
- fun:free_stacks
- fun:__deallocate_stack
- fun:pthread_join
- fun:pthread_join
+ obj:/lib*/ld-2.5.so
+ obj:/lib*/libc-2.5.so
+ obj:/lib*/libc-2.5.so
}
-
-###--- IO_file ---###
-# I'm pretty sure these are because Thrcheck cannot see
-# glibc's acquisition/releasing of locks for stdio.
{
- thrcheck-glibc2X-IOfile-1
+ thrcheck-glibc25-04
Thrcheck:Race
- fun:_IO_file_xsputn*
- fun:*vfprintf
- fun:*printf
+ obj:/lib*/libc-2.5.so
+ obj:/lib*/libc-2.5.so
}
{
- thrcheck-glibc2X-IOfile-2
+ thrcheck-glibc25-05
Thrcheck:Race
- fun:vfprintf
- fun:*printf
+ obj:/lib*/libpthread-2.5.so
+ obj:/lib*/libpthread-2.5.so
+ obj:/lib*/libpthread-2.5.so
}
{
- thrcheck-glibc2X-IOfile-3
+ thrcheck-glibc25-06
Thrcheck:Race
- fun:mempcpy
- fun:vfprintf
- fun:*printf
+ obj:/lib*/libpthread-2.5.so
+ obj:/lib*/libpthread-2.5.so
+ obj:/lib*/libc-2.5.so
}
{
- thrcheck-glibc2X-IOfile-4
+ thrcheck-glibc25-07
Thrcheck:Race
- fun:buffered_vfprintf
- fun:vfprintf
- fun:*printf
+ obj:/lib*/ld-2.5.so
+ obj:/lib*/libc-2.5.so
+ obj:/lib*/libdl-2.5.so
}
{
- thrcheck-glibc2X-IOfile-5
+ thrcheck-glibc25-08
Thrcheck:Race
- fun:new_do_write
- fun:_IO_do_write*
- fun:_IO_file_xsputn*
- fun:*printf
+ obj:/lib*/libpthread-2.5.so
+ obj:/lib*/libc-2.5.so
}
-{
- thrcheck-glibc2X-IOfile-6
- Thrcheck:Race
- fun:mempcpy
- fun:_IO_file_xsputn*
- fun:*printf
-}
-{
- thrcheck-glibc2X-IOfile-7
- Thrcheck:Race
- fun:new_do_write
- fun:_IO_do_write*
- fun:_IO_file_overflow*
- fun:_IO_file_xsputn*
-}
-{
- thrcheck-glibc2X-IOfile-8
- Thrcheck:Race
- fun:_IO_file_overflow*
- fun:_IO_file_xsputn*
- fun:*fprintf
-}
-{
- thrcheck-glibc2X-IOfile-9
- Thrcheck:Race
- fun:new_do_write
- fun:_IO_file_xsputn*
- fun:*vfprintf
-}
-{
- thrcheck-glibc2X-IOfile-10
- Thrcheck:Race
- fun:__lll_mutex_unlock_wake
- fun:*printf
-}
-
-#z###--- thread creation ---###
-#z{
-#z thrcheck-glibc2X-creation-1
-#z Thrcheck:Race
-#z fun:start_thread
-#z fun:clone
-#z}
-
-###--- thread exit ---###
+# These are very ugly. They are needed to suppress errors inside (eg)
+# NPTL's pthread_cond_signal. Why only one stack frame -- at least we
+# should see the wrapper calling the real functions, right?
+# Unfortunately, no: the real functions are handwritten assembly (in
+# the glibc-2.5 sources) and does not create a proper stack frame.
+# Therefore it's only one level of unwinding before we're back out in
+# user code rather than the 2 levels you'd expect.
{
- thrcheck-glibc2X-exit-1
+ thrcheck-glibc25-10
Thrcheck:Race
- fun:_dl_fini
- fun:exit
+ obj:/lib*/libpthread-2.5.so
+ fun:pthread_*
}
-
-###--- pthread_mutex_lock ---###
{
- thrcheck-glibc2X-pthmxlock-1
+ thrcheck-glibc25-11
Thrcheck:Race
- fun:pthread_mutex_lock
- fun:pthread_mutex_lock
-}
-{
- thrcheck-glibc2X-pthmxlock-2
- Thrcheck:Race
- fun:__lll_mutex_lock_wait
- fun:pthread_mutex_lock
-}
-
-###--- pthread_mutex_unlock ---###
-{
- thrcheck-glibc2X-pthmxunlock-1
- Thrcheck:Race
- fun:__lll_mutex_unlock_wake
- fun:pthread_mutex_unlock
- fun:pthread_mutex_unlock
-}
-
-###--- pthread_mutex_destroy ---###
-{
- thrcheck-glibc2X-pthmxdestroy-1
- Thrcheck:Race
- fun:pthread_mutex_destroy
- fun:pthread_mutex_destroy
-}
-
-###--- pthread_create ---###
-{
- thrcheck-glibc2X-pthcreate-1
- Thrcheck:Race
- fun:pthread_create@@GLIBC_*
- fun:pthread_create@*
-}
-#z{
-#z thrcheck-glibc2X-pthcreate-2
-#z Thrcheck:Race
-#z fun:do_clone
-#z fun:pthread_create@@GLIBC_*
-#z fun:pthread_create@*
-#z}
-
-###--- pthread_cond_signal ---###
-#
-# This is very ugly. It is needed to suppress errors inside
-# NPTL's pthread_cond_signal. Why only one stack frame --
-# at least we should see the wrapper calling the real function,
-# right? Unfortunately, no: the real function is handwritten
-# assembly (in the glibc-2.5 sources) and does not create a proper
-# stack frame. Therefore it's only one level of unwinding before
-# we're back out in user code rather than the 2 levels you'd expect.
-{
- thrcheck-glibc2X-condsig-1
- Thrcheck:Race
- fun:pthread_cond_signal@@GLIBC_2.3.2
-}
-{
- thrcheck-glibc2X-condsig-2
- Thrcheck:Race
- fun:__lll_mutex_unlock_wake
- fun:pthread_cond_signal@@GLIBC_2.3.2
-}
-
-###--- pthread_cond_broadcast ---###
-# ditto
-{
- thrcheck-glibc2X-condbcast-1
- Thrcheck:Race
- fun:pthread_cond_broadcast@@GLIBC_2.3.2
-}
-
-###--- pthread_cond_wait ---###
-# ditto
-{
- thrcheck-glibc2X-pthcondwait-1
- Thrcheck:Race
- fun:pthread_cond_wait@@GLIBC_2.3.2
-}
-#z{
-#z thrcheck-glibc2X-pthcondwait-2
-#z Thrcheck:Race
-#z fun:pthread_cond_wait@@GLIBC_*
-#z fun:pthread_cond_wait*
-#z}
-{
- thrcheck-glibc2X-pthcondwait-3
- Thrcheck:Race
- fun:__pthread_mutex*lock*
- fun:pthread_cond_wait@@GLIBC_2.3.2
-}
-{
- thrcheck-glibc2X-pthcondwait-4
- Thrcheck:Race
- fun:__lll_mutex_unlock_wake
- fun:pthread_cond_wait@@GLIBC_2.3.2
-}
-
-###--- pthread_cond_destroy ---###
-# ditto
-{
- thrcheck-glibc2X-pthconddestroy-1
- Thrcheck:Race
- fun:pthread_cond_destroy@@GLIBC_2.3.2
-}
-
-###--- pthread_mutex_trylock ---###
-{
- thrcheck-glibc2X-pthmxtrylock-1
- Thrcheck:Race
- fun:pthread_mutex_trylock
- fun:pthread_mutex_trylock
-}
-
-###--- pthread_cond_timedwait ---###
-# ditto
-{
- thrcheck-glibc2X-pthmxtimedwait-1
- Thrcheck:Race
- fun:pthread_cond_timedwait@@GLIBC_2.3.2
-}
-{
- thrcheck-glibc2X-pthmxtimedwait-2
- Thrcheck:Race
- fun:__lll_mutex_unlock_wake
- fun:pthread_cond_timedwait@@GLIBC_*
-}
-
-###--- pthread_rwlock_*lock ---###
-# ditto
-{
- thrcheck-glibc2X-pthrwlock{rd,wr,un}lock-1
- Thrcheck:Race
- fun:pthread_rwlock_*lock
-}
-
-###--- libpthread internal stuff ---###
-{
- thrcheck-glibc2X-libpthread-1
- Thrcheck:Race
- fun:__pthread_mutex_unlock_usercnt
- fun:pthread_mutex_unlock
-}
-{
- thrcheck-glibc2X-libpthread-2
- Thrcheck:Race
- fun:__lll_mutex_unlock_wake
- fun:_L_*unlock_*
-}
-{
- thrcheck-glibc2X-libpthread-3
- Thrcheck:Race
- fun:__lll_mutex_lock_wait
- fun:_L_mutex_lock_*
- fun:start_thread
-}
-{
- thrcheck-glibc2X-libpthread-4
- Thrcheck:Race
- fun:__lll_mutex_lock_wait
- fun:_L_mutex_lock_*
- fun:pthread_mutex_lock
-}
-{
- thrcheck-glibc2X-libpthread-5
- Thrcheck:Race
fun:mythread_wrapper
- fun:start_thread
+ obj:/lib*/libpthread-2.5.so
}
{
- thrcheck-glibc2X-libpthread-6
+ thrcheck-glibc25-12
Thrcheck:Race
- fun:__deallocate_stack
- fun:start_thread
- fun:*clone*
+ fun:pthread_cond_*@@GLIBC_2.3.2
}
{
- thrcheck-glibc2X-libpthread-7
+ thrcheck-glibc25-13
Thrcheck:Race
- fun:__deallocate_stack
- fun:__free_tcb
- fun:start_thread
+ fun:__lll_mutex_*
}
{
- thrcheck-glibc2X-libpthread-8
+ thrcheck-glibc25-14
Thrcheck:Race
- fun:__deallocate_stack
- fun:__free_tcb
- fun:pthread_join
+ fun:pthread_rwlock_*lock*
}
-###--- fork ---###
-{
- thrcheck-glibc2X-fork-1
- Thrcheck:Race
- fun:__reclaim_stacks
- fun:fork
-}
-###--- glibc-2.5 specific ---###
-{
- thrcheck-glibc25-ld25-64bit-1
- Thrcheck:Race
- obj:/lib64/ld-2.5.so
- obj:/lib64/ld-2.5.so
- obj:/lib64/ld-2.5.so
-}
-{
- thrcheck-glibc25-ld25-32bit-1
- Thrcheck:Race
- obj:/lib/ld-2.5.so
- obj:/lib/ld-2.5.so
- obj:/lib/ld-2.5.so
-}
+#aa###--- glibc-2.6.1 specific ---###
+#aa{
+#aa thrcheck-glibc26-ld261-64bit-1
+#aa Thrcheck:Race
+#aa obj:/lib64/ld-2.6.1.so
+#aa obj:/lib64/ld-2.6.1.so
+#aa obj:/lib64/ld-2.6.1.so
+#aa}
+#aa{
+#aa thrcheck-glibc26-ld261-32bit-1
+#aa Thrcheck:Race
+#aa obj:/lib/ld-2.6.1.so
+#aa obj:/lib/ld-2.6.1.so
+#aa obj:/lib/ld-2.6.1.so
+#aa}
-###--- glibc-2.6.1 specific ---###
+######------ qt4 specific (GNU mangling) ------######
{
- thrcheck-glibc26-ld261-64bit-1
- Thrcheck:Race
- obj:/lib64/ld-2.6.1.so
- obj:/lib64/ld-2.6.1.so
- obj:/lib64/ld-2.6.1.so
-}
-{
- thrcheck-glibc26-ld261-32bit-1
- Thrcheck:Race
- obj:/lib/ld-2.6.1.so
- obj:/lib/ld-2.6.1.so
- obj:/lib/ld-2.6.1.so
-}
-
-###--- qt4 specific ---###
-{
thrcheck-qt4-QMutex::lock()-twice
Thrcheck:Race
fun:_ZN6QMutex4lockEv
|
|
From: <js...@ac...> - 2007-10-28 00:16:55
|
Nightly build on g5 ( SuSE 10.1, ppc970 ) started at 2007-10-28 02:00:01 CEST Results unchanged from 24 hours ago Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 228 tests, 6 stderr failures, 2 stdout failures, 0 posttest failures == memcheck/tests/deep_templates (stdout) memcheck/tests/leak-cycle (stderr) memcheck/tests/leak-tree (stderr) memcheck/tests/pointer-trace (stderr) none/tests/faultstatus (stderr) none/tests/fdleak_cmsg (stderr) none/tests/mremap (stderr) none/tests/mremap2 (stdout) |