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

📄 chunk.c

📁 测试内存泄露工具
💻 C
📖 第 1 页 / 共 5 页
字号:
  skip_alloc_t	*other_p;  pnt_info_t	pnt_info;  int		out_len, dump_size, offset;    dmalloc_error(where);  if (slot_p == NULL) {    prev_file = NULL;    prev_line = 0;    user_size = 0;    start_user = user_pnt;  }  else {    prev_file = slot_p->sa_file;    prev_line = slot_p->sa_line;    user_size = slot_p->sa_user_size;    if (user_pnt == NULL) {      get_pnt_info(slot_p, &pnt_info);      start_user = pnt_info.pi_user_start;    }    else {      start_user = user_pnt;    }  }    /* get a proper reason string */  if (reason != NULL) {    dmalloc_message("  error details: %s", reason);  }  /* dump the pointer information */  if (start_user == NULL) {    dmalloc_message("  from '%s' prev access '%s'",		    _dmalloc_chunk_desc_pnt(where_buf, sizeof(where_buf),					    now_file, now_line),		    _dmalloc_chunk_desc_pnt(where_buf2, sizeof(where_buf2),					    prev_file, prev_line));  }  else {    dmalloc_message("  pointer '%#lx' from '%s' prev access '%s'",		    (unsigned long)start_user,		    _dmalloc_chunk_desc_pnt(where_buf, sizeof(where_buf),					    now_file, now_line),		    _dmalloc_chunk_desc_pnt(where_buf2, sizeof(where_buf2),					    prev_file, prev_line));  }    /*   * If we aren't logging bad space or we didn't error with an   * overwrite error then don't log the bad bytes.   */  if ((! BIT_IS_SET(_dmalloc_flags, DEBUG_LOG_BAD_SPACE))      || (dmalloc_errno != ERROR_UNDER_FENCE	  && dmalloc_errno != ERROR_OVER_FENCE	  && dmalloc_errno != ERROR_FREE_OVERWRITTEN)) {    return;  }    /* NOTE: display memory like this has the potential for generating a core */  if (dmalloc_errno == ERROR_UNDER_FENCE) {    /* NOTE: only dump out the proper fence-post area once */    if (! dump_bottom_b) {      out_len = expand_chars(fence_bottom, FENCE_BOTTOM_SIZE, out,			     sizeof(out));      dmalloc_message("  dump of proper fence-bottom bytes: '%.*s'",		      out_len, out);      dump_bottom_b = 1;    }    offset = -FENCE_BOTTOM_SIZE;    dump_size = DUMP_SPACE + FENCE_BOTTOM_SIZE;    if (dump_size > user_size + FENCE_OVERHEAD_SIZE) {      dump_size = user_size + FENCE_OVERHEAD_SIZE;    }  }  else if (dmalloc_errno == ERROR_OVER_FENCE	   && user_size > 0) {    /* NOTE: only dump out the proper fence-post area once */    if (! dump_top_b) {      out_len = expand_chars(fence_top, FENCE_TOP_SIZE, out, sizeof(out));      dmalloc_message("  dump of proper fence-top bytes: '%.*s'",		      out_len, out);      dump_top_b = 1;    }    /*     * The size includes the bottom fence post area.  We want it to     * align with the start of the top fence post area.     */    if (DUMP_SPACE > user_size + FENCE_OVERHEAD_SIZE) {      dump_size = user_size + FENCE_OVERHEAD_SIZE;      offset = -FENCE_BOTTOM_SIZE;    }    else {      dump_size = DUMP_SPACE;      /* we will go backwards possibly up to FENCE_BOTTOM_SIZE offset */      offset = user_size + FENCE_TOP_SIZE - DUMP_SPACE;    }  }  else {    dump_size = DUMP_SPACE;    offset = 0;    if (user_size > 0 && dump_size > user_size) {      dump_size = user_size;    }  }    dump_pnt = (char *)start_user + offset;  if (IS_IN_HEAP(dump_pnt)) {    out_len = expand_chars(dump_pnt, dump_size, out, sizeof(out));    dmalloc_message("  dump of '%#lx'%+d: '%.*s'",		    (unsigned long)start_user, offset, out_len, out);  }  else {    dmalloc_message("  dump of '%#lx'%+d failed: not in heap",		    (unsigned long)start_user, offset);  }    /* find the previous pointer in case it ran over */  if (dmalloc_errno == ERROR_UNDER_FENCE && start_user != NULL) {    other_p = find_address((char *)start_user - FENCE_BOTTOM_SIZE - 1,			   1 /* not exact pointer */, skip_update);    if (other_p != NULL) {      dmalloc_message("  prev pointer '%#lx' (size %u) may have run over from '%s'",		      (unsigned long)other_p->sa_mem, other_p->sa_user_size,		      _dmalloc_chunk_desc_pnt(where_buf, sizeof(where_buf),					      other_p->sa_file,					      other_p->sa_line));    }  }  /* find the next pointer in case it ran under */  else if (dmalloc_errno == ERROR_OVER_FENCE	   && start_user != NULL	   && slot_p != NULL) {    other_p = find_address((char *)slot_p->sa_mem + slot_p->sa_total_size,			   1 /* not exact pointer */, skip_update);    if (other_p != NULL) {      dmalloc_message("  next pointer '%#lx' (size %u) may have run under from '%s'",		      (unsigned long)other_p->sa_mem, other_p->sa_user_size,		      _dmalloc_chunk_desc_pnt(where_buf, sizeof(where_buf),					      other_p->sa_file,					      other_p->sa_line));    }  }}/* * static int fence_read * * DESCRIPTION * * Check a pointer for fence-post magic numbers. * * RETURNS: * * Success - 1 if the fence posts are good. * * Failure - 0 if they are not. * * ARGUMENTS: * * info_p -> Pointer information that we are checking. */static	int	fence_read(const pnt_info_t *info_p){  /* check magic numbers in bottom of allocation block */  if (memcmp(fence_bottom, info_p->pi_fence_bottom, FENCE_BOTTOM_SIZE) != 0) {    dmalloc_errno = ERROR_UNDER_FENCE;    return 0;  }    /* check numbers at top of allocation block */  if (memcmp(fence_top, info_p->pi_fence_top, FENCE_TOP_SIZE) != 0) {    dmalloc_errno = ERROR_OVER_FENCE;    return 0;  }    return 1;}/* * static void clear_alloc * * DESCRIPTION * * Setup allocations by writing fence post and doing any necessary * clearing of memory. * * RETURNS: * * Success - 1 if the fence posts are good. * * Failure - 0 if they are not. * * ARGUMENTS: * * slot_p <-> Slot we are clearing. * * info_p -> Pointer to information about the allocation. * * old_size -> If there was an old-size that we have copied into the * new pointer then set this.  If 0 then it will clear the entire * allocation. * * func_id -> ID of the function which is doing the allocation.  Used * to determine if we should 0 memory for [re]calloc. */static	void	clear_alloc(skip_alloc_t *slot_p, pnt_info_t *info_p,			    const unsigned int old_size, const int func_id){  char	*start_p;  int	num;    /*   * NOTE: The alloc blank flag is set so we blank a slot when it is   * allocated.  It used to be that the allocated spaces were blanked   * and the free spaces of the allocated chunk were blanked only if   * the FREE_BLANK flag was enabled.  Wrong!   */    /*   * Set our slot blank flag if the flags are set now.  This will   * carry over with a realloc.   */  if (BIT_IS_SET(_dmalloc_flags, DEBUG_ALLOC_BLANK)      || BIT_IS_SET(_dmalloc_flags, DEBUG_CHECK_BLANK)) {    BIT_SET(slot_p->sa_flags, ALLOC_FLAG_BLANK);  }    /*   * If we have a fence post protected valloc then there is almost a   * full block at the front what is "free".  Set it with blank chars.   */  if (info_p->pi_fence_b) {    num = (char *)info_p->pi_fence_bottom - (char *)info_p->pi_alloc_start;    /* alloc-blank NOT free-blank */    if (num > 0 && BIT_IS_SET(slot_p->sa_flags, ALLOC_FLAG_BLANK)) {      memset(info_p->pi_alloc_start, ALLOC_BLANK_CHAR, num);    }  }    /*   * If we are allocating or extending memory, write in our alloc   * chars.   */  start_p = (char *)info_p->pi_user_start + old_size;    num = (char *)info_p->pi_user_bounds - start_p;  if (num > 0) {    if (func_id == DMALLOC_FUNC_CALLOC || func_id == DMALLOC_FUNC_RECALLOC) {      memset(start_p, 0, num);    }    else if (BIT_IS_SET(slot_p->sa_flags, ALLOC_FLAG_BLANK)) {      memset(start_p, ALLOC_BLANK_CHAR, num);    }  }    /* write in fence-post info */  if (info_p->pi_fence_b) {    memcpy(info_p->pi_fence_bottom, fence_bottom, FENCE_BOTTOM_SIZE);    memcpy(info_p->pi_fence_top, fence_top, FENCE_TOP_SIZE);  }    /*   * Now clear the rest of the block above any fence post space with   * free characters.   *   * NOTE alloc-blank NOT free-blank   */  if (BIT_IS_SET(slot_p->sa_flags, ALLOC_FLAG_BLANK)) {        if (info_p->pi_fence_b) {      start_p = (char *)info_p->pi_fence_top + FENCE_TOP_SIZE;    }    else {      start_p = info_p->pi_user_bounds;    }        num = (char *)info_p->pi_alloc_bounds - start_p;    if (num > 0) {      memset(start_p, ALLOC_BLANK_CHAR, num);    }  }}/************************** administration functions *************************//* * static int create_divided_chunks * * DESCRIPTION: * * Get a divided-block from the free list or heap allocation. * * RETURNS: * * Success - 1 * * Failure - 0 * * ARGUMENTS: * * div_size -> Size of the divided block that we are allocating. */static	int	create_divided_chunks(const unsigned int div_size){  void		*mem, *bounds_p;    /* allocate a 1 block chunk that we will cut up into pieces */  mem = _dmalloc_heap_alloc(BLOCK_SIZE);  if (mem == HEAP_ALLOC_ERROR) {    /* error code set in _dmalloc_heap_alloc */    return 0;  }  user_block_c++;    /*   * now run through the block and add the the locations to the   * free-list   */    /* end of the block */  bounds_p = (char *)mem + BLOCK_SIZE - div_size;    for (; mem <= bounds_p; mem = (char *)mem + div_size) {    /* insert the rest of the blocks into the free-list */    if (insert_address(mem, 1 /* free list */, div_size) == NULL) {      /* error set in insert_address */      return 0;    }    free_space_bytes += div_size;  }    return 1;}/* * static skip_alloc_t *use_free_memory * * DESCRIPTION: * * Find a free memory chunk and remove it from the free list and put * it on the used list if available. * * RETURNS: * * Success - Valid slot pointer * * Failure - NULL * * ARGUMENTS: * * size -> Size of the block that we are looking for. * * update_p -> Pointer to the skip_alloc entry we are using to hold * the update pointers. */static	skip_alloc_t	*use_free_memory(const unsigned int size,					 skip_alloc_t *update_p){  skip_alloc_t	*slot_p;  #if FREED_POINTER_DELAY  /*   * check the free wait list to see if any of the waiting pointers   * need to be moved off and inserted into the free list   */  for (slot_p = free_wait_list_head; slot_p != NULL; ) {    skip_alloc_t	*next_p;        /* we are done if we find a pointer delay in the future */    if (slot_p->sa_use_iter + FREED_POINTER_DELAY > _dmalloc_iter_c) {      break;    }        /* put slot on free list */    next_p = slot_p->sa_next_p[0];    if (! insert_slot(slot_p, 1 /* free list */)) {      /* error dumped in insert_slot */      return NULL;    }        /* adjust our linked list */    slot_p = next_p;    free_wait_list_head = slot_p;    if (slot_p == NULL) {      free_wait_list_tail = NULL;    }  }#endif    /* find a free block which matches the size */   slot_p = find_free_size(size, update_p);  if (slot_p == NULL) {    return NULL;  }    /* sanity check */  if (slot_p->sa_total_size != size) {    dmalloc_errno = ERROR_ADDRESS_LIST;    dmalloc_error("use_free_memory");    return NULL;  }    /* remove from free list */  if (! remove_slot(slot_p, update_p)) {    /* error reported in remove_slot */    return NULL;  }    /* set to user allocated space */  slot_p->sa_flags = ALLOC_FLAG_USER;    /* insert it into our address list */  if (! insert_slot(slot_p, 0 /* used list */)) {    /* error set in insert_slot */    return NULL;  }    free_space_bytes -= slot_p->sa_total_size;    return slot_p;}/* * static skip_alloc_t *get_divided_memory * * DESCRIPTION: * * Get a divided memory block from the free list or heap allocation. * * RETURNS: * * Success - Valid skip slot pointer. * * Failure - NULL * * ARGUMENTS: * * size -> Size of the block that we are allocating. */static	skip_alloc_t	*get_divided_memory(const unsigned int size){  skip_alloc_t	*slot_p;  unsigned int	need_size;  int		*bits_p;    for (bits_p = bit_sizes;; bits_p++) {    if (*bits_p >= size) {      break;    }  }  need_size = *bits_p;    /* find a free block which matches the size */   slot_p = use_free_memory(need_size, skip_update);  if (slot_p != NULL) {    return slot_p;  }    /* need to get more slots */  if (! create_divided_chunks(need_size)) {    /* errors dumped in  create_divided_chunks */    return NULL;  }    /* now we ask again for the free memory */  slot_p = use_free_memory(need_size, skip_update);  if (slot_p == NULL) {    /* huh?  This isn't right. */    dmalloc_errno = ERROR_ADDRESS_LIST;    dmalloc_error("get_divided_memory");    return NULL;  }    return slot_p;}/* * static skip_alloc_t *get_memory * * DESCRIPTION: * * Get a block from the free list or heap allocation. * * RETURNS: * * Success - Valid skip slot pointer. * * Failure - NULL * * ARGUMENTS: * * size -> Size of the block that we are allocating. */static	skip_alloc_t	*get_memory(const unsigned int size){  skip_alloc_t	*slot_p, *update_p;  void		*mem;  unsigned int	need_size, block_n;    /* do we need to print admin info? */  if (BIT_IS_SET(_dmalloc_flags, DEBUG_LOG_ADMIN)) {    dmalloc_message("need %d bytes", size);  }    /* will this allocate put us over the limit? */

⌨️ 快捷键说明

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