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

📄 chunk.c

📁 测试内存泄露工具
💻 C
📖 第 1 页 / 共 5 页
字号:
    /* extern pointer information set in _dmalloc_heap_alloc */  return block_p;}/* * static int remove_slot * * DESCRIPTION: * * Remove a slot from the skip list. * * RETURNS: * * Success - 1 * * Failure - 0 * * ARGUMENTS: * * delete_p -> Pointer to the block we are deleting from the list. * * update_p -> Pointer to the skip_alloc entry we are using to hold * the update pointers. */static	int	remove_slot(skip_alloc_t *delete_p, skip_alloc_t *update_p){  skip_alloc_t	*adjust_p;  int		level_c;    /* update the block skip list */  for (level_c = 0; level_c <= MAX_SKIP_LEVEL; level_c++) {        /*     * The update node holds pointers to the slots which are pointing     * to the one we want since we need to update those pointers     * ahead.     */    adjust_p = update_p->sa_next_p[level_c];        /*     * If the pointer in question is not pointing to the deleted slot     * then the deleted slot is shorter than this level and we are     * done.  This is guaranteed if we have a proper skip list.     */    if (adjust_p->sa_next_p[level_c] != delete_p) {      break;    }        /*     * We are deleting a slot after each of the slots in the update     * array.  So for each level, we get the slot we are adjusting, we     * set it's next pointers to the next pointers at the same level     * from the deleted slot.     */    adjust_p->sa_next_p[level_c] = delete_p->sa_next_p[level_c];  }    /*   * Sanity check here, we should always have at least 1 pointer to   * the found node that we are deleting.   */  if (level_c == 0) {    dmalloc_errno = ERROR_ADDRESS_LIST;    dmalloc_error("remove_slot");    return 0;  }    return 1;}/* * static skip_alloc_t *get_slot * * DESCRIPTION: * * Get a new slot of a certain size.  This calls alloc_slot and then * does a whole bunch of things if alloc_slots generates the need for * two new slots.  Jumping through hoops to get this right. * * RETURNS: * * Success - Valid skip-alloc pointer. * * Failure - NULL * * ARGUMENTS: * * None. */static	skip_alloc_t	*get_slot(void){  skip_alloc_t	*new_p;  int		level_n, slot_size;  void		*admin_mem;    /* generate the level for our new slot */  level_n = random_level(MAX_SKIP_LEVEL);  slot_size = SKIP_SLOT_SIZE(level_n);    /* get an extry from the free list */  new_p = entry_free_list[level_n];  if (new_p != NULL) {    /* shift the linked list over */    entry_free_list[level_n] = new_p->sa_next_p[0];    /* zero our slot entry */    memset(new_p, 0, slot_size);    new_p->sa_level_n = level_n;    return new_p;  }    /*   * Okay, this is a little wild.  Holding on?   *   * So we are trying to get a slot of a certain size to store   * something in a skip list.  We didn't have any on the free-list so   * now we will allocate a block.  We allocate a block of memory to   * hold the slots meaning that we may need 1 new slot to account for   * the admin and external memory in addition to the 1 requested.   *   * To do it right, would take a recursive call to get_slot which I   * am not willing to do so we will have 2 blocks in a row which have   * the same height.  This is less than efficient but oh well.   */    /* add in all of the unused slots to the linked list */  admin_mem = alloc_slots(level_n);  if (admin_mem == NULL) {    /* error code set in alloc_slots */    return NULL;  }    /* get one for the admin memory */  new_p = entry_free_list[level_n];  if (new_p == NULL) {    /*     * HUH?  This isn't right.  We should have created a whole bunch     * of addresses     */    dmalloc_errno = ERROR_ADDRESS_LIST;    dmalloc_error("get_slot");    return NULL;  }  entry_free_list[level_n] = new_p->sa_next_p[0];  memset(new_p, 0, slot_size);  new_p->sa_flags = ALLOC_FLAG_ADMIN;  new_p->sa_mem = admin_mem;  new_p->sa_total_size = BLOCK_SIZE;  new_p->sa_level_n = level_n;    /* now put it in the used list */  if (! insert_slot(new_p, 0 /* used list */)) {    /* error reported above */    return NULL;  }    /* now get one for the user */  new_p = entry_free_list[level_n];  if (new_p == NULL) {    /*     * HUH?  This isn't right.  We should have created a whole bunch     * of addresses     */    dmalloc_errno = ERROR_ADDRESS_LIST;    dmalloc_error("get_slot");    return NULL;  }  entry_free_list[level_n] = new_p->sa_next_p[0];  memset(new_p, 0, slot_size);  new_p->sa_level_n = level_n;    /* level_np set up top */  return new_p;}/* * static skip_alloc_t *insert_address * * DESCRIPTION: * * Insert an address entry into a skip list. * * RETURNS: * * Success - Valid slot pointer. * * Failure - NULL * * ARGUMENTS: * * address -> Address we are inserting into the address list. * * free_b -> Insert a free address in the free-size list otherwise it * will go into the used address list. * * tot_size -> Total size of the chunk that we are inserting into the * list. */static	skip_alloc_t	*insert_address(void *address, const int free_b,					const unsigned int tot_size){  skip_alloc_t	*new_p;    /* get a new entry */  new_p = get_slot();  if (new_p == NULL) {    /* error code set in get_slot */    return NULL;  }  if (free_b) {    new_p->sa_flags = ALLOC_FLAG_FREE;  }  else {    new_p->sa_flags = ALLOC_FLAG_USER;  }  new_p->sa_mem = address;  new_p->sa_total_size = tot_size;    /* now try and insert the slot into the skip-list */  if (! insert_slot(new_p, free_b)) {    /* error code set in insert_slot */    return NULL;  }    return new_p;}/******************************* misc routines *******************************//* * static int expand_chars * * DESCRIPTION: * * Copies a buffer into a output buffer while translates * non-printables into %03o octal values.  If it can, it will also * translate certain \ characters (\r, \n, etc.) into \\%c.  The * routine is useful for printing out binary values. * * Note: It does _not_ add a \0 at the end of the output buffer. * * RETURNS: * * Returns the number of characters added to the output buffer. * * ARGUMENTS: * * buf - the buffer to convert. * * buf_size - size of the buffer.  If < 0 then it will expand till it * sees a \0 character. * * out - destination buffer for the convertion. * * out_size - size of the output buffer. */static	int	expand_chars(const void *buf, const int buf_size,			     char *out, const int out_size){  int			buf_c;  const unsigned char	*buf_p, *spec_p;  char	 		*out_p = out, *bounds_p;    /* setup our max pointer */  bounds_p = out + out_size;    /* run through the input buffer, counting the characters as we go */  for (buf_c = 0, buf_p = (const unsigned char *)buf;; buf_c++, buf_p++) {        /* did we reach the end of the buffer? */    if (buf_size < 0) {      if (*buf_p == '\0') {	break;      }    }    else {      if (buf_c >= buf_size) {	break;      }    }        /* search for special characters */    for (spec_p = (unsigned char *)SPECIAL_CHARS + 1;	 *(spec_p - 1) != '\0';	 spec_p += 2) {      if (*spec_p == *buf_p) {	break;      }    }        /* did we find one? */    if (*(spec_p - 1) != '\0') {      if (out_p + 2 >= bounds_p) {	break;      }      out_p += loc_snprintf(out_p, bounds_p - out_p, "\\%c", *(spec_p - 1));      continue;    }        /* print out any 7-bit printable characters */    if (*buf_p < 128 && isprint(*buf_p)) {      if (out_p + 1 >= bounds_p) {	break;      }      *out_p = *(char *)buf_p;      out_p += 1;    }    else {      if (out_p + 4 >= bounds_p) {	break;      }      out_p += loc_snprintf(out_p, bounds_p - out_p, "\\%03o", *buf_p);    }  }  /* try to punch the null if we have space in case the %.*s doesn't work */  if (out_p < bounds_p) {    *out_p = '\0';  }    return out_p - out;}/* * static void get_pnt_info * * DESCRIPTION: * * With a slot, set a number of pointers to places within the block. * * RETURNS: * * None. * * ARGUMENTS: * * slot_p -> Pointer to a slot structure that we are getting info on. * * info_p <-> Pointer to an info structure that we are filling with * information. */static	void	get_pnt_info(const skip_alloc_t *slot_p, pnt_info_t *info_p){  info_p->pi_fence_b = BIT_IS_SET(slot_p->sa_flags, ALLOC_FLAG_FENCE);  info_p->pi_valloc_b = BIT_IS_SET(slot_p->sa_flags, ALLOC_FLAG_VALLOC);  info_p->pi_blanked_b = BIT_IS_SET(slot_p->sa_flags, ALLOC_FLAG_BLANK);    info_p->pi_alloc_start = slot_p->sa_mem;    if (info_p->pi_fence_b) {    if (info_p->pi_valloc_b) {      info_p->pi_user_start = (char *)info_p->pi_alloc_start + BLOCK_SIZE;      info_p->pi_fence_bottom = (char *)info_p->pi_user_start -	FENCE_BOTTOM_SIZE;    }    else {      info_p->pi_fence_bottom = info_p->pi_alloc_start;      info_p->pi_user_start = (char *)info_p->pi_alloc_start +	FENCE_BOTTOM_SIZE;    }  }  else {    info_p->pi_fence_bottom = NULL;    info_p->pi_user_start = info_p->pi_alloc_start;  }    info_p->pi_user_bounds = (char *)info_p->pi_user_start +    slot_p->sa_user_size;    info_p->pi_alloc_bounds = (char *)slot_p->sa_mem + slot_p->sa_total_size;    if (info_p->pi_fence_b) {    info_p->pi_fence_top = info_p->pi_user_bounds;    info_p->pi_upper_bounds = (char *)info_p->pi_alloc_bounds - FENCE_TOP_SIZE;  }  else {    info_p->pi_fence_top = NULL;    info_p->pi_upper_bounds = info_p->pi_alloc_bounds;  }}/* * static char *display_pnt * * DESCRIPTION: * * Write into a buffer a discription of a pointer. * * RETURNS: * * Pointer to buffer 1st argument. * * ARGUMENTS: * * user_pnt -> Pointer that we are displaying. * * alloc_p -> Pointer to the skip slot which we are displaying. * * buf <-> Passed in buffer which will be filled with a description of * the pointer. * * buf_size -> Size of the buffer in bytes. */static	char	*display_pnt(const void *user_pnt, const skip_alloc_t *alloc_p,			     char *buf, const int buf_size){  char	*buf_p, *bounds_p;  int	elapsed_b;    buf_p = buf;  bounds_p = buf_p + buf_size;    buf_p += loc_snprintf(buf_p, bounds_p - buf_p, "%#lx",			(unsigned long)user_pnt);  #if LOG_PNT_SEEN_COUNT  buf_p += loc_snprintf(buf_p, bounds_p - buf_p, "|s%lu", alloc_p->sa_seen_c);#endif  #if LOG_PNT_ITERATION  buf_p += loc_snprintf(buf_p, bounds_p - buf_p, "|i%lu",			alloc_p->sa_iteration);#endif    if (BIT_IS_SET(_dmalloc_flags, DEBUG_LOG_ELAPSED_TIME)) {    elapsed_b = 1;  }  else {    elapsed_b = 0;  }  if (elapsed_b || BIT_IS_SET(_dmalloc_flags, DEBUG_LOG_CURRENT_TIME)) {#if LOG_PNT_TIMEVAL    {      char	time_buf[64];      buf_p += loc_snprintf(buf_p, bounds_p - buf_p, "|w%s",			    _dmalloc_ptimeval(&alloc_p->sa_timeval, time_buf,					      sizeof(time_buf), elapsed_b));    }#else#if LOG_PNT_TIME    {      char	time_buf[64];      buf_p += loc_snprintf(buf_p, bounds_p - buf_p, "|w%s",			    _dmalloc_ptime(&alloc_p->sa_time, time_buf,					   sizeof(time_buf), elapsed_b));    }#endif#endif  }  #if LOG_PNT_THREAD_ID  {    char	thread_id[256];        buf_p += loc_snprintf(buf_p, bounds_p - buf_p, "|t");    THREAD_ID_TO_STRING(thread_id, sizeof(thread_id), alloc_p->sa_thread_id);    buf_p += loc_snprintf(buf_p, bounds_p - buf_p, "%s", thread_id);  }#endif    return buf;}/* * static void log_error_info * * DESCRIPTION: * * Logging information about a pointer, usually during an error * condition. * * RETURNS: * * None. * * ARGUMENTS: * * now_file -> File from where we generated the error. * * now_line -> Line number from where we generated the error. * * user_pnt -> Pointer in question.  This can be 0L then it will use * the slot_p memory pointer. * * slot_p -> Pointer to the slot associated with the user_pnt or 0L. * * reason -> Reason string why something happened. * * where -> What routine is calling log_error_info.  For instance * malloc or chunk_check. */static	void	log_error_info(const char *now_file,			       const unsigned int now_line,			       const void *user_pnt,			       const skip_alloc_t *slot_p,			       const char *reason, const char *where){  static int	dump_bottom_b = 0, dump_top_b = 0;  char		out[(DUMP_SPACE + FENCE_BOTTOM_SIZE + FENCE_TOP_SIZE) * 4];  char		where_buf[MAX_FILE_LENGTH + 64];  char		where_buf2[MAX_FILE_LENGTH + 64];  const char	*prev_file;  const void	*dump_pnt = user_pnt;  const void	*start_user;  unsigned int	prev_line, user_size;

⌨️ 快捷键说明

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