⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chunk.c

📁 测试内存泄露工具
💻 C
📖 第 1 页 / 共 5 页
字号:
  int		final = 1;    if (BIT_IS_SET(_dmalloc_flags, DEBUG_LOG_TRANS)) {    dmalloc_message("checking heap");  }    heap_check_c++;    /*   * first, run through all of the admin structures and check for   * validity   */  for (level_c = 0; level_c < MAX_SKIP_LEVEL; level_c++) {    unsigned int	*magic3_p, magic3;        /* run through the blocks and test them */    for (block_p = entry_blocks[level_c];	 block_p != NULL;	 block_p = block_p->eb_next_p) {            /* better be in the heap */      if (! IS_IN_HEAP(block_p)) {	dmalloc_errno = ERROR_ADMIN_LIST;	dmalloc_error("_dmalloc_chunk_heap_check");	return 0;      }            /* get the magic3 at the end of the block */      magic3_p = (unsigned int *)((char *)block_p + BLOCK_SIZE -				  sizeof(*magic3_p));      memcpy(&magic3, magic3_p, sizeof(magic3));            /* check magics */      if (block_p->eb_magic1 != ENTRY_BLOCK_MAGIC1	  || block_p->eb_magic2 != ENTRY_BLOCK_MAGIC2	  || magic3 != ENTRY_BLOCK_MAGIC3) {	dmalloc_errno = ERROR_ADMIN_LIST;	dmalloc_error("_dmalloc_chunk_heap_check");	return 0;      }            /* check for a valid level */      if (block_p->eb_level_n != level_c) {	dmalloc_errno = ERROR_ADMIN_LIST;	dmalloc_error("_dmalloc_chunk_heap_check");	return 0;      }            /* now we look up the block and make sure it exists and is valid */      slot_p = find_address(block_p, 1 /* exact */, skip_update);      if (slot_p == NULL) {	dmalloc_errno = ERROR_ADMIN_LIST;	dmalloc_error("_dmalloc_chunk_heap_check");	return 0;      }      if ((! BIT_IS_SET(slot_p->sa_flags, ALLOC_FLAG_ADMIN))	  || slot_p->sa_mem != block_p	  || slot_p->sa_total_size != BLOCK_SIZE	  || slot_p->sa_level_n != level_c) {	dmalloc_errno = ERROR_ADMIN_LIST;	dmalloc_error("_dmalloc_chunk_heap_check");	return 0;      }            /*       * NOTE: we could now check each of the entries in the block to       * make sure that they are valid and on the used or free list       */    }  }    /*   * Now run through the used pointers and check each one.   */  for (slot_p = skip_address_list->sa_next_p[0];       ;       slot_p = slot_p->sa_next_p[0]) {    skip_alloc_t	*block_slot_p;        /*     * switch to the free list in the middle after we've checked the     * used pointer slots     */    if (slot_p == NULL) {      checking_list_c++;      if (checking_list_c == 1) {	slot_p = skip_free_list->sa_next_p[0];      }#if FREED_POINTER_DELAY      else if (checking_list_c == 2) {	slot_p = free_wait_list_head;      }#endif      else {	/* we are done */	break;      }      if (slot_p == NULL) {	break;      }    }        /* better be in the heap */    if (! IS_IN_HEAP(slot_p)) {      dmalloc_errno = ERROR_ADDRESS_LIST;      dmalloc_error("_dmalloc_chunk_heap_check");      return 0;    }        /*     * now we look up the slot pointer itself and make sure it exists     * in a valid block     */    block_slot_p = find_address(slot_p, 0 /* not exact pointer */,				skip_update);    if (block_slot_p == NULL) {      dmalloc_errno = ERROR_ADMIN_LIST;      dmalloc_error("_dmalloc_chunk_heap_check");      return 0;    }        /* point at the block */    block_p = block_slot_p->sa_mem;        /* check block magic */    if (block_p->eb_magic1 != ENTRY_BLOCK_MAGIC1) {      dmalloc_errno = ERROR_ADDRESS_LIST;      dmalloc_error("_dmalloc_chunk_heap_check");      return 0;    }        /* make sure the slot level matches */    if (slot_p->sa_level_n != block_p->eb_level_n) {      dmalloc_errno = ERROR_ADDRESS_LIST;      dmalloc_error("_dmalloc_chunk_heap_check");      return 0;    }        /* now check the allocation */    if (checking_list_c == 0) {      ret = check_used_slot(slot_p, NULL /* no user pnt */,			    0 /* loose pnt checking */);      if (! ret) {	/* error set in check_slot */	log_error_info(NULL, 0, NULL, slot_p, "checking user pointer",		       "_dmalloc_chunk_heap_check");	/* not a critical error */	final = 0;      }    }    else {      ret = check_free_slot(slot_p);      if (! ret) {	/* error set in check_slot */	log_error_info(NULL, 0, NULL, slot_p, "checking free pointer",		       "_dmalloc_chunk_heap_check");	/* not a critical error */	final = 0;      }    }  }    return final;}/* * int _dmalloc_chunk_pnt_check * * DESCRIPTION: * * Run extensive tests on a pointer. * * RETURNS: * * Success - 1 if the pointer is okay * * Failure - 0 if not * * ARGUMENTS: * * func -> Function string which is checking the pointer. * * user_pnt -> Pointer we are checking. * * exact_b -> Set to 1 to find the pointer specifically.  Otherwise we * can find the pointer inside of an allocation. * * min_size -> Make sure that pnt can hold at least that many bytes. * If -1 then do a strlen + 1 for the \0.  If 0 then ignore. */int	_dmalloc_chunk_pnt_check(const char *func, const void *user_pnt,				 const int exact_b, const int min_size){  skip_alloc_t	*slot_p;  unsigned int	min;  pnt_info_t	pnt_info;    if (BIT_IS_SET(_dmalloc_flags, DEBUG_LOG_TRANS)) {    if (func == NULL) {      dmalloc_message("checking pointer '%#lx'", (unsigned long)user_pnt);    }    else {      dmalloc_message("checking func '%s' pointer '%#lx'",		      func, (unsigned long)user_pnt);    }  }    /* try to find the address */  slot_p = find_address(user_pnt, 0 /* not exact pointer */, skip_update);  if (slot_p == NULL) {    if (exact_b) {      dmalloc_errno = ERROR_NOT_FOUND;      log_error_info(NULL, 0, user_pnt, NULL, "pointer-check", func);      return 0;    }    else {      dmalloc_errno = ERROR_NONE;      return 1;    }  }    /* now make sure that the user slot is valid */  if (! check_used_slot(slot_p, user_pnt, exact_b)) {    /* dmalloc_error set in check_used_slot */    log_error_info(NULL, 0, user_pnt, slot_p, "pointer-check", func);    return 0;  }    /* if min_size is < 0 then do a strlen and take into account the \0 */  if (min_size != 0) {    if (min_size > 0) {      min = min_size;    }    else {      /* length of the string + 1 for the \0 */      min = strlen((char *)user_pnt) + 1;    }        /* get info about the pointer */    get_pnt_info(slot_p, &pnt_info);        /* are we within bounds on the user pointer and size */    if ((char *)user_pnt < (char *)pnt_info.pi_user_start	|| (char *)user_pnt + min > (char *)pnt_info.pi_user_bounds) {      dmalloc_errno = ERROR_WOULD_OVERWRITE;      log_error_info(NULL, 0, user_pnt, slot_p, "pointer-check", func);      return 0;    }  }    return 1;}/************************** low-level user functions *************************//* * void *_dmalloc_chunk_malloc * * DESCRIPTION: * * Allocate a chunk of memory. * * RETURNS: * * Success - Valid pointer. * * Failure - NULL * * ARGUMENTS: * * file -> File-name or return-address location of the allocation. * * line -> Line-number location of the allocation. * * size -> Number of bytes to allocate. * * func_id -> Calling function-id as defined in dmalloc.h. * * alignment -> If greater than 0 then try to align the returned * block. */void	*_dmalloc_chunk_malloc(const char *file, const unsigned int line,			       const unsigned long size, const int func_id,			       const unsigned int alignment){  unsigned long	needed_size;  int		valloc_b = 0, memalign_b = 0, fence_b = 0;  char		where_buf[MAX_FILE_LENGTH + 64], disp_buf[64];  skip_alloc_t	*slot_p;  pnt_info_t	pnt_info;  const char	*trans_log;    /* counts calls to malloc */  if (func_id == DMALLOC_FUNC_CALLOC) {    func_calloc_c++;  }  else if (alignment == BLOCK_SIZE) {    func_valloc_c++;    valloc_b = 1;  }  else if (alignment > 0) {    func_memalign_c++;    memalign_b = 1;  }  else if (func_id == DMALLOC_FUNC_NEW) {    func_new_c++;  }  else if (func_id != DMALLOC_FUNC_REALLOC	   && func_id != DMALLOC_FUNC_RECALLOC) {    func_malloc_c++;  }  #if ALLOW_ALLOC_ZERO_SIZE == 0  if (size == 0) {    dmalloc_errno = ERROR_BAD_SIZE;    log_error_info(file, line, NULL, NULL, "bad zero byte allocation request",		   "malloc");    return MALLOC_ERROR;  }#endif  #if LARGEST_ALLOCATION  /* have we exceeded the upper bounds */  if (size > LARGEST_ALLOCATION) {    dmalloc_errno = ERROR_TOO_BIG;    log_error_info(file, line, NULL, NULL, "allocation too big", "malloc");    return MALLOC_ERROR;  }#endif    needed_size = size;    /* adjust the size */  if (BIT_IS_SET(_dmalloc_flags, DEBUG_CHECK_FENCE)) {    needed_size += FENCE_OVERHEAD_SIZE;    fence_b = 1;        /*     * If the user is requesting a page-aligned block of data then we     * will need another block below the allocation just for the fence     * information.  Ugh.     */    if (valloc_b) {      needed_size += BLOCK_SIZE;    }  }  else if (valloc_b && needed_size <= BLOCK_SIZE / 2) {    /*     * If we are valloc-ing, make sure that we get a blocksized chunk     * because they are always block aligned.  We know here that fence     * posting is not on otherwise it would have been set above.     */    needed_size = BLOCK_SIZE;  }    /* get some space for our memory */  slot_p = get_memory(needed_size);  if (slot_p == NULL) {    /* errno set in get_slot */    return MALLOC_ERROR;  }  if (fence_b) {    BIT_SET(slot_p->sa_flags, ALLOC_FLAG_FENCE);  }  if (valloc_b) {    BIT_SET(slot_p->sa_flags, ALLOC_FLAG_VALLOC);  }  slot_p->sa_user_size = size;    /* initialize the bblocks */  alloc_cur_given += slot_p->sa_total_size;  alloc_max_given = MAX(alloc_max_given, alloc_cur_given);    get_pnt_info(slot_p, &pnt_info);    /* clear the allocation */  clear_alloc(slot_p, &pnt_info, 0 /* no old-size */, func_id);    slot_p->sa_file = file;  slot_p->sa_line = line;  slot_p->sa_use_iter = _dmalloc_iter_c;#if LOG_PNT_SEEN_COUNT  slot_p->sa_seen_c++;#endif#if LOG_PNT_ITERATION  slot_p->sa_iteration = _dmalloc_iter_c;#endif  if (BIT_IS_SET(_dmalloc_flags, DEBUG_LOG_ELAPSED_TIME)      || BIT_IS_SET(_dmalloc_flags, DEBUG_LOG_CURRENT_TIME)) {#if LOG_PNT_TIMEVAL    GET_TIMEVAL(slot_p->sa_timeval);#else#if LOG_PNT_TIME    slot_p->sa_time = time(NULL);#endif#endif  }  #if LOG_PNT_THREAD_ID  slot_p->sa_thread_id = THREAD_GET_ID();#endif    /* do we need to print transaction info? */  if (BIT_IS_SET(_dmalloc_flags, DEBUG_LOG_TRANS)) {    switch (func_id) {    case DMALLOC_FUNC_CALLOC:      trans_log = "calloc";      break;    case DMALLOC_FUNC_MEMALIGN:      trans_log = "memalign";      break;    case DMALLOC_FUNC_VALLOC:      trans_log = "valloc";      break;    default:      trans_log = "alloc";      break;    }    dmalloc_message("*** %s: at '%s' for %ld bytes, got '%s'",		    trans_log,		    _dmalloc_chunk_desc_pnt(where_buf, sizeof(where_buf),					    file, line),		    size, display_pnt(pnt_info.pi_user_start, slot_p, disp_buf,				      sizeof(disp_buf)));  }  #if MEMORY_TABLE_TOP_LOG  _dmalloc_table_insert(mem_table_alloc, MEM_ALLOC_ENTRIES, file, line,			size, &mem_table_alloc_c);#endif    /* monitor current allocation level */  alloc_current += size;  alloc_maximum = MAX(alloc_maximum, alloc_current);  _dmalloc_alloc_total += size;  alloc_one_max = MAX(alloc_one_max, size);    /* monitor pointer usage */  alloc_cur_pnts++;  alloc_max_pnts = MAX(alloc_max_pnts, alloc_cur_pnts);  alloc_tot_pnts++;    return pnt_info.pi_user_start;}/* * int _dmalloc_chunk_free * * DESCRIPTION: * * Free a user pointer from the heap. * * RETURNS: * * Success - FREE_NOERROR * * Failure - FREE_ERROR * * ARGUMENTS: * * file -> File-name or return-address location of the allocation. * * line -> Line-number location of the allocation. * * user_pnt -> Pointer we are freeing. * * func_id -> Function ID */int	_dmalloc_chunk_free(const char *file, const unsigned int line,			    void *user_pnt, const int func_id){  char		where_buf[MAX_FILE_LENGTH + 64];  char		where_buf2[MAX_FILE_LENGTH + 64], disp_buf[64];  skip_alloc_t	*slot_p, *update_p;    /* counts calls to free */  if (func_id == DMALLOC_FUNC_DELETE) {    func_delete_c++;  }  else if (func_id == DMALLOC_FUNC_REALLOC	   || func_id == DMALLOC_FUNC_RECALLOC) {    /* ignore these because they will alredy be accounted for in realloc */  }  else {    func_free_c++;  }    if (user_pnt == NULL) {    #if ALLOW_FREE_NULL_MESSAGE    /* does the user want a specific message? */    dmalloc_message("WARNING: tried to free(0) from '%s'",		    _dmalloc_chunk_desc_pnt(where_buf, sizeof(where_buf),					    file, line));#endif        /*     * NOTE: we have here both a default in the settings.h file and a     * runtime token in case people want to turn it on or off at     * runtime.     */    if (BIT_IS_SET(_dmalloc_flags, DEBUG_ERROR_FREE_NULL)) {      dmalloc_errno = ERROR_IS_NULL

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -