]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
drd: Enable XML output. See also #282949. To do: document the output format.
authorBart Van Assche <bvanassche@acm.org>
Tue, 11 Oct 2011 19:08:39 +0000 (19:08 +0000)
committerBart Van Assche <bvanassche@acm.org>
Tue, 11 Oct 2011 19:08:39 +0000 (19:08 +0000)
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@12137

17 files changed:
drd/drd_error.c
drd/drd_main.c
drd/drd_thread.c
drd/tests/Makefile.am
drd/tests/annotate_barrier_xml.stderr.exp [new file with mode: 0644]
drd/tests/annotate_barrier_xml.vgtest [new file with mode: 0644]
drd/tests/annotate_trace_memory_xml.stderr.exp [new file with mode: 0644]
drd/tests/annotate_trace_memory_xml.vgtest [new file with mode: 0644]
drd/tests/bar_bad_xml.stderr.exp [new file with mode: 0644]
drd/tests/bar_bad_xml.vgtest [new file with mode: 0644]
drd/tests/filter_stderr_and_thread_no
drd/tests/filter_thread_no [new file with mode: 0755]
drd/tests/filter_xml_and_thread_no [new file with mode: 0644]
drd/tests/fp_race_xml.stderr.exp [new file with mode: 0644]
drd/tests/fp_race_xml.vgtest [new file with mode: 0644]
drd/tests/thread_name_xml.stderr.exp [new file with mode: 0644]
drd/tests/thread_name_xml.vgtest [new file with mode: 0644]

index 0bd0a1013dc77183af050a9905eb528644d2e217..35c2b627196f397ffbf0bcabfcf638b9fae84fe1 100644 (file)
 #include "pub_tool_tooliface.h"   /* VG_(needs_tool_errors)() */
 
 
+/* Local function declarations. */
+
+static Char* drd_get_error_name(Error* e);
+
+
 /* Local variables. */
 
 static Bool s_show_conflicting_segments = True;
@@ -56,7 +61,28 @@ void DRD_(trace_msg)(const char* format, ...)
 {
    va_list vargs;
    va_start(vargs, format);
-   VG_(vmessage)(Vg_UserMsg, format, vargs);
+   if (VG_(clo_xml)) {
+      VG_(printf_xml)("<traceline>\n  ");
+      VG_(vprintf_xml)(format, vargs);
+      VG_(printf_xml)("</traceline>\n");
+   } else {
+      VG_(vmessage)(Vg_UserMsg, format, vargs);
+   }
+   va_end(vargs);
+}
+
+/**
+ * Emit error message detail in the format requested by the user.
+ */
+static void print_err_detail(const char* format, ...) PRINTF_CHECK(1, 2);
+static void print_err_detail(const char* format, ...)
+{
+   va_list vargs;
+   va_start(vargs, format);
+   if (VG_(clo_xml))
+      VG_(vprintf_xml)(format, vargs);
+   else
+      VG_(vmessage)(Vg_UserMsg, format, vargs);
    va_end(vargs);
 }
 
@@ -89,20 +115,30 @@ static void first_observed(const Addr obj)
    DrdClientobj* cl;
 
    cl = DRD_(clientobj_get_any)(obj);
-   if (cl)
-   {
+   if (cl) {
       tl_assert(cl->any.first_observed_at);
-      VG_(message)(Vg_UserMsg,
-                   "%s 0x%lx was first observed at:\n",
-                   DRD_(clientobj_type_name)(cl->any.type),
-                   obj);
-      VG_(pp_ExeContext)(cl->any.first_observed_at);
+      if (VG_(clo_xml)) {
+         print_err_detail("  <first_observed_at>\n"
+                          "    <what>%pS</what>\n"
+                          "    <address>0x%lx</address>\n",
+                          DRD_(clientobj_type_name)(cl->any.type), obj);
+         VG_(pp_ExeContext)(cl->any.first_observed_at);
+         print_err_detail("  </first_observed_at>\n");
+      } else {
+         print_err_detail("%s 0x%lx was first observed at:\n",
+                          DRD_(clientobj_type_name)(cl->any.type), obj);
+         VG_(pp_ExeContext)(cl->any.first_observed_at);
+      }
    }
 }
 
 static
 void drd_report_data_race(Error* const err, const DataRaceErrInfo* const dri)
 {
+   const Bool xml = VG_(clo_xml);
+   const char* const what_prefix = xml ? "  <what>" : "";
+   const char* const what_suffix = xml ? "</what>" : "";
+   const char* const indent = xml ? "  " : "";
    AddrInfo ai;
 
    XArray* /* of HChar */ descr1
@@ -143,44 +179,50 @@ void drd_report_data_race(Error* const err, const DataRaceErrInfo* const dri)
       /* No.  Do Plan B. */
       describe_malloced_addr(dri->addr, &ai);
    }
-   VG_(message)(Vg_UserMsg,
-                "Conflicting %s by thread %d at 0x%08lx size %ld\n",
-                dri->access_type == eStore ? "store" : "load",
-                dri->tid,
-                dri->addr,
-                dri->size);
+
+   print_err_detail("%sConflicting %s by thread %d at 0x%08lx size %ld%s\n",
+                    what_prefix, dri->access_type == eStore ? "store" : "load",
+                    dri->tid, dri->addr, dri->size, what_suffix);
+
    VG_(pp_ExeContext)(VG_(get_error_where)(err));
-   if (descr1 != NULL)
-   {
-      VG_(message)(Vg_UserMsg, "%s\n", (HChar*)VG_(indexXA)(descr1, 0));
+   if (descr1 != NULL) {
+      print_err_detail("%s%s\n", indent, (HChar*)VG_(indexXA)(descr1, 0));
       if (descr2 != NULL)
-         VG_(message)(Vg_UserMsg, "%s\n", (HChar*)VG_(indexXA)(descr2, 0));
-   }
-   else if (ai.akind == eMallocd && ai.lastchange)
-   {
-      VG_(message)(Vg_UserMsg,
-                   "Address 0x%lx is at offset %ld from 0x%lx."
-                   " Allocation context:\n",
-                   dri->addr, ai.rwoffset, dri->addr - ai.rwoffset);
+         print_err_detail("%s%s\n", indent, (HChar*)VG_(indexXA)(descr2, 0));
+   } else if (ai.akind == eMallocd && ai.lastchange) {
+      if (xml)
+         print_err_detail("  <auxwhat>\n    <text>");
+      print_err_detail("Address 0x%lx is at offset %ld from 0x%lx.",
+                       dri->addr, ai.rwoffset, dri->addr - ai.rwoffset);
+      if (xml)
+         print_err_detail("</text>\n");
+      else
+         print_err_detail(" Allocation context:\n");
       VG_(pp_ExeContext)(ai.lastchange);
-   }
-   else
-   {
+      if (xml)
+         print_err_detail("  </auxwhat>\n");
+   } else {
       char sect_name[64];
       VgSectKind sect_kind;
 
       sect_kind = VG_(DebugInfo_sect_kind)(sect_name, sizeof(sect_name),
                                            dri->addr);
-      if (sect_kind != Vg_SectUnknown)
-      {
-         VG_(message)(Vg_UserMsg,
-                      "Allocation context: %s section of %s\n",
-                      VG_(pp_SectKind)(sect_kind),
-                      sect_name);
-      }
-      else
-      {
-         VG_(message)(Vg_UserMsg, "Allocation context: unknown.\n");
+      if (xml) {
+         print_err_detail("  <auxwhat><text>");
+         if (sect_kind != Vg_SectUnknown) {
+            print_err_detail("      Allocation context: %pS section of %pS\n",
+                             VG_(pp_SectKind)(sect_kind), sect_name);
+         } else {
+            print_err_detail("      Allocation context: unknown.\n");
+         }
+         print_err_detail("  </text><auxwhat>\n");
+      } else {
+         if (sect_kind != Vg_SectUnknown) {
+            print_err_detail("Allocation context: %s section of %s\n",
+                             VG_(pp_SectKind)(sect_kind), sect_name);
+         } else {
+            print_err_detail("Allocation context: unknown.\n");
+         }
       }
    }
    if (s_show_conflicting_segments)
@@ -238,8 +280,7 @@ static void drd_tool_error_before_pp(Error* const e)
 
    err_extra = VG_(get_error_extra)(e);
 
-   if (err_extra && *err_extra != s_last_tid_printed)
-   {
+   if (err_extra && *err_extra != s_last_tid_printed && !VG_(clo_xml)) {
       VG_(umsg)("%s:\n", DRD_(thread_get_name)(*err_extra));
       s_last_tid_printed = *err_extra;
    }
@@ -248,6 +289,13 @@ static void drd_tool_error_before_pp(Error* const e)
 /** Report an error to the user. */
 static void drd_tool_error_pp(Error* const e)
 {
+   const Bool xml = VG_(clo_xml);
+   const char* const what_prefix = xml ? "  <what>" : "";
+   const char* const what_suffix = xml ? "</what>" : "";
+
+   if (xml)
+      VG_(printf_xml)( "  <kind>%pS</kind>\n", drd_get_error_name(e));
+
    switch (VG_(get_error_kind)(e))
    {
    case DataRaceErr: {
@@ -257,20 +305,13 @@ static void drd_tool_error_pp(Error* const e)
    case MutexErr: {
       MutexErrInfo* p = (MutexErrInfo*)(VG_(get_error_extra)(e));
       tl_assert(p);
-      if (p->recursion_count >= 0)
-      {
-         VG_(message)(Vg_UserMsg,
-                      "%s: mutex 0x%lx, recursion count %d, owner %d.\n",
-                      VG_(get_error_string)(e),
-                      p->mutex,
-                      p->recursion_count,
-                      p->owner);
-      }
-      else
-      {
-         VG_(message)(Vg_UserMsg,
-                      "The object at address 0x%lx is not a mutex.\n",
-                      p->mutex);
+      if (p->recursion_count >= 0) {
+         print_err_detail("%s%s: mutex 0x%lx, recursion count %d, owner %d."
+                          "%s\n", what_prefix, VG_(get_error_string)(e),
+                          p->mutex, p->recursion_count, p->owner, what_suffix);
+      } else {
+         print_err_detail("%sThe object at address 0x%lx is not a mutex.%s\n",
+                          what_prefix, p->mutex, what_suffix);
       }
       VG_(pp_ExeContext)(VG_(get_error_where)(e));
       first_observed(p->mutex);
@@ -278,32 +319,27 @@ static void drd_tool_error_pp(Error* const e)
    }
    case CondErr: {
       CondErrInfo* cdei =(CondErrInfo*)(VG_(get_error_extra)(e));
-      VG_(message)(Vg_UserMsg,
-                   "%s: cond 0x%lx\n",
-                   VG_(get_error_string)(e),
-                   cdei->cond);
+      print_err_detail("%s%s: cond 0x%lx%s\n", what_prefix,
+                       VG_(get_error_string)(e), cdei->cond, what_suffix);
       VG_(pp_ExeContext)(VG_(get_error_where)(e));
       first_observed(cdei->cond);
       break;
    }
    case CondDestrErr: {
       CondDestrErrInfo* cdi = (CondDestrErrInfo*)(VG_(get_error_extra)(e));
-      VG_(message)(Vg_UserMsg,
-                   "%s: cond 0x%lx, mutex 0x%lx locked by thread %d\n",
-                   VG_(get_error_string)(e),
-                   cdi->cond, cdi->mutex,
-                   cdi->owner);
+      print_err_detail("%s%s: cond 0x%lx, mutex 0x%lx locked by thread %d%s\n",
+                       what_prefix, VG_(get_error_string)(e), cdi->cond,
+                       cdi->mutex, cdi->owner, what_suffix);
       VG_(pp_ExeContext)(VG_(get_error_where)(e));
       first_observed(cdi->mutex);
       break;
    }
    case CondRaceErr: {
       CondRaceErrInfo* cei = (CondRaceErrInfo*)(VG_(get_error_extra)(e));
-      VG_(message)(Vg_UserMsg,
-                   "Probably a race condition: condition variable 0x%lx has"
-                   " been signaled but the associated mutex 0x%lx is not"
-                   " locked by the signalling thread.\n",
-                   cei->cond, cei->mutex);
+      print_err_detail("%sProbably a race condition: condition variable 0x%lx"
+                       " has been signaled but the associated mutex 0x%lx is"
+                       " not locked by the signalling thread.%s\n",
+                       what_prefix, cei->cond, cei->mutex, what_suffix);
       VG_(pp_ExeContext)(VG_(get_error_where)(e));
       first_observed(cei->cond);
       first_observed(cei->mutex);
@@ -311,12 +347,9 @@ static void drd_tool_error_pp(Error* const e)
    }
    case CondWaitErr: {
       CondWaitErrInfo* cwei = (CondWaitErrInfo*)(VG_(get_error_extra)(e));
-      VG_(message)(Vg_UserMsg,
-                   "%s: condition variable 0x%lx, mutexes 0x%lx and 0x%lx\n",
-                   VG_(get_error_string)(e),
-                   cwei->cond,
-                   cwei->mutex1,
-                   cwei->mutex2);
+      print_err_detail("%s%s: condition variable 0x%lx, mutexes 0x%lx and"
+                       " 0x%lx%s\n", what_prefix, VG_(get_error_string)(e),
+                       cwei->cond, cwei->mutex1, cwei->mutex2, what_suffix);
       VG_(pp_ExeContext)(VG_(get_error_where)(e));
       first_observed(cwei->cond);
       first_observed(cwei->mutex1);
@@ -326,10 +359,8 @@ static void drd_tool_error_pp(Error* const e)
    case SemaphoreErr: {
       SemaphoreErrInfo* sei = (SemaphoreErrInfo*)(VG_(get_error_extra)(e));
       tl_assert(sei);
-      VG_(message)(Vg_UserMsg,
-                   "%s: semaphore 0x%lx\n",
-                   VG_(get_error_string)(e),
-                   sei->semaphore);
+      print_err_detail("%s%s: semaphore 0x%lx%s\n", VG_(get_error_string)(e),
+                       what_prefix, sei->semaphore, what_suffix);
       VG_(pp_ExeContext)(VG_(get_error_where)(e));
       first_observed(sei->semaphore);
       break;
@@ -337,17 +368,17 @@ static void drd_tool_error_pp(Error* const e)
    case BarrierErr: {
       BarrierErrInfo* bei = (BarrierErrInfo*)(VG_(get_error_extra)(e));
       tl_assert(bei);
-      VG_(message)(Vg_UserMsg,
-                   "%s: barrier 0x%lx\n",
-                   VG_(get_error_string)(e),
-                   bei->barrier);
+      print_err_detail("%s%s: barrier 0x%lx%s\n", what_prefix,
+                       VG_(get_error_string)(e), bei->barrier, what_suffix);
       VG_(pp_ExeContext)(VG_(get_error_where)(e));
-      if (bei->other_context)
-      {
-         VG_(message)(Vg_UserMsg,
-                      "Conflicting wait call by thread %d:\n",
-                      bei->other_tid);
+      if (bei->other_context) {
+         if (xml)
+            print_err_detail("  <confl_wait_call>\n");
+         print_err_detail("%sConflicting wait call by thread %d:%s\n",
+                          what_prefix, bei->other_tid, what_suffix);
          VG_(pp_ExeContext)(bei->other_context);
+         if (xml)
+            print_err_detail("  </confl_wait_call>\n");
       }
       first_observed(bei->barrier);
       break;
@@ -355,10 +386,8 @@ static void drd_tool_error_pp(Error* const e)
    case RwlockErr: {
       RwlockErrInfo* p = (RwlockErrInfo*)(VG_(get_error_extra)(e));
       tl_assert(p);
-      VG_(message)(Vg_UserMsg,
-                   "%s: rwlock 0x%lx.\n",
-                   VG_(get_error_string)(e),
-                   p->rwlock);
+      print_err_detail("%s%s: rwlock 0x%lx.%s\n", what_prefix,
+                       VG_(get_error_string)(e), p->rwlock, what_suffix);
       VG_(pp_ExeContext)(VG_(get_error_where)(e));
       first_observed(p->rwlock);
       break;
@@ -367,21 +396,25 @@ static void drd_tool_error_pp(Error* const e)
       HoldtimeErrInfo* p =(HoldtimeErrInfo*)(VG_(get_error_extra)(e));
       tl_assert(p);
       tl_assert(p->acquired_at);
-      VG_(message)(Vg_UserMsg, "Acquired at:\n");
+      if (xml)
+         print_err_detail("  <acquired_at>\n");
+      else
+         print_err_detail("Acquired at:\n");
       VG_(pp_ExeContext)(p->acquired_at);
-      VG_(message)(Vg_UserMsg,
-                   "Lock on %s 0x%lx was held during %d ms (threshold: %d ms).\n",
-                   VG_(get_error_string)(e),
-                   p->synchronization_object,
-                   p->hold_time_ms,
-                   p->threshold_ms);
+      print_err_detail("%sLock on %s 0x%lx was held during %d ms"
+                       " (threshold: %d ms).%s\n", what_prefix,
+                       VG_(get_error_string)(e), p->synchronization_object,
+                       p->hold_time_ms, p->threshold_ms, what_suffix);
       VG_(pp_ExeContext)(VG_(get_error_where)(e));
+      if (xml)
+         print_err_detail("  </acquired_at>\n");
       first_observed(p->synchronization_object);
       break;
    }
    case GenericErr: {
       GenericErrInfo* gei = (GenericErrInfo*)(VG_(get_error_extra)(e));
-      VG_(message)(Vg_UserMsg, "%s\n", VG_(get_error_string)(e));
+      print_err_detail("%s%s%s\n", what_prefix, VG_(get_error_string)(e),
+                       what_suffix);
       VG_(pp_ExeContext)(VG_(get_error_where)(e));
       if (gei->addr)
         first_observed(gei->addr);
@@ -389,33 +422,30 @@ static void drd_tool_error_pp(Error* const e)
    }
    case InvalidThreadId: {
       InvalidThreadIdInfo* iti =(InvalidThreadIdInfo*)(VG_(get_error_extra)(e));
-      VG_(message)(Vg_UserMsg,
-                   "%s 0x%llx\n", VG_(get_error_string)(e), iti->ptid);
+      print_err_detail("%s%s 0x%llx%s\n", what_prefix, VG_(get_error_string)(e),
+                       iti->ptid, what_suffix);
       VG_(pp_ExeContext)(VG_(get_error_where)(e));
       break;
    }
    case UnimpHgClReq: {
       UnimpClReqInfo* uicr =(UnimpClReqInfo*)(VG_(get_error_extra)(e));
-      VG_(message)(Vg_UserMsg,
-                   "The annotation macro %s has not yet been implemented in"
-                   " <valgrind/helgrind.h>\n",
-                   /*VG_(get_error_string)(e),*/ uicr->descr);
+      print_err_detail("%sThe annotation macro %s has not yet been implemented"
+                       " in %ps%s\n", what_prefix, uicr->descr,
+                       "<valgrind/helgrind.h>", what_suffix);
       VG_(pp_ExeContext)(VG_(get_error_where)(e));
       break;
    }
    case UnimpDrdClReq: {
       UnimpClReqInfo* uicr =(UnimpClReqInfo*)(VG_(get_error_extra)(e));
-      VG_(message)(Vg_UserMsg,
-                   "The annotation macro %s has not yet been implemented in"
-                   " <valgrind/drd.h>\n",
-                   uicr->descr);
+      print_err_detail("%sThe annotation macro %s has not yet been implemented"
+                       " in %ps%s\n", what_prefix, uicr->descr,
+                       "<valgrind/drd.h>", what_suffix);
       VG_(pp_ExeContext)(VG_(get_error_where)(e));
       break;
    }
    default:
-      VG_(message)(Vg_UserMsg,
-                   "%s\n",
-                   VG_(get_error_string)(e));
+      print_err_detail("%s%s%s\n", what_prefix, VG_(get_error_string)(e),
+                       what_suffix);
       VG_(pp_ExeContext)(VG_(get_error_where)(e));
       break;
    }
index 5d13affdffe197f441053472717ed022d88660e4..afd0eae62540691cd327cd261cd82642697846c4 100644 (file)
@@ -573,9 +573,8 @@ void drd_pre_thread_create(const ThreadId creator, const ThreadId created)
    }
    if (DRD_(thread_get_trace_fork_join)())
    {
-      VG_(message)(Vg_DebugMsg,
-                   "drd_pre_thread_create creator = %d, created = %d\n",
-                   drd_creator, created);
+      DRD_(trace_msg)("drd_pre_thread_create creator = %d, created = %d\n",
+                      drd_creator, created);
    }
 }
 
@@ -592,9 +591,7 @@ void drd_post_thread_create(const ThreadId vg_created)
    drd_created = DRD_(thread_post_create)(vg_created);
    if (DRD_(thread_get_trace_fork_join)())
    {
-      VG_(message)(Vg_DebugMsg,
-                   "drd_post_thread_create created = %d\n",
-                   drd_created);
+      DRD_(trace_msg)("drd_post_thread_create created = %d\n", drd_created);
    }
    if (! DRD_(get_check_stack_accesses)())
    {
@@ -615,15 +612,11 @@ static void drd_thread_finished(ThreadId vg_tid)
    drd_tid = DRD_(VgThreadIdToDrdThreadId)(vg_tid);
    if (DRD_(thread_get_trace_fork_join)())
    {
-      VG_(message)(Vg_DebugMsg,
-                   "drd_thread_finished tid = %d%s\n",
-                   drd_tid,
-                   DRD_(thread_get_joinable)(drd_tid)
-                   ? ""
-                   : " (which is a detached thread)");
+      DRD_(trace_msg)("drd_thread_finished tid = %d%s\n", drd_tid,
+                      DRD_(thread_get_joinable)(drd_tid)
+                      ? "" : " (which is a detached thread)");
    }
-   if (s_show_stack_usage)
-   {
+   if (s_show_stack_usage && !VG_(clo_xml)) {
       const SizeT stack_size = DRD_(thread_get_stack_size)(drd_tid);
       const SizeT used_stack
          = (DRD_(thread_get_stack_max)(drd_tid)
@@ -633,11 +626,8 @@ static void drd_thread_finished(ThreadId vg_tid)
                    " on its stack. Margin: %ld bytes.\n",
                    drd_tid,
                    DRD_(thread_get_joinable)(drd_tid)
-                   ? ""
-                   : " (which is a detached thread)",
-                   used_stack,
-                   stack_size,
-                   stack_size - used_stack);
+                   ? "" : " (which is a detached thread)",
+                   used_stack, stack_size, stack_size - used_stack);
 
    }
    drd_stop_using_mem(DRD_(thread_get_stack_min)(drd_tid),
@@ -689,12 +679,11 @@ static void DRD_(fini)(Int exitcode)
 {
    // thread_print_all();
    if (VG_(clo_verbosity) == 1 && !VG_(clo_xml)) {
-      VG_(message)(Vg_UserMsg,
-                   "For counts of detected and suppressed errors, "
+      VG_(message)(Vg_UserMsg, "For counts of detected and suppressed errors, "
                    "rerun with: -v\n");
    }
 
-   if (VG_(clo_stats) || s_print_stats)
+   if ((VG_(clo_stats) || s_print_stats) && !VG_(clo_xml))
    {
       ULong pu = DRD_(thread_get_update_conflict_set_count)();
       ULong pu_seg_cr = DRD_(thread_get_update_conflict_set_new_sg_count)();
@@ -706,21 +695,21 @@ static void DRD_(fini)(Int exitcode)
                    DRD_(thread_get_context_switch_count)());
       VG_(message)(Vg_UserMsg,
                    "confl set: %lld full updates and %lld partial updates;\n",
-                  DRD_(thread_get_compute_conflict_set_count)(),
-                  pu);
+                   DRD_(thread_get_compute_conflict_set_count)(),
+                   pu);
       VG_(message)(Vg_UserMsg,
                    "           %lld partial updates during segment creation,\n",
-                  pu_seg_cr);
+                   pu_seg_cr);
       VG_(message)(Vg_UserMsg,
                    "           %lld because of mutex/sema/cond.var. operations,\n",
-                  pu_mtx_cv);
+                   pu_mtx_cv);
       VG_(message)(Vg_UserMsg,
                    "           %lld because of barrier/rwlock operations and\n",
                   pu - pu_seg_cr - pu_mtx_cv - pu_join);
       VG_(message)(Vg_UserMsg,
                    "           %lld partial updates because of thread join"
-                  " operations.\n",
-                  pu_join);
+                   " operations.\n",
+                   pu_join);
       VG_(message)(Vg_UserMsg,
                    " segments: created %lld segments, max %lld alive,\n",
                    DRD_(sg_get_segments_created_count)(),
@@ -767,6 +756,7 @@ void drd_pre_clo_init(void)
    VG_(needs_command_line_options)(DRD_(process_cmd_line_option),
                                    DRD_(print_usage),
                                    DRD_(print_debug_usage));
+   VG_(needs_xml_output)          ();
 
    // Error handling.
    DRD_(register_error_handlers)();
index a9cd5fb274581aefb572cfc51ee59393dbe0f001..c50dd4ceb3da0c0bfaa7972848b00c011786aad4 100644 (file)
@@ -390,7 +390,7 @@ void DRD_(thread_post_join)(DrdThreadId drd_joiner, DrdThreadId drd_joinee)
                        ", new vc: %s", vc);
          VG_(free)(vc);
       }
-      DRD_(trace_msg)("%s\n", msg);
+      DRD_(trace_msg)("%pS\n", msg);
       VG_(free)(msg);
    }
 
@@ -1249,29 +1249,19 @@ void DRD_(thread_print_all)(void)
 }
 
 /** Show a call stack involved in a data race. */
-static void show_call_stack(const DrdThreadId tid,
-                            const Char* const msg,
-                            ExeContext* const callstack)
+static void show_call_stack(const DrdThreadId tid, ExeContext* const callstack)
 {
    const ThreadId vg_tid = DRD_(DrdThreadIdToVgThreadId)(tid);
 
-   VG_(message)(Vg_UserMsg, "%s (thread %d)\n", msg, tid);
-
-   if (vg_tid != VG_INVALID_THREADID)
-   {
+   if (vg_tid != VG_INVALID_THREADID) {
       if (callstack)
-      {
          VG_(pp_ExeContext)(callstack);
-      }
       else
-      {
          VG_(get_and_pp_StackTrace)(vg_tid, VG_(clo_backtrace_size));
-      }
-   }
-   else
-   {
-      VG_(message)(Vg_UserMsg,
-                   "   (thread finished, call stack no longer available)\n");
+   } else {
+      if (!VG_(clo_xml))
+         VG_(message)(Vg_UserMsg,
+                      "   (thread finished, call stack no longer available)\n");
    }
 }
 
@@ -1310,10 +1300,21 @@ thread_report_conflicting_segments_segment(const DrdThreadId tid,
                                               access_type))
                {
                   tl_assert(q->stacktrace);
-                  show_call_stack(i,        "Other segment start",
-                                  q->stacktrace);
-                  show_call_stack(i,        "Other segment end",
-                                  q->next ? q->next->stacktrace : 0);
+                  if (VG_(clo_xml))
+                     VG_(printf_xml)("  <other_segment_start>\n");
+                  else
+                     VG_(message)(Vg_UserMsg,
+                                  "Other segment start (thread %d)\n", i);
+                  show_call_stack(i, q->stacktrace);
+                  if (VG_(clo_xml))
+                     VG_(printf_xml)("  </other_segment_start>\n"
+                                     "  <other_segment_end>\n");
+                  else
+                     VG_(message)(Vg_UserMsg,
+                                  "Other segment end (thread %d)\n", i);
+                  show_call_stack(i, q->next ? q->next->stacktrace : 0);
+                  if (VG_(clo_xml))
+                     VG_(printf_xml)("  </other_segment_end>\n");
                }
             }
          }
index 3d171e1d0a8c18b9a61a5b7aa0ac4e12daae304d..eadb34ab324bc0b1a7cf4dd2d74ab3f22c106e21 100644 (file)
@@ -8,6 +8,8 @@ dist_noinst_SCRIPTS =               \
        filter_stderr               \
        filter_stderr_and_thread_no \
        filter_stderr_and_thread_no_and_offset \
+       filter_thread_no            \
+       filter_xml_and_thread_no    \
        run_openmp_test             \
        supported_libpthread        \
        supported_sem_init
@@ -19,6 +21,8 @@ noinst_HEADERS =                                    \
 EXTRA_DIST =                                        \
        annotate_barrier.stderr.exp                 \
        annotate_barrier.vgtest                     \
+       annotate_barrier_xml.stderr.exp             \
+       annotate_barrier_xml.vgtest                 \
        annotate_hb_err.stderr.exp                  \
        annotate_hb_err.vgtest                      \
        annotate_hb_race.stderr.exp                 \
@@ -55,12 +59,16 @@ EXTRA_DIST =                                        \
        annotate_ignore_write2.vgtest               \
        annotate_trace_memory.stderr.exp            \
        annotate_trace_memory.vgtest                \
+       annotate_trace_memory_xml.stderr.exp        \
+       annotate_trace_memory_xml.vgtest            \
        annotate_static.stderr.exp                  \
        annotate_static.vgtest                      \
        atomic_var.stderr.exp                       \
        atomic_var.vgtest                           \
        bar_bad.stderr.exp                          \
        bar_bad.vgtest                              \
+       bar_bad_xml.stderr.exp                      \
+       bar_bad_xml.vgtest                          \
        bar_trivial.stderr.exp                      \
        bar_trivial.stdout.exp                      \
        bar_trivial.vgtest                          \
@@ -78,6 +86,8 @@ EXTRA_DIST =                                        \
        fp_race.vgtest                              \
        fp_race2.stderr.exp                         \
        fp_race2.vgtest                             \
+       fp_race_xml.stderr.exp                      \
+       fp_race_xml.vgtest                          \
        free_is_write.stderr.exp                    \
        free_is_write.vgtest                        \
        free_is_write2.stderr.exp                   \
@@ -271,6 +281,8 @@ EXTRA_DIST =                                        \
        tc24_nonzero_sem.vgtest                     \
        thread_name.stderr.exp                      \
        thread_name.vgtest                          \
+       thread_name_xml.stderr.exp                  \
+       thread_name_xml.vgtest                      \
        threaded-fork.stderr.exp                    \
        threaded-fork.vgtest                        \
        trylock.stderr.exp                          \
diff --git a/drd/tests/annotate_barrier_xml.stderr.exp b/drd/tests/annotate_barrier_xml.stderr.exp
new file mode 100644 (file)
index 0000000..63355da
--- /dev/null
@@ -0,0 +1,335 @@
+<?xml version="1.0"?>
+
+<valgrindoutput>
+
+<protocolversion>4</protocolversion>
+<protocoltool>drd</protocoltool>
+
+<preamble>
+  <line>...</line>
+  <line>...</line>
+  <line>...</line>
+  <line>...</line>
+</preamble>
+
+<pid>...</pid>
+<ppid>...</ppid>
+<tool>drd</tool>
+
+<args>
+  <vargv>...</vargv>
+  <argv>
+    <exe>./annotate_barrier</exe>
+    <arg>2</arg>
+    <arg>1</arg>
+    <arg>1</arg>
+  </argv>
+</args>
+
+<status>
+  <state>RUNNING</state>
+  <time>...</time>
+</status>
+
+<error>
+  <unique>0x........</unique>
+  <tid>...</tid>
+  <kind>UnimpDrdClReq</kind>
+  <what>The annotation macro ANNOTATE_BARRIER_INIT has not yet been implemented in &lt;valgrind/drd.h&gt;</what>
+  <stack>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>barrier_init</fn>
+      <dir>...</dir>
+      <file>annotate_barrier.c</file>
+      <line>...</line>
+    </frame>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>barriers_and_races</fn>
+      <dir>...</dir>
+      <file>annotate_barrier.c</file>
+      <line>...</line>
+    </frame>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>main</fn>
+      <dir>...</dir>
+      <file>annotate_barrier.c</file>
+      <line>...</line>
+    </frame>
+  </stack>
+</error>
+
+<error>
+  <unique>0x........</unique>
+  <tid>...</tid>
+  <kind>UnimpDrdClReq</kind>
+  <what>The annotation macro ANNOTATE_BARRIER_WAIT_BEFORE has not yet been implemented in &lt;valgrind/drd.h&gt;</what>
+  <stack>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>barrier_wait</fn>
+      <dir>...</dir>
+      <file>annotate_barrier.c</file>
+      <line>...</line>
+    </frame>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>threadfunc</fn>
+      <dir>...</dir>
+      <file>annotate_barrier.c</file>
+      <line>...</line>
+    </frame>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>vgDrd_thread_wrapper</fn>
+      <dir>...</dir>
+      <file>drd_pthread_intercepts.c</file>
+      <line>...</line>
+    </frame>
+  </stack>
+</error>
+
+<error>
+  <unique>0x........</unique>
+  <tid>...</tid>
+  <kind>UnimpDrdClReq</kind>
+  <what>The annotation macro ANNOTATE_BARRIER_WAIT_AFTER has not yet been implemented in &lt;valgrind/drd.h&gt;</what>
+  <stack>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>barrier_wait</fn>
+      <dir>...</dir>
+      <file>annotate_barrier.c</file>
+      <line>...</line>
+    </frame>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>threadfunc</fn>
+      <dir>...</dir>
+      <file>annotate_barrier.c</file>
+      <line>...</line>
+    </frame>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>vgDrd_thread_wrapper</fn>
+      <dir>...</dir>
+      <file>drd_pthread_intercepts.c</file>
+      <line>...</line>
+    </frame>
+  </stack>
+</error>
+
+<error>
+  <unique>0x........</unique>
+  <tid>...</tid>
+  <kind>UnimpDrdClReq</kind>
+  <what>The annotation macro ANNOTATE_BARRIER_WAIT_BEFORE has not yet been implemented in &lt;valgrind/drd.h&gt;</what>
+  <stack>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>barrier_wait</fn>
+      <dir>...</dir>
+      <file>annotate_barrier.c</file>
+      <line>...</line>
+    </frame>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>threadfunc</fn>
+      <dir>...</dir>
+      <file>annotate_barrier.c</file>
+      <line>...</line>
+    </frame>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>vgDrd_thread_wrapper</fn>
+      <dir>...</dir>
+      <file>drd_pthread_intercepts.c</file>
+      <line>...</line>
+    </frame>
+  </stack>
+</error>
+
+<error>
+  <unique>0x........</unique>
+  <tid>...</tid>
+  <kind>ConflictingAccess</kind>
+  <what>Conflicting store by thread 2 at 0x........ size 4</what>
+  <stack>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>threadfunc</fn>
+      <dir>...</dir>
+      <file>annotate_barrier.c</file>
+      <line>...</line>
+    </frame>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>vgDrd_thread_wrapper</fn>
+      <dir>...</dir>
+      <file>drd_pthread_intercepts.c</file>
+      <line>...</line>
+    </frame>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>start_thread</fn>
+      <dir>...</dir>
+      <file>pthread_create.c</file>
+      <line>...</line>
+    </frame>
+  </stack>
+  <auxwhat>
+    <text>Address 0x........ is at offset 0 from 0x.........</text>
+  <stack>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>malloc</fn>
+      <dir>...</dir>
+      <file>vg_replace_malloc.c</file>
+      <line>...</line>
+    </frame>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>barriers_and_races</fn>
+      <dir>...</dir>
+      <file>annotate_barrier.c</file>
+      <line>...</line>
+    </frame>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>main</fn>
+      <dir>...</dir>
+      <file>annotate_barrier.c</file>
+      <line>...</line>
+    </frame>
+  </stack>
+  </auxwhat>
+</error>
+
+<error>
+  <unique>0x........</unique>
+  <tid>...</tid>
+  <kind>UnimpDrdClReq</kind>
+  <what>The annotation macro ANNOTATE_BARRIER_WAIT_AFTER has not yet been implemented in &lt;valgrind/drd.h&gt;</what>
+  <stack>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>barrier_wait</fn>
+      <dir>...</dir>
+      <file>annotate_barrier.c</file>
+      <line>...</line>
+    </frame>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>threadfunc</fn>
+      <dir>...</dir>
+      <file>annotate_barrier.c</file>
+      <line>...</line>
+    </frame>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>vgDrd_thread_wrapper</fn>
+      <dir>...</dir>
+      <file>drd_pthread_intercepts.c</file>
+      <line>...</line>
+    </frame>
+  </stack>
+</error>
+
+<error>
+  <unique>0x........</unique>
+  <tid>...</tid>
+  <kind>UnimpDrdClReq</kind>
+  <what>The annotation macro ANNOTATE_BARRIER_DESTROY has not yet been implemented in &lt;valgrind/drd.h&gt;</what>
+  <stack>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>barrier_destroy</fn>
+      <dir>...</dir>
+      <file>annotate_barrier.c</file>
+      <line>...</line>
+    </frame>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>barriers_and_races</fn>
+      <dir>...</dir>
+      <file>annotate_barrier.c</file>
+      <line>...</line>
+    </frame>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>main</fn>
+      <dir>...</dir>
+      <file>annotate_barrier.c</file>
+      <line>...</line>
+    </frame>
+  </stack>
+</error>
+
+Done.
+
+<status>
+  <state>FINISHED</state>
+  <time>...</time>
+</status>
+
+<errorcounts>
+  <pair>
+    <count>...</count>
+    <unique>0x........</unique>
+  </pair>
+  <pair>
+    <count>...</count>
+    <unique>0x........</unique>
+  </pair>
+  <pair>
+    <count>...</count>
+    <unique>0x........</unique>
+  </pair>
+  <pair>
+    <count>...</count>
+    <unique>0x........</unique>
+  </pair>
+  <pair>
+    <count>...</count>
+    <unique>0x........</unique>
+  </pair>
+  <pair>
+    <count>...</count>
+    <unique>0x........</unique>
+  </pair>
+  <pair>
+    <count>...</count>
+    <unique>0x........</unique>
+  </pair>
+</errorcounts>
+
+<suppcounts>...</suppcounts>
+
+</valgrindoutput>
+
diff --git a/drd/tests/annotate_barrier_xml.vgtest b/drd/tests/annotate_barrier_xml.vgtest
new file mode 100644 (file)
index 0000000..f0ec0ce
--- /dev/null
@@ -0,0 +1,4 @@
+prereq: test -e annotate_barrier && ./supported_libpthread
+vgopts: --read-var-info=yes --check-stack-var=yes --show-confl-seg=no --num-callers=3 --xml=yes --xml-fd=2
+prog: annotate_barrier 2 1 1
+stderr_filter: ../../memcheck/tests/filter_xml
diff --git a/drd/tests/annotate_trace_memory_xml.stderr.exp b/drd/tests/annotate_trace_memory_xml.stderr.exp
new file mode 100644 (file)
index 0000000..22edcf2
--- /dev/null
@@ -0,0 +1,141 @@
+<?xml version="1.0"?>
+
+<valgrindoutput>
+
+<protocolversion>4</protocolversion>
+<protocoltool>drd</protocoltool>
+
+<preamble>
+  <line>...</line>
+  <line>...</line>
+  <line>...</line>
+  <line>...</line>
+</preamble>
+
+<pid>...</pid>
+<ppid>...</ppid>
+<tool>drd</tool>
+
+<args>
+  <vargv>...</vargv>
+  <argv>
+    <exe>./tsan_unittest</exe>
+    <arg>1</arg>
+  </argv>
+</args>
+
+<status>
+  <state>RUNNING</state>
+  <time>...</time>
+</status>
+
+FLAGS [phb=1, fm=0]
+test01: positive
+<traceline>
+  store 0x........ size 4 (thread x / vc ...)
+</traceline>
+  <stack>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>test01::Worker()</fn>
+      <dir>...</dir>
+      <file>tsan_unittest.cpp</file>
+      <line>...</line>
+    </frame>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>MyThread::ThreadBody(MyThread*)</fn>
+      <dir>...</dir>
+      <file>tsan_thread_wrappers_pthread.h</file>
+      <line>...</line>
+    </frame>
+  </stack>
+<traceline>
+  store 0x........ size 4 (thread x / vc ...)
+</traceline>
+  <stack>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>test01::Parent()</fn>
+      <dir>...</dir>
+      <file>tsan_unittest.cpp</file>
+      <line>...</line>
+    </frame>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>test01::Run()</fn>
+      <dir>...</dir>
+      <file>tsan_unittest.cpp</file>
+      <line>...</line>
+    </frame>
+  </stack>
+<error>
+  <unique>0x........</unique>
+  <tid>...</tid>
+  <kind>ConflictingAccess</kind>
+  <what>Conflicting store by thread x at 0x........ size 4</what>
+  <stack>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>test01::Parent()</fn>
+      <dir>...</dir>
+      <file>tsan_unittest.cpp</file>
+      <line>...</line>
+    </frame>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>test01::Run()</fn>
+      <dir>...</dir>
+      <file>tsan_unittest.cpp</file>
+      <line>...</line>
+    </frame>
+  </stack>
+  <auxwhat><text>      Allocation context: BSS section of tsan_unittest
+  </text><auxwhat>
+</error>
+
+<traceline>
+  load  0x........ size 4 (thread x / vc ...)
+</traceline>
+  <stack>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>test01::Run()</fn>
+      <dir>...</dir>
+      <file>tsan_unittest.cpp</file>
+      <line>...</line>
+    </frame>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>main</fn>
+      <dir>...</dir>
+      <file>tsan_unittest.cpp</file>
+      <line>...</line>
+    </frame>
+  </stack>
+       GLOB=2
+
+<status>
+  <state>FINISHED</state>
+  <time>...</time>
+</status>
+
+<errorcounts>
+  <pair>
+    <count>...</count>
+    <unique>0x........</unique>
+  </pair>
+</errorcounts>
+
+<suppcounts>...</suppcounts>
+
+</valgrindoutput>
+
diff --git a/drd/tests/annotate_trace_memory_xml.vgtest b/drd/tests/annotate_trace_memory_xml.vgtest
new file mode 100644 (file)
index 0000000..c5aaaa5
--- /dev/null
@@ -0,0 +1,5 @@
+prereq: test -e tsan_unittest && ./supported_libpthread
+vgopts: --read-var-info=yes --check-stack-var=yes --show-confl-seg=no --num-callers=2 --xml=yes --xml-fd=2
+prog: tsan_unittest
+args: 1
+stderr_filter: ./filter_xml_and_thread_no
diff --git a/drd/tests/bar_bad_xml.stderr.exp b/drd/tests/bar_bad_xml.stderr.exp
new file mode 100644 (file)
index 0000000..acb9656
--- /dev/null
@@ -0,0 +1,315 @@
+<?xml version="1.0"?>
+
+<valgrindoutput>
+
+<protocolversion>4</protocolversion>
+<protocoltool>drd</protocoltool>
+
+<preamble>
+  <line>...</line>
+  <line>...</line>
+  <line>...</line>
+  <line>...</line>
+</preamble>
+
+<pid>...</pid>
+<ppid>...</ppid>
+<tool>drd</tool>
+
+<args>
+  <vargv>...</vargv>
+  <argv>
+    <exe>./../../helgrind/tests/bar_bad</exe>
+  </argv>
+</args>
+
+<status>
+  <state>RUNNING</state>
+  <time>...</time>
+</status>
+
+
+initialise a barrier with zero count
+<error>
+  <unique>0x........</unique>
+  <tid>...</tid>
+  <kind>BarrierErr</kind>
+  <what>pthread_barrier_init: 'count' argument is zero: barrier 0x........</what>
+  <stack>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>pthread_barrier_init</fn>
+      <dir>...</dir>
+      <file>drd_pthread_intercepts.c</file>
+      <line>...</line>
+    </frame>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>main</fn>
+      <dir>...</dir>
+      <file>bar_bad.c</file>
+      <line>...</line>
+    </frame>
+  </stack>
+</error>
+
+
+initialise a barrier twice
+<error>
+  <unique>0x........</unique>
+  <tid>...</tid>
+  <kind>BarrierErr</kind>
+  <what>Barrier reinitialization: barrier 0x........</what>
+  <stack>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>pthread_barrier_init</fn>
+      <dir>...</dir>
+      <file>drd_pthread_intercepts.c</file>
+      <line>...</line>
+    </frame>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>main</fn>
+      <dir>...</dir>
+      <file>bar_bad.c</file>
+      <line>...</line>
+    </frame>
+  </stack>
+  <first_observed_at>
+    <what>barrier</what>
+    <address>0x........</address>
+  <stack>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>pthread_barrier_init</fn>
+      <dir>...</dir>
+      <file>drd_pthread_intercepts.c</file>
+      <line>...</line>
+    </frame>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>main</fn>
+      <dir>...</dir>
+      <file>bar_bad.c</file>
+      <line>...</line>
+    </frame>
+  </stack>
+  </first_observed_at>
+</error>
+
+
+initialise a barrier which has threads waiting on it
+<error>
+  <unique>0x........</unique>
+  <tid>...</tid>
+  <kind>BarrierErr</kind>
+  <what>Barrier reinitialization: barrier 0x........</what>
+  <stack>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>pthread_barrier_init</fn>
+      <dir>...</dir>
+      <file>drd_pthread_intercepts.c</file>
+      <line>...</line>
+    </frame>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>main</fn>
+      <dir>...</dir>
+      <file>bar_bad.c</file>
+      <line>...</line>
+    </frame>
+  </stack>
+  <first_observed_at>
+    <what>barrier</what>
+    <address>0x........</address>
+  <stack>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>pthread_barrier_init</fn>
+      <dir>...</dir>
+      <file>drd_pthread_intercepts.c</file>
+      <line>...</line>
+    </frame>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>main</fn>
+      <dir>...</dir>
+      <file>bar_bad.c</file>
+      <line>...</line>
+    </frame>
+  </stack>
+  </first_observed_at>
+</error>
+
+
+destroy a barrier that has waiting threads
+<error>
+  <unique>0x........</unique>
+  <tid>...</tid>
+  <kind>BarrierErr</kind>
+  <what>Destruction of a barrier with active waiters: barrier 0x........</what>
+  <stack>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>pthread_barrier_destroy</fn>
+      <dir>...</dir>
+      <file>drd_pthread_intercepts.c</file>
+      <line>...</line>
+    </frame>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>main</fn>
+      <dir>...</dir>
+      <file>bar_bad.c</file>
+      <line>...</line>
+    </frame>
+  </stack>
+  <first_observed_at>
+    <what>barrier</what>
+    <address>0x........</address>
+  <stack>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>pthread_barrier_init</fn>
+      <dir>...</dir>
+      <file>drd_pthread_intercepts.c</file>
+      <line>...</line>
+    </frame>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>main</fn>
+      <dir>...</dir>
+      <file>bar_bad.c</file>
+      <line>...</line>
+    </frame>
+  </stack>
+  </first_observed_at>
+</error>
+
+
+destroy a barrier that was never initialised
+<error>
+  <unique>0x........</unique>
+  <tid>...</tid>
+  <kind>GenericErr</kind>
+  <what>Not a barrier</what>
+  <stack>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>pthread_barrier_destroy</fn>
+      <dir>...</dir>
+      <file>drd_pthread_intercepts.c</file>
+      <line>...</line>
+    </frame>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>main</fn>
+      <dir>...</dir>
+      <file>bar_bad.c</file>
+      <line>...</line>
+    </frame>
+  </stack>
+</error>
+
+<error>
+  <unique>0x........</unique>
+  <tid>...</tid>
+  <kind>BarrierErr</kind>
+  <what>Destruction of barrier that is being waited upon: barrier 0x........</what>
+  <stack>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>free</fn>
+      <dir>...</dir>
+      <file>vg_replace_malloc.c</file>
+      <line>...</line>
+    </frame>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>main</fn>
+      <dir>...</dir>
+      <file>bar_bad.c</file>
+      <line>...</line>
+    </frame>
+  </stack>
+  <first_observed_at>
+    <what>barrier</what>
+    <address>0x........</address>
+  <stack>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>pthread_barrier_init</fn>
+      <dir>...</dir>
+      <file>drd_pthread_intercepts.c</file>
+      <line>...</line>
+    </frame>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>main</fn>
+      <dir>...</dir>
+      <file>bar_bad.c</file>
+      <line>...</line>
+    </frame>
+  </stack>
+  </first_observed_at>
+</error>
+
+
+<status>
+  <state>FINISHED</state>
+  <time>...</time>
+</status>
+
+<errorcounts>
+  <pair>
+    <count>...</count>
+    <unique>0x........</unique>
+  </pair>
+  <pair>
+    <count>...</count>
+    <unique>0x........</unique>
+  </pair>
+  <pair>
+    <count>...</count>
+    <unique>0x........</unique>
+  </pair>
+  <pair>
+    <count>...</count>
+    <unique>0x........</unique>
+  </pair>
+  <pair>
+    <count>...</count>
+    <unique>0x........</unique>
+  </pair>
+  <pair>
+    <count>...</count>
+    <unique>0x........</unique>
+  </pair>
+</errorcounts>
+
+<suppcounts>...</suppcounts>
+
+</valgrindoutput>
+
diff --git a/drd/tests/bar_bad_xml.vgtest b/drd/tests/bar_bad_xml.vgtest
new file mode 100644 (file)
index 0000000..d626dc3
--- /dev/null
@@ -0,0 +1,4 @@
+prereq: test -e ../../helgrind/tests/bar_bad && ./supported_libpthread
+vgopts: --xml=yes --xml-fd=2
+prog: ../../helgrind/tests/bar_bad
+stderr_filter: ../../memcheck/tests/filter_xml
index 3993f6f2f39630f9f17aef0d69c5d1686ddd073c..2dac0ad0e75d7a6982257289c1d3ed27a73b28aa 100755 (executable)
@@ -1,9 +1,3 @@
 #! /bin/sh
 
-./filter_stderr |
-
-# Get rid of the numbers as these make some tests more scheduling sensitive
-# -- those where there are multiple threads which play interchangeable roles.
-grep -v "^Thread [0-9][0-9]*:$" |
-sed -e "s:hread [0-9][0-9]*:hread x:g" \
-    -e "s:of thread [0-9][0-9]*$:of thread x:g"
+./filter_stderr | ./filter_thread_no
diff --git a/drd/tests/filter_thread_no b/drd/tests/filter_thread_no
new file mode 100755 (executable)
index 0000000..f70c7b6
--- /dev/null
@@ -0,0 +1,7 @@
+#! /bin/sh
+
+# Get rid of the numbers as these make some tests more scheduling sensitive
+# -- those where there are multiple threads which play interchangeable roles.
+grep -v "^Thread [0-9][0-9]*:$" |
+sed -e "s:hread [0-9][0-9]*:hread x:g" \
+    -e "s:of thread [0-9][0-9]*$:of thread x:g"
diff --git a/drd/tests/filter_xml_and_thread_no b/drd/tests/filter_xml_and_thread_no
new file mode 100644 (file)
index 0000000..4e65091
--- /dev/null
@@ -0,0 +1,3 @@
+#! /bin/sh
+
+../../memcheck/tests/filter_xml | ./filter_thread_no
diff --git a/drd/tests/fp_race_xml.stderr.exp b/drd/tests/fp_race_xml.stderr.exp
new file mode 100644 (file)
index 0000000..485f02e
--- /dev/null
@@ -0,0 +1,118 @@
+<?xml version="1.0"?>
+
+<valgrindoutput>
+
+<protocolversion>4</protocolversion>
+<protocoltool>drd</protocoltool>
+
+<preamble>
+  <line>...</line>
+  <line>...</line>
+  <line>...</line>
+  <line>...</line>
+</preamble>
+
+<pid>...</pid>
+<ppid>...</ppid>
+<tool>drd</tool>
+
+<args>
+  <vargv>...</vargv>
+  <argv>
+    <exe>./fp_race</exe>
+  </argv>
+</args>
+
+<status>
+  <state>RUNNING</state>
+  <time>...</time>
+</status>
+
+<traceline>
+  drd_pre_thread_create creator = 0, created = 1
+</traceline>
+<traceline>
+  drd_post_thread_create created = 1
+</traceline>
+<traceline>
+  drd_pre_thread_create creator = 1, created = 2
+</traceline>
+<traceline>
+  drd_post_thread_create created = 2
+</traceline>
+<traceline>
+  drd_thread_finished tid = 2
+</traceline>
+<error>
+  <unique>0x........</unique>
+  <tid>...</tid>
+  <kind>ConflictingAccess</kind>
+  <what>Conflicting load by thread 1 at 0x........ size 8</what>
+  <stack>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>main</fn>
+      <dir>...</dir>
+      <file>fp_race.c</file>
+      <line>...</line>
+    </frame>
+  </stack>
+  <auxwhat>Location 0x........ is 0 bytes inside local var "s_d3"</auxwhat>
+  <xauxwhat><text>declared at fp_race.c:24, in frame #? of thread 1</text> <file>fp_race.c</file> <line>...</line> </xauxwhat>
+  <other_segment_start>
+  </other_segment_start>
+  <other_segment_end>
+  </other_segment_end>
+</error>
+
+<error>
+  <unique>0x........</unique>
+  <tid>...</tid>
+  <kind>ConflictingAccess</kind>
+  <what>Conflicting store by thread 1 at 0x........ size 8</what>
+  <stack>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>main</fn>
+      <dir>...</dir>
+      <file>fp_race.c</file>
+      <line>...</line>
+    </frame>
+  </stack>
+  <auxwhat>Location 0x........ is 0 bytes inside local var "s_d3"</auxwhat>
+  <xauxwhat><text>declared at fp_race.c:24, in frame #? of thread 1</text> <file>fp_race.c</file> <line>...</line> </xauxwhat>
+  <other_segment_start>
+  </other_segment_start>
+  <other_segment_end>
+  </other_segment_end>
+</error>
+
+<traceline>
+  drd_post_thread_join joiner = 1, joinee = 2, new vc: [ 1: 4, 2: 1 ]
+</traceline>
+<traceline>
+  drd_thread_finished tid = 1
+</traceline>
+
+<status>
+  <state>FINISHED</state>
+  <time>...</time>
+</status>
+
+<errorcounts>
+  <pair>
+    <count>...</count>
+    <unique>0x........</unique>
+  </pair>
+  <pair>
+    <count>...</count>
+    <unique>0x........</unique>
+  </pair>
+</errorcounts>
+
+<suppcounts>...</suppcounts>
+
+</valgrindoutput>
+
diff --git a/drd/tests/fp_race_xml.vgtest b/drd/tests/fp_race_xml.vgtest
new file mode 100644 (file)
index 0000000..12b3b57
--- /dev/null
@@ -0,0 +1,4 @@
+prereq: ./supported_libpthread
+vgopts: --read-var-info=yes --xml=yes --xml-fd=2 --trace-fork-join=yes
+prog: fp_race
+stderr_filter: ../../memcheck/tests/filter_xml
diff --git a/drd/tests/thread_name_xml.stderr.exp b/drd/tests/thread_name_xml.stderr.exp
new file mode 100644 (file)
index 0000000..36b5360
--- /dev/null
@@ -0,0 +1,443 @@
+<?xml version="1.0"?>
+
+<valgrindoutput>
+
+<protocolversion>4</protocolversion>
+<protocoltool>drd</protocoltool>
+
+<preamble>
+  <line>...</line>
+  <line>...</line>
+  <line>...</line>
+  <line>...</line>
+</preamble>
+
+<pid>...</pid>
+<ppid>...</ppid>
+<tool>drd</tool>
+
+<args>
+  <vargv>...</vargv>
+  <argv>
+    <exe>./thread_name</exe>
+  </argv>
+</args>
+
+<status>
+  <state>RUNNING</state>
+  <time>...</time>
+</status>
+
+
+thread_func instance 1
+
+<error>
+  <unique>0x........</unique>
+  <tid>...</tid>
+  <kind>MutexErr</kind>
+  <what>The object at address 0x........ is not a mutex.</what>
+  <stack>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>pthread_mutex_unlock</fn>
+      <dir>...</dir>
+      <file>drd_pthread_intercepts.c</file>
+      <line>...</line>
+    </frame>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>thread_func</fn>
+      <dir>...</dir>
+      <file>thread_name.c</file>
+      <line>...</line>
+    </frame>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>vgDrd_thread_wrapper</fn>
+      <dir>...</dir>
+      <file>drd_pthread_intercepts.c</file>
+      <line>...</line>
+    </frame>
+  </stack>
+</error>
+
+
+thread_func instance 2
+
+<error>
+  <unique>0x........</unique>
+  <tid>...</tid>
+  <kind>MutexErr</kind>
+  <what>The object at address 0x........ is not a mutex.</what>
+  <stack>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>pthread_mutex_unlock</fn>
+      <dir>...</dir>
+      <file>drd_pthread_intercepts.c</file>
+      <line>...</line>
+    </frame>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>thread_func</fn>
+      <dir>...</dir>
+      <file>thread_name.c</file>
+      <line>...</line>
+    </frame>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>vgDrd_thread_wrapper</fn>
+      <dir>...</dir>
+      <file>drd_pthread_intercepts.c</file>
+      <line>...</line>
+    </frame>
+  </stack>
+</error>
+
+
+thread_func instance 3
+
+<error>
+  <unique>0x........</unique>
+  <tid>...</tid>
+  <kind>MutexErr</kind>
+  <what>The object at address 0x........ is not a mutex.</what>
+  <stack>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>pthread_mutex_unlock</fn>
+      <dir>...</dir>
+      <file>drd_pthread_intercepts.c</file>
+      <line>...</line>
+    </frame>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>thread_func</fn>
+      <dir>...</dir>
+      <file>thread_name.c</file>
+      <line>...</line>
+    </frame>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>vgDrd_thread_wrapper</fn>
+      <dir>...</dir>
+      <file>drd_pthread_intercepts.c</file>
+      <line>...</line>
+    </frame>
+  </stack>
+</error>
+
+
+thread_func instance 4
+
+<error>
+  <unique>0x........</unique>
+  <tid>...</tid>
+  <kind>MutexErr</kind>
+  <what>The object at address 0x........ is not a mutex.</what>
+  <stack>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>pthread_mutex_unlock</fn>
+      <dir>...</dir>
+      <file>drd_pthread_intercepts.c</file>
+      <line>...</line>
+    </frame>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>thread_func</fn>
+      <dir>...</dir>
+      <file>thread_name.c</file>
+      <line>...</line>
+    </frame>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>vgDrd_thread_wrapper</fn>
+      <dir>...</dir>
+      <file>drd_pthread_intercepts.c</file>
+      <line>...</line>
+    </frame>
+  </stack>
+</error>
+
+
+thread_func instance 5
+
+<error>
+  <unique>0x........</unique>
+  <tid>...</tid>
+  <kind>MutexErr</kind>
+  <what>The object at address 0x........ is not a mutex.</what>
+  <stack>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>pthread_mutex_unlock</fn>
+      <dir>...</dir>
+      <file>drd_pthread_intercepts.c</file>
+      <line>...</line>
+    </frame>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>thread_func</fn>
+      <dir>...</dir>
+      <file>thread_name.c</file>
+      <line>...</line>
+    </frame>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>vgDrd_thread_wrapper</fn>
+      <dir>...</dir>
+      <file>drd_pthread_intercepts.c</file>
+      <line>...</line>
+    </frame>
+  </stack>
+</error>
+
+
+thread_func instance 6
+
+<error>
+  <unique>0x........</unique>
+  <tid>...</tid>
+  <kind>MutexErr</kind>
+  <what>The object at address 0x........ is not a mutex.</what>
+  <stack>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>pthread_mutex_unlock</fn>
+      <dir>...</dir>
+      <file>drd_pthread_intercepts.c</file>
+      <line>...</line>
+    </frame>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>thread_func</fn>
+      <dir>...</dir>
+      <file>thread_name.c</file>
+      <line>...</line>
+    </frame>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>vgDrd_thread_wrapper</fn>
+      <dir>...</dir>
+      <file>drd_pthread_intercepts.c</file>
+      <line>...</line>
+    </frame>
+  </stack>
+</error>
+
+
+thread_func instance 7
+
+<error>
+  <unique>0x........</unique>
+  <tid>...</tid>
+  <kind>MutexErr</kind>
+  <what>The object at address 0x........ is not a mutex.</what>
+  <stack>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>pthread_mutex_unlock</fn>
+      <dir>...</dir>
+      <file>drd_pthread_intercepts.c</file>
+      <line>...</line>
+    </frame>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>thread_func</fn>
+      <dir>...</dir>
+      <file>thread_name.c</file>
+      <line>...</line>
+    </frame>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>vgDrd_thread_wrapper</fn>
+      <dir>...</dir>
+      <file>drd_pthread_intercepts.c</file>
+      <line>...</line>
+    </frame>
+  </stack>
+</error>
+
+
+thread_func instance 8
+
+<error>
+  <unique>0x........</unique>
+  <tid>...</tid>
+  <kind>MutexErr</kind>
+  <what>The object at address 0x........ is not a mutex.</what>
+  <stack>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>pthread_mutex_unlock</fn>
+      <dir>...</dir>
+      <file>drd_pthread_intercepts.c</file>
+      <line>...</line>
+    </frame>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>thread_func</fn>
+      <dir>...</dir>
+      <file>thread_name.c</file>
+      <line>...</line>
+    </frame>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>vgDrd_thread_wrapper</fn>
+      <dir>...</dir>
+      <file>drd_pthread_intercepts.c</file>
+      <line>...</line>
+    </frame>
+  </stack>
+</error>
+
+
+thread_func instance 9
+
+<error>
+  <unique>0x........</unique>
+  <tid>...</tid>
+  <kind>MutexErr</kind>
+  <what>The object at address 0x........ is not a mutex.</what>
+  <stack>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>pthread_mutex_unlock</fn>
+      <dir>...</dir>
+      <file>drd_pthread_intercepts.c</file>
+      <line>...</line>
+    </frame>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>thread_func</fn>
+      <dir>...</dir>
+      <file>thread_name.c</file>
+      <line>...</line>
+    </frame>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>vgDrd_thread_wrapper</fn>
+      <dir>...</dir>
+      <file>drd_pthread_intercepts.c</file>
+      <line>...</line>
+    </frame>
+  </stack>
+</error>
+
+
+thread_func instance 10
+
+<error>
+  <unique>0x........</unique>
+  <tid>...</tid>
+  <kind>MutexErr</kind>
+  <what>The object at address 0x........ is not a mutex.</what>
+  <stack>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>pthread_mutex_unlock</fn>
+      <dir>...</dir>
+      <file>drd_pthread_intercepts.c</file>
+      <line>...</line>
+    </frame>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>thread_func</fn>
+      <dir>...</dir>
+      <file>thread_name.c</file>
+      <line>...</line>
+    </frame>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>vgDrd_thread_wrapper</fn>
+      <dir>...</dir>
+      <file>drd_pthread_intercepts.c</file>
+      <line>...</line>
+    </frame>
+  </stack>
+</error>
+
+
+<status>
+  <state>FINISHED</state>
+  <time>...</time>
+</status>
+
+<errorcounts>
+  <pair>
+    <count>...</count>
+    <unique>0x........</unique>
+  </pair>
+  <pair>
+    <count>...</count>
+    <unique>0x........</unique>
+  </pair>
+  <pair>
+    <count>...</count>
+    <unique>0x........</unique>
+  </pair>
+  <pair>
+    <count>...</count>
+    <unique>0x........</unique>
+  </pair>
+  <pair>
+    <count>...</count>
+    <unique>0x........</unique>
+  </pair>
+  <pair>
+    <count>...</count>
+    <unique>0x........</unique>
+  </pair>
+  <pair>
+    <count>...</count>
+    <unique>0x........</unique>
+  </pair>
+  <pair>
+    <count>...</count>
+    <unique>0x........</unique>
+  </pair>
+  <pair>
+    <count>...</count>
+    <unique>0x........</unique>
+  </pair>
+  <pair>
+    <count>...</count>
+    <unique>0x........</unique>
+  </pair>
+</errorcounts>
+
+<suppcounts>...</suppcounts>
+
+</valgrindoutput>
+
diff --git a/drd/tests/thread_name_xml.vgtest b/drd/tests/thread_name_xml.vgtest
new file mode 100644 (file)
index 0000000..f931e48
--- /dev/null
@@ -0,0 +1,4 @@
+prereq: test -e thread_name && ./supported_libpthread
+vgopts: --read-var-info=yes --check-stack-var=yes --num-callers=3 --xml=yes --xml-fd=2
+prog: thread_name
+stderr_filter: ../../memcheck/tests/filter_xml