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
(4) |
2
(3) |
3
(7) |
4
(7) |
5
(6) |
6
(5) |
|
7
(21) |
8
(14) |
9
(8) |
10
(10) |
11
(7) |
12
(4) |
13
|
|
14
(3) |
15
(11) |
16
(4) |
17
|
18
|
19
|
20
|
|
21
(3) |
22
(4) |
23
(2) |
24
(3) |
25
|
26
(4) |
27
(2) |
|
28
(6) |
29
|
30
(2) |
31
(7) |
|
|
|
|
From: <sv...@va...> - 2010-03-21 17:28:17
|
Author: bart
Date: 2010-03-21 17:28:10 +0000 (Sun, 21 Mar 2010)
New Revision: 11096
Log:
Resynchronized client requests with the latest version of TSan's header file
<dynamic_annotations.h>.
Modified:
trunk/drd/drd.h
trunk/drd/drd_clientreq.c
trunk/drd/drd_error.c
trunk/drd/drd_error.h
Modified: trunk/drd/drd.h
===================================================================
--- trunk/drd/drd.h 2010-03-21 17:24:47 UTC (rev 11095)
+++ trunk/drd/drd.h 2010-03-21 17:28:10 UTC (rev 11096)
@@ -128,6 +128,11 @@
#define ANNOTATE_CONDVAR_SIGNAL(cv) do { } while(0)
/**
+ * Tell DRD that the condition variable at address cv is about to be signaled.
+ */
+#define ANNOTATE_CONDVAR_SIGNAL_ALL(cv) do { } while(0)
+
+/**
* Tell DRD that waiting on condition variable at address cv succeeded and that
* the memory operations performed after this annotation should be considered
* to happen after the matching ANNOTATE_CONDVAR_SIGNAL(cv). Since this is the
@@ -136,6 +141,14 @@
*/
#define ANNOTATE_CONDVAR_WAIT(cv) do { } while(0)
+/**
+ * Tell DRD to consider the memory operations that happened before a mutex
+ * unlock event and after the subsequent mutex lock event on the same mutex as
+ * ordered. This is how DRD always behaves, so this macro has been defined
+ * such that it has no effect.
+ */
+#define ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX(mtx) do { } while(0)
+
/** Deprecated -- don't use this annotation. */
#define ANNOTATE_MUTEX_IS_USED_AS_CONDVAR(mtx) do { } while(0)
@@ -198,6 +211,27 @@
*/
#define ANNOTATE_WRITERLOCK_RELEASED(rwlock) ANNOTATE_RWLOCK_RELEASED(rwlock, 1)
+/*
+ * Report that a barrier has been initialized with a given barrier count. The
+ * third argument specifies whether or not reinitialization is allowed, that
+ * is, whether or not it is allowed to call barrier_init() several times
+ * without calling barrier_destroy().
+ */
+#define ANNOTATE_BARRIER_INIT(barrier, count, reinitialization_allowed) \
+ DRDCL_(annotate_barrier_init)(barrier, count, reinitialization_allowed)
+
+/* Report that a barrier has been destroyed. */
+#define ANNOTATE_BARRIER_DESTROY(barrier) \
+ DRDCL_(annotate_barrier_destroy)(barrier)
+
+/* Report that the calling thread is about to start waiting for a barrier. */
+#define ANNOTATE_BARRIER_WAIT_BEFORE(barrier) \
+ DRDCL_(annotate_barrier_wait_before)(barrier)
+
+/* Report that the calling thread has just finished waiting for a barrier. */
+#define ANNOTATE_BARRIER_WAIT_AFTER(barrier) \
+ DRDCL_(annotate_barrier_wait_after)(barrier)
+
/**
* Tell DRD that a FIFO queue has been created. The abbreviation PCQ stands for
* <em>producer-consumer</em>.
@@ -230,6 +264,11 @@
#define ANNOTATE_BENIGN_RACE(addr, descr) \
DRDCL_(ignore_range)(addr, sizeof(*addr))
+/* Same as ANNOTATE_BENIGN_RACE(address, description), but applies to
+ the memory range [address, address+size). */
+#define ANNOTATE_BENIGN_RACE_SIZED(address, size, description) \
+ DRDCL_(ignore_range)(addr, size)
+
/** Tell DRD to ignore all reads performed by the current thread. */
#define ANNOTATE_IGNORE_READS_BEGIN() DRDCL_(set_record_loads)(0)
@@ -317,6 +356,10 @@
VG_USERREQ__DRD_SET_THREAD_NAME,
/* args: null-terminated character string. */
+ /* Tell DRD that a DRD annotation has not yet been implemented. */
+ VG_USERREQ__DRD_ANNOTATION_UNIMP,
+ /* args: Char*. */
+
/* Tell DRD that a user-defined reader-writer synchronization object
* has been created. */
VG_USERREQ__DRD_ANNOTATE_RWLOCK_CREATE
@@ -338,8 +381,8 @@
= VG_USERREQ_TOOL_BASE('H','G') + 256 + 18,
/* args: Addr, Int is_rw. */
- /* Tell DRD that an annotation has not yet been implemented. */
- VG_USERREQ__DRD_ANNOTATION_UNIMP
+ /* Tell DRD that a Helgrind annotation has not yet been implemented. */
+ VG_USERREQ__HELGRIND_ANNOTATION_UNIMP
= VG_USERREQ_TOOL_BASE('H','G') + 256 + 32,
/* args: Char*. */
@@ -487,4 +530,79 @@
rwlock, is_w, 0, 0, 0);
}
+static __inline__
+void DRDCL_(annotate_barrier_init)(const void* barrier, const unsigned count,
+ const int reinitialization_allowed)
+{
+ int res;
+ VALGRIND_DO_CLIENT_REQUEST(res, 0,
+ VG_USERREQ__DRD_ANNOTATION_UNIMP,
+ "ANNOTATE_BARRIER_INIT", 0, 0, 0, 0);
+}
+
+static __inline__
+void DRDCL_(annotate_barrier_destroy)(const void* barrier)
+{
+ int res;
+ VALGRIND_DO_CLIENT_REQUEST(res, 0,
+ VG_USERREQ__DRD_ANNOTATION_UNIMP,
+ "ANNOTATE_BARRIER_DESTROY", 0, 0, 0, 0);
+}
+
+static __inline__
+void DRDCL_(annotate_barrier_wait_before)(const void* barrier)
+{
+ int res;
+ VALGRIND_DO_CLIENT_REQUEST(res, 0,
+ VG_USERREQ__DRD_ANNOTATION_UNIMP,
+ "ANNOTATE_BARRIER_WAIT_BEFORE", 0, 0, 0, 0);
+}
+
+static __inline__
+void DRDCL_(annotate_barrier_wait_after)(const void* barrier)
+{
+ int res;
+ VALGRIND_DO_CLIENT_REQUEST(res, 0,
+ VG_USERREQ__DRD_ANNOTATION_UNIMP,
+ "ANNOTATE_BARRIER_WAIT_AFTER", 0, 0, 0, 0);
+}
+
+
+/**
+ * @addtogroup RaceDetectionAnnotations
+ */
+/*@{*/
+
+#ifdef __cplusplus
+/* ANNOTATE_UNPROTECTED_READ is the preferred way to annotate racy reads.
+
+ Instead of doing
+ ANNOTATE_IGNORE_READS_BEGIN();
+ ... = x;
+ ANNOTATE_IGNORE_READS_END();
+ one can use
+ ... = ANNOTATE_UNPROTECTED_READ(x); */
+template <typename T>
+inline T ANNOTATE_UNPROTECTED_READ(const volatile T& x) {
+ ANNOTATE_IGNORE_READS_BEGIN();
+ const T result = x;
+ ANNOTATE_IGNORE_READS_END();
+ return result;
+}
+/* Apply ANNOTATE_BENIGN_RACE_SIZED to a static variable. */
+#define ANNOTATE_BENIGN_RACE_STATIC(static_var, description) \
+ namespace { \
+ static class static_var##_annotator \
+ { \
+ public: \
+ static_var##_annotator() \
+ { \
+ ANNOTATE_BENIGN_RACE(&static_var, #static_var ": " description); \
+ } \
+ } the_##static_var##_annotator; \
+ }
+#endif
+
+/*@}*/
+
#endif /* __VALGRIND_DRD_H */
Modified: trunk/drd/drd_clientreq.c
===================================================================
--- trunk/drd/drd_clientreq.c 2010-03-21 17:24:47 UTC (rev 11095)
+++ trunk/drd/drd_clientreq.c 2010-03-21 17:28:10 UTC (rev 11096)
@@ -484,6 +484,21 @@
DRD_(clean_memory)(arg[1], arg[2]);
break;
+ case VG_USERREQ__HELGRIND_ANNOTATION_UNIMP:
+ {
+ /* Note: it is assumed below that the text arg[1] points to is never
+ * freed, e.g. because it points to static data.
+ */
+ UnimpClReqInfo UICR =
+ { DRD_(thread_get_running_tid)(), (Char*)arg[1] };
+ VG_(maybe_record_error)(vg_tid,
+ UnimpHgClReq,
+ VG_(get_IP)(vg_tid),
+ "",
+ &UICR);
+ }
+ break;
+
case VG_USERREQ__DRD_ANNOTATION_UNIMP:
{
/* Note: it is assumed below that the text arg[1] points to is never
@@ -492,7 +507,7 @@
UnimpClReqInfo UICR =
{ DRD_(thread_get_running_tid)(), (Char*)arg[1] };
VG_(maybe_record_error)(vg_tid,
- UnimpClReq,
+ UnimpDrdClReq,
VG_(get_IP)(vg_tid),
"",
&UICR);
Modified: trunk/drd/drd_error.c
===================================================================
--- trunk/drd/drd_error.c 2010-03-21 17:24:47 UTC (rev 11095)
+++ trunk/drd/drd_error.c 2010-03-21 17:28:10 UTC (rev 11096)
@@ -385,7 +385,7 @@
VG_(pp_ExeContext)(VG_(get_error_where)(e));
break;
}
- case UnimpClReq: {
+ case UnimpHgClReq: {
UnimpClReqInfo* uicr =(UnimpClReqInfo*)(VG_(get_error_extra)(e));
VG_(message)(Vg_UserMsg,
"The annotation macro %s has not yet been implemented in"
@@ -394,6 +394,15 @@
VG_(pp_ExeContext)(VG_(get_error_where)(e));
break;
}
+ case UnimpDrdClReq: {
+ UnimpClReqInfo* uicr =(UnimpClReqInfo*)(VG_(get_error_extra)(e));
+ VG_(message)(Vg_UserMsg,
+ "The annotation macro %s has not yet been implemented in"
+ " <valgrind/drd.h>\n",
+ uicr->descr);
+ VG_(pp_ExeContext)(VG_(get_error_where)(e));
+ break;
+ }
default:
VG_(message)(Vg_UserMsg,
"%s\n",
@@ -431,8 +440,10 @@
return sizeof(GenericErrInfo);
case InvalidThreadId:
return sizeof(InvalidThreadIdInfo);
- case UnimpClReq:
+ case UnimpHgClReq:
return sizeof(UnimpClReqInfo);
+ case UnimpDrdClReq:
+ return sizeof(UnimpClReqInfo);
default:
tl_assert(False);
break;
@@ -474,8 +485,10 @@
skind = GenericErr;
else if (VG_(strcmp)(name, STR_InvalidThreadId) == 0)
skind = InvalidThreadId;
- else if (VG_(strcmp)(name, STR_UnimpClReq) == 0)
- skind = UnimpClReq;
+ else if (VG_(strcmp)(name, STR_UnimpHgClReq) == 0)
+ skind = UnimpHgClReq;
+ else if (VG_(strcmp)(name, STR_UnimpDrdClReq) == 0)
+ skind = UnimpDrdClReq;
else
return False;
@@ -522,7 +535,8 @@
case HoldtimeErr: return VGAPPEND(STR_, HoldtimeErr);
case GenericErr: return VGAPPEND(STR_, GenericErr);
case InvalidThreadId: return VGAPPEND(STR_, InvalidThreadId);
- case UnimpClReq: return VGAPPEND(STR_, UnimpClReq);
+ case UnimpHgClReq: return VGAPPEND(STR_, UnimpHgClReq);
+ case UnimpDrdClReq: return VGAPPEND(STR_, UnimpDrdClReq);
default:
tl_assert(0);
}
Modified: trunk/drd/drd_error.h
===================================================================
--- trunk/drd/drd_error.h 2010-03-21 17:24:47 UTC (rev 11095)
+++ trunk/drd/drd_error.h 2010-03-21 17:28:10 UTC (rev 11096)
@@ -61,8 +61,10 @@
GenericErr = 11,
#define STR_InvalidThreadId "InvalidThreadId"
InvalidThreadId = 12,
-#define STR_UnimpClReq "UnimpClReq"
- UnimpClReq = 13,
+#define STR_UnimpHgClReq "UnimpHgClReq"
+ UnimpHgClReq = 13,
+#define STR_UnimpDrdClReq "UnimpDrdClReq"
+ UnimpDrdClReq = 14,
} DrdErrorKind;
/* The classification of a faulting address. */
|
|
From: <sv...@va...> - 2010-03-21 17:24:59
|
Author: bart
Date: 2010-03-21 17:24:47 +0000 (Sun, 21 Mar 2010)
New Revision: 11095
Log:
Added two additional regression tests.
Added:
trunk/drd/tests/annotate_barrier.c
trunk/drd/tests/annotate_barrier.stderr.exp
trunk/drd/tests/annotate_barrier.vgtest
trunk/drd/tests/annotate_static.cpp
trunk/drd/tests/annotate_static.stderr.exp
trunk/drd/tests/annotate_static.vgtest
Modified:
trunk/drd/tests/
trunk/drd/tests/Makefile.am
Property changes on: trunk/drd/tests
___________________________________________________________________
Name: svn:ignore
- *.dSYM
*.stderr.diff*
*.stderr.out
*.stdout.diff*
*.stdout.out
.deps
Makefile
Makefile.in
annotate_hb_err
annotate_hb_race
annotate_ignore_rw
annotate_ignore_write
annotate_publish_hg
annotate_rwlock
annotate_smart_pointer
atomic_var
bar_bad
bar_trivial
boost_thread
circular_buffer
custom_alloc
drd_bitmap_test
fp_race
hg01_all_ok
hg02_deadlock
hg03_inherit
hg04_race
hg05_race2
hg06_readshared
hold_lock
linuxthreads_det
matinv
memory_allocation
monitor_example
new_delete
omp_matinv
omp_prime
omp_printf
pth_barrier
pth_barrier_race
pth_barrier_reinit
pth_broadcast
pth_cancel_locked
pth_cleanup_handler
pth_cond_race
pth_create_chain
pth_create_glibc_2_0
pth_detached
pth_detached_sem
pth_inconsistent_cond_wait
pth_mutex_reinit
pth_process_shared_mutex
pth_spinlock
qt4_atomic
qt4_mutex
qt4_rwlock
qt4_semaphore
recursive_mutex
rwlock_race
rwlock_test
rwlock_type_checking
sem_as_mutex
sem_open
sigalrm
tc01_simple_race
tc02_simple_tls
tc03_re_excl
tc04_free_lock
tc05_simple_race
tc06_two_races
tc07_hbl1
tc08_hbl2
tc09_bad_unlock
tc10_rec_lock
tc11_XCHG
tc12_rwl_trivial
tc13_laog1
tc15_laog_lockdel
tc16_byterace
tc17_sembar
tc18_semabuse
tc19_shadowmem
tc20_verifywrap
tc21_pthonce
tc22_exit_w_lock
tc23_bogus_condwait
tc24_nonzero_sem
thread_name
trylock
tsan_unittest
unit_bitmap
unit_vc
vg_regtest.tmp*
+ *.dSYM
*.stderr.diff*
*.stderr.out
*.stdout.diff*
*.stdout.out
.deps
annotate_barrier
annotate_hb_err
annotate_hb_race
annotate_ignore_rw
annotate_ignore_write
annotate_publish_hg
annotate_rwlock
annotate_smart_pointer
annotate_static
atomic_var
bar_bad
bar_trivial
boost_thread
circular_buffer
custom_alloc
drd_bitmap_test
fp_race
hg01_all_ok
hg02_deadlock
hg03_inherit
hg04_race
hg05_race2
hg06_readshared
hold_lock
linuxthreads_det
Makefile
Makefile.in
matinv
memory_allocation
monitor_example
new_delete
omp_matinv
omp_prime
omp_printf
pth_barrier
pth_barrier_race
pth_barrier_reinit
pth_broadcast
pth_cancel_locked
pth_cleanup_handler
pth_cond_race
pth_create_chain
pth_create_glibc_2_0
pth_detached
pth_detached_sem
pth_inconsistent_cond_wait
pth_mutex_reinit
pth_process_shared_mutex
pth_spinlock
qt4_atomic
qt4_mutex
qt4_rwlock
qt4_semaphore
recursive_mutex
rwlock_race
rwlock_test
rwlock_type_checking
sem_as_mutex
sem_open
sigalrm
tc01_simple_race
tc02_simple_tls
tc03_re_excl
tc04_free_lock
tc05_simple_race
tc06_two_races
tc07_hbl1
tc08_hbl2
tc09_bad_unlock
tc10_rec_lock
tc11_XCHG
tc12_rwl_trivial
tc13_laog1
tc15_laog_lockdel
tc16_byterace
tc17_sembar
tc18_semabuse
tc19_shadowmem
tc20_verifywrap
tc21_pthonce
tc22_exit_w_lock
tc23_bogus_condwait
tc24_nonzero_sem
thread_name
trylock
tsan_unittest
unit_bitmap
unit_vc
vg_regtest.tmp*
Modified: trunk/drd/tests/Makefile.am
===================================================================
--- trunk/drd/tests/Makefile.am 2010-03-15 09:03:25 UTC (rev 11094)
+++ trunk/drd/tests/Makefile.am 2010-03-21 17:24:47 UTC (rev 11095)
@@ -14,6 +14,8 @@
tsan_thread_wrappers_pthread.h
EXTRA_DIST = \
+ annotate_barrier.stderr.exp \
+ annotate_barrier.vgtest \
annotate_hb_err.stderr.exp \
annotate_hb_err.vgtest \
annotate_hb_race.stderr.exp \
@@ -48,6 +50,8 @@
annotate_ignore_write2.vgtest \
annotate_trace_memory.stderr.exp \
annotate_trace_memory.vgtest \
+ annotate_static.stderr.exp \
+ annotate_static.vgtest \
atomic_var.stderr.exp \
atomic_var.vgtest \
bar_bad.stderr.exp \
@@ -255,6 +259,7 @@
annotate_ignore_rw \
annotate_ignore_write \
annotate_publish_hg \
+ annotate_static \
custom_alloc \
fp_race \
hold_lock \
@@ -290,6 +295,7 @@
if HAVE_BUILTIN_ATOMIC
check_PROGRAMS += \
+ annotate_barrier \
annotate_rwlock \
annotate_smart_pointer \
atomic_var \
@@ -355,6 +361,8 @@
annotate_smart_pointer_SOURCES = annotate_smart_pointer.cpp
endif
+annotate_static_SOURCES = annotate_static.cpp
+
if HAVE_OPENMP
omp_matinv_CFLAGS = $(AM_CFLAGS) -fopenmp
omp_matinv_LDFLAGS = -fopenmp
Added: trunk/drd/tests/annotate_barrier.c
===================================================================
--- trunk/drd/tests/annotate_barrier.c (rev 0)
+++ trunk/drd/tests/annotate_barrier.c 2010-03-21 17:24:47 UTC (rev 11095)
@@ -0,0 +1,158 @@
+/*
+ * Test whether all data races are detected in a multithreaded program with
+ * user-annotated barriers. See also pth_barrier.c.
+ */
+
+
+#define _GNU_SOURCE
+
+
+#include <pthread.h> /* pthread_create() */
+#include <stdio.h> /* fprintf() */
+#include <stdlib.h> /* atoi() */
+#include <string.h> /* memset() */
+#include "../../drd/drd.h"
+
+
+/* Local datatypes. */
+
+typedef struct
+{
+ /*
+ * number of threads that must call barrier_wait() before any of them
+ * successfully return from the call.
+ */
+ unsigned thread_count;
+ /* number of barrier_wait() calls since last barrier. */
+ volatile unsigned wait_count;
+ /*
+ * barrier count. Only the least significant bit matters -- a single bit
+ * counter would be sufficient.
+ */
+ volatile unsigned barrier_count;
+} barrier_t;
+
+struct threadinfo
+{
+ barrier_t* b;
+ pthread_t tid;
+ int* array;
+ int iterations;
+};
+
+
+/* Local variables. */
+
+static int s_silent;
+
+
+/* Local functions. */
+
+static void barrier_init(barrier_t* b, unsigned count)
+{
+ b->thread_count = count;
+ b->wait_count = 0;
+ b->barrier_count = 0;
+ ANNOTATE_BARRIER_INIT(b, count, 0);
+}
+
+static void barrier_destroy(barrier_t* b)
+{
+ ANNOTATE_BARRIER_DESTROY(b);
+ memset(b, 0, sizeof(*b));
+}
+
+static int barrier_wait(barrier_t* b)
+{
+ int res;
+ unsigned barrier_count;
+
+ res = 0;
+ ANNOTATE_BARRIER_WAIT_BEFORE(b);
+ barrier_count = b->barrier_count;
+ if (__sync_add_and_fetch(&b->wait_count, 1) == b->thread_count)
+ {
+ __sync_sub_and_fetch(&b->wait_count, b->thread_count);
+ __sync_add_and_fetch(&b->barrier_count, 1);
+ res = PTHREAD_BARRIER_SERIAL_THREAD;
+ }
+ else
+ {
+ while (b->barrier_count == barrier_count)
+ pthread_yield();
+ }
+ ANNOTATE_BARRIER_WAIT_AFTER(b);
+ return res;
+}
+
+/*
+ * Single thread, which touches p->iterations elements of array p->array.
+ * Each modification of an element of p->array is a data race.
+ */
+static void* threadfunc(struct threadinfo* p)
+{
+ int i;
+ int* const array = p->array;
+ barrier_t* const b = p->b;
+ if (! s_silent)
+ printf("thread %lx iteration 0\n", pthread_self());
+ barrier_wait(b);
+ for (i = 0; i < p->iterations; i++)
+ {
+ if (! s_silent)
+ printf("thread %lx iteration %d; writing to %p\n",
+ pthread_self(), i + 1, &array[i]);
+ array[i] = i;
+ barrier_wait(b);
+ }
+ return 0;
+}
+
+/* Actual test, consisting of nthread threads. */
+static void barriers_and_races(const int nthread, const int iterations)
+{
+ int i;
+ struct threadinfo* t;
+ barrier_t b;
+ int* array;
+
+ t = malloc(nthread * sizeof(struct threadinfo));
+ array = malloc(iterations * sizeof(array[0]));
+
+ if (! s_silent)
+ printf("&array[0] = %p\n", array);
+
+ barrier_init(&b, nthread);
+
+ for (i = 0; i < nthread; i++)
+ {
+ t[i].b = &b;
+ t[i].array = array;
+ t[i].iterations = iterations;
+ pthread_create(&t[i].tid, 0, (void*(*)(void*))threadfunc, &t[i]);
+ }
+
+ for (i = 0; i < nthread; i++)
+ pthread_join(t[i].tid, 0);
+
+ barrier_destroy(&b);
+
+ free(array);
+ free(t);
+}
+
+int main(int argc, char** argv)
+{
+ int nthread;
+ int iterations;
+
+ nthread = (argc > 1) ? atoi(argv[1]) : 2;
+ iterations = (argc > 2) ? atoi(argv[2]) : 3;
+ s_silent = (argc > 3) ? atoi(argv[3]) : 0;
+
+ barriers_and_races(nthread, iterations);
+
+ fprintf(stderr, "Done.\n");
+
+ return 0;
+}
Added: trunk/drd/tests/annotate_barrier.stderr.exp
===================================================================
--- trunk/drd/tests/annotate_barrier.stderr.exp (rev 0)
+++ trunk/drd/tests/annotate_barrier.stderr.exp 2010-03-21 17:24:47 UTC (rev 11095)
@@ -0,0 +1,47 @@
+
+The annotation macro ANNOTATE_BARRIER_INIT has not yet been implemented in <valgrind/drd.h>
+ at 0x........: vgDrdCl_annotate_barrier_init (drd.h:?)
+ by 0x........: barrier_init (annotate_barrier.c:?)
+ by 0x........: barriers_and_races (annotate_barrier.c:?)
+
+Thread 2:
+The annotation macro ANNOTATE_BARRIER_WAIT_BEFORE has not yet been implemented in <valgrind/drd.h>
+ at 0x........: vgDrdCl_annotate_barrier_wait_before (drd.h:?)
+ by 0x........: barrier_wait (annotate_barrier.c:?)
+ by 0x........: threadfunc (annotate_barrier.c:?)
+
+Thread 3:
+The annotation macro ANNOTATE_BARRIER_WAIT_AFTER has not yet been implemented in <valgrind/drd.h>
+ at 0x........: vgDrdCl_annotate_barrier_wait_after (drd.h:?)
+ by 0x........: barrier_wait (annotate_barrier.c:?)
+ by 0x........: threadfunc (annotate_barrier.c:?)
+
+The annotation macro ANNOTATE_BARRIER_WAIT_BEFORE has not yet been implemented in <valgrind/drd.h>
+ at 0x........: vgDrdCl_annotate_barrier_wait_before (drd.h:?)
+ by 0x........: barrier_wait (annotate_barrier.c:?)
+ by 0x........: threadfunc (annotate_barrier.c:?)
+
+Thread 2:
+Conflicting store by thread 2 at 0x........ size 4
+ at 0x........: threadfunc (annotate_barrier.c:?)
+ by 0x........: vgDrd_thread_wrapper (drd_pthread_intercepts.c:?)
+ by 0x........: (within libpthread-?.?.so)
+Address 0x........ is at offset 0 from 0x......... Allocation context:
+ at 0x........: malloc (vg_replace_malloc.c:...)
+ by 0x........: barriers_and_races (annotate_barrier.c:?)
+ by 0x........: main (annotate_barrier.c:?)
+
+The annotation macro ANNOTATE_BARRIER_WAIT_AFTER has not yet been implemented in <valgrind/drd.h>
+ at 0x........: vgDrdCl_annotate_barrier_wait_after (drd.h:?)
+ by 0x........: barrier_wait (annotate_barrier.c:?)
+ by 0x........: threadfunc (annotate_barrier.c:?)
+
+Thread 1:
+The annotation macro ANNOTATE_BARRIER_DESTROY has not yet been implemented in <valgrind/drd.h>
+ at 0x........: vgDrdCl_annotate_barrier_destroy (drd.h:?)
+ by 0x........: barrier_destroy (annotate_barrier.c:?)
+ by 0x........: barriers_and_races (annotate_barrier.c:?)
+
+Done.
+
+ERROR SUMMARY: 11 errors from 7 contexts (suppressed: 0 from 0)
Added: trunk/drd/tests/annotate_barrier.vgtest
===================================================================
--- trunk/drd/tests/annotate_barrier.vgtest (rev 0)
+++ trunk/drd/tests/annotate_barrier.vgtest 2010-03-21 17:24:47 UTC (rev 11095)
@@ -0,0 +1,4 @@
+prereq: test -e annotate_barrier && ./supported_libpthread
+vgopts: --read-var-info=yes --check-stack-var=yes --show-confl-seg=no --num-callers=3
+prog: annotate_barrier 2 1 1
+stderr_filter: filter_stderr
Added: trunk/drd/tests/annotate_static.cpp
===================================================================
--- trunk/drd/tests/annotate_static.cpp (rev 0)
+++ trunk/drd/tests/annotate_static.cpp 2010-03-21 17:24:47 UTC (rev 11095)
@@ -0,0 +1,37 @@
+// Test for ANNOTATE_BENIGN_RACE_STATIC() and ANNOTATE_UNPROTECTED_READ().
+
+
+#include <pthread.h> /* pthread_create() */
+#include <stdio.h> /* fprintf() */
+#include "../../drd/drd.h"
+
+
+/* Local variables. */
+
+static int s_i;
+static volatile int s_j;
+
+ANNOTATE_BENIGN_RACE_STATIC(s_i, "Benign because duplicate assignment.");
+
+
+/* Local functions. */
+
+static void* thread_func(void*)
+{
+ s_i = ANNOTATE_UNPROTECTED_READ(s_j);
+ return 0;
+}
+
+int main(int argc, char** argv)
+{
+ pthread_t tid;
+
+ pthread_create(&tid, 0, thread_func, NULL);
+ s_j++;
+ s_i = s_j;
+ pthread_join(tid, NULL);
+
+ fprintf(stderr, "Done.\n");
+
+ return 0;
+}
Added: trunk/drd/tests/annotate_static.stderr.exp
===================================================================
--- trunk/drd/tests/annotate_static.stderr.exp (rev 0)
+++ trunk/drd/tests/annotate_static.stderr.exp 2010-03-21 17:24:47 UTC (rev 11095)
@@ -0,0 +1,4 @@
+
+Done.
+
+ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
Added: trunk/drd/tests/annotate_static.vgtest
===================================================================
--- trunk/drd/tests/annotate_static.vgtest (rev 0)
+++ trunk/drd/tests/annotate_static.vgtest 2010-03-21 17:24:47 UTC (rev 11095)
@@ -0,0 +1,4 @@
+prereq: test -e annotate_static && ./supported_libpthread
+vgopts: --read-var-info=yes --check-stack-var=yes --show-confl-seg=no
+prog: annotate_static
+stderr_filter: filter_stderr
|
|
From: Philippe W. <phi...@sk...> - 2010-03-21 02:17:21
|
Hello,
I have resumed the work on gdbserver integration in valgrind.
I think it is now in a reasonable state, so it is time for
comments/feedback/suggestions/criticisms/...
(I hope that with a lot of these, this work could be integrated
in valgrind :).
In summary, the integration of gdbserver provides to the
valgrind users a fully debuggable application under valgrind,
with interactive usage of valgrind functionalities (e.g.
incremental search for new leaks).
So, below follows a more in-depth functional and technical
description. Feel free to react.
A coregrind/m_gdbserver module (based on gdbserver from
gdb 7.0.1) has been integrated in valgrind.
With this, a user can debug its process running under valgrind
or the user can send commands from the shell prompt to a running
valgrind process (this is similar to the callgrind_control etc
commands but generalised to be usable by all tools).
To debug a valgrind process, the user has to enter the
following command at gdb prompt:
(gdb) target remote | vgctl
vgctl (valgrind control) is a relay application between gdb
and the gdbserver in valgrind.
If there is more than one valgrind process running, vgctl
will report the list of running process, and will ask
to give a --pid=xxxxx argument.
gdb will then connect to the gdbserver inside the valgrind process.
After that, the user can debug its "valgrind-ified" application
similarly to doing native debugging. In particular, the following
are properly supported:
detach/reattach to a process
(limitation: it cannot attach to a valgrind process which
has all its threads blocked in a syscall : valgrind
must be "running" to have attach working.
Also, it might be needed to increase the gdb timeout
using gdb command 'set remotetimeout xxx' to allow
more time to the valgrind process to go out of a
system call).
threads (info threads, switch thread, ...)
backtrace etc
examine memory (print variable, function args, ...)
change memory (set a variable, etc)
breakpoints (set a breakpoint, delete breakpoint, ...)
watchpoints (both software and "hardware read/write/access"
watchpoints are implemented. software watchpoints
are very slow, "hardware watchpoint" is
implemented using memcheck addressibility)
next/step/until/stepi/...
...
In addition, thanks to what valgrind provides, gdbserver in
valgrind allows the addition of interesting "gdb" new
functionalities.
These new functionalities are provided through gdb monitor command.
To give such a command to the valgrind process,
under gdb, you type:
(gdb) monitor ...here a command understood by valgrind...
The following general valgrind commands have been added:
general valgrind monitor commands:
vg.set vgctl-error <errornr> : debug me at error >= <errornr>
vg.set debuglog <intvalue> : set the valgrind debug log level to <intvalue>
vg.set gdb_output : redirect further valgrind output to gdb
vg.set log_output : redirect further valgrind output to log
vg.info all_errors : show all errors found so far
vg.info n_errs_found : show the nr of errors found so far
vg.continue : let valgrind process continue (no effect under gdb)
Note:
(in all these commands and in the below memcheck commands,
it is not needed to give the complete command or arg value).
For example,
monitor vg.set debuglog 3
and
mo vg.s d 3
are equivalent: gdb will interpret mo as monitor.
Valgrind will similarly parse the rest and understand vg.s and d.
If the given characters are ambiguous, an error msg is returned
giving the possible choices)
vg.set vgctl-error will cause gdbserver to wait for gdb at errors
with an error nr >= to the given error nr.
vg.set debuglog allows to dynamically change the log level of valgrind.
vg.set gdb_output allows valgrind output to be displayed by gdb instead
of going to the process log. vg.set log_output resets this to the normal
log output of the process.
vg.info n_errs_found and all_errors shows the nr of errors found by
valgrind and the details about these errors.
vg.continue is not useful under gdb, it is only useful for "standalone" vgctl
of a valgrind process (see later).
It is also possible to add new commands to each valgrind tool.
The following commands have been added to memcheck:
memcheck monitor commands:
mc.get_vbits <addr> <len>
returns validity bits for <len> bytes at <addr>
bit values 0 = valid, 1 = invalid
Example: mc.get_vbits 0x8049c78 10
mc.make_memory [noaccess|undefined|defined|ifaddressabledefined] <addr> <len>
mark len bytes at addr with the specified accessibility
mc.check_memory [addressable|defined] <addr> <len>
check that len bytes at addr have the specified accessibility
mc.leak_check [increased*|changed|any] [reachable|leak*] [full*|summary]
* = defaults
Examples:
mc.leak_check
mc.leak_check any summary
The memcheck commands are basically corresponding to the equivalent
memcheck client requests.
mc.leak_check is however a (slightly updated) version of the patch
in bugzilla 206802:
The 2nd and 3rd parameter corresponds to the current valgrind client
requests leak search.
The first parameter (which is new) allows an incremental reporting
of "increased" leaks/reachable
or of "changed" leaks/reachable (i.e. increased or decreased)
or of "any" leaks/reachable (i.e. increased or decreased or unchanged)
As an example: two successive mc.leak_check can give the following:
(gdb) monitor mc.leak_check
==10047== 136 (+136) bytes in 1 (+1) blocks are possibly lost in loss record 1 of 3
==10047== at 0x4004F4D: calloc (vg_replace_malloc.c:467)
==10047== by 0x78F7FA: _dl_allocate_tls (dl-tls.c:300)
==10047== by 0x91D4C4: pthread_create@@GLIBC_2.1 (allocatestack.c:561)
==10047== by 0x8048829: main (t.c:99)
==10047==
==10047== 136 (+136) bytes in 1 (+1) blocks are possibly lost in loss record 2 of 3
==10047== at 0x4004F4D: calloc (vg_replace_malloc.c:467)
==10047== by 0x78F7FA: _dl_allocate_tls (dl-tls.c:300)
==10047== by 0x91D4C4: pthread_create@@GLIBC_2.1 (allocatestack.c:561)
==10047== by 0x804884D: main (t.c:100)
==10047==
==10047== 136 (+136) bytes in 1 (+1) blocks are possibly lost in loss record 3 of 3
==10047== at 0x4004F4D: calloc (vg_replace_malloc.c:467)
==10047== by 0x78F7FA: _dl_allocate_tls (dl-tls.c:300)
==10047== by 0x91D4C4: pthread_create@@GLIBC_2.1 (allocatestack.c:561)
==10047== by 0x8048871: main (t.c:101)
==10047==
==10047== LEAK SUMMARY:
==10047== definitely lost: 0 (+0) bytes in 0 (+0) blocks
==10047== indirectly lost: 0 (+0) bytes in 0 (+0) blocks
==10047== possibly lost: 15408 (+408) bytes in 13 (+3) blocks
==10047== still reachable: 0 (+0) bytes in 0 (+0) blocks
==10047== suppressed: 0 (+0) bytes in 0 (+0) blocks
==10047==
(gdb) monitor mc.leak_check
==10047== LEAK SUMMARY:
==10047== definitely lost: 0 (+0) bytes in 0 (+0) blocks
==10047== indirectly lost: 0 (+0) bytes in 0 (+0) blocks
==10047== possibly lost: 15408 (+0) bytes in 13 (+0) blocks
==10047== still reachable: 0 (+0) bytes in 0 (+0) blocks
==10047== suppressed: 0 (+0) bytes in 0 (+0) blocks
==10047==
(gdb)
(as the 2nd leak_check does not report any new leak, all deltas are 0).
When a "increased" or "changed" leak is requested, the output shows
the total size and blocks for the leaking stack trace + the delta compared
to the last leak search.
By setting break at the relevant places in your program and calling
mc.leak_check, this might help to detect the place at which the last
pointer to a piece of memory is lost.
All these monitor commands can also be given to a valgrind process
using vgctl outside of gdb. For example, to ask the valgrind
process 123 to produce memory leak output, you can type the
following at the shell prompt:
$ vgctl --pid=123 mc.leak_check
You can tell a valgrind process to stop on errors and
use
$ vgctl vg.continue
to tell it to continue.
The help usage of vgctl is the following:
$ vgctl --help
vgctl (valgrind control) has two usages
1. standalone to send a command to a running valgrind-ified process.
Usage: vgctl [--pid=...] [--vgctl=...] ...command to send ...
2. relay application between gdb and the gdbserver embedded in valgrind.
Usage: vgctl [--pid=...] [--vgctl=...]
--pid optional argument must be given if there are multiple running valgrind processes
--vgctl optional argument must be given to both valgrind and vgctl utility
if you want to use non standard FIFOs prefixes for the communication between
valgrind processes and vgctl
Examples:
1. as standalone utility:
to ask memcheck to do a full memory report (leak and reachable)
vgctl mc.leak_check any reachable full
to ask new or increased leaks since last leak search
vgctl mc.leak
to tell a valgrind process to continue
vgctl vg.continue
to ask the list of commands supported by the valgrind tool
vgctl help
Note: only the first differentiating characters are needed in a command
e.g. the 2 lines below are the same command
vgctl mc.l a r f
vgctl mc.leak_check any reachable full
2. as gdb relay application:
type the following at gdb command prompt:
(gdb) target remote | vgctl --pid=1234
then debug your program as usual
Note: if your valgrind process is very slow or blocked in a system call
you might first need to give the gdb command
(gdb) set remotetimeout <timeout_limit__in_seconds>
to allow valgrind to respond and/or let you unblock the system call
--------------------- Implementation notes
To allow gdbserver and vgctl to interact, 3 new arguments have been added
to valgrind:
--vgctl-check=<number> check for gdb/vgctl after <number> basic blocks [5000]
--vgctl-error=<number> wait for gdb/vgctl after <number> errors [999999999]
--vgctl=<prefix> prefix for gdb/vgctl FIFOs [/tmp/vgctl-pipe]
--vgctl-check ensures that valgrind checks at regular interval
if vgctl has requested something. This is implemented by polling
the a file descriptor with the select system call.
This might be improved by rather checking a piece of shared memory
between vgctl and valgrind.
--vgctl-error=0 allows to attach before any user code has run
(so as e.g. to put breakpoints at the beginning).
A unmodified tool that reports errors will interact properly
with gdbserver without any modifications.
However, breakpoints/watchpoint/next/step/... implies
relatively easy changes to the instrumenting function
(as long as gdbserver is not effictively debugging
a block, the instrumentation is similar to the current valgrind.
When gdbserver is "active" on a block (e.g. there is a breakpoint
or gdbserver is single stepping), this block must re-instrumented
with some additional dirty helper calls.
The above changes have been implemented on x86/fedora12 and tested manually
with a small specific test program + tested on firefox.
Regression tests of valgrind have been run (6 new tests failing
to examine, half of them looks to be trivial "help output changes").
I also implemented the amd64 changes, but had only access during
two hours to a 64 bit fedora12 system. So, I could just see it was
working on the small specific test program compiled in 64 bits.
And I could not retest this recently.
Other platforms not coded (but the work to support a new platform
is normally relatively small: basically, it implies to write
a conversion between the guest states registers and the gdb register
in the file valgrind-low.c.
I have a few technical questions, if someone could help for these,
that would be nice.
* I see that all exported symbols in valgrind have a unique prefix
created with VG_ or MC_ or ...
This is not done for the "gdb gdbserver code", where I have kept
the original names. Is this a problem ? I could not create
a "symbol" collision between the user symbol and the valgrind
core gdbserver symbol.
* to replace the calls to select by shared memory implies to
create a piece of shared memory and map it at a good place
that will not interact with the user process.
Is there any information about which address could be used for
that ?
* if all this is to be integrated in valgrind, I guess someone
with svn write access should volunteer to create a branch.
* there are some registers in x86 or amd64 that I could not
translate to VEX registers. Someone with a good knowledge
of these architectures might complete this (see in valgrind-low.c)
* removing the limitation of not being able to attach to a
process blocked in system call(s) would be nice but I have
no idea on how to do that.
* there are a lot of additional possible things such as:
- more commands (e.g. vg.suppression [generate|add|delete] for last error)
- some "generic breaks" such as break on all function calls entry/exit
- vg.set for more valgrind parameters
- implement the Vcont packet handling allowing to continue/stop
selectively some threads (would imply some changes to valgrind scheduler
thread state)
Philippe
|