|
From: <sv...@va...> - 2012-07-06 23:38:31
|
philippe 2012-07-07 00:38:24 +0100 (Sat, 07 Jul 2012)
New Revision: 12721
Log:
295590 Helgrind: Assertion 'cvi->nWaiters > 0' failed when cond var being waited upon destroyed
* when cond var is destroyed, in the PRE, report an error if nwaiters > 0.
* when cond_wait succeeds, get the cond var but do not create one in helgrind
(it must exist if cond_wait was done).
Report an error if cond not found (assuming this is caused by a destroy
done while the thread was cond_wait-ing).
* added a test
Added files:
trunk/helgrind/tests/pth_destroy_cond.c
trunk/helgrind/tests/pth_destroy_cond.stderr.exp
trunk/helgrind/tests/pth_destroy_cond.stdout.exp
trunk/helgrind/tests/pth_destroy_cond.vgtest
Modified files:
trunk/NEWS
trunk/docs/internals/3_7_BUGSTATUS.txt
trunk/helgrind/hg_main.c
trunk/helgrind/tests/Makefile.am
Modified: trunk/NEWS (+1 -0)
===================================================================
--- trunk/NEWS 2012-07-06 23:52:09 +01:00 (rev 12720)
+++ trunk/NEWS 2012-07-07 00:38:24 -23:00 (rev 12721)
@@ -171,6 +171,7 @@
295089 can not annotate source for both helgrind and drd
295221 POWER Processor decimal floating point instruction support missing
295428 coregrind/m_main.c has incorrect x86 assembly for darwin
+295590 Helgrind: Assertion 'cvi->nWaiters > 0' failed when cond var being waited upon destroyed
295799 Missing \n with get_vbits in gdbserver when line is % 80 and there are some unaddressable bytes
296422 Add translation chaining support
296457 vex amd64->IR: 0x66 0xF 0x3A 0xDF 0xD1 0x1 0xE8 0x6A (dup of AES)
Added: trunk/helgrind/tests/pth_destroy_cond.vgtest (+3 -0)
===================================================================
--- trunk/helgrind/tests/pth_destroy_cond.vgtest 2012-07-06 23:52:09 +01:00 (rev 12720)
+++ trunk/helgrind/tests/pth_destroy_cond.vgtest 2012-07-07 00:38:24 -23:00 (rev 12721)
@@ -0,0 +1,3 @@
+prog: pth_destroy_cond
+vgopts: -q
+stderr_filter_args: pth_destroy_cond.c
Added: trunk/helgrind/tests/pth_destroy_cond.stderr.exp (+28 -0)
===================================================================
--- trunk/helgrind/tests/pth_destroy_cond.stderr.exp 2012-07-06 23:52:09 +01:00 (rev 12720)
+++ trunk/helgrind/tests/pth_destroy_cond.stderr.exp 2012-07-07 00:38:24 -23:00 (rev 12721)
@@ -0,0 +1,28 @@
+---Thread-Announcement------------------------------------------
+
+Thread #x was created
+ ...
+ by 0x........: pthread_create_WRK (hg_intercepts.c:...)
+ by 0x........: pthread_create@* (hg_intercepts.c:...)
+ by 0x........: main (pth_destroy_cond.c:29)
+
+----------------------------------------------------------------
+
+Thread #x: pthread_cond_destroy: destruction of condition variable being waited upon
+ at 0x........: pthread_cond_destroy_WRK (hg_intercepts.c:...)
+ by 0x........: pthread_cond_destroy@* (hg_intercepts.c:...)
+ by 0x........: ThreadFunction (pth_destroy_cond.c:18)
+ by 0x........: mythread_wrapper (hg_intercepts.c:...)
+ ...
+
+---Thread-Announcement------------------------------------------
+
+Thread #x is the program's root thread
+
+----------------------------------------------------------------
+
+Thread #x: condition variable has been destroyed while being waited upon
+ at 0x........: pthread_cond_wait_WRK (hg_intercepts.c:...)
+ by 0x........: pthread_cond_wait@* (hg_intercepts.c:...)
+ by 0x........: main (pth_destroy_cond.c:31)
+
Modified: trunk/helgrind/tests/Makefile.am (+3 -0)
===================================================================
--- trunk/helgrind/tests/Makefile.am 2012-07-06 23:52:09 +01:00 (rev 12720)
+++ trunk/helgrind/tests/Makefile.am 2012-07-07 00:38:24 -23:00 (rev 12721)
@@ -40,6 +40,8 @@
pth_barrier1.vgtest pth_barrier1.stdout.exp pth_barrier1.stderr.exp \
pth_barrier2.vgtest pth_barrier2.stdout.exp pth_barrier2.stderr.exp \
pth_barrier3.vgtest pth_barrier3.stdout.exp pth_barrier3.stderr.exp \
+ pth_destroy_cond.vgtest \
+ pth_destroy_cond.stdout.exp pth_destroy_cond.stderr.exp \
pth_spinlock.vgtest pth_spinlock.stdout.exp pth_spinlock.stderr.exp \
rwlock_race.vgtest rwlock_race.stdout.exp rwlock_race.stderr.exp \
rwlock_test.vgtest rwlock_test.stdout.exp rwlock_test.stderr.exp \
@@ -106,6 +108,7 @@
locked_vs_unlocked1 \
locked_vs_unlocked2 \
locked_vs_unlocked3 \
+ pth_destroy_cond \
t2t \
tc01_simple_race \
tc02_simple_tls \
Added: trunk/helgrind/tests/pth_destroy_cond.c (+39 -0)
===================================================================
--- trunk/helgrind/tests/pth_destroy_cond.c 2012-07-06 23:52:09 +01:00 (rev 12720)
+++ trunk/helgrind/tests/pth_destroy_cond.c 2012-07-07 00:38:24 -23:00 (rev 12721)
@@ -0,0 +1,39 @@
+#include <stdio.h>
+#include <pthread.h>
+#include <errno.h>
+// test program from johan.walles (bug 295590)
+// This test verifies that helgrind detects (and does not crash) when
+// the guest application wrongly destroys a cond var being waited
+// upon.
+pthread_mutex_t mutex;
+pthread_cond_t cond;
+pthread_t thread;
+int ready = 0;
+
+void *ThreadFunction(void *ptr)
+{
+ pthread_mutex_lock(&mutex);
+ ready = 1;
+ pthread_cond_signal(&cond);
+ pthread_cond_destroy(&cond); // ERROR!!!
+ pthread_mutex_unlock(&mutex);
+ return NULL;
+}
+
+int main()
+{
+ pthread_mutex_init(&mutex, NULL);
+ pthread_cond_init(&cond, NULL);
+
+ pthread_mutex_lock(&mutex);
+ pthread_create(&thread, NULL, ThreadFunction, (void*) NULL);
+ while (!ready) { // to insure ourselves against spurious wakeups
+ pthread_cond_wait(&cond, &mutex);
+ }
+ pthread_mutex_unlock(&mutex);
+
+ pthread_join(thread, NULL);
+ pthread_mutex_destroy(&mutex);
+ printf("finished\n");
+ return 0;
+}
Modified: trunk/helgrind/hg_main.c (+37 -3)
===================================================================
--- trunk/helgrind/hg_main.c 2012-07-06 23:52:09 +01:00 (rev 12720)
+++ trunk/helgrind/hg_main.c 2012-07-07 00:38:24 -23:00 (rev 12721)
@@ -2139,17 +2139,41 @@
}
}
-static void map_cond_to_CVInfo_delete ( void* cond ) {
+static CVInfo* map_cond_to_CVInfo_lookup_NO_alloc ( void* cond ) {
+ UWord key, val;
+ map_cond_to_CVInfo_INIT();
+ if (VG_(lookupFM)( map_cond_to_CVInfo, &key, &val, (UWord)cond )) {
+ tl_assert(key == (UWord)cond);
+ return (CVInfo*)val;
+ } else {
+ return NULL;
+ }
+}
+
+static void map_cond_to_CVInfo_delete ( ThreadId tid, void* cond ) {
+ Thread* thr;
UWord keyW, valW;
+
+ thr = map_threads_maybe_lookup( tid );
+ tl_assert(thr); /* cannot fail - Thread* must already exist */
+
map_cond_to_CVInfo_INIT();
if (VG_(delFromFM)( map_cond_to_CVInfo, &keyW, &valW, (UWord)cond )) {
CVInfo* cvi = (CVInfo*)valW;
tl_assert(keyW == (UWord)cond);
tl_assert(cvi);
tl_assert(cvi->so);
+ if (cvi->nWaiters > 0) {
+ HG_(record_error_Misc)(thr,
+ "pthread_cond_destroy:"
+ " destruction of condition variable being waited upon");
+ }
libhb_so_dealloc(cvi->so);
cvi->mx_ga = 0;
HG_(free)(cvi);
+ } else {
+ HG_(record_error_Misc)(thr,
+ "pthread_cond_destroy: destruction of unknown cond var");
}
}
@@ -2320,7 +2344,17 @@
// error-if: cond is also associated with a different mutex
- cvi = map_cond_to_CVInfo_lookup_or_alloc( cond );
+ cvi = map_cond_to_CVInfo_lookup_NO_alloc( cond );
+ if (!cvi) {
+ /* This could be either a bug in helgrind or the guest application
+ that did an error (e.g. cond var was destroyed by another thread.
+ Let's assume helgrind is perfect ...
+ Note that this is similar to drd behaviour. */
+ HG_(record_error_Misc)(thr, "condition variable has been destroyed while"
+ " being waited upon");
+ return;
+ }
+
tl_assert(cvi);
tl_assert(cvi->so);
tl_assert(cvi->nWaiters > 0);
@@ -2351,7 +2385,7 @@
"(ctid=%d, cond=%p)\n",
(Int)tid, (void*)cond );
- map_cond_to_CVInfo_delete( cond );
+ map_cond_to_CVInfo_delete( tid, cond );
}
Modified: trunk/docs/internals/3_7_BUGSTATUS.txt (+0 -4)
===================================================================
--- trunk/docs/internals/3_7_BUGSTATUS.txt 2012-07-06 23:52:09 +01:00 (rev 12720)
+++ trunk/docs/internals/3_7_BUGSTATUS.txt 2012-07-07 00:38:24 -23:00 (rev 12721)
@@ -175,10 +175,6 @@
not high prio
**possible 3.8.0 (easy to fix?)
-295590 Helgrind: hg_main.c:2298 (evh__HG_PTHREAD_COND_WAIT_POST):
- Assertion 'cvi->nWaiters > 0' failed.
- **possible 3.8.0
-
295617 ARM - Add some missing syscalls
**possible 3.8.0, needs landing
Added: trunk/helgrind/tests/pth_destroy_cond.stdout.exp (+1 -0)
===================================================================
--- trunk/helgrind/tests/pth_destroy_cond.stdout.exp 2012-07-06 23:52:09 +01:00 (rev 12720)
+++ trunk/helgrind/tests/pth_destroy_cond.stdout.exp 2012-07-07 00:38:24 -23:00 (rev 12721)
@@ -0,0 +1 @@
+finished
|