Exemplo n.º 1
0
/* This handles the in place resize of a block, as performed by the
   VALGRIND_RESIZEINPLACE_BLOCK client request.  It is unrelated to,
   and not used for, handling of the normal libc realloc()
   function. */
void MC_(handle_resizeInPlace)(ThreadId tid, Addr p,
                               SizeT oldSizeB, SizeT newSizeB, SizeT rzB)
{
    MC_Chunk* mc = VG_(HT_lookup) ( MC_(malloc_list), (UWord)p );
    if (!mc || mc->szB != oldSizeB || newSizeB == 0) {
        /* Reject if: p is not found, or oldSizeB is wrong,
           or new block would be empty. */
        MC_(record_free_error) ( tid, p );
        return;
    }

    if (oldSizeB == newSizeB)
        return;

    mc->szB = newSizeB;
    if (newSizeB < oldSizeB) {
        MC_(make_mem_noaccess)( p + newSizeB, oldSizeB - newSizeB + rzB );
    } else {
        ExeContext* ec  = VG_(record_ExeContext)(tid, 0/*first_ip_delta*/);
        UInt        ecu = VG_(get_ECU_from_ExeContext)(ec);
        MC_(make_mem_undefined_w_otag)( p + oldSizeB, newSizeB - oldSizeB,
                                        ecu | MC_OKIND_HEAP );
        if (rzB > 0)
            MC_(make_mem_noaccess)( p + newSizeB, rzB );
    }
}
Exemplo n.º 2
0
/* Compute a quick summary of the leak check. */
static void make_summary(void)
{
   Int i;

   for(i = 0; i < lc_n_shadows; i++) {
      SizeT size = lc_shadows[i]->szB;

      switch(lc_markstack[i].state) {
      case Unreached:
	 blocks_leaked++;
	 MC_(bytes_leaked) += size;
	 break;

      case Proper:
	 blocks_reachable++;
	 MC_(bytes_reachable) += size;
	 break;

      case Interior:
	 blocks_dubious++;
	 MC_(bytes_dubious) += size;
	 break;
	 
      case IndirectLeak:	/* shouldn't happen */
	 blocks_indirect++;
	 MC_(bytes_indirect) += size;
	 break;
      }
   }
}
Exemplo n.º 3
0
void MC_(create_mempool)(Addr pool, UInt rzB, Bool is_zeroed)
{
    MC_Mempool* mp;

    if (VG_(clo_verbosity) > 2) {
        VG_(message)(Vg_UserMsg, "create_mempool(0x%lx, %d, %d)\n",
                     pool, rzB, is_zeroed);
        VG_(get_and_pp_StackTrace)
        (VG_(get_running_tid)(), MEMPOOL_DEBUG_STACKTRACE_DEPTH);
    }

    mp = VG_(HT_lookup)(MC_(mempool_list), (UWord)pool);
    if (mp != NULL) {
        VG_(tool_panic)("MC_(create_mempool): duplicate pool creation");
    }

    mp = VG_(malloc)("mc.cm.1", sizeof(MC_Mempool));
    mp->pool       = pool;
    mp->rzB        = rzB;
    mp->is_zeroed  = is_zeroed;
    mp->chunks     = VG_(HT_construct)( "MC_(create_mempool)" );
    check_mempool_sane(mp);

    /* Paranoia ... ensure this area is off-limits to the client, so
       the mp->data field isn't visible to the leak checker.  If memory
       management is working correctly, anything pointer returned by
       VG_(malloc) should be noaccess as far as the client is
       concerned. */
    if (!MC_(check_mem_is_noaccess)( (Addr)mp, sizeof(MC_Mempool), NULL )) {
        VG_(tool_panic)("MC_(create_mempool): shadow area is accessible");
    }

    VG_(HT_add_node)( MC_(mempool_list), mp );
}
Exemplo n.º 4
0
/* Allocate a shadow chunk, put it on the appropriate list.
   If needed, release oldest blocks from freed list. */
static
MC_Chunk* create_MC_Chunk ( ThreadId tid, Addr p, SizeT szB,
                            MC_AllocKind kind)
{
   MC_Chunk* mc  = VG_(allocEltPA)(MC_(chunk_poolalloc));
   mc->data      = p;
   mc->szB       = szB;
   mc->allockind = kind;
   switch ( MC_(n_where_pointers)() ) {
      case 2: mc->where[1] = 0; // fallback to 1
      case 1: mc->where[0] = 0; // fallback to 0
      case 0: break;
      default: tl_assert(0);
   }
   MC_(set_allocated_at) (tid, mc);

   /* Each time a new MC_Chunk is created, release oldest blocks
      if the free list volume is exceeded. */
   if (VG_(free_queue_volume) > MC_(clo_freelist_vol))
      release_oldest_block();

   /* Paranoia ... ensure the MC_Chunk is off-limits to the client, so
      the mc->data field isn't visible to the leak checker.  If memory
      management is working correctly, any pointer returned by VG_(malloc)
      should be noaccess as far as the client is concerned. */
   if (!MC_(check_mem_is_noaccess)( (Addr)mc, sizeof(MC_Chunk), NULL )) {
      VG_(tool_panic)("create_MC_Chunk: shadow area is accessible");
   } 
   return mc;
}
Exemplo n.º 5
0
void MC_(mempool_free)(Addr pool, Addr addr)
{
    MC_Mempool*  mp;
    MC_Chunk*    mc;
    ThreadId     tid = VG_(get_running_tid)();

    mp = VG_(HT_lookup)(MC_(mempool_list), (UWord)pool);
    if (mp == NULL) {
        MC_(record_illegal_mempool_error)(tid, pool);
        return;
    }

    if (VG_(clo_verbosity) > 2) {
        VG_(message)(Vg_UserMsg, "mempool_free(0x%lx, 0x%lx)\n", pool, addr);
        VG_(get_and_pp_StackTrace) (tid, MEMPOOL_DEBUG_STACKTRACE_DEPTH);
    }

    if (MP_DETAILED_SANITY_CHECKS) check_mempool_sane(mp);
    mc = VG_(HT_remove)(mp->chunks, (UWord)addr);
    if (mc == NULL) {
        MC_(record_free_error)(tid, (Addr)addr);
        return;
    }

    if (VG_(clo_verbosity) > 2) {
        VG_(message)(Vg_UserMsg,
                     "mempool_free(0x%lx, 0x%lx) freed chunk of %ld bytes\n",
                     pool, addr, mc->szB + 0UL);
    }

    die_and_free_mem ( tid, mc, mp->rzB );
    if (MP_DETAILED_SANITY_CHECKS) check_mempool_sane(mp);
}
Exemplo n.º 6
0
/* Put a shadow chunk on the freed blocks queue, possibly freeing up
   some of the oldest blocks in the queue at the same time. */
static void add_to_freed_queue ( MC_Chunk* mc )
{
    const Bool show = False;
    const int l = (mc->szB >= MC_(clo_freelist_big_blocks) ? 0 : 1);

    /* Put it at the end of the freed list, unless the block
       would be directly released any way : in this case, we
       put it at the head of the freed list. */
    if (freed_list_end[l] == NULL) {
        tl_assert(freed_list_start[l] == NULL);
        mc->next = NULL;
        freed_list_end[l]    = freed_list_start[l] = mc;
    } else {
        tl_assert(freed_list_end[l]->next == NULL);
        if (mc->szB >= MC_(clo_freelist_vol)) {
            mc->next = freed_list_start[l];
            freed_list_start[l] = mc;
        } else {
            mc->next = NULL;
            freed_list_end[l]->next = mc;
            freed_list_end[l]       = mc;
        }
    }
    VG_(free_queue_volume) += (Long)mc->szB;
    if (show)
        VG_(printf)("mc_freelist: acquire: volume now %lld\n",
                    VG_(free_queue_volume));
    VG_(free_queue_length)++;
}
Exemplo n.º 7
0
void MC_(mempool_change)(Addr pool, Addr addrA, Addr addrB, SizeT szB)
{
    MC_Mempool*  mp;
    MC_Chunk*    mc;
    ThreadId     tid = VG_(get_running_tid)();

    if (VG_(clo_verbosity) > 2) {
        VG_(message)(Vg_UserMsg, "mempool_change(0x%lx, 0x%lx, 0x%lx, %ld)\n",
                     pool, addrA, addrB, szB);
        VG_(get_and_pp_StackTrace) (tid, MEMPOOL_DEBUG_STACKTRACE_DEPTH);
    }

    mp = VG_(HT_lookup)(MC_(mempool_list), (UWord)pool);
    if (mp == NULL) {
        MC_(record_illegal_mempool_error)(tid, pool);
        return;
    }

    check_mempool_sane(mp);

    mc = VG_(HT_remove)(mp->chunks, (UWord)addrA);
    if (mc == NULL) {
        MC_(record_free_error)(tid, (Addr)addrA);
        return;
    }

    mc->data = addrB;
    mc->szB  = szB;
    VG_(HT_add_node)( mp->chunks, mc );

    check_mempool_sane(mp);
}
Exemplo n.º 8
0
void MC_(print_malloc_stats) ( void )
{
   MC_Chunk* mc;
   SizeT     nblocks = 0;
   ULong     nbytes  = 0;
   
   if (VG_(clo_verbosity) == 0)
      return;
   if (VG_(clo_xml))
      return;

   /* Count memory still in use. */
   VG_(HT_ResetIter)(MC_(malloc_list));
   while ( (mc = VG_(HT_Next)(MC_(malloc_list))) ) {
      nblocks++;
      nbytes += (ULong)mc->szB;
   }

   VG_(message)(Vg_UserMsg, 
                "malloc/free: in use at exit: %'llu bytes in %'lu blocks.",
                nbytes, nblocks);
   VG_(message)(Vg_UserMsg, 
                "malloc/free: %'lu allocs, %'lu frees, %'llu bytes allocated.",
                cmalloc_n_mallocs,
                cmalloc_n_frees, cmalloc_bs_mallocd);
   if (VG_(clo_verbosity) > 1)
      VG_(message)(Vg_UserMsg, "");
}
Exemplo n.º 9
0
void MC_(print_malloc_stats) ( void )
{
    MC_Chunk* mc;
    SizeT     nblocks = 0;
    ULong     nbytes  = 0;

    if (VG_(clo_verbosity) == 0)
        return;
    if (VG_(clo_xml))
        return;

    /* Count memory still in use. */
    VG_(HT_ResetIter)(MC_(malloc_list));
    while ( (mc = VG_(HT_Next)(MC_(malloc_list))) ) {
        nblocks++;
        nbytes += (ULong)mc->szB;
    }

    VG_(umsg)(
        "HEAP SUMMARY:\n"
        "    in use at exit: %'llu bytes in %'lu blocks\n"
        "  total heap usage: %'lu allocs, %'lu frees, %'llu bytes allocated\n"
        "\n",
        nbytes, nblocks,
        cmalloc_n_mallocs,
        cmalloc_n_frees, cmalloc_bs_mallocd
    );
}
Exemplo n.º 10
0
void MC_(mempool_alloc)(ThreadId tid, Addr pool, Addr addr, SizeT szB)
{
   MC_Mempool* mp;

   if (VG_(clo_verbosity) > 2) {     
      VG_(message)(Vg_UserMsg, "mempool_alloc(0x%lx, 0x%lx, %ld)\n",
                               pool, addr, szB);
      VG_(get_and_pp_StackTrace) (tid, MEMPOOL_DEBUG_STACKTRACE_DEPTH);
   }

   mp = VG_(HT_lookup) ( MC_(mempool_list), (UWord)pool );
   if (mp == NULL) {
      MC_(record_illegal_mempool_error) ( tid, pool );
   } else {
      if (MP_DETAILED_SANITY_CHECKS) check_mempool_sane(mp);
      MC_(new_block)(tid, addr, szB, /*ignored*/0, mp->is_zeroed,
                     MC_AllocCustom, mp->chunks);
      if (mp->rzB > 0) {
         // This is not needed if the user application has properly
         // marked the superblock noaccess when defining the mempool.
         // We however still mark the redzones noaccess to still catch
         // some bugs if user forgot.
         MC_(make_mem_noaccess) ( addr - mp->rzB, mp->rzB);
         MC_(make_mem_noaccess) ( addr + szB, mp->rzB);
      }
      if (MP_DETAILED_SANITY_CHECKS) check_mempool_sane(mp);
   }
}
Exemplo n.º 11
0
void MC_(destroy_mempool)(Addr pool)
{
    MC_Chunk*   mc;
    MC_Mempool* mp;

    if (VG_(clo_verbosity) > 2) {
        VG_(message)(Vg_UserMsg, "destroy_mempool(0x%lx)\n", pool);
        VG_(get_and_pp_StackTrace)
        (VG_(get_running_tid)(), MEMPOOL_DEBUG_STACKTRACE_DEPTH);
    }

    mp = VG_(HT_remove) ( MC_(mempool_list), (UWord)pool );

    if (mp == NULL) {
        ThreadId tid = VG_(get_running_tid)();
        MC_(record_illegal_mempool_error) ( tid, pool );
        return;
    }
    check_mempool_sane(mp);

    // Clean up the chunks, one by one
    VG_(HT_ResetIter)(mp->chunks);
    while ( (mc = VG_(HT_Next)(mp->chunks)) ) {
        /* Note: make redzones noaccess again -- just in case user made them
           accessible with a client request... */
        MC_(make_mem_noaccess)(mc->data-mp->rzB, mc->szB + 2*mp->rzB );
    }
    // Destroy the chunk table
    VG_(HT_destruct)(mp->chunks, (void (*)(void *))delete_MC_Chunk);

    VG_(free)(mp);
}
Exemplo n.º 12
0
// Scan a block of memory between [start, start+len).  This range may
// be bogus, inaccessable, or otherwise strange; we deal with it.  For each
// valid aligned word we assume it's a pointer to a chunk a push the chunk
// onto the mark stack if so.
static void
lc_scan_memory(Addr start, SizeT len, Bool is_prior_definite, Int clique)
{
   Addr ptr = VG_ROUNDUP(start,     sizeof(Addr));
   Addr end = VG_ROUNDDN(start+len, sizeof(Addr));
   vki_sigset_t sigmask;

   if (VG_DEBUG_LEAKCHECK)
      VG_(printf)("scan %#lx-%#lx (%lu)\n", start, end, len);

   VG_(sigprocmask)(VKI_SIG_SETMASK, NULL, &sigmask);
   VG_(set_fault_catcher)(scan_all_valid_memory_catcher);

   // We might be in the middle of a page.  Do a cheap check to see if
   // it's valid;  if not, skip onto the next page.
   if (!VG_(am_is_valid_for_client)(ptr, sizeof(Addr), VKI_PROT_READ))
      ptr = VG_PGROUNDUP(ptr+1);        // First page is bad - skip it.

   while (ptr < end) {
      Addr addr;

      // Skip invalid chunks.
      if ( ! MC_(is_within_valid_secondary)(ptr) ) {
         ptr = VG_ROUNDUP(ptr+1, SM_SIZE);
         continue;
      }

      // Look to see if this page seems reasonable.
      if ((ptr % VKI_PAGE_SIZE) == 0) {
         if (!VG_(am_is_valid_for_client)(ptr, sizeof(Addr), VKI_PROT_READ)) {
            ptr += VKI_PAGE_SIZE;      // Bad page - skip it.
            continue;
         }
      }

      if (__builtin_setjmp(memscan_jmpbuf) == 0) {
         if ( MC_(is_valid_aligned_word)(ptr) ) {
            lc_scanned_szB += sizeof(Addr);
            addr = *(Addr *)ptr;
            // If we get here, the scanned word is in valid memory.  Now
            // let's see if its contents point to a chunk.
            lc_push_if_a_chunk_ptr(addr, clique, is_prior_definite);
         } else if (0 && VG_DEBUG_LEAKCHECK) {
            VG_(printf)("%#lx not valid\n", ptr);
         }
         ptr += sizeof(Addr);
      } else {
         // We need to restore the signal mask, because we were
         // longjmped out of a signal handler.
         VG_(sigprocmask)(VKI_SIG_SETMASK, &sigmask, NULL);

         ptr = VG_PGROUNDUP(ptr+1);     // Bad page - skip it.
      }
   }

   VG_(sigprocmask)(VKI_SIG_SETMASK, &sigmask, NULL);
   VG_(set_fault_catcher)(NULL);
}
Exemplo n.º 13
0
void* MC_(calloc) ( ThreadId tid, SizeT nmemb, SizeT size1 )
{
    if (complain_about_silly_args2(nmemb, size1)) {
        return NULL;
    } else {
        return MC_(new_block) ( tid, 0, nmemb*size1, VG_(clo_alignment),
                                /*is_zeroed*/True, MC_AllocMalloc, MC_(malloc_list));
    }
}
Exemplo n.º 14
0
void* MC_(memalign) ( ThreadId tid, SizeT alignB, SizeT n )
{
    if (complain_about_silly_args(n, "memalign")) {
        return NULL;
    } else {
        return MC_(new_block) ( tid, 0, n, alignB,
                                /*is_zeroed*/False, MC_AllocMalloc, MC_(malloc_list));
    }
}
Exemplo n.º 15
0
void* MC_(__builtin_vec_new) ( ThreadId tid, SizeT n )
{
    if (complain_about_silly_args(n, "__builtin_vec_new")) {
        return NULL;
    } else {
        return MC_(new_block) ( tid, 0, n, VG_(clo_alignment),
                                /*is_zeroed*/False, MC_AllocNewVec, MC_(malloc_list));
    }
}
Exemplo n.º 16
0
void* MC_(memalign) ( ThreadId tid, SizeT alignB, SizeT n )
{
   if (MC_(record_fishy_value_error)(tid, "memalign", "size", n)) {
      return NULL;
   } else {
      return MC_(new_block) ( tid, 0, n, alignB, 
         /*is_zeroed*/False, MC_AllocMalloc, MC_(malloc_list));
   }
}
Exemplo n.º 17
0
void* MC_(__builtin_vec_new) ( ThreadId tid, SizeT n )
{
   if (MC_(record_fishy_value_error)(tid, "__builtin_vec_new", "size", n)) {
      return NULL;
   } else {
      return MC_(new_block) ( tid, 0, n, VG_(clo_alignment), 
         /*is_zeroed*/False, MC_AllocNewVec, MC_(malloc_list));
   }
}
Exemplo n.º 18
0
void* MC_(malloc) ( ThreadId tid, SizeT n )
{
   if (complain_about_silly_args(n, "malloc")) {
      return NULL;
   } else {
      return MC_(new_block) ( tid, 0, n, VG_(clo_alignment), 
         MC_MALLOC_REDZONE_SZB, /*is_zeroed*/False, MC_AllocMalloc,
         MC_(malloc_list));
   }
}
Exemplo n.º 19
0
void* MC_(calloc) ( ThreadId tid, SizeT nmemb, SizeT size1 )
{
   if (MC_(record_fishy_value_error)(tid, "calloc", "nmemb", nmemb) ||
       MC_(record_fishy_value_error)(tid, "calloc", "size", size1)) {
      return NULL;
   } else {
      return MC_(new_block) ( tid, 0, nmemb*size1, VG_(clo_alignment),
         /*is_zeroed*/True, MC_AllocMalloc, MC_(malloc_list));
   }
}
Exemplo n.º 20
0
static void mc_describe_addr ( Addr a, AddrInfo* ai )
{
   ShadowChunk* sc;
   Bool         ok;
   ThreadId     tid;

   /* Nested functions, yeah.  Need the lexical scoping of 'a'. */ 

   /* Closure for searching thread stacks */
   Bool addr_is_in_bounds(Addr stack_min, Addr stack_max)
   {
      return (stack_min <= a && a <= stack_max);
   }
   /* Closure for searching malloc'd and free'd lists */
   Bool addr_is_in_block(ShadowChunk *sh_ch)
   {
      return VG_(addr_is_in_block) ( a, VG_(get_sc_data)(sh_ch),
                                        VG_(get_sc_size)(sh_ch) );
   }

   /* Perhaps it's a user-def'd block ? */
   ok = MC_(client_perm_maybe_describe)( a, ai );
   if (ok)
      return;
   /* Perhaps it's on a thread's stack? */
   tid = VG_(any_matching_thread_stack)(addr_is_in_bounds);
   if (tid != VG_INVALID_THREADID) {
      ai->akind     = Stack;
      ai->stack_tid = tid;
      return;
   }
   /* Search for a recently freed block which might bracket it. */
   sc = MC_(any_matching_freed_ShadowChunks)(addr_is_in_block);
   if (NULL != sc) {
      ai->akind      = Freed;
      ai->blksize    = VG_(get_sc_size)(sc);
      ai->rwoffset   = (Int)(a) - (Int)(VG_(get_sc_data)(sc));
      ai->lastchange = (ExeContext*)( VG_(get_sc_extra)(sc, 0) );
      return;
   }
   /* Search for a currently malloc'd block which might bracket it. */
   sc = VG_(any_matching_mallocd_ShadowChunks)(addr_is_in_block);
   if (NULL != sc) {
      ai->akind      = Mallocd;
      ai->blksize    = VG_(get_sc_size)(sc);
      ai->rwoffset   = (Int)(a) - (Int)(VG_(get_sc_data)(sc));
      ai->lastchange = (ExeContext*)( VG_(get_sc_extra)(sc, 0) );
      return;
   } 
   /* Clueless ... */
   ai->akind = Unknown;
   return;
}
Exemplo n.º 21
0
static
void record_freemismatch_error (ThreadId tid, MC_Chunk* mc)
{
   /* MC_(record_freemismatch_error) reports errors for still
      allocated blocks but we are in the middle of freeing it.  To
      report the error correctly, we re-insert the chunk (making it
      again a "clean allocated block", report the error, and then
      re-remove the chunk.  This avoids to do a VG_(HT_lookup)
      followed by a VG_(HT_remove) in all "non-erroneous cases". */
   VG_(HT_add_node)( MC_(malloc_list), mc );
   MC_(record_freemismatch_error) ( tid, mc );
   if ((mc != VG_(HT_remove) ( MC_(malloc_list), (UWord)mc->data )))
      tl_assert(0);
}
Exemplo n.º 22
0
// True if mc is a live block (not yet freed).
static Bool live_block (MC_Chunk* mc)
{
   if (mc->allockind == MC_AllocCustom) {
      MC_Mempool* mp;
      VG_(HT_ResetIter)(MC_(mempool_list));
      while ( (mp = VG_(HT_Next)(MC_(mempool_list))) ) {
         if ( in_block_list (mp->chunks, mc) )
            return True;
      }
   }
   /* Note: we fallback here for a not found MC_AllocCustom
      as such a block can be inserted in MC_(malloc_list)
      by VALGRIND_MALLOCLIKE_BLOCK. */
   return in_block_list ( MC_(malloc_list), mc );
}
Exemplo n.º 23
0
/* This one called from generated code. */
void MC_(record_value_error) ( Int size )
{
   MemCheckError err_extra;

   MC_(clear_MemCheckError)( &err_extra );
   err_extra.size = size;
   VG_(maybe_record_error)( NULL, ValueErr, /*addr*/0, /*s*/NULL, &err_extra );
}
Exemplo n.º 24
0
static void synth_LOADV ( Int sz, Int a_reg, Int tv_reg,
                          RRegSet regs_live_before,
                          RRegSet regs_live_after )
{
   Addr helper;
   UInt argv[] = { a_reg };
   UInt tagv[] = { RealReg };

   switch (sz) {
      case 4: helper = (Addr) & MC_(helperc_LOADV4); break;
      case 2: helper = (Addr) & MC_(helperc_LOADV2); break;
      case 1: helper = (Addr) & MC_(helperc_LOADV1); break;
      default: VG_(skin_panic)("synth_LOADV");
   }
   VG_(synth_ccall) ( helper, 1, 1, argv, tagv, tv_reg,
                      regs_live_before, regs_live_after );
}
Exemplo n.º 25
0
SizeT MC_(malloc_usable_size) ( ThreadId tid, void* p )
{
    MC_Chunk* mc = VG_(HT_lookup) ( MC_(malloc_list), (UWord)p );

    // There may be slop, but pretend there isn't because only the asked-for
    // area will be marked as addressable.
    return ( mc ? mc->szB : 0 );
}
Exemplo n.º 26
0
static void synth_STOREV ( Int sz, Int tv_tag, Int tv_val, Int a_reg,
                           RRegSet regs_live_before,
                           RRegSet regs_live_after )
{
   Addr helper;
   UInt argv[] = { a_reg,   tv_val };
   Tag  tagv[] = { RealReg, tv_tag };

   sk_assert(tv_tag == RealReg || tv_tag == Literal);
   switch (sz) {
      case 4: helper = (Addr) MC_(helperc_STOREV4); break;
      case 2: helper = (Addr) MC_(helperc_STOREV2); break;
      case 1: helper = (Addr) MC_(helperc_STOREV1); break;
      default: VG_(skin_panic)("synth_STOREV");
   }
   VG_(synth_ccall) ( helper, 2, 2, argv, tagv, INVALID_REALREG,
                      regs_live_before, regs_live_after );
}
Exemplo n.º 27
0
void MC_(handle_free) ( ThreadId tid, Addr p, UInt rzB, MC_AllocKind kind )
{
    MC_Chunk* mc;

    cmalloc_n_frees++;

    mc = VG_(HT_remove) ( MC_(malloc_list), (UWord)p );
    if (mc == NULL) {
        MC_(record_free_error) ( tid, p );
    } else {
        /* check if it is a matching free() / delete / delete [] */
        if (kind != mc->allockind) {
            tl_assert(p == mc->data);
            MC_(record_freemismatch_error) ( tid, mc );
        }
        die_and_free_mem ( tid, mc, rzB );
    }
}
Exemplo n.º 28
0
void MC_(mempool_alloc)(ThreadId tid, Addr pool, Addr addr, SizeT szB)
{
   MC_Mempool* mp;

   if (VG_(clo_verbosity) > 2) {     
      VG_(message)(Vg_UserMsg, "mempool_alloc(0x%lx, 0x%lx, %ld)", pool, addr, szB);
      VG_(get_and_pp_StackTrace) (tid, MEMPOOL_DEBUG_STACKTRACE_DEPTH);
   }

   mp = VG_(HT_lookup) ( MC_(mempool_list), (UWord)pool );
   if (mp == NULL) {
      MC_(record_illegal_mempool_error) ( tid, pool );
   } else {
      check_mempool_sane(mp);
      MC_(new_block)(tid, addr, szB, /*ignored*/0, mp->rzB, mp->is_zeroed,
                     MC_AllocCustom, mp->chunks);
      check_mempool_sane(mp);
   }
}
Exemplo n.º 29
0
Bool MC_(mempool_exists)(Addr pool)
{
    MC_Mempool*  mp;

    mp = VG_(HT_lookup)(MC_(mempool_list), (UWord)pool);
    if (mp == NULL) {
        return False;
    }
    return True;
}
Exemplo n.º 30
0
/* This one called from non-generated code */
void MC_(record_user_error) ( ThreadState* tst, Addr a, Bool isWrite )
{
   MemCheckError err_extra;

   sk_assert(NULL != tst);

   MC_(clear_MemCheckError)( &err_extra );
   err_extra.addrinfo.akind = Undescribed;
   err_extra.isWrite        = isWrite;
   VG_(maybe_record_error)( tst, UserErr, a, /*s*/NULL, &err_extra );
}