Пример #1
0
/* Updates the copy with address info if necessary. */
UInt HG_(update_extra) ( Error* err )
{
   XError* xe = (XError*)VG_(get_error_extra)(err);
   tl_assert(xe);
   //if (extra != NULL && Undescribed == extra->addrinfo.akind) {
   //   describe_addr ( VG_(get_error_address)(err), &(extra->addrinfo) );
   //}

   if (xe->tag == XE_Race) {

      /* See if we can come up with a source level description of the
         raced-upon address.  This is potentially expensive, which is
         why it's only done at the update_extra point, not when the
         error is initially created. */
      static Int xxx = 0;
      xxx++;
      if (0)
         VG_(printf)("HG_(update_extra): "
                     "%d conflicting-event queries\n", xxx);
      tl_assert(!xe->XE.Race.descr1);
      tl_assert(!xe->XE.Race.descr2);

      xe->XE.Race.descr1
         = VG_(newXA)( HG_(zalloc), "hg.update_extra.Race.descr1",
                       HG_(free), sizeof(HChar) );
      xe->XE.Race.descr2
         = VG_(newXA)( HG_(zalloc), "hg.update_extra.Race.descr2",
                       HG_(free), sizeof(HChar) );

      (void) VG_(get_data_description)( xe->XE.Race.descr1,
                                        xe->XE.Race.descr2,
                                        xe->XE.Race.data_addr );

      /* If there's nothing in descr1/2, free it.  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)( xe->XE.Race.descr1, 0 ))) {
         VG_(deleteXA)( xe->XE.Race.descr1 );
         xe->XE.Race.descr1 = NULL;
      }
      if (0 == VG_(strlen)( VG_(indexXA)( xe->XE.Race.descr2, 0 ))) {
         VG_(deleteXA)( xe->XE.Race.descr2 );
         xe->XE.Race.descr2 = NULL;
      }

      /* And poke around in the conflicting-event map, to see if we
         can rustle up a plausible-looking conflicting memory access
         to show. */
      if (HG_(clo_history_level) >= 2) { 
         Thr* thrp = NULL;
         ExeContext* wherep = NULL;
         Addr  acc_addr = xe->XE.Race.data_addr;
         Int   acc_szB  = xe->XE.Race.szB;
         Thr*  acc_thr  = xe->XE.Race.thr->hbthr;
         Bool  acc_isW  = xe->XE.Race.isWrite;
         SizeT conf_szB = 0;
         Bool  conf_isW = False;
         tl_assert(!xe->XE.Race.h2_ct_accEC);
         tl_assert(!xe->XE.Race.h2_ct);
         if (libhb_event_map_lookup(
                &wherep, &thrp, &conf_szB, &conf_isW,
                acc_thr, acc_addr, acc_szB, acc_isW )) {
            Thread* threadp;
            tl_assert(wherep);
            tl_assert(thrp);
            threadp = libhb_get_Thr_opaque( thrp );
            tl_assert(threadp);
            xe->XE.Race.h2_ct_accEC  = wherep;
            xe->XE.Race.h2_ct        = threadp;
            xe->XE.Race.h2_ct_accSzB = (Int)conf_szB;
            xe->XE.Race.h2_ct_accIsW = conf_isW;
        }
      }

      // both NULL or both non-NULL
      tl_assert( (!!xe->XE.Race.h2_ct) == (!!xe->XE.Race.h2_ct_accEC) );
   }

   return sizeof(XError);
}
Пример #2
0
/* Updates the copy with address info if necessary. */
UInt HG_(update_extra) ( const Error* err )
{
    XError* xe = (XError*)VG_(get_error_extra)(err);
    tl_assert(xe);
    //if (extra != NULL && Undescribed == extra->addrinfo.akind) {
    //   describe_addr ( VG_(get_error_address)(err), &(extra->addrinfo) );
    //}

    if (xe->tag == XE_Race) {

        /* Note the set of locks that the thread is (w-)holding.
           Convert the WordSetID of LockN*'s into a NULL-terminated
           vector of LockP*'s.  We don't expect to encounter any invalid
           LockNs in this conversion. */
        tl_assert(xe->XE.Race.thr);
        xe->XE.Race.locksHeldW
            = enumerate_WordSet_into_LockP_vector(
                  HG_(get_univ_lsets)(),
                  xe->XE.Race.thr->locksetW,
                  False/*!allowed_to_be_invalid*/
              );

        /* See if we can come up with a source level description of the
           raced-upon address.  This is potentially expensive, which is
           why it's only done at the update_extra point, not when the
           error is initially created. */
        static Int xxx = 0;
        xxx++;
        if (0)
            VG_(printf)("HG_(update_extra): "
                        "%d conflicting-event queries\n", xxx);

        HG_(describe_addr) (xe->XE.Race.data_addr, &xe->XE.Race.data_addrinfo);

        /* And poke around in the conflicting-event map, to see if we
           can rustle up a plausible-looking conflicting memory access
           to show. */
        if (HG_(clo_history_level) >= 2) {
            Thr*        thrp            = NULL;
            ExeContext* wherep          = NULL;
            Addr        acc_addr        = xe->XE.Race.data_addr;
            Int         acc_szB         = xe->XE.Race.szB;
            Thr*        acc_thr         = xe->XE.Race.thr->hbthr;
            Bool        acc_isW         = xe->XE.Race.isWrite;
            SizeT       conf_szB        = 0;
            Bool        conf_isW        = False;
            WordSetID   conf_locksHeldW = 0;
            tl_assert(!xe->XE.Race.h2_ct_accEC);
            tl_assert(!xe->XE.Race.h2_ct);
            if (libhb_event_map_lookup(
                        &wherep, &thrp, &conf_szB, &conf_isW, &conf_locksHeldW,
                        acc_thr, acc_addr, acc_szB, acc_isW )) {
                Thread* threadp;
                tl_assert(wherep);
                tl_assert(thrp);
                threadp = libhb_get_Thr_hgthread( thrp );
                tl_assert(threadp);
                xe->XE.Race.h2_ct_accEC  = wherep;
                xe->XE.Race.h2_ct        = threadp;
                xe->XE.Race.h2_ct_accSzB = (Int)conf_szB;
                xe->XE.Race.h2_ct_accIsW = conf_isW;
                xe->XE.Race.h2_ct_locksHeldW
                    = enumerate_WordSet_into_LockP_vector(
                          HG_(get_univ_lsets)(),
                          conf_locksHeldW,
                          True/*allowed_to_be_invalid*/
                      );
            }
        }

        // both NULL or both non-NULL
        tl_assert( (!!xe->XE.Race.h2_ct) == (!!xe->XE.Race.h2_ct_accEC) );
    }

    return sizeof(XError);
}