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

📄 chunk.c

📁 测试内存泄露工具
💻 C
📖 第 1 页 / 共 5 页
字号:
  if (_dmalloc_memory_limit > 0      && alloc_cur_given + size > _dmalloc_memory_limit) {    dmalloc_errno = ERROR_OVER_LIMIT;    dmalloc_error("get_memory");    return NULL;  }    /* do we have a divided block here? */  if (size <= BLOCK_SIZE / 2) {    return get_divided_memory(size);  }    /* round up to the nearest block size */  need_size = size + BLOCK_SIZE - 1;  block_n = need_size / BLOCK_SIZE;  need_size = block_n * BLOCK_SIZE;    update_p = skip_update;    /* find a free block which matches the size */   slot_p = use_free_memory(need_size, update_p);  if (slot_p != NULL) {    return slot_p;  }    /* if there are blocks that are larger than this */  slot_p = update_p->sa_next_p[0];  if (slot_p != NULL && slot_p->sa_total_size > size) {        /*     * now we ask again for the memory because we need to reset the     * update pointer list     */    slot_p = use_free_memory(need_size, update_p);    if (slot_p != NULL) {      /* huh?  This isn't right. */      dmalloc_errno = ERROR_ADDRESS_LIST;      dmalloc_error("get_memory");      return NULL;    }  }    /* allocate the memory necessary for the new blocks */  mem = _dmalloc_heap_alloc(need_size);  if (mem == HEAP_ALLOC_ERROR) {    /* error code set in _dmalloc_heap_alloc */    return NULL;  }  user_block_c += block_n;    /* create our slot */  slot_p = insert_address(mem, 0 /* used list */, need_size);  if (slot_p == NULL) {    /* error set in insert_address */    return NULL;  }    return slot_p;}/* * static int check_used_slot * * Check out the pointer in a allocated slot to make sure it is good. * * RETURNS: * * Success - 1 * * Failure - 0 * * ARGUMENTS: * * slot_p -> Slot that we are checking. * * user_pnt -> User pointer which was used to get the slot or NULL. * * exact_b -> Set to 1 to find the pointer specifically.  Otherwise we * can find the pointer inside of an allocation. */static	int	check_used_slot(const skip_alloc_t *slot_p,				const void *user_pnt, const int exact_b){  const char	*file, *name_p, *bounds_p, *mem_p;  unsigned int	line, num;  pnt_info_t	pnt_info;    if (! (BIT_IS_SET(slot_p->sa_flags, ALLOC_FLAG_USER)	 || BIT_IS_SET(slot_p->sa_flags, ALLOC_FLAG_EXTERN)	 || BIT_IS_SET(slot_p->sa_flags, ALLOC_FLAG_ADMIN))) {    dmalloc_errno = ERROR_SLOT_CORRUPT;    return 0;  }    /* get pointer info */  get_pnt_info(slot_p, &pnt_info);    /* if we need the exact pointer, make sure that the user_pnt agrees */  if (exact_b && user_pnt != pnt_info.pi_user_start) {    dmalloc_errno = ERROR_NOT_START_BLOCK;    return 0;  }  #if LARGEST_ALLOCATION  /* have we exceeded the upper bounds */  if (slot_p->sa_user_size > LARGEST_ALLOCATION) {    dmalloc_errno = ERROR_BAD_SIZE;    return 0;  }#endif    /* check our total block size */  if (slot_p->sa_total_size > BLOCK_SIZE / 2      && slot_p->sa_total_size % BLOCK_SIZE != 0) {    dmalloc_errno = ERROR_BAD_SIZE;    return 0;  }    /*   * If we have a valloc allocation then the _user_ pnt should be   * block aligned otherwise the chunk_pnt should be.   */  if (pnt_info.pi_valloc_b) {        if ((long)pnt_info.pi_user_start % BLOCK_SIZE != 0) {      dmalloc_errno = ERROR_NOT_ON_BLOCK;      return 0;    }    if (slot_p->sa_total_size < BLOCK_SIZE) {      dmalloc_errno = ERROR_SLOT_CORRUPT;      return 0;    }        /* now check the below space to make sure it is still clear */    if (pnt_info.pi_fence_b && pnt_info.pi_blanked_b) {      num = (char *)pnt_info.pi_fence_bottom - (char *)pnt_info.pi_alloc_start;      if (num > 0) {	for (mem_p = pnt_info.pi_alloc_start;	     mem_p < (char *)pnt_info.pi_fence_bottom;	     mem_p++) {	  if (*mem_p != ALLOC_BLANK_CHAR) {	    dmalloc_errno = ERROR_FREE_OVERWRITTEN;	    return 0;	  }	}      }    }  }    /* check out the fence-posts */  if (pnt_info.pi_fence_b && (! fence_read(&pnt_info))) {    /* errno set in fence_read */    return 0;  }    /* check above the allocation to see if it's been overwritten */  if (pnt_info.pi_blanked_b) {        if (pnt_info.pi_fence_b) {      mem_p = (char *)pnt_info.pi_fence_top + FENCE_TOP_SIZE;    }    else {      mem_p = pnt_info.pi_user_bounds;    }        for (; mem_p < (char *)pnt_info.pi_alloc_bounds; mem_p++) {      if (*mem_p != ALLOC_BLANK_CHAR) {	dmalloc_errno = ERROR_FREE_OVERWRITTEN;	return 0;      }    }  }  file = slot_p->sa_file;  line = slot_p->sa_line;    /* check line number */#if MAX_LINE_NUMBER  if (line > MAX_LINE_NUMBER) {    dmalloc_errno = ERROR_BAD_LINE;    return 0;  }#endif    /*   * Check file pointer only if file is not NULL and line is not 0   * which implies that file is a return-addr.   */#if MAX_FILE_LENGTH  if (file != DMALLOC_DEFAULT_FILE && line != DMALLOC_DEFAULT_LINE) {    /* NOTE: we don't use strlen here because we might check too far */    bounds_p = file + MAX_FILE_LENGTH;    for (name_p = file; name_p < bounds_p && *name_p != '\0'; name_p++) {    }    if (name_p >= bounds_p	|| name_p < file + MIN_FILE_LENGTH) {      dmalloc_errno = ERROR_BAD_FILE;      return 0;    }  }#endif  #if LOG_PNT_SEEN_COUNT  /*   * We divide by 2 here because realloc which returns the same   * pointer will seen_c += 2.  However, it will never be more than   * twice the iteration value.  We divide by two to not overflow   * iter_c * 2.   */  if (slot_p->sa_seen_c / 2 > _dmalloc_iter_c) {    dmalloc_errno = ERROR_SLOT_CORRUPT;    return 0;  }#endif    return 1;}/* * static int check_free_slot * * Check out the pointer in a slot to make sure it is good. * * RETURNS: * * Success - 1 * * Failure - 0 * * ARGUMENTS: * * slot_p -> Slot that we are checking. */static	int	check_free_slot(const skip_alloc_t *slot_p){  char	*check_p;    if (! BIT_IS_SET(slot_p->sa_flags, ALLOC_FLAG_FREE)) {    dmalloc_errno = ERROR_SLOT_CORRUPT;    return 0;  }    if (BIT_IS_SET(slot_p->sa_flags, ALLOC_FLAG_BLANK)) {    for (check_p = (char *)slot_p->sa_mem;	 check_p < (char *)slot_p->sa_mem + slot_p->sa_total_size;	 check_p++) {      if (*check_p != FREE_BLANK_CHAR) {	dmalloc_errno = ERROR_FREE_OVERWRITTEN;	return 0;      }    }  }  #if LOG_PNT_SEEN_COUNT  /*   * We divide by 2 here because realloc which returns the same   * pointer will seen_c += 2.  However, it will never be more than   * twice the iteration value.  We divide by two to not overflow   * iter_c * 2.   */  if (slot_p->sa_seen_c / 2 > _dmalloc_iter_c) {    dmalloc_errno = ERROR_SLOT_CORRUPT;    return 0;  }#endif    return 1;}/***************************** exported routines *****************************//* * int _dmalloc_chunk_startup *  * DESCRIPTION: * * Startup the low level malloc routines. * * RETURNS: * * Success - 1 * * Failure - 0 * * ARGUMENTS: * * None. */int	_dmalloc_chunk_startup(void){  unsigned int	value;  char		*pos_p, *max_p;  int		bit_c, *bits_p;    value = FENCE_MAGIC_BOTTOM;  max_p = fence_bottom + FENCE_BOTTOM_SIZE;  for (pos_p = fence_bottom;       pos_p < max_p;       pos_p += sizeof(value)) {    if (pos_p + sizeof(value) <= max_p) {      memcpy(pos_p, (char *)&value, sizeof(value));    }    else {      memcpy(pos_p, (char *)&value, max_p - pos_p);    }  }    value = FENCE_MAGIC_TOP;  max_p = fence_top + FENCE_TOP_SIZE;  for (pos_p = fence_top; pos_p < max_p; pos_p += sizeof(value)) {    if (pos_p + sizeof(value) <= max_p) {      memcpy(pos_p, (char *)&value, sizeof(value));    }    else {      memcpy(pos_p, (char *)&value, max_p - pos_p);    }  }    /* initialize the bits array */  bits_p = bit_sizes;  for (bit_c = 0; bit_c < BASIC_BLOCK; bit_c++) {    if ((1 << bit_c) >= CHUNK_SMALLEST_BLOCK) {      *bits_p++ = 1 << bit_c;    }  }    /* set the admin flags on the two statically allocated slots */  skip_free_list->sa_flags = ALLOC_FLAG_ADMIN;  skip_address_list->sa_flags = ALLOC_FLAG_ADMIN;    return 1;}/* * char *_dmalloc_chunk_desc_pnt * * DESCRIPTION: * * Write into a buffer a pointer description with file and * line-number. * * RETURNS: * * Pointer to buffer 1st argument. * * ARGUMENTS: * * buf <-> Passed in buffer which will be filled with a description of * the pointer. * * buf_size -> Size of the buffer in bytes. * * file -> File name, return address, or NULL. * * line -> Line number or 0. */char	*_dmalloc_chunk_desc_pnt(char *buf, const int buf_size,				 const char *file, const unsigned int line){  if (file == DMALLOC_DEFAULT_FILE && line == DMALLOC_DEFAULT_LINE) {    (void)loc_snprintf(buf, buf_size, "unknown");  }  else if (line == DMALLOC_DEFAULT_LINE) {    (void)loc_snprintf(buf, buf_size, "ra=%#lx", (unsigned long)file);  }  else if (file == DMALLOC_DEFAULT_FILE) {    (void)loc_snprintf(buf, buf_size, "ra=ERROR(line=%u)", line);  }  else {    (void)loc_snprintf(buf, buf_size, "%.*s:%u", MAX_FILE_LENGTH, file, line);  }    return buf;}/* * int _dmalloc_chunk_read_info * * DESCRIPTION: * * Return some information associated with a pointer. * * RETURNS: * * Success - 1 pointer is okay * * Failure - 0 problem with pointer * * ARGUMENTS: * * user_pnt -> Pointer we are checking. * * where <- Where the check is being made from. * * user_size_p <- Pointer to an unsigned int which, if not NULL, will * be set to the size of bytes that the user requested. * * alloc_size_p <- Pointer to an unsigned int which, if not NULL, will * be set to the total given size of bytes including block overhead. * * file_p <- Pointer to a character pointer which, if not NULL, will * be set to the file where the pointer was allocated. * * line_p <- Pointer to a character pointer which, if not NULL, will * be set to the line-number where the pointer was allocated. * * ret_attr_p <- Pointer to a void pointer, if not NULL, will be set * to the return-address where the pointer was allocated. * * seen_cp <- Pointer to an unsigned long which, if not NULL, will be * set to the number of times the pointer has been "seen". * * used_p <- Pointer to an unsigned long which, if not NULL, will be * set to the last time the pointer was "used". * * valloc_bp <- Pointer to an integer which, if not NULL, will be set * to 1 if the pointer was allocated with valloc otherwise 0. * * fence_bp <- Pointer to an integer which, if not NULL, will be set * to 1 if the pointer has the fence bit set otherwise 0. */int	_dmalloc_chunk_read_info(const void *user_pnt, const char *where,				 unsigned int *user_size_p,				 unsigned int *alloc_size_p, char **file_p,				 unsigned int *line_p, void **ret_attr_p,				 unsigned long **seen_cp,				 unsigned long *used_p, int *valloc_bp,				 int *fence_bp){  skip_alloc_t	*slot_p;    if (BIT_IS_SET(_dmalloc_flags, DEBUG_LOG_TRANS)) {    dmalloc_message("reading info about pointer '%#lx'",		    (unsigned long)user_pnt);  }    /* find the pointer with loose checking for fence */  slot_p = find_address(user_pnt, 0 /* not exact pointer */, skip_update);  if (slot_p == NULL) {    dmalloc_errno = ERROR_NOT_FOUND;    log_error_info(NULL, 0, user_pnt, NULL, "finding address in heap", where);    return 0;  }    /* might as well check the pointer now */  if (! check_used_slot(slot_p, user_pnt, 1 /* exact */)) {    /* errno set in check_slot */    log_error_info(NULL, 0, user_pnt, slot_p, "checking pointer admin", where);    return 0;  }    /* write info back to user space */  SET_POINTER(user_size_p, slot_p->sa_user_size);  SET_POINTER(alloc_size_p, slot_p->sa_total_size);  if (slot_p->sa_file == DMALLOC_DEFAULT_FILE) {    SET_POINTER(file_p, NULL);  }  else {    SET_POINTER(file_p, (char *)slot_p->sa_file);  }  SET_POINTER(line_p, slot_p->sa_line);  /* if the line is blank then the file will be 0 or the return address */  if (slot_p->sa_line == DMALLOC_DEFAULT_LINE) {    SET_POINTER(ret_attr_p, (char *)slot_p->sa_file);  }  else {    SET_POINTER(ret_attr_p, NULL);  }#if LOG_PNT_SEEN_COUNT  SET_POINTER(seen_cp, &slot_p->sa_seen_c);#else  SET_POINTER(seen_cp, NULL);#endif  SET_POINTER(used_p, slot_p->sa_use_iter);  SET_POINTER(valloc_bp, BIT_IS_SET(slot_p->sa_flags, ALLOC_FLAG_VALLOC));  SET_POINTER(fence_bp, BIT_IS_SET(slot_p->sa_flags, ALLOC_FLAG_FENCE));    return 1;}/******************************* heap checking *******************************//* * int _dmalloc_chunk_heap_check * * DESCRIPTION: * * Run extensive tests on the entire heap. * * RETURNS: * * Success - 1 if the heap is okay * * Failure - 0 if a problem was detected * * ARGUMENTS: * * None. */int	_dmalloc_chunk_heap_check(void){  skip_alloc_t	*slot_p;  entry_block_t	*block_p;  int		ret, level_c, checking_list_c = 0;

⌨️ 快捷键说明

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