#include "drd_error.h"
#include "drd_mutex.h"
#include "drd_suppression.h"
-#include "pub_tool_errormgr.h" // VG_(maybe_record_error)()
-#include "pub_tool_libcassert.h" // tl_assert()
-#include "pub_tool_libcprint.h" // VG_(printf)()
-#include "pub_tool_machine.h" // VG_(get_IP)()
-#include "pub_tool_options.h" // VG_(clo_backtrace_size)
-#include "pub_tool_threadstate.h" // VG_(get_running_tid)()
+#include "pub_tool_errormgr.h" /* VG_(maybe_record_error)() */
+#include "pub_tool_libcassert.h" /* tl_assert() */
+#include "pub_tool_libcprint.h" /* VG_(printf)() */
+#include "pub_tool_machine.h" /* VG_(get_IP)() */
+#include "pub_tool_options.h" /* VG_(clo_backtrace_size) */
+#include "pub_tool_threadstate.h" /* VG_(get_running_tid)() */
-// Local functions.
+/* Local functions. */
static void cond_cleanup(struct cond_info* p);
-// Local variables.
+/* Global variables. */
+
+Bool s_drd_report_signal_unlocked = True;
+
+
+/* Local variables. */
static Bool s_trace_cond;
-// Function definitions.
+/* Function definitions. */
void cond_set_trace(const Bool trace_cond)
{
if (cond_p && cond_p->waiter_count > 0)
{
- if (! mutex_is_locked_by(cond_p->mutex, drd_tid))
+ if (s_drd_report_signal_unlocked
+ && ! mutex_is_locked_by(cond_p->mutex, drd_tid))
{
/* A signal is sent while the associated mutex has not been locked. */
/* This can indicate but is not necessarily a race condition. */
-#if 0
CondRaceErrInfo cei;
cei.cond = cond;
cei.mutex = cond_p->mutex;
VG_(get_IP)(vg_tid),
"CondErr",
&cei);
-#endif
}
}
else
*/
-// Condition variable state information: mutex specified in pthread_cond_wait()
-// call.
-
-
#ifndef __DRD_COND_H
#define __DRD_COND_H
-#include "drd_thread.h" // DrdThreadid
-#include "pub_tool_basics.h" // Addr
+#include "drd_thread.h" /* DrdThreadid */
+#include "pub_tool_basics.h" /* Addr */
+/* Forward declarations. */
+
struct cond_info;
+/* Global variables. */
+
+extern Bool s_drd_report_signal_unlocked;
+
+
+/* Function declarations. */
+
void cond_set_trace(const Bool trace_cond);
void cond_pre_init(const Addr cond);
void cond_post_destroy(const Addr cond);
case CondRaceErr: {
CondRaceErrInfo* cei = (CondRaceErrInfo*)(VG_(get_error_extra)(e));
VG_(message)(Vg_UserMsg,
- "Race condition: condition variable 0x%lx has been"
+ "Probably a race condition: condition variable 0x%lx has been"
" signalled but the associated mutex 0x%lx is not locked"
" by the signalling thread",
cei->cond, cei->mutex);
VG_BOOL_CLO (arg, "--check-stack-var", s_drd_check_stack_accesses)
else VG_BOOL_CLO(arg, "--drd-stats", s_drd_print_stats)
+ else VG_BOOL_CLO(arg,"--report-signal-unlocked",s_drd_report_signal_unlocked)
else VG_BOOL_CLO(arg, "--segment-merging", segment_merging)
else VG_BOOL_CLO(arg, "--show-confl-seg", show_confl_seg)
else VG_BOOL_CLO(arg, "--show-stack-usage", s_show_stack_usage)
else VG_BOOL_CLO(arg, "--trace-barrier", trace_barrier)
else VG_BOOL_CLO(arg, "--trace-clientobj", trace_clientobj)
else VG_BOOL_CLO(arg, "--trace-cond", trace_cond)
- else VG_BOOL_CLO(arg, "--trace-csw", trace_csw)
else VG_BOOL_CLO(arg, "--trace-conflict-set", trace_conflict_set)
+ else VG_BOOL_CLO(arg, "--trace-csw", trace_csw)
else VG_BOOL_CLO(arg, "--trace-fork-join", s_drd_trace_fork_join)
else VG_BOOL_CLO(arg, "--trace-mutex", trace_mutex)
else VG_BOOL_CLO(arg, "--trace-rwlock", trace_rwlock)
" stack variables [no].\n"
" --exclusive-threshold=<n> Print an error message if any mutex or\n"
" writer lock is held longer than the specified time (in milliseconds).\n"
+" --report-signal-unlocked=yes|no Whether to report calls to\n"
+" pthread_cond_signal() where the mutex associated\n"
+" with the signal via pthread_cond_wait() is not\n"
+" locked at the time the signal is sent [yes].\n"
" --segment-merging=yes|no Controls segment merging [yes].\n"
" Segment merging is an algorithm to limit memory usage of the\n"
" data race detection algorithm. Disabling segment merging may\n"
pth_cond_race.vgtest \
pth_cond_race2.stderr.exp \
pth_cond_race2.vgtest \
+ pth_cond_race3.stderr.exp \
+ pth_cond_race3.vgtest \
pth_create_chain.stderr.exp \
pth_create_chain.vgtest \
pth_detached.stderr.exp \
+Thread 2:
+Probably a race condition: condition variable 0x........ has been signalled but the associated mutex 0x........ is not locked by the signalling thread
+ at 0x........: pthread_cond_signal* (drd_pthread_intercepts.c:?)
+ by 0x........: thread_func (pth_cond_race.c:?)
+ by 0x........: vg_thread_wrapper (drd_pthread_intercepts.c:?)
+ by 0x........: (within libpthread-?.?.so)
+ by 0x........: clone (in /...libc...)
-ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
+ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
--- /dev/null
+
+
+ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
--- /dev/null
+prereq: ./supported_libpthread
+prog: pth_cond_race
+vgopts: --report-signal-unlocked=no
at 0x........: pthread_cond_wait* (drd_pthread_intercepts.c:?)
by 0x........: main (tc23_bogus_condwait.c:69)
+Thread 3:
+Probably a race condition: condition variable 0x........ has been signalled but the associated mutex 0x........ is not locked by the signalling thread
+ at 0x........: pthread_cond_signal* (drd_pthread_intercepts.c:?)
+ by 0x........: rescue_me (tc23_bogus_condwait.c:20)
+ by 0x........: vg_thread_wrapper (drd_pthread_intercepts.c:?)
+ by 0x........: (within libpthread-?.?.so)
+ by 0x........: clone (in /...libc...)
+
+Thread 1:
Mutex not locked: mutex 0x........, recursion count 0, owner 0.
at 0x........: pthread_cond_wait* (drd_pthread_intercepts.c:?)
by 0x........: main (tc23_bogus_condwait.c:72)
+Thread 3:
+Probably a race condition: condition variable 0x........ has been signalled but the associated mutex 0x........ is not locked by the signalling thread
+ at 0x........: pthread_cond_signal* (drd_pthread_intercepts.c:?)
+ by 0x........: rescue_me (tc23_bogus_condwait.c:24)
+ by 0x........: vg_thread_wrapper (drd_pthread_intercepts.c:?)
+ by 0x........: (within libpthread-?.?.so)
+ by 0x........: clone (in /...libc...)
+
+Thread 1:
The object at address 0x........ is not a mutex.
at 0x........: pthread_cond_wait* (drd_pthread_intercepts.c:?)
by 0x........: main (tc23_bogus_condwait.c:75)
+Thread 3:
+Probably a race condition: condition variable 0x........ has been signalled but the associated mutex 0x........ is not locked by the signalling thread
+ at 0x........: pthread_cond_signal* (drd_pthread_intercepts.c:?)
+ by 0x........: rescue_me (tc23_bogus_condwait.c:28)
+ by 0x........: vg_thread_wrapper (drd_pthread_intercepts.c:?)
+ by 0x........: (within libpthread-?.?.so)
+ by 0x........: clone (in /...libc...)
+
+Thread 1:
Mutex not locked by calling thread: mutex 0x........, recursion count 1, owner 2.
at 0x........: pthread_cond_wait* (drd_pthread_intercepts.c:?)
by 0x........: main (tc23_bogus_condwait.c:78)
+
+Thread 3:
+Probably a race condition: condition variable 0x........ has been signalled but the associated mutex 0x........ is not locked by the signalling thread
+ at 0x........: pthread_cond_signal* (drd_pthread_intercepts.c:?)
+ by 0x........: rescue_me (tc23_bogus_condwait.c:32)
+ by 0x........: vg_thread_wrapper (drd_pthread_intercepts.c:?)
+ by 0x........: (within libpthread-?.?.so)
+ by 0x........: clone (in /...libc...)
The impossible happened: mutex 0x........ is locked simultaneously by two threads (recursion count 1, owners 2 and 1) !
Thread 2:
by 0x........: (within libpthread-?.?.so)
by 0x........: clone (in /...libc...)
-ERROR SUMMARY: 5 errors from 5 contexts (suppressed: 0 from 0)
+ERROR SUMMARY: 9 errors from 9 contexts (suppressed: 0 from 0)