Beispiel #1
0
static
void drd_report_data_race2(Error* const err, const DataRaceErrInfo* const dri)
{
  AddrInfo ai;
  const unsigned descr_size = 256;
  Char* descr1 = VG_(malloc)(descr_size);
  Char* descr2 = VG_(malloc)(descr_size);

  tl_assert(dri);
  tl_assert(dri->addr);
  tl_assert(dri->size > 0);
  tl_assert(descr1);
  tl_assert(descr2);

  descr1[0] = 0;
  descr2[0] = 0;
  VG_(get_data_description)(descr1, descr2, descr_size, dri->addr);
  if (descr1[0] == 0)
  {
    describe_malloced_addr(dri->addr, dri->size, &ai);
  }
  VG_(message)(Vg_UserMsg,
               "Conflicting %s by thread %d/%d at 0x%08lx size %ld",
               dri->access_type == eStore ? "store" : "load",
               DrdThreadIdToVgThreadId(dri->tid),
               dri->tid,
               dri->addr,
               dri->size);
  VG_(pp_ExeContext)(VG_(get_error_where)(err));
  if (descr1[0])
  {
    VG_(message)(Vg_UserMsg, "%s", descr1);
    VG_(message)(Vg_UserMsg, "%s", descr2);
  }
  else if (ai.akind == eMallocd && ai.lastchange)
  {
    VG_(message)(Vg_UserMsg,
                 "Address 0x%lx is at offset %ld from 0x%lx."
                 " Allocation context:",
                 dri->addr, ai.rwoffset, dri->addr - ai.rwoffset);
    VG_(pp_ExeContext)(ai.lastchange);
  }
  else
  {
    VG_(message)(Vg_UserMsg, "Allocation context: unknown.");
  }
  if (s_drd_show_conflicting_segments)
  {
    thread_report_conflicting_segments(dri->tid,
                                       dri->addr, dri->size, dri->access_type);
  }

  VG_(free)(descr2);
  VG_(free)(descr1);
}
Beispiel #2
0
static
void drd_report_data_race(Error* const err, const DataRaceErrInfo* const dri)
{
   const Bool xml = VG_(clo_xml);
   const HChar* const what_prefix = xml ? "  <what>" : "";
   const HChar* const what_suffix = xml ? "</what>" : "";
   const HChar* const auxwhat_prefix = xml ? "  <auxwhat>" : "";
   const HChar* const auxwhat_suffix = xml ? "</auxwhat>" : "";
   const HChar* const indent = xml ? "  " : "";
   AddrInfo ai;

   XArray* /* of HChar */ descr1
      = VG_(newXA)( VG_(malloc), "drd.error.drdr2.1",
                    VG_(free), sizeof(HChar) );
   XArray* /* of HChar */ descr2
      = VG_(newXA)( VG_(malloc), "drd.error.drdr2.2",
                    VG_(free), sizeof(HChar) );

   tl_assert(dri);
   tl_assert(dri->addr);
   tl_assert(dri->size > 0);
   tl_assert(descr1);
   tl_assert(descr2);

   (void) VG_(get_data_description)(descr1, descr2, dri->addr);
   /* If there's nothing in descr1/2, free them.  Why is it safe to to
      VG_(indexXA) at zero here?  Because VG_(get_data_description)
      guarantees to zero terminate descr1/2 regardless of the outcome
      of the call.  So there's always at least one element in each XA
      after the call.
   */
   if (0 == VG_(strlen)( VG_(indexXA)( descr1, 0 ))) {
      VG_(deleteXA)( descr1 );
      descr1 = NULL;
   }
   if (0 == VG_(strlen)( VG_(indexXA)( descr2, 0 ))) {
      VG_(deleteXA)( descr2 );
      descr2 = NULL;
   }
   /* Assume (assert) that VG_(get_data_description) fills in descr1
      before it fills in descr2 */
   if (descr1 == NULL)
      tl_assert(descr2 == NULL);
   /* So anyway.  Do we have something useful? */
   if (descr1 == NULL)
   {
      /* No.  Do Plan B. */
      describe_malloced_addr(dri->addr, &ai);
   }

   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) {
      print_err_detail("%s%s\n", indent, (HChar*)VG_(indexXA)(descr1, 0));
      if (descr2 != NULL)
         print_err_detail("%s%s\n", indent, (HChar*)VG_(indexXA)(descr2, 0));
   } else if (ai.akind == eMallocd && ai.lastchange) {
      print_err_detail("%sAddress 0x%lx is at offset %ld from 0x%lx.%s%s",
                       auxwhat_prefix, dri->addr, ai.rwoffset,
                       dri->addr - ai.rwoffset, auxwhat_suffix,
                       xml ? "\n" : "");
      if (xml)
         print_err_detail("  <allocation_context>\n");
      else
         print_err_detail(" Allocation context:\n");
      VG_(pp_ExeContext)(ai.lastchange);
      if (xml)
         print_err_detail("  </allocation_context>\n");
   } else {
      HChar sect_name[64];
      VgSectKind sect_kind;

      sect_kind = VG_(DebugInfo_sect_kind)(sect_name, sizeof(sect_name),
                                           dri->addr);
      if (sect_kind != Vg_SectUnknown) {
         print_err_detail("%sAllocation context: %ps section of %ps%s\n",
                          auxwhat_prefix, VG_(pp_SectKind)(sect_kind),
                          sect_name, auxwhat_suffix);
      } else {
         print_err_detail("%sAllocation context: unknown.%s\n",
                          auxwhat_prefix, auxwhat_suffix);
      }
   }
   if (s_show_conflicting_segments)
   {
      DRD_(thread_report_conflicting_segments)(dri->tid,
                                               dri->addr, dri->size,
                                               dri->access_type);
   }

   if (descr2)
      VG_(deleteXA)(descr2);
   if (descr1)
      VG_(deleteXA)(descr1);
}
Beispiel #3
0
static
void drd_report_data_race(Error* const err, const DataRaceErrInfo* const dri)
{
   AddrInfo ai;

   XArray* /* of HChar */ descr1
      = VG_(newXA)( VG_(malloc), "drd.error.drdr2.1",
                    VG_(free), sizeof(HChar) );
   XArray* /* of HChar */ descr2
      = VG_(newXA)( VG_(malloc), "drd.error.drdr2.2",
                    VG_(free), sizeof(HChar) );

   tl_assert(dri);
   tl_assert(dri->addr);
   tl_assert(dri->size > 0);
   tl_assert(descr1);
   tl_assert(descr2);

   (void) VG_(get_data_description)(descr1, descr2, dri->addr);
   /* If there's nothing in descr1/2, free them.  Why is it safe to to
      VG_(indexXA) at zero here?  Because VG_(get_data_description)
      guarantees to zero terminate descr1/2 regardless of the outcome
      of the call.  So there's always at least one element in each XA
      after the call.
   */
   if (0 == VG_(strlen)( VG_(indexXA)( descr1, 0 ))) {
      VG_(deleteXA)( descr1 );
      descr1 = NULL;
   }
   if (0 == VG_(strlen)( VG_(indexXA)( descr2, 0 ))) {
      VG_(deleteXA)( descr2 );
      descr2 = NULL;
   }
   /* Assume (assert) that VG_(get_data_description) fills in descr1
      before it fills in descr2 */
   if (descr1 == NULL)
      tl_assert(descr2 == NULL);
   /* So anyway.  Do we have something useful? */
   if (descr1 == NULL)
   {
      /* No.  Do Plan B. */
      describe_malloced_addr(dri->addr, dri->size, &ai);
   }
   VG_(message)(Vg_UserMsg,
                "Conflicting %s by thread %d/%d at 0x%08lx size %ld\n",
                dri->access_type == eStore ? "store" : "load",
                DRD_(DrdThreadIdToVgThreadId)(dri->tid),
                dri->tid,
                dri->addr,
                dri->size);
   VG_(pp_ExeContext)(VG_(get_error_where)(err));
   if (descr1 != NULL)
   {
      VG_(message)(Vg_UserMsg, "%s\n", (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);
      VG_(pp_ExeContext)(ai.lastchange);
   }
   else
   {
      char sect_name[64];
      VgSectKind sect_kind;

      sect_kind = VG_(seginfo_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 (s_show_conflicting_segments)
   {
      DRD_(thread_report_conflicting_segments)(dri->tid,
                                               dri->addr, dri->size,
                                               dri->access_type);
   }

   if (descr2)
      VG_(deleteXA)(descr2);
   if (descr1)
      VG_(deleteXA)(descr1);
}