- Added two additional regression tests.
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@10819
/** Tell DRD that a reader-writer lock object has been initialized. */
#define ANNOTATE_RWLOCK_CREATE(rwlock) \
- DRDCL_(annotate_rwlock)(rwlock, 0, 0)
+ DRDCL_(annotate_rwlock_create)(rwlock)
/** Tell DRD that a reader-writer lock object has been destroyed. */
#define ANNOTATE_RWLOCK_DESTROY(rwlock) \
- DRDCL_(annotate_rwlock)(rwlock, 1, 0)
+ DRDCL_(annotate_rwlock_destroy)(rwlock)
/**
* Tell DRD that a reader-writer lock has been acquired. is_w == 1 means that
* obtained.
*/
#define ANNOTATE_RWLOCK_ACQUIRED(rwlock, is_w) \
- DRDCL_(annotate_rwlock)(rwlock, 2, is_w)
+ DRDCL_(annotate_rwlock_acquired)(rwlock, is_w)
/**
* Tell DRD that a reader lock has been acquired on a reader-writer
* is about to be released.
*/
#define ANNOTATE_RWLOCK_RELEASED(rwlock, is_w) \
- DRDCL_(annotate_rwlock)(rwlock, 3, is_w)
+ DRDCL_(annotate_rwlock_released)(rwlock, is_w)
/**
* Tell DRD that a reader lock is about to be released.
VG_USERREQ__DRD_SET_THREAD_NAME,
/* args: null-terminated character string. */
+ /* Tell DRD that a user-defined reader-writer synchronization object
+ * has been created. */
+ VG_USERREQ__DRD_ANNOTATE_RWLOCK_CREATE
+ = VG_USERREQ_TOOL_BASE('H','G') + 256 + 14,
+ /* args: Addr. */
+ /* Tell DRD that a user-defined reader-writer synchronization object
+ * is about to be destroyed. */
+ VG_USERREQ__DRD_ANNOTATE_RWLOCK_DESTROY
+ = VG_USERREQ_TOOL_BASE('H','G') + 256 + 15,
+ /* args: Addr. */
+ /* Tell DRD that a lock on a user-defined reader-writer synchronization
+ * object has been acquired. */
+ VG_USERREQ__DRD_ANNOTATE_RWLOCK_ACQUIRED
+ = VG_USERREQ_TOOL_BASE('H','G') + 256 + 17,
+ /* args: Addr, Int is_rw. */
+ /* Tell DRD that a lock on a user-defined reader-writer synchronization
+ * object is about to be released. */
+ VG_USERREQ__DRD_ANNOTATE_RWLOCK_RELEASED
+ = VG_USERREQ_TOOL_BASE('H','G') + 256 + 18,
+ /* args: Addr, Int is_rw. */
+
+ /* Tell DRD that an annotation has not yet been implemented. */
+ VG_USERREQ__DRD_ANNOTATION_UNIMP
+ = VG_USERREQ_TOOL_BASE('H','G') + 256 + 32,
+ /* args: Char*. */
+
/* Tell DRD to insert a happens before annotation. */
VG_USERREQ__DRD_ANNOTATE_HAPPENS_BEFORE
= VG_USERREQ_TOOL_BASE('H','G') + 256 + 33,
= VG_USERREQ_TOOL_BASE('H','G') + 256 + 34,
/* args: Addr. */
- /* Tell DRD about an operation performed on a user-defined reader-writer
- * synchronization object. */
- VG_USERREQ__DRD_ANNOTATE_RWLOCK,
- /* args: Addr, Int operation_type, Int is_rw. */
};
}
static __inline__
-void DRDCL_(annotate_rwlock)(const void* const rwlock, const int op,
- const int is_w)
+void DRDCL_(annotate_rwlock_create)(const void* const rwlock)
+{
+ int res;
+ VALGRIND_DO_CLIENT_REQUEST(res, 0,
+ VG_USERREQ__DRD_ANNOTATE_RWLOCK_CREATE,
+ rwlock, 0, 0, 0, 0);
+}
+
+static __inline__
+void DRDCL_(annotate_rwlock_destroy)(const void* const rwlock)
+{
+ int res;
+ VALGRIND_DO_CLIENT_REQUEST(res, 0,
+ VG_USERREQ__DRD_ANNOTATE_RWLOCK_DESTROY,
+ rwlock, 0, 0, 0, 0);
+}
+
+static __inline__
+void DRDCL_(annotate_rwlock_acquired)(const void* const rwlock, const int is_w)
+{
+ int res;
+ VALGRIND_DO_CLIENT_REQUEST(res, 0,
+ VG_USERREQ__DRD_ANNOTATE_RWLOCK_ACQUIRED,
+ rwlock, is_w, 0, 0, 0);
+}
+
+static __inline__
+void DRDCL_(annotate_rwlock_released)(const void* const rwlock, const int is_w)
{
int res;
VALGRIND_DO_CLIENT_REQUEST(res, 0,
- VG_USERREQ__DRD_ANNOTATE_RWLOCK,
- rwlock, op, is_w, 0, 0);
+ VG_USERREQ__DRD_ANNOTATE_RWLOCK_RELEASED,
+ rwlock, is_w, 0, 0, 0);
}
#endif /* __VALGRIND_DRD_H */
}
break;
- case VG_USERREQ__DRD_ANNOTATE_RWLOCK:
+ case VG_USERREQ__DRD_ANNOTATE_RWLOCK_CREATE:
+ if (arg[1])
{
struct mutex_info* const mutex_p = DRD_(mutex_get)(arg[1]);
if (mutex_p && mutex_p->mutex_type == mutex_type_spinlock)
break;
}
- switch (arg[2])
+ DRD_(rwlock_pre_init)(arg[1], user_rwlock);
+ break;
+
+ case VG_USERREQ__DRD_ANNOTATE_RWLOCK_DESTROY:
+ if (arg[1])
{
- case 0:
- DRD_(rwlock_pre_init)(arg[1], user_rwlock);
- break;
- case 1:
- DRD_(rwlock_post_destroy)(arg[1], user_rwlock);
- break;
- case 2:
- tl_assert(arg[3] == !! arg[3]);
- if (arg[3])
- {
- DRD_(rwlock_pre_wrlock)(arg[1], user_rwlock);
- DRD_(rwlock_post_wrlock)(arg[1], user_rwlock, True);
- }
- else
- {
- DRD_(rwlock_pre_rdlock)(arg[1], user_rwlock);
- DRD_(rwlock_post_rdlock)(arg[1], user_rwlock, True);
- }
- break;
- case 3:
- tl_assert(arg[3] == !! arg[3]);
- DRD_(rwlock_pre_unlock)(arg[1], user_rwlock);
- break;
- default:
- tl_assert(False);
+ struct mutex_info* const mutex_p = DRD_(mutex_get)(arg[1]);
+ if (mutex_p && mutex_p->mutex_type == mutex_type_spinlock)
+ break;
+ }
+ DRD_(rwlock_post_destroy)(arg[1], user_rwlock);
+ break;
+
+ case VG_USERREQ__DRD_ANNOTATE_RWLOCK_ACQUIRED:
+ if (arg[1])
+ {
+ struct mutex_info* const mutex_p = DRD_(mutex_get)(arg[1]);
+ if (mutex_p && mutex_p->mutex_type == mutex_type_spinlock)
+ break;
+ }
+ tl_assert(arg[2] == !! arg[2]);
+ if (arg[2])
+ {
+ DRD_(rwlock_pre_wrlock)(arg[1], user_rwlock);
+ DRD_(rwlock_post_wrlock)(arg[1], user_rwlock, True);
+ }
+ else
+ {
+ DRD_(rwlock_pre_rdlock)(arg[1], user_rwlock);
+ DRD_(rwlock_post_rdlock)(arg[1], user_rwlock, True);
}
break;
+ case VG_USERREQ__DRD_ANNOTATE_RWLOCK_RELEASED:
+ if (arg[1])
+ {
+ struct mutex_info* const mutex_p = DRD_(mutex_get)(arg[1]);
+ if (mutex_p && mutex_p->mutex_type == mutex_type_spinlock)
+ break;
+ }
+ tl_assert(arg[2] == !! arg[2]);
+ DRD_(rwlock_pre_unlock)(arg[1], user_rwlock);
+ break;
+
case VG_USERREQ__DRD_START_NEW_SEGMENT:
DRD_(thread_new_segment)(DRD_(PtThreadIdToDrdThreadId)(arg[1]));
break;
DRD_(clean_memory)(arg[1], arg[2]);
break;
+ case VG_USERREQ__DRD_ANNOTATION_UNIMP:
+ {
+ /* Note: it is assumed below that the text arg[1] points to is never
+ * freed, e.g. because it points to static data.
+ */
+ UnimpClReqInfo UICR =
+ { DRD_(thread_get_running_tid)(), (Char*)arg[1] };
+ VG_(maybe_record_error)(vg_tid,
+ UnimpClReq,
+ VG_(get_IP)(vg_tid),
+ "",
+ &UICR);
+ }
+ break;
+
default:
#if 0
VG_(message)(Vg_DebugMsg, "Unrecognized client request 0x%lx 0x%lx",
VG_(pp_ExeContext)(VG_(get_error_where)(e));
break;
}
+ case UnimpClReq: {
+ UnimpClReqInfo* uicr =(UnimpClReqInfo*)(VG_(get_error_extra)(e));
+ VG_(message)(Vg_UserMsg,
+ "The annotation macro %s has not yet been implemented in"
+ " <helgrind/helgrind.h>\n",
+ /*VG_(get_error_string)(e),*/ uicr->descr);
+ VG_(pp_ExeContext)(VG_(get_error_where)(e));
+ break;
+ }
default:
VG_(message)(Vg_UserMsg,
"%s\n",
return sizeof(GenericErrInfo);
case InvalidThreadId:
return sizeof(InvalidThreadIdInfo);
+ case UnimpClReq:
+ return sizeof(UnimpClReqInfo);
default:
tl_assert(False);
break;
skind = GenericErr;
else if (VG_(strcmp)(name, STR_InvalidThreadId) == 0)
skind = InvalidThreadId;
+ else if (VG_(strcmp)(name, STR_UnimpClReq) == 0)
+ skind = UnimpClReq;
else
return False;
case HoldtimeErr: return VGAPPEND(STR_, HoldtimeErr);
case GenericErr: return VGAPPEND(STR_, GenericErr);
case InvalidThreadId: return VGAPPEND(STR_, InvalidThreadId);
+ case UnimpClReq: return VGAPPEND(STR_, UnimpClReq);
default:
tl_assert(0);
}
GenericErr = 11,
#define STR_InvalidThreadId "InvalidThreadId"
InvalidThreadId = 12,
+#define STR_UnimpClReq "UnimpClReq"
+ UnimpClReq = 13,
} DrdErrorKind;
/* The classification of a faulting address. */
ULong ptid;
} InvalidThreadIdInfo;
+typedef struct {
+ DrdThreadId tid;
+ Char* descr;
+} UnimpClReqInfo;
+
void DRD_(set_show_conflicting_segments)(const Bool scs);
void DRD_(register_error_handlers)(void);
include $(top_srcdir)/Makefile.tool-tests.am
dist_noinst_SCRIPTS = \
+ compare_error_count_with \
filter_error_summary \
filter_stderr \
filter_stderr_and_thread_no \
annotate_order_2.vgtest \
annotate_order_3.stderr.exp \
annotate_order_3.vgtest \
+ annotate_publish_hg.stderr.exp \
+ annotate_publish_hg.vgtest \
annotate_spinlock.stderr.exp \
annotate_spinlock.vgtest \
annotate_rwlock.stderr.exp \
annotate_rwlock.vgtest \
+ annotate_rwlock_hg.stderr.exp \
+ annotate_rwlock_hg.vgtest \
annotate_ignore_read.stderr.exp \
annotate_ignore_read.vgtest \
annotate_ignore_rw.stderr.exp \
check_PROGRAMS = \
annotate_ignore_rw \
annotate_ignore_write \
+ annotate_publish_hg \
custom_alloc \
fp_race \
hold_lock \
--- /dev/null
+/* Test for verifying that unsupported annotations are reported properly. */
+
+#include <stdio.h>
+#include "../../helgrind/helgrind.h"
+
+int main(int argc, char** argv)
+{
+ ANNOTATE_PUBLISH_MEMORY_RANGE(argv[0], sizeof(argv[0]));
+ fprintf(stderr, "Done.\n");
+ return 0;
+}
--- /dev/null
+
+The annotation macro ANNOTATE_PUBLISH_MEMORY_RANGE has not yet been implemented in <helgrind/helgrind.h>
+ at 0x........: main (annotate_publish_hg.c:?)
+
+Done.
+
+ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
--- /dev/null
+prereq: test -e annotate_publish_hg && ./supported_libpthread
+vgopts: --read-var-info=yes --check-stack-var=yes --show-confl-seg=no
+prog: annotate_publish_hg
+stderr_filter: filter_stderr
--- /dev/null
+Total error count is below threshold.
--- /dev/null
+prereq: test -e ../../helgrind/tests/annotate_rwlock && ./supported_libpthread
+vgopts: --read-var-info=yes --check-stack-var=yes --show-confl-seg=no
+prog: ../../helgrind/tests/annotate_rwlock
+stderr_filter: compare_error_count_with
--- /dev/null
+#!/bin/sh
+
+awk -v count=50000 '/ERROR SUMMARY/{if ($4 <= count) print "Total error count is below threshold."; else print "Total error count is above threshold" }'
at 0x........: pthread_rwlock_init (drd_pthread_intercepts.c:?)
by 0x........: main (rwlock_type_checking.c:?)
rwlock 0x........ was first observed at:
- at 0x........: vgDrdCl_annotate_rwlock (drd.h:?)
+ at 0x........: vgDrdCl_annotate_rwlock_create (drd.h:?)
by 0x........: main (rwlock_type_checking.c:?)
Attempt to use a POSIX rwlock as a user-defined rwlock: rwlock 0x.........
- at 0x........: vgDrdCl_annotate_rwlock (drd.h:?)
+ at 0x........: vgDrdCl_annotate_rwlock_released (drd.h:?)
by 0x........: main (rwlock_type_checking.c:?)
rwlock 0x........ was first observed at:
at 0x........: pthread_rwlock_init (drd_pthread_intercepts.c:?)