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
(20) |
2
(19) |
3
(7) |
|
4
(13) |
5
(24) |
6
(9) |
7
(12) |
8
(8) |
9
(34) |
10
(28) |
|
11
(20) |
12
(23) |
13
(12) |
14
(10) |
15
(15) |
16
(24) |
17
(26) |
|
18
(17) |
19
(14) |
20
(14) |
21
(8) |
22
(12) |
23
(22) |
24
(10) |
|
25
(21) |
26
(21) |
27
(18) |
28
(8) |
29
(13) |
30
(15) |
|
|
From: John R.
|
Why is the stack for signal delivery not allowed to be in a SkFileC segment, such as an array in .data or .bss? If the address is already mapped, then in coregrind/m_signals.c function VG_(extend_stack) insists on SkAnonC; or SkResvn (with SkAnonC following) if the address is not already mapped. Especially if register_stack() is called beforehand with an interval covers the address, then SkFileC should be allowed. -- John Reiser, jreiser@BitWagon.com |
|
From: John R.
|
Hi,
This patch to do_fork_clone() supports specifying the child stack pointer.
An app may do this when it believes that address space is constrained.
Most callers specify a child stack pointer of 0; the Linux kernel then
uses the actual stack pointer of the caller, thus equivalent to fork().
Patch is against a recent SVN version.
--- ./coregrind/m_syswrap/syswrap-ppc64-linux.c.orig 2007-11-01 12:16:36.000000000 -0700
+++ ./coregrind/m_syswrap/syswrap-ppc64-linux.c 2007-11-05 07:45:32.000000000 -0800
@@ -973,6 +973,7 @@
SET_STATUS_from_SysRes(
ML_(do_fork_clone)(tid,
cloneflags, /* flags */
+ (Addr)ARG2, /* child SP */
(Int *)ARG3, /* parent_tidptr */
(Int *)ARG5)); /* child_tidptr */
break;
--- ./coregrind/m_syswrap/syswrap-amd64-linux.c.orig 2007-11-01 12:16:36.000000000 -0700
+++ ./coregrind/m_syswrap/syswrap-amd64-linux.c 2007-11-05 07:45:32.000000000 -0800
@@ -422,6 +422,7 @@
SET_STATUS_from_SysRes(
ML_(do_fork_clone)(tid,
cloneflags, /* flags */
+ (Addr)ARG2, /* child ESP */
(Int *)ARG3, /* parent_tidptr */
(Int *)ARG4)); /* child_tidptr */
break;
--- ./coregrind/m_syswrap/syswrap-linux.c.orig 2007-11-01 12:16:36.000000000 -0700
+++ ./coregrind/m_syswrap/syswrap-linux.c 2007-11-05 07:46:41.000000000 -0800
@@ -294,7 +294,7 @@
/* Do a clone which is really a fork() */
-SysRes ML_(do_fork_clone) ( ThreadId tid, UInt flags,
+SysRes ML_(do_fork_clone) ( ThreadId tid, UInt flags, Addr child_esp,
Int* parent_tidptr, Int* child_tidptr )
{
vki_sigset_t fork_saved_mask;
@@ -328,6 +328,11 @@
if (!res.isError && res.res == 0) {
/* child */
+ if (child_esp != 0) {
+ ThreadState *const ctst = VG_(get_ThreadState)(tid);
+ ctst->arch.vex.guest_ESP = child_esp;
+ }
+
VG_(do_atfork_child)(tid);
/* restore signal mask */
--- ./coregrind/m_syswrap/syswrap-x86-linux.c.orig 2007-11-01 12:16:36.000000000 -0700
+++ ./coregrind/m_syswrap/syswrap-x86-linux.c 2007-11-05 07:45:32.000000000 -0800
@@ -903,6 +903,7 @@
SET_STATUS_from_SysRes(
ML_(do_fork_clone)(tid,
cloneflags, /* flags */
+ (Addr)ARG2, /* child ESP */
(Int *)ARG3, /* parent_tidptr */
(Int *)ARG5)); /* child_tidptr */
break;
--- ./coregrind/m_syswrap/syswrap-ppc32-linux.c.orig 2007-11-01 12:16:36.000000000 -0700
+++ ./coregrind/m_syswrap/syswrap-ppc32-linux.c 2007-11-05 07:45:32.000000000 -0800
@@ -995,6 +995,7 @@
SET_STATUS_from_SysRes(
ML_(do_fork_clone)(tid,
cloneflags, /* flags */
+ (Addr)ARG2, /* child SP */
(Int *)ARG3, /* parent_tidptr */
(Int *)ARG5)); /* child_tidptr */
break;
--- ./coregrind/m_syswrap/priv_syswrap-linux.h.orig 2007-11-01 12:16:36.000000000 -0700
+++ ./coregrind/m_syswrap/priv_syswrap-linux.h 2007-11-05 07:45:32.000000000 -0800
@@ -38,7 +38,7 @@
extern Addr ML_(allocstack) ( ThreadId tid );
extern void ML_(call_on_new_stack_0_1) ( Addr stack, Addr retaddr,
void (*f)(Word), Word arg1 );
-extern SysRes ML_(do_fork_clone) ( ThreadId tid, UInt flags,
+extern SysRes ML_(do_fork_clone) ( ThreadId tid, UInt flags, Addr child_esp,
Int* parent_tidptr, Int* child_tidptr );
--
John Reiser, jreiser@BitWagon.com
|
|
From: <sv...@va...> - 2007-11-05 13:31:59
|
Author: sewardj
Date: 2007-11-05 13:31:58 +0000 (Mon, 05 Nov 2007)
New Revision: 7103
Log:
Even more caveats.
Modified:
branches/THRCHECK/thrcheck/docs/tc-manual.xml
Modified: branches/THRCHECK/thrcheck/docs/tc-manual.xml
===================================================================
--- branches/THRCHECK/thrcheck/docs/tc-manual.xml 2007-11-05 12:59:31 UTC (rev 7102)
+++ branches/THRCHECK/thrcheck/docs/tc-manual.xml 2007-11-05 13:31:58 UTC (rev 7103)
@@ -1048,19 +1048,6 @@
</listitem>
<listitem>
- <para>POSIX requires that implementations of standard I/O (printf,
- fprintf, fwrite, fread, etc) are thread safe. Unfortunately GNU
- libc implements this by using internal locking primitives that
- Thrcheck is unable to intercept. Consequently Thrcheck generates
- many false race reports when you use these functions.</para>
-
- <para>Thrcheck attempts to hide these errors using the standard
- Valgrind error-suppression mechanism. So, at least for simple
- test cases, you don't see any. Nevertheless, some may slip
- through. Just something to be aware of.</para>
- </listitem>
-
- <listitem>
<para>Perform thread debugging (with Thrcheck) and memory
debugging (with Memcheck) together.</para>
@@ -1083,6 +1070,34 @@
complementary, and you may need to use them together.</para>
</listitem>
+ <listitem>
+ <para>POSIX requires that implementations of standard I/O (printf,
+ fprintf, fwrite, fread, etc) are thread safe. Unfortunately GNU
+ libc implements this by using internal locking primitives that
+ Thrcheck is unable to intercept. Consequently Thrcheck generates
+ many false race reports when you use these functions.</para>
+
+ <para>Thrcheck attempts to hide these errors using the standard
+ Valgrind error-suppression mechanism. So, at least for simple
+ test cases, you don't see any. Nevertheless, some may slip
+ through. Just something to be aware of.</para>
+ </listitem>
+
+ <listitem>
+ <para>Thrcheck's error checks do not work properly inside the
+ system threading library itself
+ (<computeroutput>libpthread.so</computeroutput>), and it usually
+ observes large numbers of (false) errors in there. Valgrind's
+ suppression system then filters these out, so you should not see
+ them.</para>
+
+ <para>If you see any race errors reported
+ where <computeroutput>libpthread.so</computeroutput> or
+ <computeroutput>ld.so</computeroutput> is the object associated
+ with the innermost stack frame, please file a bug report at
+ http://www.valgrind.org.</para>
+ </listitem>
+
</orderedlist>
</sect1>
|
|
From: <sv...@va...> - 2007-11-05 12:59:33
|
Author: sewardj
Date: 2007-11-05 12:59:31 +0000 (Mon, 05 Nov 2007)
New Revision: 7102
Log:
More glibc-2.3 fixes.
Modified:
branches/THRCHECK/glibc-2.X-thrcheck.supp
branches/THRCHECK/thrcheck/tests/filter_stderr
branches/THRCHECK/thrcheck/tests/tc20_verifywrap.stderr.exp-glibc23-amd64
branches/THRCHECK/thrcheck/tests/tc23_bogus_condwait.c
Modified: branches/THRCHECK/glibc-2.X-thrcheck.supp
===================================================================
--- branches/THRCHECK/glibc-2.X-thrcheck.supp 2007-11-05 11:10:29 UTC (rev 7101)
+++ branches/THRCHECK/glibc-2.X-thrcheck.supp 2007-11-05 12:59:31 UTC (rev 7102)
@@ -281,20 +281,38 @@
obj:/lib*/libc-2.3.*so
}
{
+ thrcheck-glibc23-008
+ Thrcheck:Race
+ obj:/lib*/libpthread-2.3.*so
+ obj:/lib*/libc-2.3.*so
+}
+{
thrcheck-glibc23-009
Thrcheck:Race
obj:/lib*/libc-2.3.*so
obj:/lib*/ld-2.3.*so
obj:/lib*/libc-2.3.*so
}
-
{
+ thrcheck-glibc23-011
+ Thrcheck:Race
+ obj:/lib*/libc-2.3.*so
+ obj:/lib*/libpthread-2.3.*so
+}
+{
thrcheck-glibc23-012
Thrcheck:Race
obj:/lib*/ld-2.3.*so
obj:/lib*/ld-2.3.*so
obj:/lib*/libc-2.3.*so
}
+{
+ thrcheck-glibc23-014
+ Thrcheck:Race
+ obj:/lib*/ld-2.3.*so
+ obj:/lib*/ld-2.3.*so
+ obj:/lib*/libpthread-2.3.*so
+}
{
thrcheck-glibc23-100
Modified: branches/THRCHECK/thrcheck/tests/filter_stderr
===================================================================
--- branches/THRCHECK/thrcheck/tests/filter_stderr 2007-11-05 11:10:29 UTC (rev 7101)
+++ branches/THRCHECK/thrcheck/tests/filter_stderr 2007-11-05 12:59:31 UTC (rev 7102)
@@ -25,6 +25,6 @@
# been built with debugging information, hence source locs are present
sed "s/(createthread.c:[0-9]*)/(in \/lib\/libpthread...)/g" |
sed "s/(clone.S:[0-9]*)/(in \/...libc...)/g" |
-sed "s/start_thread (pthread_create.c:[0-9]*)$/.../g" |
+sed "s/start_thread (pthread_create.c:[0-9]*)$/start_thread (in \/lib\/libpthread...)/g" |
$dir/../../tests/filter_test_paths
Modified: branches/THRCHECK/thrcheck/tests/tc20_verifywrap.stderr.exp-glibc23-amd64
===================================================================
--- branches/THRCHECK/thrcheck/tests/tc20_verifywrap.stderr.exp-glibc23-amd64 2007-11-05 11:10:29 UTC (rev 7101)
+++ branches/THRCHECK/thrcheck/tests/tc20_verifywrap.stderr.exp-glibc23-amd64 2007-11-05 12:59:31 UTC (rev 7102)
@@ -47,12 +47,9 @@
---------------- pthread_cond_wait et al ----------------
-Thread #1 unlocked a not-locked lock at 0x........
+Thread #1: pthread_cond_{timed}wait called with un-held mutex
at 0x........: pthread_cond_wait@* (tc_intercepts.c:...)
by 0x........: main (tc20_verifywrap.c:147)
- Lock at 0x........ was first observed
- at 0x........: pthread_mutex_init (tc_intercepts.c:...)
- by 0x........: main (tc20_verifywrap.c:145)
Thread #1's call to pthread_cond_wait failed
with error code 1 (EPERM: Operation not permitted)
@@ -65,6 +62,10 @@
FIXME: can't figure out how to verify wrap of pthread_broadcast_signal
+Thread #1: pthread_cond_{timed}wait called with un-held mutex
+ at 0x........: pthread_cond_timedwait@* (tc_intercepts.c:...)
+ by 0x........: main (tc20_verifywrap.c:165)
+
Thread #1's call to pthread_cond_timedwait failed
with error code 22 (EINVAL: Invalid argument)
at 0x........: pthread_cond_timedwait@* (tc_intercepts.c:...)
@@ -125,15 +126,9 @@
Thread #1 deallocated location 0x........ containing a locked lock
- at 0x........: main (tc20_verifywrap.c:263)
+ at 0x........: main (tc20_verifywrap.c:262)
Lock at 0x........ was first observed
at 0x........: pthread_rwlock_init (tc_intercepts.c:...)
by 0x........: main (tc20_verifywrap.c:216)
-Thread #1 deallocated location 0x........ containing a locked lock
- at 0x........: main (tc20_verifywrap.c:263)
- Lock at 0x........ was first observed
- at 0x........: pthread_mutex_init (tc_intercepts.c:...)
- by 0x........: main (tc20_verifywrap.c:145)
-
ERROR SUMMARY: 15 errors from 15 contexts (suppressed: 0 from 0)
Modified: branches/THRCHECK/thrcheck/tests/tc23_bogus_condwait.c
===================================================================
--- branches/THRCHECK/thrcheck/tests/tc23_bogus_condwait.c 2007-11-05 11:10:29 UTC (rev 7101)
+++ branches/THRCHECK/thrcheck/tests/tc23_bogus_condwait.c 2007-11-05 12:59:31 UTC (rev 7102)
@@ -1,7 +1,7 @@
/* Expect 5 errors total (4 re cvs, 1 re exiting w/lock.).
Tests passing bogus mutexes to pthread_cond_wait. */
-
+#define _GNU_SOURCE 1 /* needed by glibc <= 2.3 for pthread_rwlock_* */
#include <pthread.h>
#include <assert.h>
#include <unistd.h>
|
|
From: <sv...@va...> - 2007-11-05 11:10:28
|
Author: sewardj
Date: 2007-11-05 11:10:29 +0000 (Mon, 05 Nov 2007)
New Revision: 7101
Log:
Update suppressions and expected output.
Modified:
branches/THRCHECK/glibc-2.X-thrcheck.supp
branches/THRCHECK/thrcheck/tests/tc22_exit_w_lock.stderr.exp-glibc25-x86
Modified: branches/THRCHECK/glibc-2.X-thrcheck.supp
===================================================================
--- branches/THRCHECK/glibc-2.X-thrcheck.supp 2007-11-05 11:02:51 UTC (rev 7100)
+++ branches/THRCHECK/glibc-2.X-thrcheck.supp 2007-11-05 11:10:29 UTC (rev 7101)
@@ -69,6 +69,12 @@
obj:/lib*/libc-2.5.so
}
{
+ thrcheck-glibc25-010
+ Thrcheck:Race
+ obj:/lib*/ld-2.5.so
+ obj:/lib*/libpthread-2.5.so
+}
+{
thrcheck-glibc25-011
Thrcheck:Race
obj:/lib*/libc-2.5.so
Modified: branches/THRCHECK/thrcheck/tests/tc22_exit_w_lock.stderr.exp-glibc25-x86
===================================================================
--- branches/THRCHECK/thrcheck/tests/tc22_exit_w_lock.stderr.exp-glibc25-x86 2007-11-05 11:02:51 UTC (rev 7100)
+++ branches/THRCHECK/thrcheck/tests/tc22_exit_w_lock.stderr.exp-glibc25-x86 2007-11-05 11:10:29 UTC (rev 7101)
@@ -9,26 +9,6 @@
at 0x........: start_thread (in /lib/libpthread...)
by 0x........: ...
-Thread #1 is the program's root thread
-
-Possible data race during write of size 4 at 0x........
- at 0x........: mempcpy (in /lib/ld-2.5.so)
- by 0x........: pthread_create@GLIBC_ (in /lib/libpthread...)
- by 0x........: pthread_create@* (tc_intercepts.c:...)
- by 0x........: main (tc22_exit_w_lock.c:42)
- Old state: owned exclusively by thread #2
- New state: shared-modified by threads #1, #2
- Reason: this thread, #1, holds no locks at all
-
-Possible data race during write of size 4 at 0x........
- at 0x........: memset (in /lib/ld-2.5.so)
- by 0x........: pthread_create@GLIBC_ (in /lib/libpthread...)
- by 0x........: pthread_create@* (tc_intercepts.c:...)
- by 0x........: main (tc22_exit_w_lock.c:42)
- Old state: owned exclusively by thread #2
- New state: shared-modified by threads #1, #2
- Reason: this thread, #1, holds no locks at all
-
Thread #3 was created
at 0x........: clone (in /...libc...)
by 0x........: pthread_create@GLIBC_ (in /lib/libpthread...)
@@ -39,8 +19,10 @@
at 0x........: start_thread (in /lib/libpthread...)
by 0x........: ...
+Thread #1 is the program's root thread
+
Thread #1: Exiting thread still holds 1 lock
at 0x........: kill (in /...libc...)
by 0x........: (below main) (in /...libc...)
-ERROR SUMMARY: 5 errors from 5 contexts (suppressed: 0 from 0)
+ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 0 from 0)
|
|
From: <sv...@va...> - 2007-11-05 11:02:50
|
Author: sewardj
Date: 2007-11-05 11:02:51 +0000 (Mon, 05 Nov 2007)
New Revision: 7100
Log:
Warn against the perils of detached threads.
Modified:
branches/THRCHECK/thrcheck/docs/tc-manual.xml
Modified: branches/THRCHECK/thrcheck/docs/tc-manual.xml
===================================================================
--- branches/THRCHECK/thrcheck/docs/tc-manual.xml 2007-11-05 10:48:45 UTC (rev 7099)
+++ branches/THRCHECK/thrcheck/docs/tc-manual.xml 2007-11-05 11:02:51 UTC (rev 7100)
@@ -1025,6 +1025,29 @@
</listitem>
<listitem>
+ <para>Round up all finished threads using pthread_join. Avoid
+ detaching threads: don't create threads in the detached state, and
+ don't call pthread_detach on existing threads.</para>
+
+ <para>Using pthread_join to round up finished threads provides a
+ clear synchronisation point that both Thrcheck and programmers can
+ see. This synchronisation point allows Thrcheck to adjust its
+ memory ownership
+ models <link linkend="tc-manual.data-races.exclusive">as described
+ extensively above</link>, which helps Thrcheck produce more
+ accurate error reports.</para>
+
+ <para>If you don't call pthread_join on a thread, Thrcheck has no
+ way to know when it finishes, relative to any significant
+ synchronisation points for other threads in the program. So it
+ assumes that the thread lingers indefinitely and can potentially
+ interfere indefinitely with the memory state of the program. It
+ has every right to assume that -- after all, it might really be
+ the case that, for scheduling reasons, the exiting thread did run
+ very slowly in the last stages of its life.</para>
+ </listitem>
+
+ <listitem>
<para>POSIX requires that implementations of standard I/O (printf,
fprintf, fwrite, fread, etc) are thread safe. Unfortunately GNU
libc implements this by using internal locking primitives that
|
|
From: <sv...@va...> - 2007-11-05 10:48:43
|
Author: sewardj
Date: 2007-11-05 10:48:45 +0000 (Mon, 05 Nov 2007)
New Revision: 7099
Log:
Update expected output.
Modified:
branches/THRCHECK/thrcheck/tests/tc23_bogus_condwait.stderr.exp-glibc25-x86
Modified: branches/THRCHECK/thrcheck/tests/tc23_bogus_condwait.stderr.exp-glibc25-x86
===================================================================
--- branches/THRCHECK/thrcheck/tests/tc23_bogus_condwait.stderr.exp-glibc25-x86 2007-11-05 10:37:52 UTC (rev 7098)
+++ branches/THRCHECK/thrcheck/tests/tc23_bogus_condwait.stderr.exp-glibc25-x86 2007-11-05 10:48:45 UTC (rev 7099)
@@ -3,28 +3,18 @@
Thread #1: pthread_cond_{timed}wait called with invalid mutex
at 0x........: pthread_cond_wait@* (tc_intercepts.c:...)
- by 0x........: main (tc23_bogus_condwait.c:62)
+ by 0x........: main (tc23_bogus_condwait.c:69)
Thread #1: pthread_cond_{timed}wait called with un-held mutex
at 0x........: pthread_cond_wait@* (tc_intercepts.c:...)
- by 0x........: main (tc23_bogus_condwait.c:65)
+ by 0x........: main (tc23_bogus_condwait.c:72)
Thread #1: pthread_cond_{timed}wait called with mutex of type pthread_rwlock_t*
at 0x........: pthread_cond_wait@* (tc_intercepts.c:...)
- by 0x........: main (tc23_bogus_condwait.c:68)
+ by 0x........: main (tc23_bogus_condwait.c:75)
-Thread #3 was created
- at 0x........: clone (in /...libc...)
- by 0x........: pthread_create@GLIBC_ (in /lib/libpthread...)
- by 0x........: pthread_create@* (tc_intercepts.c:...)
- by 0x........: main (tc23_bogus_condwait.c:71)
-
-Thread #3: Exiting thread still holds 1 lock
- at 0x........: start_thread (in /lib/libpthread...)
- by 0x........: ...
-
Thread #1: pthread_cond_{timed}wait called with mutex held by a different thread
at 0x........: pthread_cond_wait@* (tc_intercepts.c:...)
- by 0x........: main (tc23_bogus_condwait.c:73)
+ by 0x........: main (tc23_bogus_condwait.c:78)
-ERROR SUMMARY: 5 errors from 5 contexts (suppressed: 0 from 0)
+ERROR SUMMARY: 4 errors from 4 contexts (suppressed: 0 from 0)
|
|
From: <sv...@va...> - 2007-11-05 10:46:20
|
Author: sewardj
Date: 2007-11-05 10:37:52 +0000 (Mon, 05 Nov 2007)
New Revision: 7098
Log:
Update expected output.
Modified:
branches/THRCHECK/thrcheck/tests/tc23_bogus_condwait.stderr.exp-glibc25-amd64
Modified: branches/THRCHECK/thrcheck/tests/tc23_bogus_condwait.stderr.exp-glibc25-amd64
===================================================================
--- branches/THRCHECK/thrcheck/tests/tc23_bogus_condwait.stderr.exp-glibc25-amd64 2007-11-05 10:22:20 UTC (rev 7097)
+++ branches/THRCHECK/thrcheck/tests/tc23_bogus_condwait.stderr.exp-glibc25-amd64 2007-11-05 10:37:52 UTC (rev 7098)
@@ -3,29 +3,18 @@
Thread #1: pthread_cond_{timed}wait called with invalid mutex
at 0x........: pthread_cond_wait@* (tc_intercepts.c:...)
- by 0x........: main (tc23_bogus_condwait.c:62)
+ by 0x........: main (tc23_bogus_condwait.c:69)
Thread #1: pthread_cond_{timed}wait called with un-held mutex
at 0x........: pthread_cond_wait@* (tc_intercepts.c:...)
- by 0x........: main (tc23_bogus_condwait.c:65)
+ by 0x........: main (tc23_bogus_condwait.c:72)
Thread #1: pthread_cond_{timed}wait called with mutex of type pthread_rwlock_t*
at 0x........: pthread_cond_wait@* (tc_intercepts.c:...)
- by 0x........: main (tc23_bogus_condwait.c:68)
+ by 0x........: main (tc23_bogus_condwait.c:75)
-Thread #3 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 (tc23_bogus_condwait.c:71)
-
-Thread #3: Exiting thread still holds 1 lock
- at 0x........: start_thread (in /lib/libpthread...)
- by 0x........: ...
-
Thread #1: pthread_cond_{timed}wait called with mutex held by a different thread
at 0x........: pthread_cond_wait@* (tc_intercepts.c:...)
- by 0x........: main (tc23_bogus_condwait.c:73)
+ by 0x........: main (tc23_bogus_condwait.c:78)
-ERROR SUMMARY: 5 errors from 5 contexts (suppressed: 0 from 0)
+ERROR SUMMARY: 4 errors from 4 contexts (suppressed: 0 from 0)
|
|
From: <sv...@va...> - 2007-11-05 10:22:22
|
Author: sewardj
Date: 2007-11-05 10:22:20 +0000 (Mon, 05 Nov 2007)
New Revision: 7097
Log:
Avoid hanging (or apparently so) when running on very slow machines.
Modified:
branches/THRCHECK/thrcheck/tests/tc23_bogus_condwait.c
Modified: branches/THRCHECK/thrcheck/tests/tc23_bogus_condwait.c
===================================================================
--- branches/THRCHECK/thrcheck/tests/tc23_bogus_condwait.c 2007-11-05 03:37:43 UTC (rev 7096)
+++ branches/THRCHECK/thrcheck/tests/tc23_bogus_condwait.c 2007-11-05 10:22:20 UTC (rev 7097)
@@ -5,11 +5,14 @@
#include <pthread.h>
#include <assert.h>
#include <unistd.h>
+#include <semaphore.h>
pthread_mutex_t mx[4];
pthread_cond_t cv;
pthread_rwlock_t rwl;
+sem_t quit_now;
+
void* rescue_me ( void* uu )
{
/* wait for, and unblock, the first wait */
@@ -24,18 +27,19 @@
sleep(1);
pthread_cond_signal( &cv );
- /* wait for grabber and main, then unblock the fourth wait */
- sleep(1+1);
+ /* wait for, and unblock, the fourth wait */
+ sleep(1);
pthread_cond_signal( &cv );
+ sem_wait( &quit_now );
return NULL;
}
void* grab_the_lock ( void* uu )
{
int r= pthread_mutex_lock( &mx[2] ); assert(!r);
- /* tc correctly complains that the thread is exiting whilst still
- holding a lock. A bit tricky to fix - we just live with it. */
+ sem_wait( &quit_now );
+ r= pthread_mutex_unlock( &mx[2] ); assert(!r);
return NULL;
}
@@ -52,9 +56,12 @@
r= pthread_cond_init(&cv, NULL); assert(!r);
r= pthread_rwlock_init(&rwl, NULL); assert(!r);
- r= pthread_create( &my_rescuer, NULL, rescue_me, NULL );
- assert(!r);
+ r= sem_init( &quit_now, 0,0 ); assert(!r);
+ r= pthread_create( &grabber, NULL, grab_the_lock, NULL ); assert(!r);
+ sleep(1); /* let the grabber get there first */
+
+ r= pthread_create( &my_rescuer, NULL, rescue_me, NULL ); assert(!r);
/* Do stupid things and hope that rescue_me gets us out of
trouble */
@@ -68,10 +75,11 @@
r= pthread_cond_wait(&cv, (pthread_mutex_t*)&rwl );
/* mx is held by someone else. */
- r= pthread_create( &grabber, NULL, grab_the_lock, NULL ); assert(!r);
- sleep(1); /* let the grabber get there first */
r= pthread_cond_wait(&cv, &mx[2] );
+ r= sem_post( &quit_now ); assert(!r);
+ r= sem_post( &quit_now ); assert(!r);
+
r= pthread_join( my_rescuer, NULL ); assert(!r);
r= pthread_join( grabber, NULL ); assert(!r);
return 0;
|
|
From: <sv...@va...> - 2007-11-05 03:37:41
|
Author: sewardj
Date: 2007-11-05 03:37:43 +0000 (Mon, 05 Nov 2007)
New Revision: 7096
Log:
More documentation wibbling.
Modified:
branches/THRCHECK/thrcheck/docs/tc-manual.xml
Modified: branches/THRCHECK/thrcheck/docs/tc-manual.xml
===================================================================
--- branches/THRCHECK/thrcheck/docs/tc-manual.xml 2007-11-05 03:17:07 UTC (rev 7095)
+++ branches/THRCHECK/thrcheck/docs/tc-manual.xml 2007-11-05 03:37:43 UTC (rev 7096)
@@ -894,8 +894,9 @@
<para>Thrcheck directly supports the following POSIX threading
abstractions: mutexes, reader-writer locks, condition variables
(but see below), and semaphores. Currently spinlocks and barriers
- are not supported, although they could be in future. See below
- for a "safe" alternative implementation of barriers.</para>
+ are not supported, although they could be in future. A prototype
+ "safe" implementation of barriers, based on semaphores, is
+ available: please contact the Valgrind authors for details.</para>
<para>At the time of writing, the following popular Linux packages
are known to implement their own threading primitives:</para>
@@ -1013,8 +1014,8 @@
<para>Make sure you are using a supported Linux distribution. At
present, Thrcheck only properly supports x86-linux and amd64-linux
with glibc-2.3 or later. The latter restriction means we only
- support the NPTL threading library. The old LinuxThreads library
- is not supported.</para>
+ support glibc's NPTL threading implementation. The old
+ LinuxThreads implementation is not supported.</para>
<para>Unsupported targets may work to varying degrees. In
particular ppc32-linux and ppc64-linux running NTPL should work,
@@ -1036,6 +1037,29 @@
through. Just something to be aware of.</para>
</listitem>
+ <listitem>
+ <para>Perform thread debugging (with Thrcheck) and memory
+ debugging (with Memcheck) together.</para>
+
+ <para>Thrcheck tracks the state of memory in detail, and memory
+ management bugs in the application are liable to cause confusion.
+ In extreme cases, applications which do many invalid reads and
+ writes (particularly to freed memory) have been known to crash
+ Thrcheck. So, ideally, you should make your application
+ Memcheck-clean before using Thrcheck.</para>
+
+ <para>It may be impossible to make your application Memcheck-clean
+ unless you first remove threading bugs. In particular, it may be
+ difficult to remove all reads and writes to freed memory in
+ multithreaded C++ destructor sequences at program termination.
+ So, ideally, you should make your application Thrcheck-clean
+ before using Memcheck.</para>
+
+ <para>Since this circularity is obviously unresolvable, at least
+ bear in mind that Memcheck and Thrcheck are to some extent
+ complementary, and you may need to use them together.</para>
+ </listitem>
+
</orderedlist>
</sect1>
@@ -1235,6 +1259,11 @@
B (presumably it will have a Plan B). Doing such checks could
generate false lock-order errors and confuse users.</para>
</listitem>
+ <listitem><para> Performance can be very poor. Slowdowns on the
+ order of 100:1 are not unusual. There is quite some scope for
+ performance improvements, though.
+ </para>
+ </listitem>
</itemizedlist>
|
|
From: Tom H. <th...@cy...> - 2007-11-05 03:31:55
|
Nightly build on alvis ( i686, Red Hat 7.3 ) started at 2007-11-05 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 == 287 tests, 33 stderr failures, 1 stdout failure, 27 post 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) massif/tests/alloc-fns-A (post) massif/tests/alloc-fns-B (post) massif/tests/basic (post) massif/tests/big-alloc (post) massif/tests/culling1 (stderr) massif/tests/culling2 (stderr) massif/tests/custom_alloc (post) massif/tests/deep-A (post) massif/tests/deep-B (stderr) massif/tests/deep-B (post) massif/tests/deep-C (stderr) massif/tests/deep-C (post) massif/tests/deep-D (post) massif/tests/ignoring (post) massif/tests/insig (post) massif/tests/long-time (post) massif/tests/new-cpp (post) massif/tests/null (post) massif/tests/one (post) massif/tests/overloaded-new (post) massif/tests/peak (post) massif/tests/peak2 (stderr) massif/tests/peak2 (post) massif/tests/realloc (stderr) massif/tests/realloc (post) massif/tests/thresholds_0_0 (post) massif/tests/thresholds_0_10 (post) massif/tests/thresholds_10_0 (post) massif/tests/thresholds_10_10 (post) massif/tests/thresholds_5_0 (post) massif/tests/thresholds_5_10 (post) massif/tests/zero1 (post) massif/tests/zero2 (post) none/tests/mremap (stderr) none/tests/mremap2 (stdout) |
|
From: Tom H. <th...@cy...> - 2007-11-05 03:24:47
|
Nightly build on lloyd ( x86_64, Fedora 7 ) started at 2007-11-05 03:05:07 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 == 320 tests, 4 stderr failures, 2 stdout failures, 0 post 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-11-05 03:23:35
|
Nightly build on dellow ( x86_64, Fedora 7 ) started at 2007-11-05 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 == 320 tests, 4 stderr failures, 2 stdout failures, 0 post 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) ================================================= == 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 == 320 tests, 4 stderr failures, 3 stdout failures, 0 post 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_cvsimple (stdout) ================================================= == Difference between 24 hours ago and now == ================================================= *** old.short Mon Nov 5 03:16:56 2007 --- new.short Mon Nov 5 03:23:36 2007 *************** *** 8,10 **** ! == 320 tests, 4 stderr failures, 3 stdout failures, 0 post failures == memcheck/tests/pointer-trace (stderr) --- 8,10 ---- ! == 320 tests, 4 stderr failures, 2 stdout failures, 0 post failures == memcheck/tests/pointer-trace (stderr) *************** *** 15,17 **** none/tests/mremap2 (stdout) - none/tests/pth_cvsimple (stdout) --- 15,16 ---- |
|
From: <sv...@va...> - 2007-11-05 03:17:08
|
Author: sewardj
Date: 2007-11-05 03:17:07 +0000 (Mon, 05 Nov 2007)
New Revision: 7095
Log:
Update expected outputs for glibc25-x86.
Added:
branches/THRCHECK/thrcheck/tests/tc22_exit_w_lock.stderr.exp-glibc25-x86
branches/THRCHECK/thrcheck/tests/tc23_bogus_condwait.stderr.exp-glibc25-x86
Modified:
branches/THRCHECK/thrcheck/tests/Makefile.am
branches/THRCHECK/thrcheck/tests/tc20_verifywrap.stderr.exp-glibc25-x86
Modified: branches/THRCHECK/thrcheck/tests/Makefile.am
===================================================================
--- branches/THRCHECK/thrcheck/tests/Makefile.am 2007-11-05 03:00:05 UTC (rev 7094)
+++ branches/THRCHECK/thrcheck/tests/Makefile.am 2007-11-05 03:17:07 UTC (rev 7095)
@@ -78,8 +78,10 @@
tc21_pthonce.stderr.exp-glibc25-x86 \
tc22_exit_w_lock.vgtest tc22_exit_w_lock.stdout.exp \
tc22_exit_w_lock.stderr.exp-glibc25-amd64 \
+ tc22_exit_w_lock.stderr.exp-glibc25-x86 \
tc23_bogus_condwait.vgtest tc23_bogus_condwait.stdout.exp \
- tc23_bogus_condwait.stderr.exp-glibc25-amd64
+ tc23_bogus_condwait.stderr.exp-glibc25-amd64 \
+ tc23_bogus_condwait.stderr.exp-glibc25-x86
check_PROGRAMS = \
hg01_all_ok \
Modified: branches/THRCHECK/thrcheck/tests/tc20_verifywrap.stderr.exp-glibc25-x86
===================================================================
--- branches/THRCHECK/thrcheck/tests/tc20_verifywrap.stderr.exp-glibc25-x86 2007-11-05 03:00:05 UTC (rev 7094)
+++ branches/THRCHECK/thrcheck/tests/tc20_verifywrap.stderr.exp-glibc25-x86 2007-11-05 03:17:07 UTC (rev 7095)
@@ -68,12 +68,9 @@
---------------- pthread_cond_wait et al ----------------
-Thread #1 unlocked a not-locked lock at 0x........
+Thread #1: pthread_cond_{timed}wait called with un-held mutex
at 0x........: pthread_cond_wait@* (tc_intercepts.c:...)
by 0x........: main (tc20_verifywrap.c:147)
- Lock at 0x........ was first observed
- at 0x........: pthread_mutex_init (tc_intercepts.c:...)
- by 0x........: main (tc20_verifywrap.c:145)
Thread #1's call to pthread_cond_wait failed
with error code 1 (EPERM: Operation not permitted)
@@ -86,6 +83,10 @@
FIXME: can't figure out how to verify wrap of pthread_broadcast_signal
+Thread #1: pthread_cond_{timed}wait called with un-held mutex
+ at 0x........: pthread_cond_timedwait@* (tc_intercepts.c:...)
+ by 0x........: main (tc20_verifywrap.c:165)
+
Thread #1's call to pthread_cond_timedwait failed
with error code 22 (EINVAL: Invalid argument)
at 0x........: pthread_cond_timedwait@* (tc_intercepts.c:...)
@@ -146,15 +147,9 @@
Thread #1 deallocated location 0x........ containing a locked lock
- at 0x........: main (tc20_verifywrap.c:262)
+ at 0x........: main (tc20_verifywrap.c:261)
Lock at 0x........ was first observed
at 0x........: pthread_rwlock_init (tc_intercepts.c:...)
by 0x........: main (tc20_verifywrap.c:216)
-Thread #1 deallocated location 0x........ containing a locked lock
- at 0x........: main (tc20_verifywrap.c:262)
- Lock at 0x........ was first observed
- at 0x........: pthread_mutex_init (tc_intercepts.c:...)
- by 0x........: main (tc20_verifywrap.c:145)
-
ERROR SUMMARY: 20 errors from 20 contexts (suppressed: 0 from 0)
Added: branches/THRCHECK/thrcheck/tests/tc22_exit_w_lock.stderr.exp-glibc25-x86
===================================================================
--- branches/THRCHECK/thrcheck/tests/tc22_exit_w_lock.stderr.exp-glibc25-x86 (rev 0)
+++ branches/THRCHECK/thrcheck/tests/tc22_exit_w_lock.stderr.exp-glibc25-x86 2007-11-05 03:17:07 UTC (rev 7095)
@@ -0,0 +1,46 @@
+
+Thread #2 was created
+ at 0x........: clone (in /...libc...)
+ by 0x........: pthread_create@GLIBC_ (in /lib/libpthread...)
+ by 0x........: pthread_create@* (tc_intercepts.c:...)
+ by 0x........: main (tc22_exit_w_lock.c:39)
+
+Thread #2: Exiting thread still holds 2 locks
+ at 0x........: start_thread (in /lib/libpthread...)
+ by 0x........: ...
+
+Thread #1 is the program's root thread
+
+Possible data race during write of size 4 at 0x........
+ at 0x........: mempcpy (in /lib/ld-2.5.so)
+ by 0x........: pthread_create@GLIBC_ (in /lib/libpthread...)
+ by 0x........: pthread_create@* (tc_intercepts.c:...)
+ by 0x........: main (tc22_exit_w_lock.c:42)
+ Old state: owned exclusively by thread #2
+ New state: shared-modified by threads #1, #2
+ Reason: this thread, #1, holds no locks at all
+
+Possible data race during write of size 4 at 0x........
+ at 0x........: memset (in /lib/ld-2.5.so)
+ by 0x........: pthread_create@GLIBC_ (in /lib/libpthread...)
+ by 0x........: pthread_create@* (tc_intercepts.c:...)
+ by 0x........: main (tc22_exit_w_lock.c:42)
+ Old state: owned exclusively by thread #2
+ New state: shared-modified by threads #1, #2
+ Reason: this thread, #1, holds no locks at all
+
+Thread #3 was created
+ at 0x........: clone (in /...libc...)
+ by 0x........: pthread_create@GLIBC_ (in /lib/libpthread...)
+ by 0x........: pthread_create@* (tc_intercepts.c:...)
+ by 0x........: main (tc22_exit_w_lock.c:42)
+
+Thread #3: Exiting thread still holds 1 lock
+ at 0x........: start_thread (in /lib/libpthread...)
+ by 0x........: ...
+
+Thread #1: Exiting thread still holds 1 lock
+ at 0x........: kill (in /...libc...)
+ by 0x........: (below main) (in /...libc...)
+
+ERROR SUMMARY: 5 errors from 5 contexts (suppressed: 0 from 0)
Added: branches/THRCHECK/thrcheck/tests/tc23_bogus_condwait.stderr.exp-glibc25-x86
===================================================================
--- branches/THRCHECK/thrcheck/tests/tc23_bogus_condwait.stderr.exp-glibc25-x86 (rev 0)
+++ branches/THRCHECK/thrcheck/tests/tc23_bogus_condwait.stderr.exp-glibc25-x86 2007-11-05 03:17:07 UTC (rev 7095)
@@ -0,0 +1,30 @@
+
+Thread #1 is the program's root thread
+
+Thread #1: pthread_cond_{timed}wait called with invalid mutex
+ at 0x........: pthread_cond_wait@* (tc_intercepts.c:...)
+ by 0x........: main (tc23_bogus_condwait.c:62)
+
+Thread #1: pthread_cond_{timed}wait called with un-held mutex
+ at 0x........: pthread_cond_wait@* (tc_intercepts.c:...)
+ by 0x........: main (tc23_bogus_condwait.c:65)
+
+Thread #1: pthread_cond_{timed}wait called with mutex of type pthread_rwlock_t*
+ at 0x........: pthread_cond_wait@* (tc_intercepts.c:...)
+ by 0x........: main (tc23_bogus_condwait.c:68)
+
+Thread #3 was created
+ at 0x........: clone (in /...libc...)
+ by 0x........: pthread_create@GLIBC_ (in /lib/libpthread...)
+ by 0x........: pthread_create@* (tc_intercepts.c:...)
+ by 0x........: main (tc23_bogus_condwait.c:71)
+
+Thread #3: Exiting thread still holds 1 lock
+ at 0x........: start_thread (in /lib/libpthread...)
+ by 0x........: ...
+
+Thread #1: pthread_cond_{timed}wait called with mutex held by a different thread
+ at 0x........: pthread_cond_wait@* (tc_intercepts.c:...)
+ by 0x........: main (tc23_bogus_condwait.c:73)
+
+ERROR SUMMARY: 5 errors from 5 contexts (suppressed: 0 from 0)
|
|
From: Tom H. <th...@cy...> - 2007-11-05 03:11:03
|
Nightly build on gill ( x86_64, Fedora Core 2 ) started at 2007-11-05 03:00: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 == 322 tests, 6 stderr failures, 1 stdout failure, 0 post 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: <sv...@va...> - 2007-11-05 03:00:04
|
Author: sewardj
Date: 2007-11-05 03:00:05 +0000 (Mon, 05 Nov 2007)
New Revision: 7094
Log:
More expected-output wibbling. Sigh.
Modified:
branches/THRCHECK/thrcheck/tests/tc20_verifywrap.stderr.exp-glibc25-amd64
Modified: branches/THRCHECK/thrcheck/tests/tc20_verifywrap.stderr.exp-glibc25-amd64
===================================================================
--- branches/THRCHECK/thrcheck/tests/tc20_verifywrap.stderr.exp-glibc25-amd64 2007-11-05 02:46:08 UTC (rev 7093)
+++ branches/THRCHECK/thrcheck/tests/tc20_verifywrap.stderr.exp-glibc25-amd64 2007-11-05 03:00:05 UTC (rev 7094)
@@ -148,7 +148,7 @@
Thread #1 deallocated location 0x........ containing a locked lock
- at 0x........: main (tc20_verifywrap.c:263)
+ at 0x........: main (tc20_verifywrap.c:262)
Lock at 0x........ was first observed
at 0x........: pthread_rwlock_init (tc_intercepts.c:...)
by 0x........: main (tc20_verifywrap.c:216)
|
|
From: <sv...@va...> - 2007-11-05 02:46:07
|
Author: sewardj
Date: 2007-11-05 02:46:08 +0000 (Mon, 05 Nov 2007)
New Revision: 7093
Log:
More output changes and expected-output changes pertaining to mutex
checking for pthread_cond_wait.
Modified:
branches/THRCHECK/thrcheck/tc_main.c
branches/THRCHECK/thrcheck/tests/tc20_verifywrap.c
branches/THRCHECK/thrcheck/tests/tc20_verifywrap.stderr.exp-glibc25-amd64
branches/THRCHECK/thrcheck/tests/tc23_bogus_condwait.stderr.exp-glibc25-amd64
Modified: branches/THRCHECK/thrcheck/tc_main.c
===================================================================
--- branches/THRCHECK/thrcheck/tc_main.c 2007-11-05 02:26:31 UTC (rev 7092)
+++ branches/THRCHECK/thrcheck/tc_main.c 2007-11-05 02:46:08 UTC (rev 7093)
@@ -6058,25 +6058,25 @@
lk_valid = False;
record_error_Misc(
thr,
- "pthread_cond_wait called with invalid mutex" );
+ "pthread_cond_{timed}wait called with invalid mutex" );
} else {
tl_assert( is_sane_LockN(lk) );
if (lk->kind == LK_rdwr) {
lk_valid = False;
record_error_Misc(
- thr, "pthread_cond_wait called with mutex "
+ thr, "pthread_cond_{timed}wait called with mutex "
"of type pthread_rwlock_t*" );
} else
if (lk->heldBy == NULL) {
lk_valid = False;
record_error_Misc(
- thr, "pthread_cond_wait called with un-held mutex");
+ thr, "pthread_cond_{timed}wait called with un-held mutex");
} else
if (lk->heldBy != NULL
&& TC_(elemBag)( lk->heldBy, (Word)thr ) == 0) {
lk_valid = False;
record_error_Misc(
- thr, "pthread_cond_wait called with mutex "
+ thr, "pthread_cond_{timed}wait called with mutex "
"held by a different thread" );
}
}
Modified: branches/THRCHECK/thrcheck/tests/tc20_verifywrap.c
===================================================================
--- branches/THRCHECK/thrcheck/tests/tc20_verifywrap.c 2007-11-05 02:26:31 UTC (rev 7092)
+++ branches/THRCHECK/thrcheck/tests/tc20_verifywrap.c 2007-11-05 02:46:08 UTC (rev 7093)
@@ -255,7 +255,6 @@
/* At this point it should complain about deallocation
of memory containing locked locks:
- mx4
rwl3
*/
Modified: branches/THRCHECK/thrcheck/tests/tc20_verifywrap.stderr.exp-glibc25-amd64
===================================================================
--- branches/THRCHECK/thrcheck/tests/tc20_verifywrap.stderr.exp-glibc25-amd64 2007-11-05 02:26:31 UTC (rev 7092)
+++ branches/THRCHECK/thrcheck/tests/tc20_verifywrap.stderr.exp-glibc25-amd64 2007-11-05 02:46:08 UTC (rev 7093)
@@ -69,12 +69,9 @@
---------------- pthread_cond_wait et al ----------------
-Thread #1 unlocked a not-locked lock at 0x........
+Thread #1: pthread_cond_{timed}wait called with un-held mutex
at 0x........: pthread_cond_wait@* (tc_intercepts.c:...)
by 0x........: main (tc20_verifywrap.c:147)
- Lock at 0x........ was first observed
- at 0x........: pthread_mutex_init (tc_intercepts.c:...)
- by 0x........: main (tc20_verifywrap.c:145)
Thread #1's call to pthread_cond_wait failed
with error code 1 (EPERM: Operation not permitted)
@@ -87,6 +84,10 @@
FIXME: can't figure out how to verify wrap of pthread_broadcast_signal
+Thread #1: pthread_cond_{timed}wait called with un-held mutex
+ at 0x........: pthread_cond_timedwait@* (tc_intercepts.c:...)
+ by 0x........: main (tc20_verifywrap.c:165)
+
Thread #1's call to pthread_cond_timedwait failed
with error code 22 (EINVAL: Invalid argument)
at 0x........: pthread_cond_timedwait@* (tc_intercepts.c:...)
@@ -152,10 +153,4 @@
at 0x........: pthread_rwlock_init (tc_intercepts.c:...)
by 0x........: main (tc20_verifywrap.c:216)
-Thread #1 deallocated location 0x........ containing a locked lock
- at 0x........: main (tc20_verifywrap.c:263)
- Lock at 0x........ was first observed
- at 0x........: pthread_mutex_init (tc_intercepts.c:...)
- by 0x........: main (tc20_verifywrap.c:145)
-
ERROR SUMMARY: 20 errors from 20 contexts (suppressed: 0 from 0)
Modified: branches/THRCHECK/thrcheck/tests/tc23_bogus_condwait.stderr.exp-glibc25-amd64
===================================================================
--- branches/THRCHECK/thrcheck/tests/tc23_bogus_condwait.stderr.exp-glibc25-amd64 2007-11-05 02:26:31 UTC (rev 7092)
+++ branches/THRCHECK/thrcheck/tests/tc23_bogus_condwait.stderr.exp-glibc25-amd64 2007-11-05 02:46:08 UTC (rev 7093)
@@ -1,15 +1,15 @@
Thread #1 is the program's root thread
-Thread #1: pthread_cond_wait called with invalid mutex
+Thread #1: pthread_cond_{timed}wait called with invalid mutex
at 0x........: pthread_cond_wait@* (tc_intercepts.c:...)
by 0x........: main (tc23_bogus_condwait.c:62)
-Thread #1: pthread_cond_wait called with un-held mutex
+Thread #1: pthread_cond_{timed}wait called with un-held mutex
at 0x........: pthread_cond_wait@* (tc_intercepts.c:...)
by 0x........: main (tc23_bogus_condwait.c:65)
-Thread #1: pthread_cond_wait called with mutex of type pthread_rwlock_t*
+Thread #1: pthread_cond_{timed}wait called with mutex of type pthread_rwlock_t*
at 0x........: pthread_cond_wait@* (tc_intercepts.c:...)
by 0x........: main (tc23_bogus_condwait.c:68)
@@ -24,7 +24,7 @@
at 0x........: start_thread (in /lib/libpthread...)
by 0x........: ...
-Thread #1: pthread_cond_wait called with mutex held by a different thread
+Thread #1: pthread_cond_{timed}wait called with mutex held by a different thread
at 0x........: pthread_cond_wait@* (tc_intercepts.c:...)
by 0x........: main (tc23_bogus_condwait.c:73)
|
|
From: <sv...@va...> - 2007-11-05 02:26:29
|
Author: sewardj
Date: 2007-11-05 02:26:31 +0000 (Mon, 05 Nov 2007)
New Revision: 7092
Log:
Add a test for detection of passing bogus mutex values to
pthread_cond_wait.
Added:
branches/THRCHECK/thrcheck/tests/tc23_bogus_condwait.c
branches/THRCHECK/thrcheck/tests/tc23_bogus_condwait.stderr.exp-glibc25-amd64
branches/THRCHECK/thrcheck/tests/tc23_bogus_condwait.stdout.exp
branches/THRCHECK/thrcheck/tests/tc23_bogus_condwait.vgtest
Modified:
branches/THRCHECK/thrcheck/tests/Makefile.am
Modified: branches/THRCHECK/thrcheck/tests/Makefile.am
===================================================================
--- branches/THRCHECK/thrcheck/tests/Makefile.am 2007-11-05 02:11:57 UTC (rev 7091)
+++ branches/THRCHECK/thrcheck/tests/Makefile.am 2007-11-05 02:26:31 UTC (rev 7092)
@@ -77,7 +77,9 @@
tc21_pthonce.stderr.exp-glibc25-amd64 \
tc21_pthonce.stderr.exp-glibc25-x86 \
tc22_exit_w_lock.vgtest tc22_exit_w_lock.stdout.exp \
- tc22_exit_w_lock.stderr.exp-glibc25-amd64
+ tc22_exit_w_lock.stderr.exp-glibc25-amd64 \
+ tc23_bogus_condwait.vgtest tc23_bogus_condwait.stdout.exp \
+ tc23_bogus_condwait.stderr.exp-glibc25-amd64
check_PROGRAMS = \
hg01_all_ok \
@@ -107,7 +109,8 @@
tc19_shadowmem \
tc20_verifywrap \
tc21_pthonce \
- tc22_exit_w_lock
+ tc22_exit_w_lock \
+ tc23_bogus_condwait
AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/include \
-I$(top_srcdir)/coregrind -I$(top_builddir)/include \
Added: branches/THRCHECK/thrcheck/tests/tc23_bogus_condwait.c
===================================================================
--- branches/THRCHECK/thrcheck/tests/tc23_bogus_condwait.c (rev 0)
+++ branches/THRCHECK/thrcheck/tests/tc23_bogus_condwait.c 2007-11-05 02:26:31 UTC (rev 7092)
@@ -0,0 +1,78 @@
+
+/* Expect 5 errors total (4 re cvs, 1 re exiting w/lock.).
+ Tests passing bogus mutexes to pthread_cond_wait. */
+
+#include <pthread.h>
+#include <assert.h>
+#include <unistd.h>
+
+pthread_mutex_t mx[4];
+pthread_cond_t cv;
+pthread_rwlock_t rwl;
+
+void* rescue_me ( void* uu )
+{
+ /* wait for, and unblock, the first wait */
+ sleep(1);
+ pthread_cond_signal( &cv );
+
+ /* wait for, and unblock, the second wait */
+ sleep(1);
+ pthread_cond_signal( &cv );
+
+ /* wait for, and unblock, the third wait */
+ sleep(1);
+ pthread_cond_signal( &cv );
+
+ /* wait for grabber and main, then unblock the fourth wait */
+ sleep(1+1);
+ pthread_cond_signal( &cv );
+
+ return NULL;
+}
+
+void* grab_the_lock ( void* uu )
+{
+ int r= pthread_mutex_lock( &mx[2] ); assert(!r);
+ /* tc correctly complains that the thread is exiting whilst still
+ holding a lock. A bit tricky to fix - we just live with it. */
+ return NULL;
+}
+
+int main ( void )
+{
+ int r;
+ pthread_t my_rescuer, grabber;
+
+ r= pthread_mutex_init(&mx[0], NULL); assert(!r);
+ r= pthread_mutex_init(&mx[1], NULL); assert(!r);
+ r= pthread_mutex_init(&mx[2], NULL); assert(!r);
+ r= pthread_mutex_init(&mx[3], NULL); assert(!r);
+
+ r= pthread_cond_init(&cv, NULL); assert(!r);
+ r= pthread_rwlock_init(&rwl, NULL); assert(!r);
+
+ r= pthread_create( &my_rescuer, NULL, rescue_me, NULL );
+ assert(!r);
+
+ /* Do stupid things and hope that rescue_me gets us out of
+ trouble */
+
+ /* mx is bogus */
+ r= pthread_cond_wait(&cv, (pthread_mutex_t*)(1 + (char*)&mx[0]) );
+
+ /* mx is not locked */
+ r= pthread_cond_wait(&cv, &mx[0]);
+
+ /* wrong flavour of lock */
+ r= pthread_cond_wait(&cv, (pthread_mutex_t*)&rwl );
+
+ /* mx is held by someone else. */
+ r= pthread_create( &grabber, NULL, grab_the_lock, NULL ); assert(!r);
+ sleep(1); /* let the grabber get there first */
+ r= pthread_cond_wait(&cv, &mx[2] );
+
+ r= pthread_join( my_rescuer, NULL ); assert(!r);
+ r= pthread_join( grabber, NULL ); assert(!r);
+ return 0;
+}
Added: branches/THRCHECK/thrcheck/tests/tc23_bogus_condwait.stderr.exp-glibc25-amd64
===================================================================
--- branches/THRCHECK/thrcheck/tests/tc23_bogus_condwait.stderr.exp-glibc25-amd64 (rev 0)
+++ branches/THRCHECK/thrcheck/tests/tc23_bogus_condwait.stderr.exp-glibc25-amd64 2007-11-05 02:26:31 UTC (rev 7092)
@@ -0,0 +1,31 @@
+
+Thread #1 is the program's root thread
+
+Thread #1: pthread_cond_wait called with invalid mutex
+ at 0x........: pthread_cond_wait@* (tc_intercepts.c:...)
+ by 0x........: main (tc23_bogus_condwait.c:62)
+
+Thread #1: pthread_cond_wait called with un-held mutex
+ at 0x........: pthread_cond_wait@* (tc_intercepts.c:...)
+ by 0x........: main (tc23_bogus_condwait.c:65)
+
+Thread #1: pthread_cond_wait called with mutex of type pthread_rwlock_t*
+ at 0x........: pthread_cond_wait@* (tc_intercepts.c:...)
+ by 0x........: main (tc23_bogus_condwait.c:68)
+
+Thread #3 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 (tc23_bogus_condwait.c:71)
+
+Thread #3: Exiting thread still holds 1 lock
+ at 0x........: start_thread (in /lib/libpthread...)
+ by 0x........: ...
+
+Thread #1: pthread_cond_wait called with mutex held by a different thread
+ at 0x........: pthread_cond_wait@* (tc_intercepts.c:...)
+ by 0x........: main (tc23_bogus_condwait.c:73)
+
+ERROR SUMMARY: 5 errors from 5 contexts (suppressed: 0 from 0)
Added: branches/THRCHECK/thrcheck/tests/tc23_bogus_condwait.stdout.exp
===================================================================
Added: branches/THRCHECK/thrcheck/tests/tc23_bogus_condwait.vgtest
===================================================================
--- branches/THRCHECK/thrcheck/tests/tc23_bogus_condwait.vgtest (rev 0)
+++ branches/THRCHECK/thrcheck/tests/tc23_bogus_condwait.vgtest 2007-11-05 02:26:31 UTC (rev 7092)
@@ -0,0 +1 @@
+prog: tc23_bogus_condwait
|
|
From: Julian S. <js...@ac...> - 2007-11-05 02:24:05
|
> The last line is the problem, it shouldn't look like that. I'm using the > address 0 specially to refer to all the allocation functions. Could > VG_(get_StackTrace)() be returning 0 as an address at the bottom of the > stack trace? Well, it's plausible. The PowerPC ELF ABI specification says that "The back chain word of the first stack frame contains a null pointer (0)." So whether a zero back chain word can somehow give rise to a zero return address, I dunno. Maybe. (abi_elf_ppc64_1.7.pdf page 29). Presumably the ppc32 ELF ABI is similar, at least in this aspect. > If so, I'll have to find a different way to encode the > allocation functions... maybe "(Addr)(-1L)". Is it possible/easy to encode them some way that doesn't involve any magic Addr values? J |
|
From: Nicholas N. <nj...@cs...> - 2007-11-05 02:15:34
|
On Sun, 4 Nov 2007, Julian Seward wrote:
>> But the result for deep-D looks strange. Can you send me the massif.out
>> file for it? Thanks.
>
> Attached.
This snapshot is strange:
#-----------
snapshot=9
#-----------
time=972
mem_heap_B=900
mem_heap_admin_B=72
mem_stacks_B=0
heap_tree=detailed
n1: 900 (heap allocation functions) malloc/new/new[], --alloc-fns, etc.
n1: 900 0xFE6737B: (within /lib/libc-2.6.1.so)
n1: 900 0xFE6759F: (below main) (in /lib/libc-2.6.1.so)
n0: 900 (heap allocation functions) malloc/new/new[], --alloc-fns, etc.
The last line is the problem, it shouldn't look like that. I'm using the
address 0 specially to refer to all the allocation functions. Could
VG_(get_StackTrace)() be returning 0 as an address at the bottom of the
stack trace? If so, I'll have to find a different way to encode the
allocation functions... maybe "(Addr)(-1L)".
Nick
|
|
From: <sv...@va...> - 2007-11-05 02:11:58
|
Author: sewardj
Date: 2007-11-05 02:11:57 +0000 (Mon, 05 Nov 2007)
New Revision: 7091
Log:
Add machinery to check for bogus mutex arguments to pthread_cond_wait,
since the documentation claims that functionality is provided :-)
Modified:
branches/THRCHECK/thrcheck/tc_intercepts.c
branches/THRCHECK/thrcheck/tc_main.c
Modified: branches/THRCHECK/thrcheck/tc_intercepts.c
===================================================================
--- branches/THRCHECK/thrcheck/tc_intercepts.c 2007-11-05 02:10:33 UTC (rev 7090)
+++ branches/THRCHECK/thrcheck/tc_intercepts.c 2007-11-05 02:11:57 UTC (rev 7091)
@@ -86,6 +86,19 @@
_arg1,_arg2,0,0,0); \
} while (0)
+#define DO_CREQ_W_WW(_resF, _creqF, _ty1F,_arg1F, _ty2F,_arg2F) \
+ do { \
+ Word _res, _arg1, _arg2; \
+ assert(sizeof(_ty1F) == sizeof(Word)); \
+ assert(sizeof(_ty2F) == sizeof(Word)); \
+ _arg1 = (Word)(_arg1F); \
+ _arg2 = (Word)(_arg2F); \
+ VALGRIND_DO_CLIENT_REQUEST(_res, 2, \
+ (_creqF), \
+ _arg1,_arg2,0,0,0); \
+ _resF = _res; \
+ } while (0)
+
#define DO_CREQ_v_WWW(_creqF, _ty1F,_arg1F, \
_ty2F,_arg2F, _ty3F, _arg3F) \
do { \
@@ -525,6 +538,8 @@
{
int ret;
OrigFn fn;
+ unsigned long mutex_is_valid;
+
VALGRIND_GET_ORIG_FN(fn);
if (TRACE_PTH_FNS) {
@@ -532,26 +547,39 @@
fflush(stderr);
}
+ /* Tell the tool a cond-wait is about to happen, so it can check
+ for bogus argument values. In return it tells us whether it
+ thinks the mutex is valid or not. */
+ DO_CREQ_W_WW(mutex_is_valid,
+ _VG_USERREQ__TC_PTHREAD_COND_WAIT_PRE,
+ pthread_cond_t*,cond, pthread_mutex_t*,mutex);
+ assert(mutex_is_valid == 1 || mutex_is_valid == 0);
+
/* Tell the tool we're about to drop the mutex. This reflects the
fact that in a cond_wait, we show up holding the mutex, and the
call atomically drops the mutex and waits for the cv to be
signalled. */
- DO_CREQ_v_W(_VG_USERREQ__TC_PTHREAD_MUTEX_UNLOCK_PRE,
- pthread_mutex_t*,mutex);
+ if (mutex_is_valid) {
+ DO_CREQ_v_W(_VG_USERREQ__TC_PTHREAD_MUTEX_UNLOCK_PRE,
+ pthread_mutex_t*,mutex);
+ }
CALL_FN_W_WW(ret, fn, cond,mutex);
- /* And now we have the mutex again, regardless of the error code
- returned. */
- // FIXME: but only if we actually had it before the call
- DO_CREQ_v_W(_VG_USERREQ__TC_PTHREAD_MUTEX_LOCK_POST,
- pthread_mutex_t*,mutex);
+ /* these conditionals look stupid, but compare w/ same logic for
+ pthread_cond_timedwait below */
+ if (ret == 0 && mutex_is_valid) {
+ /* and now we have the mutex again */
+ DO_CREQ_v_W(_VG_USERREQ__TC_PTHREAD_MUTEX_LOCK_POST,
+ pthread_mutex_t*,mutex);
+ }
- if (ret == 0) {
+ if (ret == 0 && mutex_is_valid) {
DO_CREQ_v_WW(_VG_USERREQ__TC_PTHREAD_COND_WAIT_POST,
pthread_cond_t*,cond, pthread_mutex_t*,mutex);
+ }
- } else {
+ if (ret != 0) {
DO_PthAPIerror( "pthread_cond_wait", ret );
}
@@ -570,6 +598,7 @@
{
int ret;
OrigFn fn;
+ unsigned long mutex_is_valid;
VALGRIND_GET_ORIG_FN(fn);
if (TRACE_PTH_FNS) {
@@ -578,29 +607,38 @@
fflush(stderr);
}
+ /* Tell the tool a cond-wait is about to happen, so it can check
+ for bogus argument values. In return it tells us whether it
+ thinks the mutex is valid or not. */
+ DO_CREQ_W_WW(mutex_is_valid,
+ _VG_USERREQ__TC_PTHREAD_COND_WAIT_PRE,
+ pthread_cond_t*,cond, pthread_mutex_t*,mutex);
+ assert(mutex_is_valid == 1 || mutex_is_valid == 0);
+
/* Tell the tool we're about to drop the mutex. This reflects the
fact that in a cond_wait, we show up holding the mutex, and the
call atomically drops the mutex and waits for the cv to be
signalled. */
- DO_CREQ_v_W(_VG_USERREQ__TC_PTHREAD_MUTEX_UNLOCK_PRE,
- pthread_mutex_t*,mutex);
+ if (mutex_is_valid) {
+ DO_CREQ_v_W(_VG_USERREQ__TC_PTHREAD_MUTEX_UNLOCK_PRE,
+ pthread_mutex_t*,mutex);
+ }
CALL_FN_W_WWW(ret, fn, cond,mutex,abstime);
- /* And now we have the mutex again, regardless of the error code
- returned. In particular we still have it even if
- ret==ETIMEDOUT. */
- // FIXME: but only if we actually had it before the call
- DO_CREQ_v_W(_VG_USERREQ__TC_PTHREAD_MUTEX_LOCK_POST,
- pthread_mutex_t*,mutex);
+ if ((ret == 0 || ret == ETIMEDOUT) && mutex_is_valid) {
+ /* and now we have the mutex again */
+ DO_CREQ_v_W(_VG_USERREQ__TC_PTHREAD_MUTEX_LOCK_POST,
+ pthread_mutex_t*,mutex);
+ }
- if (ret == 0) {
+ if (ret == 0 && mutex_is_valid) {
DO_CREQ_v_WW(_VG_USERREQ__TC_PTHREAD_COND_WAIT_POST,
pthread_cond_t*,cond, pthread_mutex_t*,mutex);
+ }
- } else {
- if (ret != ETIMEDOUT)
- DO_PthAPIerror( "pthread_cond_timedwait", ret );
+ if (ret != 0 && ret != ETIMEDOUT) {
+ DO_PthAPIerror( "pthread_cond_timedwait", ret );
}
if (TRACE_PTH_FNS) {
Modified: branches/THRCHECK/thrcheck/tc_main.c
===================================================================
--- branches/THRCHECK/thrcheck/tc_main.c 2007-11-05 02:10:33 UTC (rev 7090)
+++ branches/THRCHECK/thrcheck/tc_main.c 2007-11-05 02:11:57 UTC (rev 7091)
@@ -5918,7 +5918,7 @@
&& TC_(elemBag)( lk->heldBy, (Word)thr ) > 0 ) {
/* uh, it's a non-recursive lock and we already w-hold it, and
this is a real lock operation (not a speculative "tryLock"
- kind of thing. Duh. Deadlock coming up; but at least
+ kind of thing). Duh. Deadlock coming up; but at least
produce an error message. */
record_error_Misc( thr, "Attempt to re-lock a "
"non-recursive lock I already hold" );
@@ -6031,10 +6031,15 @@
}
}
-static void evh__TC_PTHREAD_COND_WAIT_PRE ( ThreadId tid,
+/* returns True if it reckons 'mutex' is valid and held by this
+ thread, else False */
+static Bool evh__TC_PTHREAD_COND_WAIT_PRE ( ThreadId tid,
void* cond, void* mutex )
{
Thread* thr;
+ Lock* lk;
+ Bool lk_valid = True;
+
if (SHOW_EVENTS >= 1)
VG_(printf)("evh__tc_PTHREAD_COND_WAIT_PRE"
"(ctid=%d, cond=%p, mutex=%p)\n",
@@ -6044,7 +6049,41 @@
thr = map_threads_maybe_lookup( tid );
tl_assert(thr); /* cannot fail - Thread* must already exist */
+ lk = map_locks_maybe_lookup( (Addr)mutex );
+
+ /* Check for stupid mutex arguments. There are various ways to be
+ a bozo. Only complain once, though, even if more than one thing
+ is wrong. */
+ if (lk == NULL) {
+ lk_valid = False;
+ record_error_Misc(
+ thr,
+ "pthread_cond_wait called with invalid mutex" );
+ } else {
+ tl_assert( is_sane_LockN(lk) );
+ if (lk->kind == LK_rdwr) {
+ lk_valid = False;
+ record_error_Misc(
+ thr, "pthread_cond_wait called with mutex "
+ "of type pthread_rwlock_t*" );
+ } else
+ if (lk->heldBy == NULL) {
+ lk_valid = False;
+ record_error_Misc(
+ thr, "pthread_cond_wait called with un-held mutex");
+ } else
+ if (lk->heldBy != NULL
+ && TC_(elemBag)( lk->heldBy, (Word)thr ) == 0) {
+ lk_valid = False;
+ record_error_Misc(
+ thr, "pthread_cond_wait called with mutex "
+ "held by a different thread" );
+ }
+ }
+
// error-if: cond is also associated with a different mutex
+
+ return lk_valid;
}
static void evh__TC_PTHREAD_COND_WAIT_POST ( ThreadId tid,
@@ -7477,17 +7516,22 @@
evh__TC_PTHREAD_COND_SIGNAL_PRE( tid, (void*)args[1] );
break;
- /* Entry into pthread_cond_wait, cond=arg[1], mutex=arg[2] */
- case _VG_USERREQ__TC_PTHREAD_COND_WAIT_PRE:
- evh__TC_PTHREAD_COND_WAIT_PRE( tid,
- (void*)args[1], (void*)args[2] );
+ /* Entry into pthread_cond_wait, cond=arg[1], mutex=arg[2].
+ Returns a flag indicating whether or not the mutex is believed to be
+ valid for this operation. */
+ case _VG_USERREQ__TC_PTHREAD_COND_WAIT_PRE: {
+ Bool mutex_is_valid
+ = evh__TC_PTHREAD_COND_WAIT_PRE( tid, (void*)args[1],
+ (void*)args[2] );
+ *ret = mutex_is_valid ? 1 : 0;
break;
+ }
/* Thread successfully completed pthread_cond_wait, cond=arg[1],
mutex=arg[2] */
case _VG_USERREQ__TC_PTHREAD_COND_WAIT_POST:
evh__TC_PTHREAD_COND_WAIT_POST( tid,
- (void*)args[1], (void*)args[2] );
+ (void*)args[1], (void*)args[2] );
break;
case _VG_USERREQ__TC_PTHREAD_RWLOCK_INIT_POST:
@@ -8371,7 +8415,7 @@
clo_happens_before = 0;
else if (VG_CLO_STREQ(arg, "--happens-before=threads"))
clo_happens_before = 1;
- else if (VG_CLO_STREQ(arg, "--happens-before=condvars"))
+ else if (VG_CLO_STREQ(arg, "--happens-before=all"))
clo_happens_before = 2;
else if (VG_CLO_STREQ(arg, "--gen-vcg=no"))
@@ -8424,8 +8468,8 @@
static void tc_print_usage ( void )
{
VG_(printf)(
-" --happens-before=none|threads|condvars [condvars] consider no events,\n"
-" thread create/join, thread create/join/cvsignal/cvwait as sync points\n"
+" --happens-before=none|threads|all [all] consider no events, thread\n"
+" create/join, create/join/cvsignal/cvwait/semwait/post 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"
);
|
|
From: <sv...@va...> - 2007-11-05 02:10:32
|
Author: sewardj
Date: 2007-11-05 02:10:33 +0000 (Mon, 05 Nov 2007)
New Revision: 7090
Log:
Last minute mods the the manual.
Modified:
branches/THRCHECK/thrcheck/docs/tc-manual.xml
Modified: branches/THRCHECK/thrcheck/docs/tc-manual.xml
===================================================================
--- branches/THRCHECK/thrcheck/docs/tc-manual.xml 2007-11-05 00:25:53 UTC (rev 7089)
+++ branches/THRCHECK/thrcheck/docs/tc-manual.xml 2007-11-05 02:10:33 UTC (rev 7090)
@@ -327,7 +327,7 @@
</itemizedlist>
<para>Understanding the memory state machine is central to
-understanding Thrcheck's race-detection algorithm. The next two
+understanding Thrcheck's race-detection algorithm. The next three
subsections explain this.</para>
</sect2>
@@ -1227,6 +1227,14 @@
and <computeroutput>http://lkml.org/lkml/2007/10/24/673</computeroutput>.
</para>
</listitem>
+ <listitem><para>Don't update the lock-order graph, and don't check
+ for errors, when a "try"-style lock operation happens (eg
+ pthread_mutex_trylock). Such calls do not add any real
+ restrictions to the locking order, since they can always fail to
+ acquire the lock, resulting in the caller going off and doing Plan
+ B (presumably it will have a Plan B). Doing such checks could
+ generate false lock-order errors and confuse users.</para>
+ </listitem>
</itemizedlist>
|
|
From: <js...@ac...> - 2007-11-05 01:17:08
|
Nightly build on g5 ( SuSE 10.1, ppc970 ) started at 2007-11-05 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 == 255 tests, 11 stderr failures, 2 stdout failures, 0 post failures == memcheck/tests/deep_templates (stdout) memcheck/tests/leak-cycle (stderr) memcheck/tests/leak-tree (stderr) memcheck/tests/pointer-trace (stderr) massif/tests/culling1 (stderr) massif/tests/culling2 (stderr) massif/tests/deep-C (stderr) massif/tests/peak2 (stderr) massif/tests/realloc (stderr) none/tests/faultstatus (stderr) none/tests/fdleak_cmsg (stderr) none/tests/mremap (stderr) none/tests/mremap2 (stdout) |
|
From: <sv...@va...> - 2007-11-05 00:25:52
|
Author: sewardj
Date: 2007-11-05 00:25:53 +0000 (Mon, 05 Nov 2007)
New Revision: 7089
Log:
Finish first version of the manual. Gaaaah!
Modified:
branches/THRCHECK/thrcheck/docs/tc-manual.xml
Modified: branches/THRCHECK/thrcheck/docs/tc-manual.xml
===================================================================
--- branches/THRCHECK/thrcheck/docs/tc-manual.xml 2007-11-04 17:11:19 UTC (rev 7088)
+++ branches/THRCHECK/thrcheck/docs/tc-manual.xml 2007-11-05 00:25:53 UTC (rev 7089)
@@ -38,26 +38,35 @@
<orderedlist>
<listitem>
- <para>Section FIXME: Misuses of the POSIX pthreads API.</para>
+ <para><link linkend="tc-manual.api-checks">
+ Misuses of the POSIX pthreads API.</link></para>
</listitem>
<listitem>
- <para>Section FIXME: Potential deadlocks arising from lock ordering
- problems.</para>
+ <para><link linkend="tc-manual.lock-orders">
+ Potential deadlocks arising from lock
+ ordering problems.</link></para>
</listitem>
<listitem>
- <para>Section FIXME: Data races -- accessing memory without adequate
- locking.</para>
+ <para><link linkend="tc-manual.data-races">
+ Data races -- accessing memory without adequate locking.
+ </link></para>
</listitem>
</orderedlist>
-<para>Section FIXME contains guidance on how to get the best out of Thrcheck.
-This is really a discussion about debugging strategies and how to
-organise your program to enhance its verifiability.</para>
+<para>Following those is a section containing
+<link linkend="tc-manual.effective-use">
+hints and tips on how to get the best out of Thrcheck.</link>
+</para>
-<para>Section FIXME contains a summary of command-line options.</para>
+<para>Then there is a
+<link linkend="tc-manual.options">summary of command-line
+options.</link>
+</para>
-<para>Finally, Section FIXME contains a brief list of areas in which Thrcheck
-could be improved.</para>
+<para>Finally, there is
+<link linkend="tc-manual.todolist">a brief summary of areas in which Thrcheck
+could be improved.</link>
+</para>
</sect1>
@@ -71,7 +80,7 @@
is therefore able to report on various common problems. Although
these are unglamourous errors, their presence can lead to undefined
program behaviour and hard-to-find bugs later in execution. The
-detected errors include:</para>
+detected errors are:</para>
<itemizedlist>
<listitem><para>unlocking an invalid mutex</para></listitem>
@@ -87,11 +96,20 @@
versa</para></listitem>
<listitem><para>when a POSIX pthread function fails with an
error code that must be handled</para></listitem>
+ <listitem><para>when a thread exits whilst still holding locked
+ locks</para></listitem>
+ <listitem><para>calling <computeroutput>pthread_cond_wait</computeroutput>
+ with a not-locked mutex, or one locked by a different
+ thread</para></listitem>
</itemizedlist>
<para>Checks pertaining to the validity of mutexes are generally also
performed for reader-writer locks.</para>
+<para>Various kinds of this-can't-possibly-happen events are also
+reported. These usually indicate bugs in the system threading
+library.</para>
+
<para>Reported errors always contain a primary stack trace indicating
where the error was detected. They may also contain auxiliary stack
traces giving additional information. In particular, most errors
@@ -114,8 +132,9 @@
<para>Thrcheck has a way of summarising thread identities, as
evidenced here by the text "<computeroutput>Thread
#1</computeroutput>". This is so that it can speak about threads and
-sets of threads without overwhelming you with details. See FIXME
-below for details.</para>
+sets of threads without overwhelming you with details. See
+<link linkend="tc-manual.data-races.errmsgs">below</link>
+for more information on interpreting error messages.</para>
</sect1>
@@ -219,7 +238,7 @@
<sect2 id="tc-manual.data-races.example" xreflabel="Simple Race">
-<title>A simple data race</title>
+<title>A Simple Data Race</title>
<para>About the simplest possible example of a race is as follows. In
this program, it is impossible to know what the value
@@ -371,13 +390,20 @@
attempts to write to it, a race is then reported.</para>
<para>This technique is known as "lockset inference" and was
-introduced in FIXME. It has been widely implemented since then.
-Thrcheck incorporates several refinements aimed at reducing the false
-error rate generated by a naive version of the algorithm. In section
-FIXME a summary of the complete algorithm used by Thrcheck is
-presented. First, however, it is important to understand details of
-transitions pertaining to the Exclusive-ownership state.</para>
+introduced in: "Eraser: A Dynamic Data Race Detector for Multithreaded
+Programs" (Stefan Savage, Michael Burrows, Greg Nelson, Patrick
+Sobalvarro and Thomas Anderson, ACM Transactions on Computer Systems,
+15(4):391-411, November 1997).</para>
+<para>Lockset inference has since been widely implemented, studied and
+extended. Thrcheck incorporates several refinements aimed at avoiding
+the high false error rate that naive versions of the algorithm suffer
+from. A
+<link linkend="tc-manual.data-races.summary">summary of the complete
+algorithm used by Thrcheck</link> is presented below. First, however,
+it is important to understand details of transitions pertaining to the
+Exclusive-ownership state.</para>
+
</sect2>
@@ -449,10 +475,13 @@
pthread_create and pthread_join calls, an error is still
reported.</para>
-<para>This technique was introduced in FIXME with the name Thread
-Lifetime Segments. Thrcheck implements an extended version of it.
-Specifically, Thrcheck allows transfer of exclusive ownership in the
-following situations:</para>
+<para>This technique was introduced with the name "thread lifetime
+segments" in "Runtime Checking of Multithreaded Applications with
+Visual Threads" (Jerry J. Harrow, Jr, Proceedings of the 7th
+International SPIN Workshop on Model Checking of Software Stanford,
+California, USA, August 2000, LNCS 1885, pp331--342). Thrcheck
+implements an extended version of it. Specifically, Thrcheck allows
+transfer of exclusive ownership in the following situations:</para>
<itemizedlist>
<listitem><para>At thread creation: a child can acquire ownership of
@@ -464,16 +493,16 @@
(thread that is exiting) at the point it exited.</para>
</listitem>
<listitem><para>At condition variable signallings and broadcasts. A
- thread Twait which completes a pthread_cond_wait call as a result of
+ thread Tw which completes a pthread_cond_wait call as a result of
a signal or broadcast on the same condition variable by some other
- thread Tsig, may acquire ownership of memory held exclusively by
- Tsig prior to the pthread_cond_signal/broadcast
+ thread Ts, may acquire ownership of memory held exclusively by
+ Ts prior to the pthread_cond_signal/broadcast
call.</para>
</listitem>
- <listitem><para>At semaphore posts (sem_post) calls. A thread Twait
+ <listitem><para>At semaphore posts (sem_post) calls. A thread Tw
which completes a sem_wait call call as a result of a sem_post call
- on the same semaphore by some other thread Tpost, may acquire
- ownership of memory held exclusively by Tpost prior to the sem_post
+ on the same semaphore by some other thread Tp, may acquire
+ ownership of memory held exclusively by Tp prior to the sem_post
call.</para>
</listitem>
</itemizedlist>
@@ -809,8 +838,9 @@
<para>Also, this message implies that Thrcheck did not see any
synchronisation event between threads #4 and #5 that would have
-allowed #5 to acquire exclusive ownership from #4. See FIXME for a
-discussion of transfers of exclusive ownership states between
+allowed #5 to acquire exclusive ownership from #4. See
+<link linkend="tc-manual.data-races.exclusive">above</link>
+for a discussion of transfers of exclusive ownership states between
threads.</para>
</sect2>
@@ -936,9 +966,10 @@
<para>The root cause of this synchronisation lossage is
particularly hard to understand, so an example is helpful. It was
- discussed at length by Arndt Muehlenfeldt [FIXME]. The canonical
- POSIX-recommended usage scheme for condition variables is as
- follows:</para>
+ discussed at length by Arndt Muehlenfeld ("Runtime Race Detection
+ in Multi-Threaded Programs", Dissertation, TU Graz, Austria). The
+ canonical POSIX-recommended usage scheme for condition variables
+ is as follows:</para>
<programlisting><![CDATA[
b is a Boolean condition, which is False most of the time
@@ -981,9 +1012,9 @@
<listitem>
<para>Make sure you are using a supported Linux distribution. At
present, Thrcheck only properly supports x86-linux and amd64-linux
- with glibc-2.3 or later. The latter restriction really says that
- we only support the NPTL threading library. The old LinuxThreads
- library is not supported.</para>
+ with glibc-2.3 or later. The latter restriction means we only
+ support the NPTL threading library. The old LinuxThreads library
+ is not supported.</para>
<para>Unsupported targets may work to varying degrees. In
particular ppc32-linux and ppc64-linux running NTPL should work,
@@ -992,6 +1023,19 @@
the lwarx/stwcx instructions.</para>
</listitem>
+ <listitem>
+ <para>POSIX requires that implementations of standard I/O (printf,
+ fprintf, fwrite, fread, etc) are thread safe. Unfortunately GNU
+ libc implements this by using internal locking primitives that
+ Thrcheck is unable to intercept. Consequently Thrcheck generates
+ many false race reports when you use these functions.</para>
+
+ <para>Thrcheck attempts to hide these errors using the standard
+ Valgrind error-suppression mechanism. So, at least for simple
+ test cases, you don't see any. Nevertheless, some may slip
+ through. Just something to be aware of.</para>
+ </listitem>
+
</orderedlist>
</sect1>
@@ -1002,48 +1046,39 @@
<sect1 id="tc-manual.options" xreflabel="Thrcheck Options">
<title>Thrcheck Options</title>
-<para>Currently there is only one Thrcheck-specific option:</para>
+<para>The following end-user options are available:</para>
<!-- start of xi:include in the manpage -->
<variablelist id="tc.opts.list">
<varlistentry id="opt.happens-before" xreflabel="--happens-before">
<term>
- <option><![CDATA[--happens-before=none|threads|condvars
- [default: condvars] ]]></option>
+ <option><![CDATA[--happens-before=none|threads|all
+ [default: all] ]]></option>
</term>
<listitem>
- <para>This option is mostly useful for debugging Thrcheck
- itself. It isn't much use to end users and is a bit difficult
- to explain.
- </para>
<para>Thrcheck always regards locks as the basis for
inter-thread synchronisation. However, by default, before
reporting a race error, Thrcheck will also check whether
certain other kinds of inter-thread synchronisation events
happened. It may be that if such events took place, then no
race really occurred, and so no error needs to be reported.
- This enables Thrcheck to correctly handle the
- worker-thread and worker-thread-pool idioms.
+ See <link linkend="tc-manual.data-races.exclusive">above</link>
+ for a discussion of transfers of exclusive ownership states
+ between threads.
</para>
- <para>With <varname>--happens-before=condvars</varname>, both
- thread creation/joinage, and condition variable
- signal/broadcast/waits are regarded as sources of
- synchronisation, and so both the worker-thread and
- worker-thread-pool idioms are correctly handled. "Correctly
- handled" means that Thrcheck will not falsely report race
- errors for correct uses of these idioms.
+ <para>With <varname>--happens-before=all</varname>, the
+ following events are regarded as sources of synchronisation:
+ thread creation/joinage, condition variable
+ signal/broadcast/waits, and semaphore posts/waits.
</para>
<para>With <varname>--happens-before=threads</varname>, only
thread creation/joinage events are regarded as sources of
- synchronisation, and so only the worker-thread idiom is
- correctly handled. The worker-thread-pool is not correctly
- handled.
+ synchronisation.
</para>
<para>With <varname>--happens-before=none</varname>, no events
(apart, of course, from locking) are regarded as sources of
- synchronisation. And so neither the worker-thread nor
- worker-thread-pool idioms are correctly handled.
+ synchronisation.
</para>
<para>Changing this setting from the default will increase your
false-error rate but give little or no gain. The only advantage
@@ -1055,34 +1090,146 @@
</listitem>
</varlistentry>
+ <varlistentry id="opt.trace-addr" xreflabel="--trace-addr">
+ <term>
+ <option><![CDATA[--trace-addr=0xXXYYZZ
+ ]]></option> and
+ <option><![CDATA[--trace-level=0|1|2 [default: 1]
+ ]]></option>
+ </term>
+ <listitem>
+ <para>Requests that Thrcheck produces a log of all state changes
+ to location 0xXXYYZZ. This can be helpful in tracking down
+ tricky races. <varname>--trace-level</varname> controls the
+ verbosity of the log. At the default setting (1), a one-line
+ summary of is printed for each state change. At level 2 a
+ complete stack trace is printed for each state change.</para>
+ </listitem>
+ </varlistentry>
+
</variablelist>
<!-- end of xi:include in the manpage -->
-</sect1>
+<!-- start of xi:include in the manpage -->
+<para>In addition, the following debugging options are available for
+Thrcheck:</para>
+<variablelist id="tc.debugopts.list">
-<sect1 id="tc-manual.otherstuff" xreflabel="Other Stuff">
-<title>Other Stuff</title>
+ <varlistentry id="opt.trace-malloc" xreflabel="--trace-malloc">
+ <term>
+ <option><![CDATA[--trace-malloc=no|yes [no]
+ ]]></option>
+ </term>
+ <listitem>
+ <para>Show all client malloc (etc) and free (etc) requests.</para>
+ </listitem>
+ </varlistentry>
-<para>FIXME: this section will contain other stuff that it is
-important to document:</para>
+ <varlistentry id="opt.gen-vcg" xreflabel="--gen-vcg">
+ <term>
+ <option><![CDATA[--gen-vcg=no|yes|yes-w-vts [no]
+ ]]></option>
+ </term>
+ <listitem>
+ <para>At exit, write to stderr a dump of the happens-before
+ graph computed by Thrcheck, in a format suitable for the VCG
+ graph visualisation tool. A suitable command line is:</para>
+ <para><computeroutput>valgrind --tool=thrcheck
+ --gen-vcg=yes my_app 2>&1
+ | grep xxxxxx | sed "s/xxxxxx//g"
+ | xvcg -</computeroutput></para>
+ <para>With <varname>--gen-vcg=yes</varname>, the basic
+ happens-before graph is shown. With
+ <varname>--gen-vcg=yes-w-vts</varname>, the vector timestamp
+ for each node is also shown.</para>
+ </listitem>
+ </varlistentry>
-<itemizedlist>
- <listitem><para>LOCK prefixes on x86/amd64
- instructions</para></listitem>
- <listitem><para>Reader-writer locks, and semaphores?
- </para></listitem>
- <listitem><para>Other stuff I forgot?
- </para></listitem>
-</itemizedlist>
+ <varlistentry id="opt.cmp-race-err-addrs"
+ xreflabel="--cmp-race-err-addrs">
+ <term>
+ <option><![CDATA[--cmp-race-err-addrs=no|yes [no]
+ ]]></option>
+ </term>
+ <listitem>
+ <para>Controls whether or not race (data) addresses should be
+ taken into account when removing duplicates of race errors.
+ With <varname>--cmp-race-err-addrs=no</varname>, two otherwise
+ identical race errors will be considered to be the same if
+ their race addresses differ. With
+ With <varname>--cmp-race-err-addrs=yes</varname> they will be
+ considered different. This is provided to help make certain
+ regression tests work reliably.</para>
+ </listitem>
+ </varlistentry>
-Inconsistent cv/mx associations
-Thread exiting whilst holding locks
+ <varlistentry id="opt.tc-sanity-flags" xreflabel="--tc-sanity-flags">
+ <term>
+ <option><![CDATA[--tc-sanity-flags=<XXXXX> (X = 0|1) [00000]
+ ]]></option>
+ </term>
+ <listitem>
+ <para>Run extensive sanity checks on Thrcheck's internal
+ data structures at events defined by the bitstring, as
+ follows:</para>
+ <para><computeroutput>10000 </computeroutput>after changes to
+ the lock order acquisition graph</para>
+ <para><computeroutput>01000 </computeroutput>after every client
+ memory access (NB: not currently used)</para>
+ <para><computeroutput>00100 </computeroutput>after every client
+ memory range permission setting of 256 bytes or greater</para>
+ <para><computeroutput>00010 </computeroutput>after every client
+ lock or unlock event</para>
+ <para><computeroutput>00001 </computeroutput>after every client
+ thread creation or joinage event</para>
+ <para>Note these will make Thrcheck run very slowly, often to
+ the point of being completely unusable.</para>
+ </listitem>
+ </varlistentry>
-waiting for a condition variable without holding
- the associated mutex
+</variablelist>
+<!-- end of xi:include in the manpage -->
-better printing of lock cycles
+
</sect1>
+<sect1 id="tc-manual.todolist" xreflabel="To Do List">
+<title>A To-Do List for Thrcheck</title>
+
+<para>The following is a list of loose ends which should be tidied up
+some time.</para>
+
+<itemizedlist>
+ <listitem><para>Track which mutexes are associated with which
+ condition variables, and emit a warning if this becomes
+ inconsistent.</para>
+ </listitem>
+ <listitem><para>For lock order errors, print the complete lock
+ cycle, rather than only doing for size-2 cycles as at
+ present.</para>
+ </listitem>
+ <listitem><para>Document the VALGRIND_HG_CLEAN_MEMORY client
+ request.</para>
+ </listitem>
+ <listitem><para>Possibly a client request to forcibly transfer
+ ownership of memory from one thread to another. Requires further
+ consideration.</para>
+ </listitem>
+ <listitem><para>Add a new client request that marks an address range
+ as being "shared-modified with empty lockset" (the error state),
+ and describe how to use it.</para>
+ </listitem>
+ <listitem><para>Document races caused by gcc's thread-unsafe code
+ generation for speculative stores. In the interim see
+ <computeroutput>http://gcc.gnu.org/ml/gcc/2007-10/msg00266.html
+ </computeroutput>
+ and <computeroutput>http://lkml.org/lkml/2007/10/24/673</computeroutput>.
+ </para>
+ </listitem>
+
+</itemizedlist>
+
+</sect1>
+
</chapter>
|