From: Bart Van Assche Date: Sat, 15 Aug 2009 10:50:35 +0000 (+0000) Subject: - Made the ANNOTATE_RWLOCK_*() macros binary compatible with Helgrind. X-Git-Tag: svn/VALGRIND_3_5_0~31 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=80fdc5a9e92327a7cb2689a04aa5d1e86021bc83;p=thirdparty%2Fvalgrind.git - Made the ANNOTATE_RWLOCK_*() macros binary compatible with Helgrind. - Added two additional regression tests. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@10819 --- diff --git a/drd/drd.h b/drd/drd.h index 37230d100c..83720e6580 100644 --- a/drd/drd.h +++ b/drd/drd.h @@ -158,11 +158,11 @@ /** 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 @@ -170,7 +170,7 @@ * 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 @@ -190,7 +190,7 @@ * 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. @@ -320,6 +320,32 @@ enum { 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, @@ -329,10 +355,6 @@ enum { = 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. */ }; @@ -433,13 +455,39 @@ void DRDCL_(annotate_happens_after)(const void* const addr) } 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 */ diff --git a/drd/drd_clientreq.c b/drd/drd_clientreq.c index 7b1ffafc55..8aa89ff3bf 100644 --- a/drd/drd_clientreq.c +++ b/drd/drd_clientreq.c @@ -136,42 +136,57 @@ static Bool handle_client_request(ThreadId vg_tid, UWord* arg, UWord* ret) } 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; @@ -482,6 +497,21 @@ static Bool handle_client_request(ThreadId vg_tid, UWord* arg, UWord* ret) 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", diff --git a/drd/drd_error.c b/drd/drd_error.c index 74291f52aa..4b1c2fad9d 100644 --- a/drd/drd_error.c +++ b/drd/drd_error.c @@ -383,6 +383,15 @@ static void drd_tool_error_pp(Error* const e) 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" + " \n", + /*VG_(get_error_string)(e),*/ uicr->descr); + VG_(pp_ExeContext)(VG_(get_error_where)(e)); + break; + } default: VG_(message)(Vg_UserMsg, "%s\n", @@ -420,6 +429,8 @@ static UInt drd_tool_error_update_extra(Error* e) return sizeof(GenericErrInfo); case InvalidThreadId: return sizeof(InvalidThreadIdInfo); + case UnimpClReq: + return sizeof(UnimpClReqInfo); default: tl_assert(False); break; @@ -461,6 +472,8 @@ static Bool drd_is_recognized_suppression(Char* const name, Supp* const supp) 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; @@ -507,6 +520,7 @@ static Char* drd_get_error_name(Error* e) 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); } diff --git a/drd/drd_error.h b/drd/drd_error.h index cc3fcd0007..6af6cdd0f9 100644 --- a/drd/drd_error.h +++ b/drd/drd_error.h @@ -61,6 +61,8 @@ typedef enum { GenericErr = 11, #define STR_InvalidThreadId "InvalidThreadId" InvalidThreadId = 12, +#define STR_UnimpClReq "UnimpClReq" + UnimpClReq = 13, } DrdErrorKind; /* The classification of a faulting address. */ @@ -168,6 +170,11 @@ typedef struct { 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); diff --git a/drd/tests/Makefile.am b/drd/tests/Makefile.am index ad3592481c..1918ede9df 100644 --- a/drd/tests/Makefile.am +++ b/drd/tests/Makefile.am @@ -2,6 +2,7 @@ include $(top_srcdir)/Makefile.tool-tests.am dist_noinst_SCRIPTS = \ + compare_error_count_with \ filter_error_summary \ filter_stderr \ filter_stderr_and_thread_no \ @@ -21,10 +22,14 @@ EXTRA_DIST = \ 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 \ @@ -239,6 +244,7 @@ EXTRA_DIST = \ check_PROGRAMS = \ annotate_ignore_rw \ annotate_ignore_write \ + annotate_publish_hg \ custom_alloc \ fp_race \ hold_lock \ diff --git a/drd/tests/annotate_publish_hg.c b/drd/tests/annotate_publish_hg.c new file mode 100644 index 0000000000..12c5e442f0 --- /dev/null +++ b/drd/tests/annotate_publish_hg.c @@ -0,0 +1,11 @@ +/* Test for verifying that unsupported annotations are reported properly. */ + +#include +#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; +} diff --git a/drd/tests/annotate_publish_hg.stderr.exp b/drd/tests/annotate_publish_hg.stderr.exp new file mode 100644 index 0000000000..66eea7c924 --- /dev/null +++ b/drd/tests/annotate_publish_hg.stderr.exp @@ -0,0 +1,7 @@ + +The annotation macro ANNOTATE_PUBLISH_MEMORY_RANGE has not yet been implemented in + at 0x........: main (annotate_publish_hg.c:?) + +Done. + +ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0) diff --git a/drd/tests/annotate_publish_hg.vgtest b/drd/tests/annotate_publish_hg.vgtest new file mode 100644 index 0000000000..3c75d3f52a --- /dev/null +++ b/drd/tests/annotate_publish_hg.vgtest @@ -0,0 +1,4 @@ +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 diff --git a/drd/tests/annotate_rwlock_hg.stderr.exp b/drd/tests/annotate_rwlock_hg.stderr.exp new file mode 100644 index 0000000000..12a0d6df93 --- /dev/null +++ b/drd/tests/annotate_rwlock_hg.stderr.exp @@ -0,0 +1 @@ +Total error count is below threshold. diff --git a/drd/tests/annotate_rwlock_hg.vgtest b/drd/tests/annotate_rwlock_hg.vgtest new file mode 100644 index 0000000000..fd2562414a --- /dev/null +++ b/drd/tests/annotate_rwlock_hg.vgtest @@ -0,0 +1,4 @@ +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 diff --git a/drd/tests/compare_error_count_with b/drd/tests/compare_error_count_with new file mode 100755 index 0000000000..48abf3edee --- /dev/null +++ b/drd/tests/compare_error_count_with @@ -0,0 +1,3 @@ +#!/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" }' diff --git a/drd/tests/rwlock_type_checking.stderr.exp b/drd/tests/rwlock_type_checking.stderr.exp index 9ecacde13e..c1ee6dbed7 100644 --- a/drd/tests/rwlock_type_checking.stderr.exp +++ b/drd/tests/rwlock_type_checking.stderr.exp @@ -3,11 +3,11 @@ Attempt to use a user-defined rwlock as a POSIX rwlock: rwlock 0x......... 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:?)