]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
- Made the ANNOTATE_RWLOCK_*() macros binary compatible with Helgrind.
authorBart Van Assche <bvanassche@acm.org>
Sat, 15 Aug 2009 10:50:35 +0000 (10:50 +0000)
committerBart Van Assche <bvanassche@acm.org>
Sat, 15 Aug 2009 10:50:35 +0000 (10:50 +0000)
- Added two additional regression tests.

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@10819

12 files changed:
drd/drd.h
drd/drd_clientreq.c
drd/drd_error.c
drd/drd_error.h
drd/tests/Makefile.am
drd/tests/annotate_publish_hg.c [new file with mode: 0644]
drd/tests/annotate_publish_hg.stderr.exp [new file with mode: 0644]
drd/tests/annotate_publish_hg.vgtest [new file with mode: 0644]
drd/tests/annotate_rwlock_hg.stderr.exp [new file with mode: 0644]
drd/tests/annotate_rwlock_hg.vgtest [new file with mode: 0644]
drd/tests/compare_error_count_with [new file with mode: 0755]
drd/tests/rwlock_type_checking.stderr.exp

index 37230d100c9afd6c7b82589370f8fd8cbb07a90b..83720e6580fa0076fb3427b5dd277a2c6bc7f311 100644 (file)
--- a/drd/drd.h
+++ b/drd/drd.h
 
 /** 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.
@@ -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 */
index 7b1ffafc55d00cc4d271588b6be35537526b1715..8aa89ff3bfd653ba150e1a4bd24b45927fcc3e7e 100644 (file)
@@ -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",
index 74291f52aa17e9ac3571df3c7d38a9b3e95a7ec2..4b1c2fad9d6c4737d6a7827ed2601d9d9b8899d2 100644 (file)
@@ -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"
+                   " <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",
@@ -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);
    }
index cc3fcd000708019f735731d141601888afe2b6a6..6af6cdd0f91fcd9f46bd750aff52e73d165396a8 100644 (file)
@@ -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);
 
index ad3592481caf27a3a278035715b4731801709f00..1918ede9df13bc6beb1a47999dea1e4f3eb29b7c 100644 (file)
@@ -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 (file)
index 0000000..12c5e44
--- /dev/null
@@ -0,0 +1,11 @@
+/* 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;
+}
diff --git a/drd/tests/annotate_publish_hg.stderr.exp b/drd/tests/annotate_publish_hg.stderr.exp
new file mode 100644 (file)
index 0000000..66eea7c
--- /dev/null
@@ -0,0 +1,7 @@
+
+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)
diff --git a/drd/tests/annotate_publish_hg.vgtest b/drd/tests/annotate_publish_hg.vgtest
new file mode 100644 (file)
index 0000000..3c75d3f
--- /dev/null
@@ -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 (file)
index 0000000..12a0d6d
--- /dev/null
@@ -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 (file)
index 0000000..fd25624
--- /dev/null
@@ -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 (executable)
index 0000000..48abf3e
--- /dev/null
@@ -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" }'
index 9ecacde13efe1282b3f863f602ce14cbc5c1ac95..c1ee6dbed75b27ecf6c528b562b13e42b5154288 100644 (file)
@@ -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:?)