예제 #1
0
void HG_(describe_addr) ( Addr a, /*OUT*/AddrInfo* ai )
{
   tl_assert(ai->tag == Addr_Undescribed);

   /* hctxt/tnr/haddr/hszB describe the addr if it is a heap block. */
   ExeContext* hctxt;
   UInt        tnr;
   Addr        haddr;
   SizeT       hszB;

   /* First, see if it's in any heap block.  Unfortunately this
      means a linear search through all allocated heap blocks.  The
      assertion says that if it's detected as a heap block, then we
      must have an allocation context for it, since all heap blocks
      should have an allocation context. */
   Bool is_heapblock
      = HG_(mm_find_containing_block)( 
           &hctxt,
           &tnr,
           &haddr,
           &hszB,
           a
        );
   if (is_heapblock) {
      tl_assert(is_heapblock == (hctxt != NULL));
      ai->tag = Addr_Block;
      ai->Addr.Block.block_kind = Block_Mallocd;
      ai->Addr.Block.block_desc = "block";
      ai->Addr.Block.block_szB  = hszB;
      ai->Addr.Block.rwoffset   = (Word)(a) - (Word)(haddr);
      ai->Addr.Block.allocated_at = hctxt;
      VG_(initThreadInfo) (&ai->Addr.Block.alloc_tinfo);
      ai->Addr.Block.alloc_tinfo.tnr = tnr;
      ai->Addr.Block.freed_at = VG_(null_ExeContext)();;
   } else {
      /* No block found. Search a non-heap block description. */
      VG_(describe_addr) (a, ai);

      /* In case ai contains a tid, set tnr to the corresponding helgrind
         thread number. */
      if (ai->tag == Addr_Stack) {
         Thread* thr = get_admin_threads();

         tl_assert(ai->Addr.Stack.tinfo.tid);
         while (thr) {
            if (thr->coretid == ai->Addr.Stack.tinfo.tid) {
               ai->Addr.Stack.tinfo.tnr = thr->errmsg_index;
               break;
            }
            thr = thr->admin;
         }
      }
   }
}
예제 #2
0
/* This is the "this error is due to be printed shortly; so have a
   look at it any print any preamble you want" function.  We use it to
   announce any previously un-announced threads in the upcoming error
   message.
*/
void HG_(before_pp_Error) ( const Error* err )
{
    XError* xe;
    tl_assert(err);
    xe = (XError*)VG_(get_error_extra)(err);
    tl_assert(xe);

    switch (VG_(get_error_kind)(err)) {
    case XE_Misc:
        announce_one_thread( xe->XE.Misc.thr );
        break;
    case XE_LockOrder:
        announce_one_thread( xe->XE.LockOrder.thr );
        break;
    case XE_PthAPIerror:
        announce_one_thread( xe->XE.PthAPIerror.thr );
        break;
    case XE_UnlockBogus:
        announce_one_thread( xe->XE.UnlockBogus.thr );
        break;
    case XE_UnlockForeign:
        announce_one_thread( xe->XE.UnlockForeign.thr );
        announce_one_thread( xe->XE.UnlockForeign.owner );
        break;
    case XE_UnlockUnlocked:
        announce_one_thread( xe->XE.UnlockUnlocked.thr );
        break;
    case XE_Race:
        announce_one_thread( xe->XE.Race.thr );
        if (xe->XE.Race.h2_ct)
            announce_one_thread( xe->XE.Race.h2_ct );
        if (xe->XE.Race.h1_ct)
            announce_one_thread( xe->XE.Race.h1_ct );
        if (xe->XE.Race.data_addrinfo.Addr.Block.alloc_tinfo.tnr) {
            Thread* thr = get_admin_threads();
            while (thr) {
                if (thr->errmsg_index
                        == xe->XE.Race.data_addrinfo.Addr.Block.alloc_tinfo.tnr) {
                    announce_one_thread (thr);
                    break;
                }
                thr = thr->admin;
            }
        }
        break;
    default:
        tl_assert(0);
    }
}