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
(8) |
2
(8) |
3
(15) |
4
(14) |
5
(12) |
6
(40) |
7
(9) |
|
8
(5) |
9
(12) |
10
(9) |
11
(13) |
12
(7) |
13
(7) |
14
(19) |
|
15
(18) |
16
(13) |
17
(16) |
18
(8) |
19
(16) |
20
(16) |
21
(12) |
|
22
(21) |
23
(39) |
24
(27) |
25
(33) |
26
(41) |
27
(17) |
28
(15) |
|
From: Pharaoh . <pha...@gm...> - 2009-02-21 17:36:51
|
On Sat, Feb 21, 2009 at 12:47 AM, Stephen McCamant <sm...@cs...>wrote: > >>>>> "P" == Pharaoh <pha...@gm...> writes: > > P> Hello list, > P> I am trying to learn how Valgrind works, by going through the code > P> and trying out test cases out of interest. The tool reports stack > P> traces for errors with function name etc. How does Valgrind do it? > P> I mean, I don't see libbfd being used anywhere neither any glibc > P> apis is used to collect the stack info. Also, how are the addresses > P> converted to symbol names? > > P> Any pointers will be helpful. > > The Valgrind core support for stack traces (as used by Memcheck, etc.) > works in roughly the same way as something like GDB does. At the time > it wants to record/print a stack trace, it walks up the linked frames > on the stack to getting calling addresses. Then it tries to translate > each address into a function name (using the executable's ELF symbol > table) and potentially also a source file and line number (using DWARF > or stabs debugging information). The Valgrind code that does this is > custom written, in part because there have historically been various > obstacles to linking external libraries with Valgrind, and I think > also just that's the style the main developers prefer. > > To look at the code in the core that supports this, see: > > coregrind/m_debuginfo/* > coregrind/m_stacktrace.c > > Most Valgrind tools don't use the strategy of recording at runtime > when each function starts and finishes: though this would sometimes be > useful if the stack gets corrupted or the information needed for a > backtrace is missing, it's tricky to get working robustly in the face > of things like longjmp() and tail calls. But some tools do track calls > and returns, such as Callgrind and the Fjalar and Flowcheck tools that > I and our group at MIT worked on. > > http://groups.csail.mit.edu/pag/fjalar/ > http://people.csail.mit.edu/smcc/projects/secret-flow/ > > Hope this helps, > > -- Stephen > Yes, this was exactly the kind of details I was looking for. Thanks everyone. -Pharaoh. |
|
From: <sv...@va...> - 2009-02-21 16:17:55
|
Author: bart
Date: 2009-02-21 16:17:50 +0000 (Sat, 21 Feb 2009)
New Revision: 9214
Log:
- Bug fix: swapped order of VG_(OSetGen_Remove)() and
(*p->any.cleanup)(p) such that the "first observed at" information is
now included in error messages.
- Performance optimization: started using VG_(OSetGen_ResetIterAt)().
Modified:
trunk/drd/drd_clientobj.c
trunk/drd/tests/bar_bad.stderr.exp
trunk/drd/tests/tc04_free_lock.stderr.exp
trunk/drd/tests/tc09_bad_unlock.stderr.exp
trunk/drd/tests/tc20_verifywrap.stderr.exp-glibc2.3
trunk/drd/tests/tc20_verifywrap.stderr.exp-glibc2.5
trunk/drd/tests/tc20_verifywrap.stderr.exp-glibc2.5-ppc
trunk/drd/tests/tc20_verifywrap.stderr.exp-glibc2.8
trunk/drd/tests/tc20_verifywrap2.stderr.exp-glibc2.3
trunk/drd/tests/tc20_verifywrap2.stderr.exp-glibc2.3-b
trunk/drd/tests/tc20_verifywrap2.stderr.exp-glibc2.5
trunk/drd/tests/tc20_verifywrap2.stderr.exp-glibc2.5-ppc
trunk/drd/tests/tc20_verifywrap2.stderr.exp-glibc2.8
Modified: trunk/drd/drd_clientobj.c
===================================================================
--- trunk/drd/drd_clientobj.c 2009-02-21 16:13:50 UTC (rev 9213)
+++ trunk/drd/drd_clientobj.c 2009-02-21 16:17:50 UTC (rev 9214)
@@ -85,9 +85,10 @@
return VG_(OSetGen_Lookup)(s_clientobj_set, &addr);
}
-/** Return the data associated with the client object at client address addr
- * and that has object type t. Return 0 if there is no client object in the
- * set with the specified start address.
+/**
+ * Return the data associated with the client object at client address addr
+ * and that has object type t. Return 0 if there is no client object in the
+ * set with the specified start address.
*/
DrdClientobj* DRD_(clientobj_get)(const Addr addr, const ObjType t)
{
@@ -144,6 +145,12 @@
return p;
}
+/**
+ * Remove the information that was stored about the client object.
+ *
+ * @param[in] addr Address of the client object in the client address space.
+ * @param[in] t Type of the client object.
+ */
Bool DRD_(clientobj_remove)(const Addr addr, const ObjType t)
{
DrdClientobj* p;
@@ -154,27 +161,28 @@
return clientobj_remove_obj(p);
}
+/**
+ * Remove the information that was stored about the client object p.
+ *
+ * @note The order of operations below is important. The client object is
+ * removed from the client object set after the cleanup function has been
+ * called such that if the cleanup function can still use the function
+ * DRD_(clientobj_get_any)(). This happens e.g. in the function
+ * first_observed() in drd_error.c.
+ */
static Bool clientobj_remove_obj(DrdClientobj* const p)
{
- DrdClientobj* q;
+ tl_assert(p);
if (s_trace_clientobj)
{
VG_(message)(Vg_UserMsg, "Removing client object 0x%lx of type %d",
p->any.a1, p->any.type);
-#if 0
- VG_(get_and_pp_StackTrace)(VG_(get_running_tid)(),
- VG_(clo_backtrace_size));
-#endif
}
- tl_assert(p);
- q = VG_(OSetGen_Remove)(s_clientobj_set, &p->any.a1);
- tl_assert(p == q);
-
- tl_assert(VG_(OSetGen_Lookup)(s_clientobj_set, &p->any.a1) == 0);
tl_assert(p->any.cleanup);
(*p->any.cleanup)(p);
+ VG_(OSetGen_Remove)(s_clientobj_set, &p->any.a1);
VG_(OSetGen_FreeNode)(s_clientobj_set, p);
return True;
}
@@ -196,13 +204,10 @@
if (a1 <= p->any.a1 && p->any.a1 < a2)
{
removed_at = p->any.a1;
- DRD_(clientobj_remove)(p->any.a1, p->any.type);
+ clientobj_remove_obj(p);
/* The above call removes an element from the oset and hence */
/* invalidates the iterator. Set the iterator back. */
- VG_(OSetGen_ResetIter)(s_clientobj_set);
- while ((p = VG_(OSetGen_Next)(s_clientobj_set)) != 0
- && p->any.a1 <= removed_at)
- { }
+ VG_(OSetGen_ResetIterAt)(s_clientobj_set, &removed_at);
}
else
{
Modified: trunk/drd/tests/bar_bad.stderr.exp
===================================================================
--- trunk/drd/tests/bar_bad.stderr.exp 2009-02-21 16:13:50 UTC (rev 9213)
+++ trunk/drd/tests/bar_bad.stderr.exp 2009-02-21 16:17:50 UTC (rev 9214)
@@ -34,6 +34,9 @@
Destruction of barrier that is being waited upon: barrier 0x........
at 0x........: pthread_barrier_destroy (drd_pthread_intercepts.c:?)
by 0x........: main (bar_bad.c:?)
+barrier 0x........ was first observed at:
+ at 0x........: pthread_barrier_init (drd_pthread_intercepts.c:?)
+ by 0x........: main (bar_bad.c:?)
destroy a barrier that was never initialised
@@ -44,3 +47,6 @@
Destruction of barrier that is being waited upon: barrier 0x........
at 0x........: free (vg_replace_malloc.c:...)
by 0x........: main (bar_bad.c:?)
+barrier 0x........ was first observed at:
+ at 0x........: pthread_barrier_init (drd_pthread_intercepts.c:?)
+ by 0x........: main (bar_bad.c:?)
Modified: trunk/drd/tests/tc04_free_lock.stderr.exp
===================================================================
--- trunk/drd/tests/tc04_free_lock.stderr.exp 2009-02-21 16:13:50 UTC (rev 9213)
+++ trunk/drd/tests/tc04_free_lock.stderr.exp 2009-02-21 16:17:50 UTC (rev 9214)
@@ -2,17 +2,32 @@
Destroying locked mutex: mutex 0x........, recursion count 1, owner 1.
at 0x........: free (vg_replace_malloc.c:...)
by 0x........: main (tc04_free_lock.c:24)
+mutex 0x........ was first observed at:
+ at 0x........: pthread_mutex_init (drd_pthread_intercepts.c:?)
+ by 0x........: main (tc04_free_lock.c:20)
Destroying locked mutex: mutex 0x........, recursion count 1, owner 1.
at 0x........: bar (tc04_free_lock.c:40)
by 0x........: main (tc04_free_lock.c:26)
+mutex 0x........ was first observed at:
+ at 0x........: pthread_mutex_lock (drd_pthread_intercepts.c:?)
+ by 0x........: bar (tc04_free_lock.c:38)
+ by 0x........: main (tc04_free_lock.c:26)
Destroying locked mutex: mutex 0x........, recursion count 1, owner 1.
at 0x........: foo (tc04_free_lock.c:49)
by 0x........: main (tc04_free_lock.c:27)
+mutex 0x........ was first observed at:
+ at 0x........: pthread_mutex_init (drd_pthread_intercepts.c:?)
+ by 0x........: foo (tc04_free_lock.c:46)
+ by 0x........: main (tc04_free_lock.c:27)
Destroying locked mutex: mutex 0x........, recursion count 1, owner 1.
at 0x........: bar (tc04_free_lock.c:40)
by 0x........: main (tc04_free_lock.c:28)
+mutex 0x........ was first observed at:
+ at 0x........: pthread_mutex_lock (drd_pthread_intercepts.c:?)
+ by 0x........: bar (tc04_free_lock.c:38)
+ by 0x........: main (tc04_free_lock.c:28)
ERROR SUMMARY: 4 errors from 4 contexts (suppressed: 0 from 0)
Modified: trunk/drd/tests/tc09_bad_unlock.stderr.exp
===================================================================
--- trunk/drd/tests/tc09_bad_unlock.stderr.exp 2009-02-21 16:13:50 UTC (rev 9213)
+++ trunk/drd/tests/tc09_bad_unlock.stderr.exp 2009-02-21 16:17:50 UTC (rev 9214)
@@ -29,6 +29,10 @@
Destroying locked mutex: mutex 0x........, recursion count 1, owner 1.
at 0x........: nearly_main (tc09_bad_unlock.c:45)
by 0x........: main (tc09_bad_unlock.c:49)
+mutex 0x........ was first observed at:
+ at 0x........: pthread_mutex_init (drd_pthread_intercepts.c:?)
+ by 0x........: nearly_main (tc09_bad_unlock.c:31)
+ by 0x........: main (tc09_bad_unlock.c:49)
---------------------
Mutex not locked by calling thread: mutex 0x........, recursion count 0, owner 1.
@@ -61,5 +65,9 @@
Destroying locked mutex: mutex 0x........, recursion count 1, owner 1.
at 0x........: nearly_main (tc09_bad_unlock.c:45)
by 0x........: main (tc09_bad_unlock.c:50)
+mutex 0x........ was first observed at:
+ at 0x........: pthread_mutex_init (drd_pthread_intercepts.c:?)
+ by 0x........: nearly_main (tc09_bad_unlock.c:31)
+ by 0x........: main (tc09_bad_unlock.c:50)
ERROR SUMMARY: 8 errors from 8 contexts (suppressed: 0 from 0)
Modified: trunk/drd/tests/tc20_verifywrap.stderr.exp-glibc2.3
===================================================================
--- trunk/drd/tests/tc20_verifywrap.stderr.exp-glibc2.3 2009-02-21 16:13:50 UTC (rev 9213)
+++ trunk/drd/tests/tc20_verifywrap.stderr.exp-glibc2.3 2009-02-21 16:17:50 UTC (rev 9214)
@@ -24,6 +24,9 @@
Destroying locked mutex: mutex 0x........, recursion count 1, owner 1.
at 0x........: pthread_mutex_destroy (drd_pthread_intercepts.c:?)
by 0x........: main (tc20_verifywrap.c:102)
+mutex 0x........ was first observed at:
+ at 0x........: pthread_mutex_init (drd_pthread_intercepts.c:?)
+ by 0x........: main (tc20_verifywrap.c:100)
make pthread_mutex_lock fail: skipped on glibc < 2.4
@@ -132,8 +135,14 @@
Destroying locked rwlock: rwlock 0x.........
at 0x........: main (tc20_verifywrap.c:262)
+rwlock 0x........ was first observed at:
+ at 0x........: pthread_rwlock_init* (drd_pthread_intercepts.c:?)
+ by 0x........: main (tc20_verifywrap.c:216)
Destroying locked mutex: mutex 0x........, recursion count 1, owner 1.
at 0x........: main (tc20_verifywrap.c:262)
+mutex 0x........ was first observed at:
+ at 0x........: pthread_mutex_init (drd_pthread_intercepts.c:?)
+ by 0x........: main (tc20_verifywrap.c:145)
ERROR SUMMARY: 15 errors from 15 contexts (suppressed: 0 from 0)
Modified: trunk/drd/tests/tc20_verifywrap.stderr.exp-glibc2.5
===================================================================
--- trunk/drd/tests/tc20_verifywrap.stderr.exp-glibc2.5 2009-02-21 16:13:50 UTC (rev 9213)
+++ trunk/drd/tests/tc20_verifywrap.stderr.exp-glibc2.5 2009-02-21 16:17:50 UTC (rev 9214)
@@ -24,6 +24,9 @@
Destroying locked mutex: mutex 0x........, recursion count 1, owner 1.
at 0x........: pthread_mutex_destroy (drd_pthread_intercepts.c:?)
by 0x........: main (tc20_verifywrap.c:102)
+mutex 0x........ was first observed at:
+ at 0x........: pthread_mutex_init (drd_pthread_intercepts.c:?)
+ by 0x........: main (tc20_verifywrap.c:100)
The object at address 0x........ is not a mutex.
at 0x........: pthread_mutex_lock (drd_pthread_intercepts.c:?)
@@ -136,8 +139,14 @@
Destroying locked rwlock: rwlock 0x.........
at 0x........: main (tc20_verifywrap.c:262)
+rwlock 0x........ was first observed at:
+ at 0x........: pthread_rwlock_init* (drd_pthread_intercepts.c:?)
+ by 0x........: main (tc20_verifywrap.c:216)
Destroying locked mutex: mutex 0x........, recursion count 1, owner 1.
at 0x........: main (tc20_verifywrap.c:262)
+mutex 0x........ was first observed at:
+ at 0x........: pthread_mutex_init (drd_pthread_intercepts.c:?)
+ by 0x........: main (tc20_verifywrap.c:145)
ERROR SUMMARY: 16 errors from 16 contexts (suppressed: 0 from 0)
Modified: trunk/drd/tests/tc20_verifywrap.stderr.exp-glibc2.5-ppc
===================================================================
--- trunk/drd/tests/tc20_verifywrap.stderr.exp-glibc2.5-ppc 2009-02-21 16:13:50 UTC (rev 9213)
+++ trunk/drd/tests/tc20_verifywrap.stderr.exp-glibc2.5-ppc 2009-02-21 16:17:50 UTC (rev 9214)
@@ -24,6 +24,9 @@
Destroying locked mutex: mutex 0x........, recursion count 1, owner 1.
at 0x........: pthread_mutex_destroy (drd_pthread_intercepts.c:?)
by 0x........: main (tc20_verifywrap.c:102)
+mutex 0x........ was first observed at:
+ at 0x........: pthread_mutex_init (drd_pthread_intercepts.c:?)
+ by 0x........: main (tc20_verifywrap.c:100)
The object at address 0x........ is not a mutex.
at 0x........: pthread_mutex_lock (drd_pthread_intercepts.c:?)
Modified: trunk/drd/tests/tc20_verifywrap.stderr.exp-glibc2.8
===================================================================
--- trunk/drd/tests/tc20_verifywrap.stderr.exp-glibc2.8 2009-02-21 16:13:50 UTC (rev 9213)
+++ trunk/drd/tests/tc20_verifywrap.stderr.exp-glibc2.8 2009-02-21 16:17:50 UTC (rev 9214)
@@ -24,6 +24,9 @@
Destroying locked mutex: mutex 0x........, recursion count 1, owner 1.
at 0x........: pthread_mutex_destroy (drd_pthread_intercepts.c:?)
by 0x........: main (tc20_verifywrap.c:102)
+mutex 0x........ was first observed at:
+ at 0x........: pthread_mutex_init (drd_pthread_intercepts.c:?)
+ by 0x........: main (tc20_verifywrap.c:100)
The object at address 0x........ is not a mutex.
at 0x........: pthread_mutex_lock (drd_pthread_intercepts.c:?)
Modified: trunk/drd/tests/tc20_verifywrap2.stderr.exp-glibc2.3
===================================================================
--- trunk/drd/tests/tc20_verifywrap2.stderr.exp-glibc2.3 2009-02-21 16:13:50 UTC (rev 9213)
+++ trunk/drd/tests/tc20_verifywrap2.stderr.exp-glibc2.3 2009-02-21 16:17:50 UTC (rev 9214)
@@ -159,10 +159,16 @@
Destroying locked rwlock: rwlock 0x.........
at 0x........: main (tc20_verifywrap.c:262)
+rwlock 0x........ was first observed at:
+ at 0x........: pthread_rwlock_init* (drd_pthread_intercepts.c:?)
+ by 0x........: main (tc20_verifywrap.c:216)
[1/1] mutex_destroy error checking mutex 0x........ rc 1 owner 1
Destroying locked mutex: mutex 0x........, recursion count 1, owner 1.
at 0x........: main (tc20_verifywrap.c:262)
+mutex 0x........ was first observed at:
+ at 0x........: pthread_mutex_init (drd_pthread_intercepts.c:?)
+ by 0x........: main (tc20_verifywrap.c:145)
[1/1] mutex_destroy invalid mutex 0x........ rc 0 owner 0
[1/1] mutex_trylock recursive mutex 0x........ rc 0 owner 0
[1/1] post_mutex_lock recursive mutex 0x........ rc 0 owner 0
Modified: trunk/drd/tests/tc20_verifywrap2.stderr.exp-glibc2.3-b
===================================================================
--- trunk/drd/tests/tc20_verifywrap2.stderr.exp-glibc2.3-b 2009-02-21 16:13:50 UTC (rev 9213)
+++ trunk/drd/tests/tc20_verifywrap2.stderr.exp-glibc2.3-b 2009-02-21 16:17:50 UTC (rev 9214)
@@ -159,10 +159,16 @@
Destroying locked rwlock: rwlock 0x.........
at 0x........: main (tc20_verifywrap.c:262)
+rwlock 0x........ was first observed at:
+ at 0x........: pthread_rwlock_init* (drd_pthread_intercepts.c:?)
+ by 0x........: main (tc20_verifywrap.c:216)
[1/1] mutex_destroy error checking mutex 0x........ rc 1 owner 1
Destroying locked mutex: mutex 0x........, recursion count 1, owner 1.
at 0x........: main (tc20_verifywrap.c:262)
+mutex 0x........ was first observed at:
+ at 0x........: pthread_mutex_init (drd_pthread_intercepts.c:?)
+ by 0x........: main (tc20_verifywrap.c:145)
[1/1] mutex_destroy invalid mutex 0x........ rc 0 owner 0
[1/1] mutex_trylock recursive mutex 0x........ rc 0 owner 0
[1/1] post_mutex_lock recursive mutex 0x........ rc 0 owner 0
Modified: trunk/drd/tests/tc20_verifywrap2.stderr.exp-glibc2.5
===================================================================
--- trunk/drd/tests/tc20_verifywrap2.stderr.exp-glibc2.5 2009-02-21 16:13:50 UTC (rev 9213)
+++ trunk/drd/tests/tc20_verifywrap2.stderr.exp-glibc2.5 2009-02-21 16:17:50 UTC (rev 9214)
@@ -29,6 +29,9 @@
Destroying locked mutex: mutex 0x........, recursion count 1, owner 1.
at 0x........: pthread_mutex_destroy (drd_pthread_intercepts.c:?)
by 0x........: main (tc20_verifywrap.c:102)
+mutex 0x........ was first observed at:
+ at 0x........: pthread_mutex_init (drd_pthread_intercepts.c:?)
+ by 0x........: main (tc20_verifywrap.c:100)
[1/1] mutex_trylock invalid mutex 0x........ rc 0 owner 0
The object at address 0x........ is not a mutex.
@@ -165,10 +168,16 @@
Destroying locked rwlock: rwlock 0x.........
at 0x........: main (tc20_verifywrap.c:262)
+rwlock 0x........ was first observed at:
+ at 0x........: pthread_rwlock_init* (drd_pthread_intercepts.c:?)
+ by 0x........: main (tc20_verifywrap.c:216)
[1/1] mutex_destroy error checking mutex 0x........ rc 1 owner 1
Destroying locked mutex: mutex 0x........, recursion count 1, owner 1.
at 0x........: main (tc20_verifywrap.c:262)
+mutex 0x........ was first observed at:
+ at 0x........: pthread_mutex_init (drd_pthread_intercepts.c:?)
+ by 0x........: main (tc20_verifywrap.c:145)
[1/1] mutex_destroy invalid mutex 0x........ rc 0 owner 0
[1/1] mutex_trylock recursive mutex 0x........ rc 0 owner 0
[1/1] post_mutex_lock recursive mutex 0x........ rc 0 owner 0
Modified: trunk/drd/tests/tc20_verifywrap2.stderr.exp-glibc2.5-ppc
===================================================================
--- trunk/drd/tests/tc20_verifywrap2.stderr.exp-glibc2.5-ppc 2009-02-21 16:13:50 UTC (rev 9213)
+++ trunk/drd/tests/tc20_verifywrap2.stderr.exp-glibc2.5-ppc 2009-02-21 16:17:50 UTC (rev 9214)
@@ -29,6 +29,9 @@
Destroying locked mutex: mutex 0x........, recursion count 1, owner 1.
at 0x........: pthread_mutex_destroy (drd_pthread_intercepts.c:?)
by 0x........: main (tc20_verifywrap.c:102)
+mutex 0x........ was first observed at:
+ at 0x........: pthread_mutex_init (drd_pthread_intercepts.c:?)
+ by 0x........: main (tc20_verifywrap.c:100)
[1/1] mutex_trylock invalid mutex 0x........ rc 0 owner 0
The object at address 0x........ is not a mutex.
Modified: trunk/drd/tests/tc20_verifywrap2.stderr.exp-glibc2.8
===================================================================
--- trunk/drd/tests/tc20_verifywrap2.stderr.exp-glibc2.8 2009-02-21 16:13:50 UTC (rev 9213)
+++ trunk/drd/tests/tc20_verifywrap2.stderr.exp-glibc2.8 2009-02-21 16:17:50 UTC (rev 9214)
@@ -29,6 +29,9 @@
Destroying locked mutex: mutex 0x........, recursion count 1, owner 1.
at 0x........: pthread_mutex_destroy (drd_pthread_intercepts.c:?)
by 0x........: main (tc20_verifywrap.c:102)
+mutex 0x........ was first observed at:
+ at 0x........: pthread_mutex_init (drd_pthread_intercepts.c:?)
+ by 0x........: main (tc20_verifywrap.c:100)
[1/1] mutex_trylock invalid mutex 0x........ rc 0 owner 0
The object at address 0x........ is not a mutex.
|
|
From: <sv...@va...> - 2009-02-21 16:14:01
|
Author: bart
Date: 2009-02-21 16:13:50 +0000 (Sat, 21 Feb 2009)
New Revision: 9213
Log:
Updated test plan.
Modified:
trunk/drd/Testing.txt
Modified: trunk/drd/Testing.txt
===================================================================
--- trunk/drd/Testing.txt 2009-02-21 16:12:20 UTC (rev 9212)
+++ trunk/drd/Testing.txt 2009-02-21 16:13:50 UTC (rev 9213)
@@ -1,28 +1,34 @@
How to test DRD
~~~~~~~~~~~~~~~
-1. Run the regression tests. After having compiled DRD, run the following
- command:
+1. Start with compiling DRD.
+2. Check as follows that all global symbols in DRD have been wrapped by the
+ DRD_() macro (output must be empty):
+ nm -A drd*.o|grep ' T '|grep -v ' T vgDrd_'
+3. Check as follows that all global symbols in the preloaded shared library
+ are redirected functions (output must be empty):
+ nm -A vgpreload*.o|grep ' T '|grep -v ' T _vg'
+4. Run the regression tests as follows:
perl tests/vg_regtest drd
-2. Run Konstantin's regression tests:
+5. Run Konstantin's regression tests:
svn checkout http://data-race-test.googlecode.com/svn/trunk drt
make -C drt/unittest -s build
./vg-in-place --tool=drd --check-stack-var=yes drt/unittest/racecheck_unittest 2>&1|less
-3. Test the slowdown for matinv for various matrix sizes via the script
+6. Test the slowdown for matinv for various matrix sizes via the script
drd/scripts/run-matinv (must be about 24 for i == 1 and about
31 for i == 10 with n == 200).
-4. Test whether DRD works with standard KDE applications and whether it does
+7. Test whether DRD works with standard KDE applications and whether it does
not print any false positives. Test this both with KDE3 and KDE4.
./vg-in-place --tool=drd --var-info=yes kate
./vg-in-place --tool=drd --var-info=yes --check-stack-var=yes kate
./vg-in-place --tool=drd --var-info=yes --trace-children=yes knode
./vg-in-place --tool=drd --var-info=yes --check-stack-var=yes --trace-children=yes knode
./vg-in-place --tool=drd --var-info=yes --check-stack-var=yes /usr/bin/designer
-5. Test whether DRD works with standard GNOME applications. Expect
+8. Test whether DRD works with standard GNOME applications. Expect
race reports triggered by ORBit_RootObject_duplicate() and after
having closed the GNOME terminal window:
./vg-in-place --tool=drd --var-info=yes --trace-children=yes gnome-terminal
-6. Test DRD with Firefox. First of all, make sure that Valgrind is patched
+9. Test DRD with Firefox. First of all, make sure that Valgrind is patched
such that it supports libjemalloc.so:
drd/scripts/add-libjemalloc-support
Next, build and install Firefox 3:
|
|
From: <sv...@va...> - 2009-02-21 16:12:29
|
Author: bart
Date: 2009-02-21 16:12:20 +0000 (Sat, 21 Feb 2009)
New Revision: 9212
Log:
VG_(OSetGen_ResetIterAt)() now also works for OSet's that do not have an
explicit comparison function.
Modified:
trunk/coregrind/m_oset.c
Modified: trunk/coregrind/m_oset.c
===================================================================
--- trunk/coregrind/m_oset.c 2009-02-21 15:27:04 UTC (rev 9211)
+++ trunk/coregrind/m_oset.c 2009-02-21 16:12:20 UTC (rev 9212)
@@ -808,9 +808,6 @@
if (oset->cmp) {
cmpresS = (Word)slow_cmp(oset, k, t);
} else {
- /* this is believed to be correct, but really needs testing
- before the assertion is removed. */
- vg_assert(0);
cmpresS = fast_cmp(k, t);
}
|
|
From: <sv...@va...> - 2009-02-21 15:27:22
|
Author: bart
Date: 2009-02-21 15:27:04 +0000 (Sat, 21 Feb 2009)
New Revision: 9211
Log:
Changes:
- pthread_barrier_wait() intercept now passes the information to the DRD
tool whether or not this function returned
PTHREAD_BARRIER_SERIAL_THREAD. This information is now displayed when
the command-line option --trace-barrier=yes has been specified.
- Changed the cleanup functions for client objects that are called just
before a thread stops into callback functions.
- Added DRD_(clientobj_delete_thread)().
- Removed DRD_(clientobj_resetiter)(void) and DRD_(clientobj_next)().
- Added test for race conditions between pthread_barrier_wait() and
pthread_barrier_destroy() calls. An error message is now printed if
this condition has been detected.
- Bug fix: pthread_barrier_delete() calls on barriers being waited upon
are now reported.
- Removed DRD_() wrapper from around the name of some static variables and
functions.
Modified:
trunk/drd/drd_barrier.c
trunk/drd/drd_barrier.h
trunk/drd/drd_clientobj.c
trunk/drd/drd_clientobj.h
trunk/drd/drd_clientreq.c
trunk/drd/drd_clientreq.h
trunk/drd/drd_cond.c
trunk/drd/drd_cond.h
trunk/drd/drd_error.c
trunk/drd/drd_error.h
trunk/drd/drd_mutex.c
trunk/drd/drd_mutex.h
trunk/drd/drd_pthread_intercepts.c
trunk/drd/drd_rwlock.c
trunk/drd/drd_rwlock.h
trunk/drd/drd_semaphore.c
trunk/drd/drd_semaphore.h
trunk/drd/drd_thread.c
Modified: trunk/drd/drd_barrier.c
===================================================================
--- trunk/drd/drd_barrier.c 2009-02-21 11:52:27 UTC (rev 9210)
+++ trunk/drd/drd_barrier.c 2009-02-21 15:27:04 UTC (rev 9211)
@@ -40,57 +40,75 @@
/** Information associated with one thread participating in a barrier. */
struct barrier_thread_info
{
- UWord tid; // A DrdThreadId
+ UWord tid; // A DrdThreadId declared as UWord because
+ // this member variable is the key of an OSet.
Word iteration; // iteration of last pthread_barrier_wait()
// call thread tid participated in.
Segment* sg[2]; // Segments of the last two
// pthread_barrier() calls by thread tid.
+ ExeContext* wait_call_ctxt;// call stack for *_barrier_wait() call.
+ Segment* post_wait_sg; // Segment created after *_barrier_wait() finished
};
/* Local functions. */
-static void DRD_(barrier_cleanup)(struct barrier_info* p);
-static const char* DRD_(barrier_get_typename)(struct barrier_info* const p);
-static const char* DRD_(barrier_type_name)(const BarrierT bt);
+static void barrier_cleanup(struct barrier_info* p);
+static void barrier_delete_thread(struct barrier_info* const p,
+ const DrdThreadId tid);
+static const char* barrier_get_typename(struct barrier_info* const p);
+static const char* barrier_type_name(const BarrierT bt);
+static
+void barrier_report_wait_delete_race(const struct barrier_info* const p,
+ const struct barrier_thread_info* const q);
/* Local variables. */
-static Bool DRD_(s_trace_barrier) = False;
-static ULong DRD_(s_barrier_segment_creation_count);
+static Bool s_trace_barrier = False;
+static ULong s_barrier_segment_creation_count;
/* Function definitions. */
void DRD_(barrier_set_trace)(const Bool trace_barrier)
{
- DRD_(s_trace_barrier) = trace_barrier;
+ s_trace_barrier = trace_barrier;
}
-/** Initialize the structure *p with the specified thread ID and iteration
- * information. */
+/**
+ * Initialize the structure *p with the specified thread ID and iteration
+ * information.
+ */
static
void DRD_(barrier_thread_initialize)(struct barrier_thread_info* const p,
const DrdThreadId tid,
const Word iteration)
{
- p->tid = tid;
- p->iteration = iteration;
- p->sg[0] = 0;
- p->sg[1] = 0;
+ p->tid = tid;
+ p->iteration = iteration;
+ p->sg[0] = 0;
+ p->sg[1] = 0;
+ p->wait_call_ctxt = 0;
+ p->post_wait_sg = 0;
}
-/** Deallocate the memory that was allocated in barrier_thread_initialize(). */
+/**
+ * Deallocate the memory that is owned by members of
+ * struct barrier_thread_info.
+ */
static void DRD_(barrier_thread_destroy)(struct barrier_thread_info* const p)
{
tl_assert(p);
DRD_(sg_put)(p->sg[0]);
DRD_(sg_put)(p->sg[1]);
+ DRD_(sg_put)(p->post_wait_sg);
}
-/** Initialize the structure *p with the specified client-side barrier address,
- * barrier object size and number of participants in each barrier. */
+/**
+ * Initialize the structure *p with the specified client-side barrier address,
+ * barrier object size and number of participants in each barrier.
+ */
static
void DRD_(barrier_initialize)(struct barrier_info* const p,
const Addr barrier,
@@ -101,13 +119,16 @@
tl_assert(barrier_type == pthread_barrier || barrier_type == gomp_barrier);
tl_assert(p->a1 == barrier);
- p->cleanup = (void(*)(DrdClientobj*))DRD_(barrier_cleanup);
+ p->cleanup = (void(*)(DrdClientobj*))barrier_cleanup;
+ p->delete_thread
+ = (void(*)(DrdClientobj*, DrdThreadId))barrier_delete_thread;
p->barrier_type = barrier_type;
p->count = count;
p->pre_iteration = 0;
p->post_iteration = 0;
p->pre_waiters_left = count;
p->post_waiters_left = count;
+
tl_assert(sizeof(((struct barrier_thread_info*)0)->tid) == sizeof(Word));
tl_assert(sizeof(((struct barrier_thread_info*)0)->tid)
>= sizeof(DrdThreadId));
@@ -116,18 +137,21 @@
}
/**
- * Deallocate the memory allocated by barrier_initialize() and in p->oset.
+ * Deallocate the memory owned by the struct barrier_info object and also
+ * all the nodes in the OSet p->oset.
+ *
* Called by clientobj_destroy().
*/
-void DRD_(barrier_cleanup)(struct barrier_info* p)
+static void barrier_cleanup(struct barrier_info* p)
{
struct barrier_thread_info* q;
+ Segment* latest_sg = 0;
tl_assert(p);
if (p->pre_waiters_left != p->count)
{
- BarrierErrInfo bei = { p->a1 };
+ BarrierErrInfo bei = { p->a1, 0, 0 };
VG_(maybe_record_error)(VG_(get_running_tid)(),
BarrierErr,
VG_(get_IP)(VG_(get_running_tid)()),
@@ -136,16 +160,29 @@
&bei);
}
+ DRD_(thread_get_latest_segment)(&latest_sg, DRD_(thread_get_running_tid)());
+ tl_assert(latest_sg);
+
VG_(OSetGen_ResetIter)(p->oset);
for ( ; (q = VG_(OSetGen_Next)(p->oset)) != 0; )
{
+ if (q->post_wait_sg
+ && ! DRD_(vc_lte)(&q->post_wait_sg->vc, &latest_sg->vc))
+ {
+ barrier_report_wait_delete_race(p, q);
+ }
+
DRD_(barrier_thread_destroy)(q);
}
VG_(OSetGen_Destroy)(p->oset);
+
+ DRD_(sg_put)(latest_sg);
}
-/** Look up the client-side barrier address barrier in s_barrier[]. If not
- * found, add it. */
+/**
+ * Look up the client-side barrier address barrier in s_barrier[]. If not
+ * found, add it.
+ */
static
struct barrier_info*
DRD_(barrier_get_or_allocate)(const Addr barrier,
@@ -165,17 +202,21 @@
return p;
}
-/** Look up the address of the information associated with the client-side
- * barrier object. */
+/**
+ * Look up the address of the information associated with the client-side
+ * barrier object.
+ */
static struct barrier_info* DRD_(barrier_get)(const Addr barrier)
{
tl_assert(offsetof(DrdClientobj, barrier) == 0);
return &(DRD_(clientobj_get)(barrier, ClientBarrier)->barrier);
}
-/** Initialize a barrier with client address barrier, client size size, and
- * where count threads participate in each barrier.
- * Called before pthread_barrier_init().
+/**
+ * Initialize a barrier with client address barrier, client size size, and
+ * where count threads participate in each barrier.
+ *
+ * Called before pthread_barrier_init().
*/
void DRD_(barrier_init)(const Addr barrier,
const BarrierT barrier_type, const Word count,
@@ -187,7 +228,7 @@
if (count == 0)
{
- BarrierErrInfo bei = { barrier };
+ BarrierErrInfo bei = { barrier, 0, 0 };
VG_(maybe_record_error)(VG_(get_running_tid)(),
BarrierErr,
VG_(get_IP)(VG_(get_running_tid)()),
@@ -200,7 +241,7 @@
p = DRD_(barrier_get)(barrier);
if (p)
{
- BarrierErrInfo bei = { barrier };
+ BarrierErrInfo bei = { barrier, 0, 0 };
VG_(maybe_record_error)(VG_(get_running_tid)(),
BarrierErr,
VG_(get_IP)(VG_(get_running_tid)()),
@@ -210,7 +251,7 @@
}
p = DRD_(barrier_get_or_allocate)(barrier, barrier_type, count);
- if (DRD_(s_trace_barrier))
+ if (s_trace_barrier)
{
if (reinitialization)
{
@@ -218,7 +259,7 @@
"[%d/%d] barrier_reinit %s 0x%lx count %ld -> %ld",
VG_(get_running_tid)(),
DRD_(thread_get_running_tid)(),
- DRD_(barrier_get_typename)(p),
+ barrier_get_typename(p),
barrier,
p->count,
count);
@@ -229,7 +270,7 @@
"[%d/%d] barrier_init %s 0x%lx",
VG_(get_running_tid)(),
DRD_(thread_get_running_tid)(),
- DRD_(barrier_get_typename)(p),
+ barrier_get_typename(p),
barrier);
}
}
@@ -238,7 +279,7 @@
{
if (p->pre_waiters_left != p->count || p->post_waiters_left != p->count)
{
- BarrierErrInfo bei = { p->a1 };
+ BarrierErrInfo bei = { p->a1, 0, 0 };
VG_(maybe_record_error)(VG_(get_running_tid)(),
BarrierErr,
VG_(get_IP)(VG_(get_running_tid)()),
@@ -250,20 +291,20 @@
}
}
-/** Called after pthread_barrier_destroy(). */
+/** Called after pthread_barrier_destroy() / gomp_barrier_destroy(). */
void DRD_(barrier_destroy)(const Addr barrier, const BarrierT barrier_type)
{
struct barrier_info* p;
p = DRD_(barrier_get)(barrier);
- if (DRD_(s_trace_barrier))
+ if (s_trace_barrier)
{
VG_(message)(Vg_UserMsg,
"[%d/%d] barrier_destroy %s 0x%lx",
VG_(get_running_tid)(),
DRD_(thread_get_running_tid)(),
- DRD_(barrier_get_typename)(p),
+ barrier_get_typename(p),
barrier);
}
@@ -280,7 +321,7 @@
if (p->pre_waiters_left != p->count || p->post_waiters_left != p->count)
{
- BarrierErrInfo bei = { p->a1 };
+ BarrierErrInfo bei = { p->a1, 0, 0 };
VG_(maybe_record_error)(VG_(get_running_tid)(),
BarrierErr,
VG_(get_IP)(VG_(get_running_tid)()),
@@ -291,7 +332,7 @@
DRD_(clientobj_remove)(p->a1, ClientBarrier);
}
-/** Called before pthread_barrier_wait(). */
+/** Called before pthread_barrier_wait() / gomp_barrier_wait(). */
void DRD_(barrier_pre_wait)(const DrdThreadId tid, const Addr barrier,
const BarrierT barrier_type)
{
@@ -302,6 +343,11 @@
p = DRD_(barrier_get)(barrier);
if (p == 0 && barrier_type == gomp_barrier)
{
+ /*
+ * gomp_barrier_wait() call has been intercepted but gomp_barrier_init()
+ * not. The only cause I know of that can trigger this is that libgomp.so
+ * has been compiled with --enable-linux-futex.
+ */
VG_(message)(Vg_UserMsg, "");
VG_(message)(Vg_UserMsg,
"Please verify whether gcc has been configured"
@@ -312,17 +358,18 @@
}
tl_assert(p);
- if (DRD_(s_trace_barrier))
+ if (s_trace_barrier)
{
VG_(message)(Vg_UserMsg,
"[%d/%d] barrier_pre_wait %s 0x%lx iteration %ld",
VG_(get_running_tid)(),
DRD_(thread_get_running_tid)(),
- DRD_(barrier_get_typename)(p),
+ barrier_get_typename(p),
barrier,
p->pre_iteration);
}
+ /* Allocate the per-thread data structure if necessary. */
q = VG_(OSetGen_Lookup)(p->oset, &word_tid);
if (q == 0)
{
@@ -331,8 +378,21 @@
VG_(OSetGen_Insert)(p->oset, q);
tl_assert(VG_(OSetGen_Lookup)(p->oset, &word_tid) == q);
}
+
+ /* Record *_barrier_wait() call context. */
+ q->wait_call_ctxt = VG_(record_ExeContext)(VG_(get_running_tid)(), 0);
+
+ /*
+ * Store a pointer to the latest segment of the current thread in the
+ * per-thread data structure.
+ */
DRD_(thread_get_latest_segment)(&q->sg[p->pre_iteration], tid);
+ /*
+ * If the same number of threads as the barrier count indicates have
+ * called the pre *_barrier_wait() wrapper, toggle p->pre_iteration and
+ * reset the p->pre_waiters_left counter.
+ */
if (--p->pre_waiters_left <= 0)
{
p->pre_iteration = 1 - p->pre_iteration;
@@ -340,107 +400,144 @@
}
}
-/** Called after pthread_barrier_wait(). */
+/** Called after pthread_barrier_wait() / gomp_barrier_wait(). */
void DRD_(barrier_post_wait)(const DrdThreadId tid, const Addr barrier,
- const BarrierT barrier_type, const Bool waited)
+ const BarrierT barrier_type, const Bool waited,
+ const Bool serializing)
{
struct barrier_info* p;
+ const UWord word_tid = tid;
+ struct barrier_thread_info* q;
+ struct barrier_thread_info* r;
p = DRD_(barrier_get)(barrier);
- if (DRD_(s_trace_barrier))
+ if (s_trace_barrier)
{
VG_(message)(Vg_UserMsg,
- "[%d/%d] barrier_post_wait %s 0x%lx iteration %ld",
+ "[%d/%d] barrier_post_wait %s 0x%lx iteration %ld%s",
VG_(get_running_tid)(),
tid,
- p ? DRD_(barrier_get_typename)(p) : "(?)",
+ p ? barrier_get_typename(p) : "(?)",
barrier,
- p ? p->post_iteration : -1);
+ p ? p->post_iteration : -1,
+ serializing ? " (serializing)" : "");
}
- /* If p == 0, this means that the barrier has been destroyed after */
- /* *_barrier_wait() returned and before this function was called. Just */
- /* return in that case. */
+ /*
+ * If p == 0, this means that the barrier has been destroyed after
+ * *_barrier_wait() returned and before this function was called. Just
+ * return in that case -- race conditions between *_barrier_wait()
+ * and *_barrier_destroy() are detected by the *_barrier_destroy() wrapper.
+ */
if (p == 0)
return;
- if (waited)
+ /* If the *_barrier_wait() call returned an error code, exit. */
+ if (! waited)
+ return;
+
+ q = VG_(OSetGen_Lookup)(p->oset, &word_tid);
+ if (q == 0)
{
- const UWord word_tid = tid;
- struct barrier_thread_info* q;
- struct barrier_thread_info* r;
+ BarrierErrInfo bei = { p->a1, 0, 0 };
+ VG_(maybe_record_error)(VG_(get_running_tid)(),
+ BarrierErr,
+ VG_(get_IP)(VG_(get_running_tid)()),
+ "Error in barrier implementation"
+ " -- barrier_wait() started before"
+ " barrier_destroy() and finished after"
+ " barrier_destroy()",
+ &bei);
- q = VG_(OSetGen_Lookup)(p->oset, &word_tid);
- if (q == 0)
+ q = VG_(OSetGen_AllocNode)(p->oset, sizeof(*q));
+ DRD_(barrier_thread_initialize)(q, tid, p->pre_iteration);
+ VG_(OSetGen_Insert)(p->oset, q);
+ tl_assert(VG_(OSetGen_Lookup)(p->oset, &word_tid) == q);
+ }
+ /*
+ * Combine all vector clocks that were stored in the pre_barrier_wait
+ * wrapper with the vector clock of the current thread.
+ */
+ VG_(OSetGen_ResetIter)(p->oset);
+ for ( ; (r = VG_(OSetGen_Next)(p->oset)) != 0; )
+ {
+ if (r != q)
{
- BarrierErrInfo bei = { p->a1 };
- VG_(maybe_record_error)(VG_(get_running_tid)(),
- BarrierErr,
- VG_(get_IP)(VG_(get_running_tid)()),
- "Error in barrier implementation"
- " -- barrier_wait() started before"
- " barrier_destroy() and finished after"
- " barrier_destroy()",
- &bei);
-
- q = VG_(OSetGen_AllocNode)(p->oset, sizeof(*q));
- DRD_(barrier_thread_initialize)(q, tid, p->pre_iteration);
- VG_(OSetGen_Insert)(p->oset, q);
- tl_assert(VG_(OSetGen_Lookup)(p->oset, &word_tid) == q);
+ tl_assert(r->sg[p->post_iteration]);
+ DRD_(thread_combine_vc2)(tid, &r->sg[p->post_iteration]->vc);
}
- VG_(OSetGen_ResetIter)(p->oset);
- for ( ; (r = VG_(OSetGen_Next)(p->oset)) != 0; )
- {
- if (r != q)
- {
- tl_assert(r->sg[p->post_iteration]);
- DRD_(thread_combine_vc2)(tid, &r->sg[p->post_iteration]->vc);
- }
- }
+ }
- DRD_(thread_new_segment)(tid);
- DRD_(s_barrier_segment_creation_count)++;
+ /* Create a new segment and store a pointer to that segment. */
+ DRD_(thread_new_segment)(tid);
+ DRD_(thread_get_latest_segment)(&q->post_wait_sg, tid);
+ s_barrier_segment_creation_count++;
- if (--p->post_waiters_left <= 0)
- {
- p->post_iteration = 1 - p->post_iteration;
- p->post_waiters_left = p->count;
- }
+ /*
+ * If the same number of threads as the barrier count indicates have
+ * called the post *_barrier_wait() wrapper, toggle p->post_iteration and
+ * reset the p->post_waiters_left counter.
+ */
+ if (--p->post_waiters_left <= 0)
+ {
+ p->post_iteration = 1 - p->post_iteration;
+ p->post_waiters_left = p->count;
}
}
-/** Call this function when thread tid stops to exist. */
-void DRD_(barrier_thread_delete)(const DrdThreadId tid)
+/** Called when thread tid stops to exist. */
+static void barrier_delete_thread(struct barrier_info* const p,
+ const DrdThreadId tid)
{
- struct barrier_info* p;
+ struct barrier_thread_info* q;
+ const UWord word_tid = tid;
- DRD_(clientobj_resetiter)();
- for ( ; (p = &(DRD_(clientobj_next)(ClientBarrier)->barrier)) != 0; )
+ q = VG_(OSetGen_Remove)(p->oset, &word_tid);
+
+ /*
+ * q is only non-zero if the barrier object has been used by thread tid
+ * after the barrier_init() call and before the thread finished.
+ */
+ if (q)
{
- struct barrier_thread_info* q;
- const UWord word_tid = tid;
- q = VG_(OSetGen_Remove)(p->oset, &word_tid);
- /* q is only non-zero if the barrier object has been used by thread tid
- * after the barrier_init() call and before the thread finished.
- */
- if (q)
- {
- DRD_(barrier_thread_destroy)(q);
- VG_(OSetGen_FreeNode)(p->oset, q);
- }
+ DRD_(barrier_thread_destroy)(q);
+ VG_(OSetGen_FreeNode)(p->oset, q);
}
}
-static const char* DRD_(barrier_get_typename)(struct barrier_info* const p)
+/**
+ * Report that *_barrier_destroy() has been called but that this call was
+ * not synchronized with the last *_barrier_wait() call on the same barrier.
+ */
+static
+void barrier_report_wait_delete_race(const struct barrier_info* const p,
+ const struct barrier_thread_info* const q)
{
tl_assert(p);
+ tl_assert(q);
- return DRD_(barrier_type_name)(p->barrier_type);
+ {
+ BarrierErrInfo bei
+ = { p->a1, q->tid, q->wait_call_ctxt };
+ VG_(maybe_record_error)(VG_(get_running_tid)(),
+ BarrierErr,
+ VG_(get_IP)(VG_(get_running_tid)()),
+ "Destruction of barrier not synchronized with"
+ " barrier wait call",
+ &bei);
+ }
}
-static const char* DRD_(barrier_type_name)(const BarrierT bt)
+static const char* barrier_get_typename(struct barrier_info* const p)
{
+ tl_assert(p);
+
+ return barrier_type_name(p->barrier_type);
+}
+
+static const char* barrier_type_name(const BarrierT bt)
+{
switch (bt)
{
case pthread_barrier:
@@ -453,5 +550,5 @@
ULong DRD_(get_barrier_segment_creation_count)(void)
{
- return DRD_(s_barrier_segment_creation_count);
+ return s_barrier_segment_creation_count;
}
Modified: trunk/drd/drd_barrier.h
===================================================================
--- trunk/drd/drd_barrier.h 2009-02-21 11:52:27 UTC (rev 9210)
+++ trunk/drd/drd_barrier.h 2009-02-21 15:27:04 UTC (rev 9211)
@@ -45,8 +45,8 @@
void DRD_(barrier_pre_wait)(const DrdThreadId tid, const Addr barrier,
const BarrierT barrier_type);
void DRD_(barrier_post_wait)(const DrdThreadId tid, const Addr barrier,
- const BarrierT barrier_type, const Bool waited);
-void DRD_(barrier_thread_delete)(const DrdThreadId threadid);
+ const BarrierT barrier_type, const Bool waited,
+ const Bool serializing);
void DRD_(barrier_stop_using_mem)(const Addr a1, const Addr a2);
ULong DRD_(get_barrier_segment_creation_count)(void);
Modified: trunk/drd/drd_clientobj.c
===================================================================
--- trunk/drd/drd_clientobj.c 2009-02-21 11:52:27 UTC (rev 9210)
+++ trunk/drd/drd_clientobj.c 2009-02-21 15:27:04 UTC (rev 9211)
@@ -37,26 +37,29 @@
/* Local variables. */
-static OSet* DRD_(s_clientobj_set);
-static Bool DRD_(s_trace_clientobj);
+static OSet* s_clientobj_set;
+static Bool s_trace_clientobj;
+/* Local functions. */
+
+static Bool clientobj_remove_obj(DrdClientobj* const p);
+
+
/* Function definitions. */
void DRD_(clientobj_set_trace)(const Bool trace)
{
- DRD_(s_trace_clientobj) = trace;
+ s_trace_clientobj = trace;
}
/** Initialize the client object set. */
void DRD_(clientobj_init)(void)
{
- tl_assert(DRD_(s_clientobj_set) == 0);
- DRD_(s_clientobj_set) = VG_(OSetGen_Create)(0, 0,
- VG_(malloc),
- "drd.clientobj.ci.1",
- VG_(free));
- tl_assert(DRD_(s_clientobj_set));
+ tl_assert(s_clientobj_set == 0);
+ s_clientobj_set = VG_(OSetGen_Create)(0, 0, VG_(malloc),
+ "drd.clientobj.ci.1", VG_(free));
+ tl_assert(s_clientobj_set);
}
/**
@@ -66,19 +69,20 @@
*/
void DRD_(clientobj_cleanup)(void)
{
- tl_assert(DRD_(s_clientobj_set));
- tl_assert(VG_(OSetGen_Size)(DRD_(s_clientobj_set)) == 0);
- VG_(OSetGen_Destroy)(DRD_(s_clientobj_set));
- DRD_(s_clientobj_set) = 0;
+ tl_assert(s_clientobj_set);
+ tl_assert(VG_(OSetGen_Size)(s_clientobj_set) == 0);
+ VG_(OSetGen_Destroy)(s_clientobj_set);
+ s_clientobj_set = 0;
}
-/** Return the data associated with the client object at client address addr.
- * Return 0 if there is no client object in the set with the specified start
- * address.
+/**
+ * Return the data associated with the client object at client address addr.
+ * Return 0 if there is no client object in the set with the specified start
+ * address.
*/
DrdClientobj* DRD_(clientobj_get_any)(const Addr addr)
{
- return VG_(OSetGen_Lookup)(DRD_(s_clientobj_set), &addr);
+ return VG_(OSetGen_Lookup)(s_clientobj_set, &addr);
}
/** Return the data associated with the client object at client address addr
@@ -88,7 +92,7 @@
DrdClientobj* DRD_(clientobj_get)(const Addr addr, const ObjType t)
{
DrdClientobj* p;
- p = VG_(OSetGen_Lookup)(DRD_(s_clientobj_set), &addr);
+ p = VG_(OSetGen_Lookup)(s_clientobj_set, &addr);
if (p && p->any.type == t)
return p;
return 0;
@@ -102,8 +106,8 @@
DrdClientobj *p;
tl_assert(a1 < a2);
- VG_(OSetGen_ResetIter)(DRD_(s_clientobj_set));
- for ( ; (p = VG_(OSetGen_Next)(DRD_(s_clientobj_set))) != 0; )
+ VG_(OSetGen_ResetIter)(s_clientobj_set);
+ for ( ; (p = VG_(OSetGen_Next)(s_clientobj_set)) != 0; )
{
if (a1 <= p->any.a1 && p->any.a1 < a2)
{
@@ -122,20 +126,20 @@
DrdClientobj* p;
tl_assert(! DRD_(clientobj_present)(a1, a1 + 1));
- tl_assert(VG_(OSetGen_Lookup)(DRD_(s_clientobj_set), &a1) == 0);
+ tl_assert(VG_(OSetGen_Lookup)(s_clientobj_set, &a1) == 0);
- if (DRD_(s_trace_clientobj))
+ if (s_trace_clientobj)
{
VG_(message)(Vg_UserMsg, "Adding client object 0x%lx of type %d", a1, t);
}
- p = VG_(OSetGen_AllocNode)(DRD_(s_clientobj_set), sizeof(*p));
+ p = VG_(OSetGen_AllocNode)(s_clientobj_set, sizeof(*p));
VG_(memset)(p, 0, sizeof(*p));
p->any.a1 = a1;
p->any.type = t;
p->any.first_observed_at = VG_(record_ExeContext)(VG_(get_running_tid)(), 0);
- VG_(OSetGen_Insert)(DRD_(s_clientobj_set), p);
- tl_assert(VG_(OSetGen_Lookup)(DRD_(s_clientobj_set), &a1) == p);
+ VG_(OSetGen_Insert)(s_clientobj_set, p);
+ tl_assert(VG_(OSetGen_Lookup)(s_clientobj_set, &a1) == p);
DRD_(start_suppression)(a1, a1 + 1, "clientobj");
return p;
}
@@ -144,28 +148,35 @@
{
DrdClientobj* p;
- if (DRD_(s_trace_clientobj))
+ p = VG_(OSetGen_Lookup)(s_clientobj_set, &addr);
+ tl_assert(p);
+ tl_assert(p->any.type == t);
+ return clientobj_remove_obj(p);
+}
+
+static Bool clientobj_remove_obj(DrdClientobj* const p)
+{
+ DrdClientobj* q;
+
+ if (s_trace_clientobj)
{
VG_(message)(Vg_UserMsg, "Removing client object 0x%lx of type %d",
- addr, t);
+ p->any.a1, p->any.type);
#if 0
VG_(get_and_pp_StackTrace)(VG_(get_running_tid)(),
VG_(clo_backtrace_size));
#endif
}
- p = VG_(OSetGen_Lookup)(DRD_(s_clientobj_set), &addr);
- tl_assert(p->any.type == t);
- p = VG_(OSetGen_Remove)(DRD_(s_clientobj_set), &addr);
- if (p)
- {
- tl_assert(VG_(OSetGen_Lookup)(DRD_(s_clientobj_set), &addr) == 0);
- tl_assert(p->any.cleanup);
- (*p->any.cleanup)(p);
- VG_(OSetGen_FreeNode)(DRD_(s_clientobj_set), p);
- return True;
- }
- return False;
+ tl_assert(p);
+ q = VG_(OSetGen_Remove)(s_clientobj_set, &p->any.a1);
+ tl_assert(p == q);
+
+ tl_assert(VG_(OSetGen_Lookup)(s_clientobj_set, &p->any.a1) == 0);
+ tl_assert(p->any.cleanup);
+ (*p->any.cleanup)(p);
+ VG_(OSetGen_FreeNode)(s_clientobj_set, p);
+ return True;
}
void DRD_(clientobj_stop_using_mem)(const Addr a1, const Addr a2)
@@ -173,13 +184,13 @@
Addr removed_at;
DrdClientobj* p;
- tl_assert(DRD_(s_clientobj_set));
+ tl_assert(s_clientobj_set);
if (! DRD_(is_any_suppressed)(a1, a2))
return;
- VG_(OSetGen_ResetIter)(DRD_(s_clientobj_set));
- p = VG_(OSetGen_Next)(DRD_(s_clientobj_set));
+ VG_(OSetGen_ResetIter)(s_clientobj_set);
+ p = VG_(OSetGen_Next)(s_clientobj_set);
for ( ; p != 0; )
{
if (a1 <= p->any.a1 && p->any.a1 < a2)
@@ -188,30 +199,34 @@
DRD_(clientobj_remove)(p->any.a1, p->any.type);
/* The above call removes an element from the oset and hence */
/* invalidates the iterator. Set the iterator back. */
- VG_(OSetGen_ResetIter)(DRD_(s_clientobj_set));
- while ((p = VG_(OSetGen_Next)(DRD_(s_clientobj_set))) != 0
+ VG_(OSetGen_ResetIter)(s_clientobj_set);
+ while ((p = VG_(OSetGen_Next)(s_clientobj_set)) != 0
&& p->any.a1 <= removed_at)
{ }
}
else
{
- p = VG_(OSetGen_Next)(DRD_(s_clientobj_set));
+ p = VG_(OSetGen_Next)(s_clientobj_set);
}
}
}
-void DRD_(clientobj_resetiter)(void)
+/**
+ * Delete the per-thread information stored in client objects for the
+ * specified thread.
+ */
+void DRD_(clientobj_delete_thread)(const DrdThreadId tid)
{
- VG_(OSetGen_ResetIter)(DRD_(s_clientobj_set));
-}
+ DrdClientobj *p;
-DrdClientobj* DRD_(clientobj_next)(const ObjType t)
-{
- DrdClientobj* p;
- while ((p = VG_(OSetGen_Next)(DRD_(s_clientobj_set))) != 0
- && p->any.type != t)
- ;
- return p;
+ VG_(OSetGen_ResetIter)(s_clientobj_set);
+ for ( ; (p = VG_(OSetGen_Next)(s_clientobj_set)) != 0; )
+ {
+ if (p->any.delete_thread)
+ {
+ (*p->any.delete_thread)(p, tid);
+ }
+ }
}
const char* DRD_(clientobj_type_name)(const ObjType t)
Modified: trunk/drd/drd_clientobj.h
===================================================================
--- trunk/drd/drd_clientobj.h 2009-02-21 11:52:27 UTC (rev 9210)
+++ trunk/drd/drd_clientobj.h 2009-02-21 15:27:04 UTC (rev 9211)
@@ -53,7 +53,8 @@
{
Addr a1;
ObjType type;
- void (*cleanup)(union drd_clientobj*);
+ void (*cleanup)(union drd_clientobj*);
+ void (*delete_thread)(union drd_clientobj*, DrdThreadId);
ExeContext* first_observed_at;
};
@@ -62,6 +63,7 @@
Addr a1;
ObjType type;
void (*cleanup)(union drd_clientobj*);
+ void (*delete_thread)(union drd_clientobj*, DrdThreadId);
ExeContext* first_observed_at;
MutexT mutex_type; // pthread_mutex_t or pthread_spinlock_t.
int recursion_count; // 0 if free, >= 1 if locked.
@@ -75,7 +77,8 @@
{
Addr a1;
ObjType type;
- void (*cleanup)(union drd_clientobj*);
+ void (*cleanup)(union drd_clientobj*);
+ void (*delete_thread)(union drd_clientobj*, DrdThreadId);
ExeContext* first_observed_at;
int waiter_count;
Addr mutex; // Client mutex specified in pthread_cond_wait() call, and
@@ -87,6 +90,7 @@
Addr a1;
ObjType type;
void (*cleanup)(union drd_clientobj*);
+ void (*delete_thread)(union drd_clientobj*, DrdThreadId);
ExeContext* first_observed_at;
UInt waits_to_skip; // Number of sem_wait() calls to skip
// (due to the value assigned by sem_init()).
@@ -101,14 +105,15 @@
Addr a1;
ObjType type;
void (*cleanup)(union drd_clientobj*);
+ void (*delete_thread)(union drd_clientobj*, DrdThreadId);
ExeContext* first_observed_at;
BarrierT barrier_type; // pthread_barrier or gomp_barrier.
Word count; // Participant count in a barrier wait.
- Word pre_iteration; // pthread_barrier_wait() call count modulo two.
- Word post_iteration; // pthread_barrier_wait() call count modulo two.
+ Word pre_iteration; // pre barrier completion count modulo two.
+ Word post_iteration; // post barrier completion count modulo two.
Word pre_waiters_left; // number of waiters left for a complete barrier.
Word post_waiters_left; // number of waiters left for a complete barrier.
- OSet* oset; // Thread-specific barrier information.
+ OSet* oset; // Per-thread barrier information.
};
struct rwlock_info
@@ -116,6 +121,7 @@
Addr a1;
ObjType type;
void (*cleanup)(union drd_clientobj*);
+ void (*delete_thread)(union drd_clientobj*, DrdThreadId);
ExeContext* first_observed_at;
OSet* thread_info;
ULong acquiry_time_ms;
@@ -144,8 +150,7 @@
DrdClientobj* DRD_(clientobj_add)(const Addr a1, const ObjType t);
Bool DRD_(clientobj_remove)(const Addr addr, const ObjType t);
void DRD_(clientobj_stop_using_mem)(const Addr a1, const Addr a2);
-void DRD_(clientobj_resetiter)(void);
-DrdClientobj* DRD_(clientobj_next)(const ObjType t);
+void DRD_(clientobj_delete_thread)(const DrdThreadId tid);
const char* DRD_(clientobj_type_name)(const ObjType t);
Modified: trunk/drd/drd_clientreq.c
===================================================================
--- trunk/drd/drd_clientreq.c 2009-02-21 11:52:27 UTC (rev 9210)
+++ trunk/drd/drd_clientreq.c 2009-02-21 15:27:04 UTC (rev 9211)
@@ -327,7 +327,7 @@
case VG_USERREQ__POST_BARRIER_WAIT:
if (DRD_(thread_leave_synchr)(drd_tid) == 0)
- DRD_(barrier_post_wait)(drd_tid, arg[1], arg[2], arg[3]);
+ DRD_(barrier_post_wait)(drd_tid, arg[1], arg[2], arg[3], arg[4]);
break;
case VG_USERREQ__PRE_RWLOCK_INIT:
Modified: trunk/drd/drd_clientreq.h
===================================================================
--- trunk/drd/drd_clientreq.h 2009-02-21 11:52:27 UTC (rev 9210)
+++ trunk/drd/drd_clientreq.h 2009-02-21 15:27:04 UTC (rev 9211)
@@ -178,7 +178,7 @@
/* args: Addr barrier, BarrierT type. */
/* To notify the drd tool of a pthread_barrier_wait call. */
VG_USERREQ__POST_BARRIER_WAIT,
- /* args: Addr barrier, BarrierT type, Word has_waited */
+ /* args: Addr barrier, BarrierT type, Word has_waited, Word serializing */
/* To notify the drd tool of a pthread_rwlock_init call. */
VG_USERREQ__PRE_RWLOCK_INIT,
Modified: trunk/drd/drd_cond.c
===================================================================
--- trunk/drd/drd_cond.c 2009-02-21 11:52:27 UTC (rev 9210)
+++ trunk/drd/drd_cond.c 2009-02-21 15:27:04 UTC (rev 9211)
@@ -65,9 +65,10 @@
tl_assert(p->a1 == cond);
tl_assert(p->type == ClientCondvar);
- p->cleanup = (void(*)(DrdClientobj*))(DRD_(cond_cleanup));
- p->waiter_count = 0;
- p->mutex = 0;
+ p->cleanup = (void(*)(DrdClientobj*))(DRD_(cond_cleanup));
+ p->delete_thread = 0;
+ p->waiter_count = 0;
+ p->mutex = 0;
}
/**
@@ -328,7 +329,3 @@
DRD_(cond_signal)(cond);
}
-
-/** Called after pthread_cond_destroy(). */
-void DRD_(cond_thread_delete)(const DrdThreadId tid)
-{ }
Modified: trunk/drd/drd_cond.h
===================================================================
--- trunk/drd/drd_cond.h 2009-02-21 11:52:27 UTC (rev 9210)
+++ trunk/drd/drd_cond.h 2009-02-21 15:27:04 UTC (rev 9211)
@@ -45,7 +45,6 @@
int DRD_(cond_post_wait)(const Addr cond);
void DRD_(cond_pre_signal)(const Addr cond);
void DRD_(cond_pre_broadcast)(const Addr cond);
-void DRD_(cond_thread_delete)(const DrdThreadId tid);
#endif /* __DRD_COND_H */
Modified: trunk/drd/drd_error.c
===================================================================
--- trunk/drd/drd_error.c 2009-02-21 11:52:27 UTC (rev 9210)
+++ trunk/drd/drd_error.c 2009-02-21 15:27:04 UTC (rev 9211)
@@ -42,12 +42,12 @@
/* Local variables. */
-static Bool DRD_(s_show_conflicting_segments) = True;
+static Bool s_show_conflicting_segments = True;
void DRD_(set_show_conflicting_segments)(const Bool scs)
{
- DRD_(s_show_conflicting_segments) = scs;
+ s_show_conflicting_segments = scs;
}
/**
@@ -55,8 +55,7 @@
* messages, putting the result in ai.
*/
static
-void DRD_(describe_malloced_addr)(Addr const a, SizeT const len,
- AddrInfo* const ai)
+void describe_malloced_addr(Addr const a, SizeT const len, AddrInfo* const ai)
{
Addr data;
@@ -76,7 +75,7 @@
* call stack will either refer to a pthread_*_init() or a pthread_*lock()
* call.
*/
-static void DRD_(first_observed)(const Addr obj)
+static void first_observed(const Addr obj)
{
DrdClientobj* cl;
@@ -93,8 +92,7 @@
}
static
-void DRD_(drd_report_data_race)(Error* const err,
- const DataRaceErrInfo* const dri)
+void drd_report_data_race(Error* const err, const DataRaceErrInfo* const dri)
{
AddrInfo ai;
const unsigned descr_size = 256;
@@ -112,7 +110,7 @@
VG_(get_data_description)(descr1, descr2, descr_size, dri->addr);
if (descr1[0] == 0)
{
- DRD_(describe_malloced_addr)(dri->addr, dri->size, &ai);
+ describe_malloced_addr(dri->addr, dri->size, &ai);
}
VG_(message)(Vg_UserMsg,
"Conflicting %s by thread %d/%d at 0x%08lx size %ld",
@@ -153,7 +151,7 @@
VG_(message)(Vg_UserMsg, "Allocation context: unknown.");
}
}
- if (DRD_(s_show_conflicting_segments))
+ if (s_show_conflicting_segments)
{
DRD_(thread_report_conflicting_segments)(dri->tid,
dri->addr, dri->size,
@@ -164,17 +162,17 @@
VG_(free)(descr1);
}
-static Bool DRD_(drd_tool_error_eq)(VgRes res, Error* e1, Error* e2)
+static Bool drd_tool_error_eq(VgRes res, Error* e1, Error* e2)
{
return False;
}
-static void DRD_(drd_tool_error_pp)(Error* const e)
+static void drd_tool_error_pp(Error* const e)
{
switch (VG_(get_error_kind)(e))
{
case DataRaceErr: {
- DRD_(drd_report_data_race)(e, VG_(get_error_extra)(e));
+ drd_report_data_race(e, VG_(get_error_extra)(e));
break;
}
case MutexErr: {
@@ -196,7 +194,7 @@
p->mutex);
}
VG_(pp_ExeContext)(VG_(get_error_where)(e));
- DRD_(first_observed)(p->mutex);
+ first_observed(p->mutex);
break;
}
case CondErr: {
@@ -206,7 +204,7 @@
VG_(get_error_string)(e),
cdei->cond);
VG_(pp_ExeContext)(VG_(get_error_where)(e));
- DRD_(first_observed)(cdei->cond);
+ first_observed(cdei->cond);
break;
}
case CondDestrErr: {
@@ -217,7 +215,7 @@
cdi->cond, cdi->mutex,
DRD_(DrdThreadIdToVgThreadId)(cdi->tid), cdi->tid);
VG_(pp_ExeContext)(VG_(get_error_where)(e));
- DRD_(first_observed)(cdi->mutex);
+ first_observed(cdi->mutex);
break;
}
case CondRaceErr: {
@@ -228,8 +226,8 @@
" by the signalling thread.",
cei->cond, cei->mutex);
VG_(pp_ExeContext)(VG_(get_error_where)(e));
- DRD_(first_observed)(cei->cond);
- DRD_(first_observed)(cei->mutex);
+ first_observed(cei->cond);
+ first_observed(cei->mutex);
break;
}
case CondWaitErr: {
@@ -241,9 +239,9 @@
cwei->mutex1,
cwei->mutex2);
VG_(pp_ExeContext)(VG_(get_error_where)(e));
- DRD_(first_observed)(cwei->cond);
- DRD_(first_observed)(cwei->mutex1);
- DRD_(first_observed)(cwei->mutex2);
+ first_observed(cwei->cond);
+ first_observed(cwei->mutex1);
+ first_observed(cwei->mutex2);
break;
}
case SemaphoreErr: {
@@ -254,18 +252,26 @@
VG_(get_error_string)(e),
sei->semaphore);
VG_(pp_ExeContext)(VG_(get_error_where)(e));
- DRD_(first_observed)(sei->semaphore);
+ first_observed(sei->semaphore);
break;
}
case BarrierErr: {
- BarrierErrInfo* bei =(BarrierErrInfo*)(VG_(get_error_extra)(e));
+ BarrierErrInfo* bei = (BarrierErrInfo*)(VG_(get_error_extra)(e));
tl_assert(bei);
VG_(message)(Vg_UserMsg,
"%s: barrier 0x%lx",
VG_(get_error_string)(e),
bei->barrier);
VG_(pp_ExeContext)(VG_(get_error_where)(e));
- DRD_(first_observed)(bei->barrier);
+ if (bei->other_context)
+ {
+ VG_(message)(Vg_UserMsg,
+ "Conflicting wait call by thread %d/%d:",
+ DRD_(DrdThreadIdToVgThreadId)(bei->other_tid),
+ bei->other_tid);
+ VG_(pp_ExeContext)(bei->other_context);
+ }
+ first_observed(bei->barrier);
break;
}
case RwlockErr: {
@@ -276,7 +282,7 @@
VG_(get_error_string)(e),
p->rwlock);
VG_(pp_ExeContext)(VG_(get_error_where)(e));
- DRD_(first_observed)(p->rwlock);
+ first_observed(p->rwlock);
break;
}
case HoldtimeErr: {
@@ -292,7 +298,7 @@
p->hold_time_ms,
p->threshold_ms);
VG_(pp_ExeContext)(VG_(get_error_where)(e));
- DRD_(first_observed)(p->synchronization_object);
+ first_observed(p->synchronization_object);
break;
}
case GenericErr: {
@@ -310,7 +316,7 @@
}
}
-static UInt DRD_(drd_tool_error_update_extra)(Error* e)
+static UInt drd_tool_error_update_extra(Error* e)
{
switch (VG_(get_error_kind)(e))
{
@@ -342,7 +348,7 @@
}
}
-static Bool DRD_(drd_tool_error_recog)(Char* const name, Supp* const supp)
+static Bool drd_tool_error_recog(Char* const name, Supp* const supp)
{
SuppKind skind = 0;
@@ -376,12 +382,12 @@
}
static
-Bool DRD_(drd_tool_error_read_extra)(Int fd, Char* buf, Int nBuf, Supp* supp)
+Bool drd_tool_error_read_extra(Int fd, Char* buf, Int nBuf, Supp* supp)
{
return True;
}
-static Bool DRD_(drd_tool_error_matches)(Error* const e, Supp* const supp)
+static Bool drd_tool_error_matches(Error* const e, Supp* const supp)
{
switch (VG_(get_supp_kind)(supp))
{
@@ -389,7 +395,7 @@
return True;
}
-static Char* DRD_(drd_tool_error_name)(Error* e)
+static Char* drd_tool_error_name(Error* e)
{
switch (VG_(get_error_kind)(e))
{
@@ -410,19 +416,19 @@
return 0;
}
-static void DRD_(drd_tool_error_print_extra)(Error* e)
+static void drd_tool_error_print_extra(Error* e)
{ }
void DRD_(register_error_handlers)(void)
{
// Tool error reporting.
- VG_(needs_tool_errors)(DRD_(drd_tool_error_eq),
- DRD_(drd_tool_error_pp),
+ VG_(needs_tool_errors)(drd_tool_error_eq,
+ drd_tool_error_pp,
True,
- DRD_(drd_tool_error_update_extra),
- DRD_(drd_tool_error_recog),
- DRD_(drd_tool_error_read_extra),
- DRD_(drd_tool_error_matches),
- DRD_(drd_tool_error_name),
- DRD_(drd_tool_error_print_extra));
+ drd_tool_error_update_extra,
+ drd_tool_error_recog,
+ drd_tool_error_read_extra,
+ drd_tool_error_matches,
+ drd_tool_error_name,
+ drd_tool_error_print_extra);
}
Modified: trunk/drd/drd_error.h
===================================================================
--- trunk/drd/drd_error.h 2009-02-21 11:52:27 UTC (rev 9210)
+++ trunk/drd/drd_error.h 2009-02-21 15:27:04 UTC (rev 9211)
@@ -128,7 +128,9 @@
} SemaphoreErrInfo;
typedef struct {
- Addr barrier;
+ Addr barrier;
+ DrdThreadId other_tid;
+ ExeContext* other_context;
} BarrierErrInfo;
typedef struct {
Modified: trunk/drd/drd_mutex.c
===================================================================
--- trunk/drd/drd_mutex.c 2009-02-21 11:52:27 UTC (rev 9210)
+++ trunk/drd/drd_mutex.c 2009-02-21 15:27:04 UTC (rev 9211)
@@ -38,16 +38,17 @@
/* Local functions. */
-static void DRD_(mutex_cleanup)(struct mutex_info* p);
-static Bool DRD_(mutex_is_locked)(struct mutex_info* const p);
+static void mutex_cleanup(struct mutex_info* p);
+static Bool mutex_is_locked(struct mutex_info* const p);
+static void mutex_delete_thread(struct mutex_info* p, const DrdThreadId tid);
/* Local variables. */
-static Bool DRD_(s_trace_mutex);
-static ULong DRD_(s_mutex_lock_count);
-static ULong DRD_(s_mutex_segment_creation_count);
-static UInt DRD_(s_mutex_lock_threshold_ms) = 1000 * 1000;
+static Bool s_trace_mutex;
+static ULong s_mutex_lock_count;
+static ULong s_mutex_segment_creation_count;
+static UInt s_mutex_lock_threshold_ms = 1000 * 1000;
/* Function definitions. */
@@ -55,12 +56,12 @@
void DRD_(mutex_set_trace)(const Bool trace_mutex)
{
tl_assert(!! trace_mutex == trace_mutex);
- DRD_(s_trace_mutex) = trace_mutex;
+ s_trace_mutex = trace_mutex;
}
void DRD_(mutex_set_lock_threshold)(const UInt lock_threshold_ms)
{
- DRD_(s_mutex_lock_threshold_ms) = lock_threshold_ms;
+ s_mutex_lock_threshold_ms = lock_threshold_ms;
}
static
@@ -71,7 +72,9 @@
tl_assert(mutex_type != mutex_type_unknown);
tl_assert(p->a1 == mutex);
- p->cleanup = (void(*)(DrdClientobj*))&(DRD_(mutex_cleanup));
+ p->cleanup = (void(*)(DrdClientobj*))mutex_cleanup;
+ p->delete_thread
+ = (void(*)(DrdClientobj*, DrdThreadId))mutex_delete_thread;
p->mutex_type = mutex_type;
p->recursion_count = 0;
p->owner = DRD_INVALID_THREADID;
@@ -81,11 +84,11 @@
}
/** Deallocate the memory that was allocated by mutex_initialize(). */
-static void DRD_(mutex_cleanup)(struct mutex_info* p)
+static void mutex_cleanup(struct mutex_info* p)
{
tl_assert(p);
- if (DRD_(s_trace_mutex))
+ if (s_trace_mutex)
{
VG_(message)(Vg_UserMsg,
"[%d/%d] mutex_destroy %s 0x%lx rc %d owner %d",
@@ -97,7 +100,7 @@
p ? p->owner : DRD_INVALID_THREADID);
}
- if (DRD_(mutex_is_locked)(p))
+ if (mutex_is_locked(p))
{
MutexErrInfo MEI = { p->a1, p->recursion_count, p->owner };
VG_(maybe_record_error)(VG_(get_running_tid)(),
@@ -162,7 +165,7 @@
tl_assert(mutex_type != mutex_type_unknown);
- if (DRD_(s_trace_mutex))
+ if (s_trace_mutex)
{
VG_(message)(Vg_UserMsg,
"[%d/%d] mutex_init %s 0x%lx",
@@ -225,7 +228,7 @@
if (mutex_type == mutex_type_unknown)
mutex_type = p->mutex_type;
- if (DRD_(s_trace_mutex))
+ if (s_trace_mutex)
{
VG_(message)(Vg_UserMsg,
"[%d/%d] %s %s 0x%lx rc %d owner %d",
@@ -279,7 +282,7 @@
p = DRD_(mutex_get)(mutex);
- if (DRD_(s_trace_mutex))
+ if (s_trace_mutex)
{
VG_(message)(Vg_UserMsg,
"[%d/%d] %s %s 0x%lx rc %d owner %d%s",
@@ -306,12 +309,12 @@
DRD_(thread_combine_vc2)(drd_tid, &p->last_locked_segment->vc);
}
DRD_(thread_new_segment)(drd_tid);
- DRD_(s_mutex_segment_creation_count)++;
+ s_mutex_segment_creation_count++;
p->owner = drd_tid;
p->acquiry_time_ms = VG_(read_millisecond_timer)();
p->acquired_at = VG_(record_ExeContext)(VG_(get_running_tid)(), 0);
- DRD_(s_mutex_lock_count)++;
+ s_mutex_lock_count++;
}
else if (p->owner != drd_tid)
{
@@ -346,7 +349,7 @@
if (mutex_type == mutex_type_unknown)
mutex_type = p->mutex_type;
- if (DRD_(s_trace_mutex))
+ if (s_trace_mutex)
{
VG_(message)(Vg_UserMsg,
"[%d/%d] mutex_unlock %s 0x%lx rc %d",
@@ -399,13 +402,13 @@
if (p->recursion_count == 0)
{
- if (DRD_(s_mutex_lock_threshold_ms) > 0)
+ if (s_mutex_lock_threshold_ms > 0)
{
ULong held = VG_(read_millisecond_timer)() - p->acquiry_time_ms;
- if (held > DRD_(s_mutex_lock_threshold_ms))
+ if (held > s_mutex_lock_threshold_ms)
{
HoldtimeErrInfo HEI
- = { mutex, p->acquired_at, held, DRD_(s_mutex_lock_threshold_ms) };
+ = { mutex, p->acquired_at, held, s_mutex_lock_threshold_ms };
VG_(maybe_record_error)(vg_tid,
HoldtimeErr,
VG_(get_IP)(vg_tid),
@@ -421,7 +424,7 @@
DRD_(thread_get_latest_segment)(&p->last_locked_segment, drd_tid);
DRD_(thread_new_segment)(drd_tid);
p->acquired_at = 0;
- DRD_(s_mutex_segment_creation_count)++;
+ s_mutex_segment_creation_count++;
}
}
@@ -466,7 +469,7 @@
}
/** Return true if the specified mutex is locked by any thread. */
-static Bool DRD_(mutex_is_locked)(struct mutex_info* const p)
+static Bool mutex_is_locked(struct mutex_info* const p)
{
tl_assert(p);
return (p->recursion_count > 0);
@@ -493,33 +496,29 @@
* Call this function when thread tid stops to exist, such that the
* "last owner" field can be cleared if it still refers to that thread.
*/
-void DRD_(mutex_thread_delete)(const DrdThreadId tid)
+static void mutex_delete_thread(struct mutex_info* p, const DrdThreadId tid)
{
- struct mutex_info* p;
+ tl_assert(p);
- DRD_(clientobj_resetiter)();
- for ( ; (p = &(DRD_(clientobj_next)(ClientMutex)->mutex)) != 0; )
+ if (p->owner == tid && p->recursion_count > 0)
{
- if (p->owner == tid && p->recursion_count > 0)
- {
- MutexErrInfo MEI
- = { p->a1, p->recursion_count, p->owner };
- VG_(maybe_record_error)(VG_(get_running_tid)(),
- MutexErr,
- VG_(get_IP)(VG_(get_running_tid)()),
- "Mutex still locked at thread exit",
- &MEI);
- p->owner = VG_INVALID_THREADID;
- }
+ MutexErrInfo MEI
+ = { p->a1, p->recursion_count, p->owner };
+ VG_(maybe_record_error)(VG_(get_running_tid)(),
+ MutexErr,
+ VG_(get_IP)(VG_(get_running_tid)()),
+ "Mutex still locked at thread exit",
+ &MEI);
+ p->owner = VG_INVALID_THREADID;
}
}
ULong DRD_(get_mutex_lock_count)(void)
{
- return DRD_(s_mutex_lock_count);
+ return s_mutex_lock_count;
}
ULong DRD_(get_mutex_segment_creation_count)(void)
{
- return DRD_(s_mutex_segment_creation_count);
+ return s_mutex_segment_creation_count;
}
Modified: trunk/drd/drd_mutex.h
===================================================================
--- trunk/drd/drd_mutex.h 2009-02-21 11:52:27 UTC (rev 9210)
+++ trunk/drd/drd_mutex.h 2009-02-21 15:27:04 UTC (rev 9211)
@@ -50,7 +50,6 @@
const char* DRD_(mutex_type_name)(const MutexT mt);
Bool DRD_(mutex_is_locked_by)(const Addr mutex, const DrdThreadId tid);
int DRD_(mutex_get_recursion_count)(const Addr mutex);
-void DRD_(mutex_thread_delete)(const DrdThreadId tid);
ULong DRD_(get_mutex_lock_count)(void);
ULong DRD_(get_mutex_segment_creation_count)(void);
Modified: trunk/drd/drd_pthread_intercepts.c
===================================================================
--- trunk/drd/drd_pthread_intercepts.c 2009-02-21 11:52:27 UTC (rev 9210)
+++ trunk/drd/drd_pthread_intercepts.c 2009-02-21 15:27:04 UTC (rev 9211)
@@ -194,8 +194,10 @@
}
/**
- * Return 1 if the LinuxThread implementation has been detected, and 0
- * otherwise. For more information about the confstr() function, see also
+ * Return 1 if the LinuxThreads implementation of POSIX Threads has been
+ * detected, and 0 otherwise.
+ *
+ * @see For more information about the confstr() function, see also
* http://www.opengroup.org/onlinepubs/009695399/functions/confstr.html
*/
static int DRD_(detected_linuxthreads)(void)
@@ -283,7 +285,7 @@
/*
* Find out whether the thread will be started as a joinable thread
* or as a detached thread. If no thread attributes have been specified,
- * the new thread will be started as a joinable thread.
+ * this means that the new thread will be started as a joinable thread.
*/
thread_args.detachstate = PTHREAD_CREATE_JOINABLE;
if (attr)
@@ -706,7 +708,7 @@
VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_BARRIER_WAIT,
barrier, pthread_barrier,
ret == 0 || ret == PTHREAD_BARRIER_SERIAL_THREAD,
- 0, 0);
+ ret == PTHREAD_BARRIER_SERIAL_THREAD, 0);
return ret;
}
Modified: trunk/drd/drd_rwlock.c
===================================================================
--- trunk/drd/drd_rwlock.c 2009-02-21 11:52:27 UTC (rev 9210)
+++ trunk/drd/drd_rwlock.c 2009-02-21 15:27:04 UTC (rev 9211)
@@ -49,7 +49,9 @@
/* Local functions. */
-static void DRD_(rwlock_cleanup)(struct rwlock_info* p);
+static void rwlock_cleanup(struct rwlock_info* p);
+static void rwlock_delete_thread(struct rwlock_info* const p,
+ const DrdThreadId tid);
/* Local variables. */
@@ -184,7 +186,8 @@
tl_assert(p->a1 == rwlock);
tl_assert(p->type == ClientRwlock);
- p->cleanup = (void(*)(DrdClientobj*))&(DRD_(rwlock_cleanup));
+ p->cleanup = (void(*)(DrdClientobj*))rwlock_cleanup;
+ p->delete_thread = (void(*)(DrdClientobj*, DrdThreadId))rwlock_delete_thread;
p->thread_info = VG_(OSetGen_Create)(
0, 0, VG_(malloc), "drd.rwlock.ri.1", VG_(free));
p->acquiry_time_ms = 0;
@@ -192,7 +195,7 @@
}
/** Deallocate the memory that was allocated by rwlock_initialize(). */
-static void DRD_(rwlock_cleanup)(struct rwlock_info* p)
+static void rwlock_cleanup(struct rwlock_info* p)
{
struct rwlock_thread_info* q;
@@ -568,26 +571,21 @@
* Call this function when thread tid stops to exist, such that the
* "last owner" field can be cleared if it still refers to that thread.
*/
-void DRD_(rwlock_thread_delete)(const DrdThreadId tid)
+static void rwlock_delete_thread(struct rwlock_info* const p,
+ const DrdThreadId tid)
{
- struct rwlock_info* p;
-
- DRD_(clientobj_resetiter)();
- for ( ; (p = &(DRD_(clientobj_next)(ClientRwlock)->rwlock)) != 0; )
+ struct rwlock_thread_info* q;
+ if (DRD_(rwlock_is_locked_by)(p, tid))
{
- struct rwlock_thread_info* q;
- if (DRD_(rwlock_is_locked_by)(p, tid))
- {
- RwlockErrInfo REI = { p->a1 };
- VG_(maybe_record_error)(VG_(get_running_tid)(),
- RwlockErr,
- VG_(get_IP)(VG_(get_running_tid)()),
- "Reader-writer lock still locked at thread exit",
- &REI);
- q = DRD_(lookup_or_insert_node)(p->thread_info, tid);
- q->reader_nesting_count = 0;
- q->writer_nesting_count = 0;
- }
+ RwlockErrInfo REI = { p->a1 };
+ VG_(maybe_record_error)(VG_(get_running_tid)(),
+ RwlockErr,
+ VG_(get_IP)(VG_(get_running_tid)()),
+ "Reader-writer lock still locked at thread exit",
+ &REI);
+ q = DRD_(lookup_or_insert_node)(p->thread_info, tid);
+ q->reader_nesting_count = 0;
+ q->writer_nesting_count = 0;
}
}
Modified: trunk/drd/drd_rwlock.h
===================================================================
--- trunk/drd/drd_rwlock.h 2009-02-21 11:52:27 UTC (rev 9210)
+++ trunk/drd/drd_rwlock.h 2009-02-21 15:27:04 UTC (rev 9211)
@@ -47,7 +47,6 @@
void DRD_(rwlock_pre_wrlock)(const Addr rwlock);
void DRD_(rwlock_post_wrlock)(const Addr rwlock, const Bool took_lock);
void DRD_(rwlock_pre_unlock)(const Addr rwlock);
-void DRD_(rwlock_thread_delete)(const DrdThreadId tid);
ULong DRD_(get_rwlock_segment_creation_count)(void);
Modified: trunk/drd/drd_semaphore.c
===================================================================
--- trunk/drd/drd_semaphore.c 2009-02-21 11:52:27 UTC (rev 9210)
+++ trunk/drd/drd_semaphore.c 2009-02-21 15:27:04 UTC (rev 9211)
@@ -36,13 +36,13 @@
/* Local functions. */
-static void DRD_(semaphore_cleanup)(struct semaphore_info* p);
+static void semaphore_cleanup(struct semaphore_info* p);
/* Local variables. */
-static Bool DRD_(s_trace_semaphore);
-static ULong DRD_(s_semaphore_segment_creation_count);
+static Bool s_trace_semaphore;
+static ULong s_semaphore_segment_creation_count;
/* Function definitions. */
@@ -85,7 +85,7 @@
/** Enable or disable tracing of semaphore actions. */
void DRD_(semaphore_set_trace)(const Bool trace_semaphore)
{
- DRD_(s_trace_semaphore) = trace_semaphore;
+ s_trace_semaphore = trace_semaphore;
}
/**
@@ -100,7 +100,8 @@
tl_assert(p->a1 == semaphore);
tl_assert(p->type == ClientSemaphore);
- p->cleanup = (void(*)(DrdClientobj*))(DRD_(semaphore_cleanup));
+ p->cleanup = (void(*)(DrdClientobj*))semaphore_cleanup;
+ p->delete_thread = 0;
p->waits_to_skip = 0;
p->value = 0;
p->waiters = 0;
@@ -113,7 +114,7 @@
* Free the memory that was allocated by semaphore_initialize(). Called by
* DRD_(clientobj_remove)().
*/
-static void DRD_(semaphore_cleanup)(struct semaphore_info* p)
+static void semaphore_cleanup(struct semaphore_info* p)
{
Segment* sg;
@@ -172,7 +173,7 @@
struct semaphore_info* p;
Segment* sg;
- if (DRD_(s_trace_semaphore))
+ if (s_trace_semaphore)
{
VG_(message)(Vg_UserMsg,
"[%d/%d] semaphore_init 0x%lx value %u",
@@ -214,7 +215,7 @@
p = DRD_(semaphore_get)(semaphore);
- if (DRD_(s_trace_semaphore))
+ if (s_trace_semaphore)
{
VG_(message)(Vg_UserMsg,
"[%d/%d] semaphore_destroy 0x%lx value %u",
@@ -262,7 +263,7 @@
Segment* sg;
p = DRD_(semaphore_get)(semaphore);
- if (DRD_(s_trace_semaphore))
+ if (s_trace_semaphore)
{
VG_(message)(Vg_UserMsg,
"[%d/%d] semaphore_wait 0x%lx value %u -> %u",
@@ -304,7 +305,7 @@
}
DRD_(sg_put)(sg);
DRD_(thread_new_segment)(tid);
- DRD_(s_semaphore_segment_creation_count)++;
+ s_semaphore_segment_creation_count++;
}
}
}
@@ -318,7 +319,7 @@
p = DRD_(semaphore_get_or_allocate)(semaphore);
p->value++;
- if (DRD_(s_trace_semaphore))
+ if (s_trace_semaphore)
{
VG_(message)(Vg_UserMsg,
"[%d/%d] semaphore_post 0x%lx value %u -> %u",
@@ -334,7 +335,7 @@
DRD_(thread_get_latest_segment)(&sg, tid);
tl_assert(sg);
DRD_(segment_push)(p, sg);
- DRD_(s_semaphore_segment_creation_count)++;
+ s_semaphore_segment_creation_count++;
}
/** Called after sem_post() finished successfully. */
@@ -352,10 +353,7 @@
/* redirected functions. */
}
-void DRD_(semaphore_thread_delete)(const DrdThreadId threadid)
-{ }
-
ULong DRD_(get_semaphore_segment_creation_count)(void)
{
- return DRD_(s_semaphore_segment_creation_count);
+ return s_semaphore_segment_creation_count;
}
Modified: trunk/drd/drd_semaphore.h
===================================================================
--- trunk/drd/drd_semaphore.h 2009-02-21 11:52:27 UTC (rev 9210)
+++ trunk/drd/drd_semaphore.h 2009-02-21 15:27:04 UTC (rev 9211)
@@ -47,7 +47,6 @@
void DRD_(semaphore_pre_post)(const DrdThreadId tid, const Addr semaphore);
void DRD_(semaphore_post_post)(const DrdThreadId tid, const Addr semaphore,
const Bool waited);
-void DRD_(semaphore_thread_delete)(const DrdThreadId tid);
ULong DRD_(get_semaphore_segment_creation_count)(void);
Modified: trunk/drd/drd_thread.c
===================================================================
--- trunk/drd/drd_thread.c 2009-02-21 11:52:27 UTC (rev 9210)
+++ trunk/drd/drd_thread.c 2009-02-21 15:27:04 UTC (rev 9211)
@@ -24,6 +24,7 @@
#include "drd_error.h"
#include "drd_barrier.h"
+#include "drd_clientobj.h"
#include "drd_cond.h"
#include "drd_mutex.h"
#include "drd_segment.h"
@@ -302,11 +303,8 @@
- DRD_(thread_get_stack_size)(drd_joinee),
DRD_(thread_get_stack_max)(drd_joinee));
}
+ DRD_(clientobj_delete_thread)(drd_joinee);
DRD_(thread_delete)(drd_joinee);
- DRD_(mutex_thread_delete)(drd_joinee);
- DRD_(cond_thread_delete)(drd_joinee);
- DRD_(semaphore_thread_delete)(drd_joinee);
- DRD_(barrier_thread_delete)(drd_joinee);
}
/**
|
|
From: <sv...@va...> - 2009-02-21 12:29:31
|
Author: sewardj
Date: 2009-02-21 11:52:27 +0000 (Sat, 21 Feb 2009)
New Revision: 9210
Log:
merge bug-fix components of r9106:
Fix a minor bug, whereby a stack entry of zero would cause a "(heap
allocation functions)" line to be written.
Modified:
branches/VALGRIND_3_4_BRANCH/massif/ms_main.c
Modified: branches/VALGRIND_3_4_BRANCH/massif/ms_main.c
===================================================================
--- branches/VALGRIND_3_4_BRANCH/massif/ms_main.c 2009-02-21 09:45:38 UTC (rev 9209)
+++ branches/VALGRIND_3_4_BRANCH/massif/ms_main.c 2009-02-21 11:52:27 UTC (rev 9210)
@@ -1925,7 +1925,7 @@
switch (sxpt->tag) {
case SigSXPt:
// Print the SXPt itself.
- if (sxpt->Sig.ip == 0) {
+ if (0 == depth) {
ip_desc =
"(heap allocation functions) malloc/new/new[], --alloc-fns, etc.";
} else {
|
|
From: <sv...@va...> - 2009-02-21 11:21:45
|
Author: sewardj Date: 2009-02-21 11:21:39 +0000 (Sat, 21 Feb 2009) New Revision: 377 Log: Make Valkyrie-1.4.0 available. Modified: trunk/downloads/current.html Modified: trunk/downloads/current.html =================================================================== --- trunk/downloads/current.html 2009-02-05 09:41:54 UTC (rev 376) +++ trunk/downloads/current.html 2009-02-21 11:21:39 UTC (rev 377) @@ -57,20 +57,21 @@ <div class="hr_brown"><hr/></div> -<h3>Valkyrie 1.3.0</h3> +<h3>Valkyrie 1.4.0</h3> -<p><a href="/downloads/valkyrie-1.3.0.tar.bz2">valkyrie 1.3.0 (tar.bz2)</a> -[365Kb] - June 30 2008.<br /> -<span class="md5sum">md5: ec7069a23ec90670be74d3fc3a46f574</span></p> +<p><a href="/downloads/valkyrie-1.4.0.tar.bz2">valkyrie 1.4.0 (tar.bz2)</a> +[365Kb] - 21 Feb 2009.<br /> +<span class="md5sum">md5: 9f0eb896e85485874566496dc1587139</span></p> <p><a href="http://www.open-works.co.uk/projects/valkyrie.html">Valkyrie</a> -is a GUI for valgrind 3.3.0 and 3.3.1. It also has an XML merging tool for +is a GUI for the Valgrind 3.4.x releases. It also has an XML merging tool for Memcheck outputs (vk_logmerge). This tarball is known to build and work with -valgrind-3.3.0.</p> +valgrind-3.4.0.</p> -<p>This version of Valkyrie does not support the new Valgrind 3.4.0 - release. However, we plan to release a new Valkyrie version (1.4.0) - on or before 9 Jan 2009, which does support Valgrind 3.4.0.</p> +<p>This version of Valkyrie does not support the older Valgrind 3.3.x + releases. If you need a GUI for Valgrind 3.3.x, instead use + <a href="/downloads/valkyrie-1.3.0.tar.bz2">valkyrie 1.3.0 + (tar.bz2)</a> instead.</p> <div class="hr_brown"><hr/></div> |
|
From: <sv...@va...> - 2009-02-21 09:45:45
|
Author: bart Date: 2009-02-21 09:45:38 +0000 (Sat, 21 Feb 2009) New Revision: 9209 Log: Updated svn:ignore property in multiple directories. Modified: trunk/massif/tests/ trunk/memcheck/tests/ trunk/memcheck/tests/linux/ trunk/memcheck/tests/x86-linux/ trunk/none/tests/linux/ trunk/tests/ Property changes on: trunk/massif/tests ___________________________________________________________________ Name: svn:ignore - alloc-fns basic basic_malloc big-alloc culling1 culling2 custom_alloc deep .deps ignoring insig long-names long-time Makefile Makefile.in massif.*.aux massif.*.hp massif.*.html massif.*.ps massif.*.txt new-cpp null one overloaded-new peak *.post.diff* *.post.out realloc *.stderr.diff* *.stderr.out *.stdout.diff* *.stdout.out thresholds zero + *.post.diff* *.post.out *.stderr.diff* *.stderr.out *.stdout.diff* *.stdout.out .deps alloc-fns basic basic_malloc big-alloc culling1 culling2 custom_alloc deep ignoring insig long-names long-time Makefile Makefile.in malloc_usable massif.*.aux massif.*.hp massif.*.html massif.*.ps massif.*.txt massif.out.* new-cpp null one overloaded-new peak realloc thresholds zero Property changes on: trunk/memcheck/tests ___________________________________________________________________ Name: svn:ignore - addressable badaddrvalue badfree badjump badjump2 badloop badpoll badrw brk brk2 buflen_check clientperm clientstackperm custom_alloc deep_templates .deps describe-block dir doublefree erringfds error_counts errs1 execve execve2 exitprog file_locking filter_leak_check_size filter_stderr fprw fwrite hello inits inline leak-0 leak-cycle leakotron leak-pool leak-regroot leak-tree linux-capget linux-syscalls-2007 linux-syslog-syscall linux-timerfd-syscall long_namespace_xml lsframe1 lsframe2 Makefile Makefile.in mallinfo malloc1 malloc2 malloc3 malloc_free_fill malloc_usable manuel1 manuel2 manuel3 match-overrun memalign2 memalign_test memcmptest mempool metadata mismatches mmaptest nanoleak nanoleak2 new_nothrow new_override noisy_child null_socket origin1-yes origin2-not-quite origin3-no origin4-many origin5-bz2 origin6-fp oset_test overlap partial_load partiallydefinedeq pdb-realloc pdb-realloc2 pipe pointer-trace post-syscall realloc1 realloc2 realloc3 scalar scalar_exit_group scalar_fork scalar_supp scalar_vfork sh-mem sh-mem-random sigaltstack sigkill signal2 sigprocmask stack_changes stack_switch *.stderr.diff* *.stderr.out *.stdout.diff* *.stdout.out strchr str_tester supp1 supp2 suppfree supp_unknown threadederrno trivialleak varinfo1 varinfo2 varinfo3 varinfo4 varinfo5 varinfo5so.so varinfo6 vcpu_bz2 vcpu_fbench vcpu_fnfns vgtest_ume weirdioctl with space wrap1 wrap2 wrap3 wrap4 wrap5 wrap6 wrap7 wrap7so.so wrap8 writev xml1 zeropage + *.stderr.diff* *.stderr.out *.stdout.diff* *.stdout.out .deps addressable badaddrvalue badfree badjump badjump2 badloop badpoll badrw brk brk2 buflen_check clientperm clientstackperm custom_alloc deep_templates describe-block dir doublefree erringfds error_counts errs1 execve execve2 exitprog file_locking filter_leak_check_size filter_stderr fprw fwrite hello inits inline leak-0 leak-cycle leak-pool leak-regroot leak-tree leakotron linux-capget linux-syscalls-2007 linux-syslog-syscall linux-timerfd-syscall long_namespace_xml lsframe1 lsframe2 Makefile Makefile.in mallinfo malloc1 malloc2 malloc3 malloc_free_fill malloc_usable manuel1 manuel2 manuel3 match-overrun memalign2 memalign_test memcmptest mempool metadata mismatches mmaptest nanoleak nanoleak2 new_nothrow new_override noisy_child null_socket origin1-yes origin2-not-quite origin3-no origin4-many origin5-bz2 origin6-fp oset_test overlap partiallydefinedeq partial_load pdb-realloc pdb-realloc2 pipe pointer-trace post-syscall realloc1 realloc2 realloc3 scalar scalar_exit_group scalar_fork scalar_supp scalar_vfork sh-mem sh-mem-random sigaltstack sigkill signal2 sigprocmask stack_changes stack_switch strchr str_tester supp1 supp2 suppfree supp_unknown threadederrno trivialleak unit_libcbase unit_oset varinfo1 varinfo2 varinfo3 varinfo4 varinfo5 varinfo5so.so varinfo6 vcpu_bz2 vcpu_fbench vcpu_fnfns vgtest_ume weirdioctl with space wrap1 wrap2 wrap3 wrap4 wrap5 wrap6 wrap7 wrap7so.so wrap8 writev xml1 zeropage Property changes on: trunk/memcheck/tests/linux ___________________________________________________________________ Name: svn:ignore + .deps brk capget Makefile Makefile.in stack_switch timerfd-syscall Property changes on: trunk/memcheck/tests/x86-linux ___________________________________________________________________ Name: svn:ignore + .deps Makefile Makefile.in scalar scalar_exit_group scalar_fork scalar_supp scalar_vfork Property changes on: trunk/none/tests/linux ___________________________________________________________________ Name: svn:ignore + .deps Makefile Makefile.in mremap mremap2 Property changes on: trunk/tests ___________________________________________________________________ Name: svn:ignore - cputest .deps Makefile Makefile.in toobig-allocs true vg_regtest + .deps arch_test cputest Makefile Makefile.in os_test toobig-allocs true vg_regtest |
|
From: <sv...@va...> - 2009-02-21 09:39:15
|
Author: bart
Date: 2009-02-21 09:39:09 +0000 (Sat, 21 Feb 2009)
New Revision: 9208
Log:
Documentation updates.
Modified:
trunk/drd/drd_mutex.c
trunk/drd/drd_rwlock.c
Modified: trunk/drd/drd_mutex.c
===================================================================
--- trunk/drd/drd_mutex.c 2009-02-20 19:53:50 UTC (rev 9207)
+++ trunk/drd/drd_mutex.c 2009-02-21 09:39:09 UTC (rev 9208)
@@ -328,9 +328,8 @@
/**
* Update mutex_info state when unlocking the pthread_mutex_t mutex.
*
- * @param mutex Pointer to pthread_mutex_t data structure in the client space.
- * @param tid ThreadId of the thread calling pthread_mutex_unlock().
- * @param vc Pointer to the current vector clock of thread tid.
+ * @param[in] mutex Address of the client mutex.
+ * @param[in] mutex_type Mutex type.
*
* @return New value of the mutex recursion count.
*
Modified: trunk/drd/drd_rwlock.c
===================================================================
--- trunk/drd/drd_rwlock.c 2009-02-20 19:53:50 UTC (rev 9207)
+++ trunk/drd/drd_rwlock.c 2009-02-21 09:39:09 UTC (rev 9208)
@@ -464,12 +464,13 @@
/**
* Update rwlock_info state when unlocking the pthread_rwlock_t rwlock.
- * Note: this function must be called before pthread_rwlock_unlock() is called,
- * or a race condition is triggered !
+ *
+ * @param rwlock Pointer to pthread_rwlock_t data structure in the client space.
+ *
* @return New value of the rwlock recursion count.
- * @param rwlock Pointer to pthread_rwlock_t data structure in the client space.
- * @param tid ThreadId of the thread calling pthread_rwlock_unlock().
- * @param vc Pointer to the current vector clock of thread tid.
+ *
+ * @note This function must be called before pthread_rwlock_unlock() is called,
+ * or a race condition is triggered !
*/
void DRD_(rwlock_pre_unlock)(const Addr rwlock)
{
|
|
From: Tom H. <th...@cy...> - 2009-02-21 03:48:26
|
Nightly build on vauxhall ( x86_64, Fedora 10 ) started at 2009-02-21 03:20:06 GMT Results differ from 24 hours ago Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... done Regression test results follow == 488 tests, 0 stderr failures, 0 stdout failures, 0 post failures == ================================================= == Results from 24 hours ago == ================================================= Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... done Regression test results follow == 487 tests, 0 stderr failures, 0 stdout failures, 0 post failures == ================================================= == Difference between 24 hours ago and now == ================================================= *** old.short Sat Feb 21 03:34:14 2009 --- new.short Sat Feb 21 03:48:21 2009 *************** *** 8,10 **** ! == 487 tests, 0 stderr failures, 0 stdout failures, 0 post failures == --- 8,10 ---- ! == 488 tests, 0 stderr failures, 0 stdout failures, 0 post failures == |
|
From: Tom H. <th...@cy...> - 2009-02-21 03:44:42
|
Nightly build on lloyd ( x86_64, Fedora 7 ) started at 2009-02-21 03:05:06 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 == 479 tests, 5 stderr failures, 0 stdout failures, 0 post failures == exp-ptrcheck/tests/ccc (stderr) exp-ptrcheck/tests/preen_invars (stderr) exp-ptrcheck/tests/pth_create (stderr) exp-ptrcheck/tests/pth_specific (stderr) helgrind/tests/tc20_verifywrap (stderr) ================================================= == 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 == 478 tests, 5 stderr failures, 0 stdout failures, 0 post failures == exp-ptrcheck/tests/ccc (stderr) exp-ptrcheck/tests/preen_invars (stderr) exp-ptrcheck/tests/pth_create (stderr) exp-ptrcheck/tests/pth_specific (stderr) helgrind/tests/tc20_verifywrap (stderr) ================================================= == Difference between 24 hours ago and now == ================================================= *** old.short Sat Feb 21 03:24:46 2009 --- new.short Sat Feb 21 03:44:34 2009 *************** *** 8,10 **** ! == 478 tests, 5 stderr failures, 0 stdout failures, 0 post failures == exp-ptrcheck/tests/ccc (stderr) --- 8,10 ---- ! == 479 tests, 5 stderr failures, 0 stdout failures, 0 post failures == exp-ptrcheck/tests/ccc (stderr) |
|
From: Tom H. <th...@cy...> - 2009-02-21 03:32:35
|
Nightly build on mg ( x86_64, Fedora 9 ) started at 2009-02-21 03:10:07 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 == 485 tests, 4 stderr failures, 2 stdout failures, 0 post failures == exp-ptrcheck/tests/ccc (stderr) exp-ptrcheck/tests/preen_invars (stderr) exp-ptrcheck/tests/pth_create (stderr) exp-ptrcheck/tests/pth_specific (stderr) memcheck/tests/linux/timerfd-syscall (stdout) none/tests/linux/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 == 484 tests, 4 stderr failures, 2 stdout failures, 0 post failures == exp-ptrcheck/tests/ccc (stderr) exp-ptrcheck/tests/preen_invars (stderr) exp-ptrcheck/tests/pth_create (stderr) exp-ptrcheck/tests/pth_specific (stderr) memcheck/tests/linux/timerfd-syscall (stdout) none/tests/linux/mremap2 (stdout) ================================================= == Difference between 24 hours ago and now == ================================================= *** old.short Sat Feb 21 03:21:17 2009 --- new.short Sat Feb 21 03:32:23 2009 *************** *** 8,10 **** ! == 484 tests, 4 stderr failures, 2 stdout failures, 0 post failures == exp-ptrcheck/tests/ccc (stderr) --- 8,10 ---- ! == 485 tests, 4 stderr failures, 2 stdout failures, 0 post failures == exp-ptrcheck/tests/ccc (stderr) |