Esempio n. 1
0
static int
find_marked_nodes_helper(const char *func, const char *file, int line,
                         int todo, arena_range_t *rp)
{
    Flink	*oldptr;
    Flink	*ptr;
    DebugInfo_t	*mptr;
    chain_t	*chain = rp->r_type == RANGE_ARENA
                     ? &rp->un.r_arena->a_malloc_chain
                     : &rp->un.r_block->malloc_chain;

    oldptr = (Flink *)_malloc_start;
    for(ptr = chain->head; ; oldptr = ptr, ptr = ptr->f_next)
    {
        /*
         * Since the malloc chain is a forward only chain, any
         * pointer that we get should always be positioned in
         * memory following the previous pointer.  If this is not
         * so, we must have a corrupted chain.
         */
        if( ptr )
        {
#if 0
            if((ulong_t)ptr < (ulong_t)oldptr)
            {
                malloc_errno = M_CODE_CHAIN_BROKE;
                if( todo )
                {
                    malloc_fatal(func,file,line,oldptr);
                }
                break;
            }
#endif
        }
        else
        {
            if( chain->tail && (oldptr != chain->tail) )
            {
                /*
                 * This should never happen.  If it does, then
                 * we got a real problem.
                 */
                malloc_errno = M_CODE_NO_END;
                if( todo )
                {
                    malloc_fatal(func,file,line,oldptr);
                }
            }
            break;
        }

        /*
         * verify that ptr is within the malloc region...
         * since we started within the malloc chain this should never
         * happen.
         */
        if( ((ulong_t)ptr < (ulong_t)rp->r_start) ||
                ((ulong_t)ptr > (ulong_t)rp->r_end) )
        {
            malloc_errno = M_CODE_BAD_PTR;
            if( todo )
            {
                malloc_fatal(func,file,line,oldptr);
            }
            break;
        }
        mptr = &((Dhead *)ptr)->d_debug;

        /*
         * verify magic flag is set
         */

        if (!MAGIC_MATCH(mptr))
        {
            malloc_errno = M_CODE_BAD_MAGIC;
            if( todo )
            {
                malloc_warning(func,file,line, NULL);
            }
            continue;
        }

        /*
         * verify segments are correctly linked together
         */
        if( (ptr->f_prev && (ptr->f_prev->f_next != ptr) ) ||
                (ptr->f_next && (ptr->f_next->f_prev != ptr) ) )
        {
            malloc_errno = M_CODE_BAD_CONNECT;
            if( todo )
            {
                malloc_warning(func,file,line,ptr);
            }
            continue;
        }

        /*
         * If this segment is allocated
         */
        if( (mptr->flag & M_INUSE) != 0 )
        {
            char *data = (char *)((Dhead *)ptr + 1);
            ulong_t start = (ulong_t)data;
            ulong_t end = (ulong_t)(data + DH_ULEN(ptr));
            Block *bp = (Block *)data;

            /*
             * If this segment is a Block, skip it
             */
            if (bp->magic == BLOCK_MAGIC) continue;

            if ( (mptr->flag & M_REFERENCED) != 0)  { /* it's marked */
                ulong_t child = start;
                Dhead *dh;
                arena_range_t range;
                /*
                 * scan through the block on dword-aligned
                 * boundaries looking for unmarked children
                 */
                do {
                    if ((child = find_child((ulong_t)child, (ulong_t)end, &dh, &range)) != NULL) {
                        child += 4;
                        if ((dh->d_debug.flag & M_REFERENCED) == 0) {

                            /* if we found an unmarked child, add the parent to
                             * the mark stack.
                             */
                            _mark_stack_push(start, end);
                            break;
                        }
                    }
                } while (child != 0);
            }
        }
    } /* for(... */
    return 0;
}
Esempio n. 2
0
/*
 * Must be called with the mutex locked!
 */
static int
DBFmalloc_chain_check_helper(const char *func,const char *file,int line,
	int todo, arena_range_t *rp, int *cont)
{
    void		* oldptr;
    Flink		* ptr;
    DebugInfo_t		* mptr;
    chain_t		* chain = rp->r_type == RANGE_ARENA
    				? &rp->un.r_arena->a_malloc_chain
    				: &rp->un.r_block->malloc_chain;
    int rtn = 0;

    oldptr = NULL;

    for(ptr = chain->head; ptr; oldptr = ptr, ptr = ptr->f_next)
    {
	/*
	 * Since the malloc chain is a forward only chain, any
	 * pointer that we get should always be positioned in 
	 * memory following the previous pointer.  If this is not
	 * so, we must have a corrupted chain.
	 */
	if( ptr )
	{
#if 0
	    if((ulong_t)ptr < (ulong_t)oldptr )
	    {
		malloc_errno = M_CODE_CHAIN_BROKE;
		if( todo )
		{
		    malloc_fatal(func,file,line,oldptr);
		}
		rtn++;
		*cont = 0;
		break;
	    }
#endif
	}
	else
	{
	    if( chain->tail && (oldptr != chain->tail) )
	    {
		/*
		 * This should never happen.  If it does, then
		 * we got a real problem.
		 */
		malloc_errno = M_CODE_NO_END;
		if( todo )
		{
		    malloc_fatal(func,file,line,oldptr);
		}
		rtn++;
	    }
	    *cont = 0;
	    break;
	}
		
	/*
	 * verify that ptr is within the malloc region...
	 * since we started within the malloc chain this should never
	 * happen.
	 */
	if( ((ulong_t)ptr < (ulong_t)rp->r_start) ||
		((ulong_t)ptr > (ulong_t)rp->r_end) )
	{
	    malloc_errno = M_CODE_BAD_PTR;
	    if( todo )
	    {
		malloc_fatal(func,file,line,oldptr);
	    }
	    rtn++;
	    *cont = 0;
	    break;
	}

	mptr = &((Dhead *)ptr)->d_debug;
	/* 
	 * verify magic flag is set
	 */
		
        if( ((Dhead *)ptr)->d_crc != LinkCRC(ptr))
        {
	    malloc_errno = M_CODE_BAD_CRC;
	    malloc_warning(func,file,line,(void *)ptr);
	    rtn++;
	    continue;
        }

	if (!MAGIC_MATCH(mptr))
	{
	    malloc_errno = M_CODE_BAD_MAGIC;
	    if( todo )
	    {
		malloc_warning(func,file,line, NULL);
	    }
	    rtn++;
	    continue;
	}


	/* 
	 * verify segments are correctly linked together
	 */
	if( (ptr->f_prev && ptr->f_prev->f_next != ptr) ||
		(ptr->f_next && ptr->f_next->f_prev != ptr) )
	{
	    malloc_errno = M_CODE_BAD_CONNECT;
	    if( todo )
	    {
		malloc_warning(func,file,line,ptr);
	    }
	    rtn++;
	    continue;
	}

	/*
	 * If this segment is allocated
	 */
	if( (mptr->flag & M_INUSE) != 0 )
	{
	    /*
	     * verify no overflow of data area
	     */

	    // FIX:
	    if (_malloc_fill_area && _malloc_fill_area < mptr->hist_id)
	    {
	        if (todo)
	        {
	            if (malloc_check_fill(func,file,line,(Dhead *)ptr) != 0)
	            {
			rtn++;
			*cont = 0;
			break;
	            }
	        }
	    }
	}
    } /* for(... */
    return rtn;
}
Esempio n. 3
0
SIZETYPE
DBmalloc_size(	CONST char *		file,
				int					line,
				CONST DATATYPE *	cptr )
{
	char *func = "malloc_size";
	register struct mlist *ptr;

	// initialize the malloc sub-system.

	MALLOC_INIT();

	#ifdef MALLOC_PTHREAD

		if ( !malloc_preamble )
			pthread_mutex_lock( &malloc_mutex );

	#endif

	// IF malloc chain checking is on, go do it.

	if (malloc_opts & MOPT_CKCHAIN)
	{
		VOIDCAST DBFmalloc_chain_check(func, file, line, 1);
	}

	//
	// verify that cptr is within the malloc region and that it is on
	// the correct alignment
	//

	if (	(cptr < malloc_data_start)					||
			(cptr > malloc_data_end)					||
			((((long) cptr) & malloc_round) != 0))
	{
		malloc_errno = M_CODE_BAD_PTR;
		malloc_warning(func, file, line, (struct mlist *) NULL);

		#ifdef MALLOC_PTHREAD

			if ( !malloc_preamble )
				pthread_mutex_unlock( &malloc_mutex );

		#endif

		return( (SIZETYPE) -1 );
	}

	//
	// convert pointer to mlist struct pointer.  To do this we must 
	// move the pointer backwards the correct number of bytes...
	//

	ptr = DATATOMLIST(cptr);

	// check the magic number 

	if ((ptr->flag & M_MAGIC_BITS) != M_MAGIC)
	{
		malloc_errno = M_CODE_BAD_MAGIC;
		malloc_warning(func, file, line, (struct mlist *) NULL);

		#ifdef MALLOC_PTHREAD

			if ( !malloc_preamble )
				pthread_mutex_unlock( &malloc_mutex );

		#endif

		return( (SIZETYPE) -1 );
	}

	// if this segment is not flagged as being in use

	if (!(ptr->flag & M_INUSE))
	{
		malloc_errno = M_CODE_NOT_INUSE;
		malloc_warning(func, file, line, ptr);

		#ifdef MALLOC_PTHREAD

			if ( !malloc_preamble )
				pthread_mutex_unlock( &malloc_mutex );

		#endif

		return( (SIZETYPE) -1 );
	}

	// check to see that the pointers are still connected

	if ((ptr->prev && (ptr->prev->next != ptr)) ||
		(ptr->next && (ptr->next->prev != ptr)) ||
		((ptr->next == NULL) && (ptr->prev == NULL)))
	{
		malloc_errno = M_CODE_BAD_CONNECT;
		malloc_warning(func, file, line, ptr);

		#ifdef MALLOC_PTHREAD

			if ( !malloc_preamble )
				pthread_mutex_unlock( &malloc_mutex );

		#endif

		return( (SIZETYPE) -1 );
	}

	// check fill regions for overflow

	VOIDCAST FILLCHECK(func, file, line, ptr, SHOWERRORS);

	#ifdef MALLOC_PTHREAD

		if ( !malloc_preamble )
			pthread_mutex_unlock( &malloc_mutex );

	#endif

	return( ptr->r_size );

}		// end of DBmalloc_size(...)