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

📄 dmalloc_t.c

📁 测试内存泄露工具
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * Test program for malloc code * * Copyright 2000 by Gray Watson * * This file is part of the dmalloc package. * * Permission to use, copy, modify, and distribute this software for * any purpose and without fee is hereby granted, provided that the * above copyright notice and this permission notice appear in all * copies, and that the name of Gray Watson not be used in advertising * or publicity pertaining to distribution of the document or software * without specific, written prior permission. * * Gray Watson makes no representations about the suitability of the * software described herein for any purpose.  It is provided "as is" * without express or implied warranty. * * The author may be contacted via http://dmalloc.com/ * * $Id: dmalloc_t.c,v 1.117 2004/10/19 14:50:44 gray Exp $ *//* * Test program for the malloc library.  Current it is interactive although * should be script based. */#include <stdio.h>				/* for stdin */#if HAVE_STDLIB_H# include <stdlib.h>				/* for atoi + */#endif#if HAVE_STRING_H# include <string.h>#endif#if HAVE_UNISTD_H# include <unistd.h>#endif#include "conf.h"#include "compat.h"				/* for loc_snprintf */#if HAVE_TIME# ifdef TIME_INCLUDE#  include TIME_INCLUDE# endif#endif#include "dmalloc.h"#include "dmalloc_argv.h"#include "dmalloc_rand.h"/* * NOTE: these are only needed to test certain features of the library. */#include "debug_tok.h"#include "error_val.h"#include "heap.h"				/* for external testing */#define INTER_CHAR		'i'#define DEFAULT_ITERATIONS	10000#define MAX_POINTERS		1024#define MAX_ALLOC		(1024 * 1024)#define MIN_AVAIL		10/* pointer tracking structure */typedef struct pnt_info_st {  long			pi_crc;			/* crc of storage */  int			pi_size;		/* size of storage */  void			*pi_pnt;		/* pnt to storage */  struct pnt_info_st	*pi_next;		/* pnt to next */} pnt_info_t;static	pnt_info_t	*pointer_grid;/* argument variables */static	int		default_iter_n = DEFAULT_ITERATIONS; /* # of iters */static	char		*env_string = NULL;		/* env options */static	int		interactive_b = ARGV_FALSE;	/* interactive flag */static	int		log_trans_b = ARGV_FALSE;	/* log transactions */static	int		no_special_b = ARGV_FALSE;	/* no-special flag */static	int		max_alloc = MAX_ALLOC;		/* amt of mem to use */static	int		max_pointers = MAX_POINTERS;	/* # of pnts to use */static	int		random_debug_b = ARGV_FALSE;	/* random flag */static	int		silent_b = ARGV_FALSE;		/* silent flag */static	unsigned int	seed_random = 0;		/* random seed */static	int		verbose_b = ARGV_FALSE;		/* verbose flag */static	argv_t		arg_list[] = {  { INTER_CHAR,	"interactive",		ARGV_BOOL_INT,		&interactive_b,    NULL,			"turn on interactive mode" },  { 'e',	"env-string",		ARGV_CHAR_P,		&env_string,    "string",			"string of env commands to set" },  { 'l',	"log-trans",		ARGV_BOOL_INT,		&log_trans_b,    NULL,			"log transactions via tracking-func" },  { 'm',	"max-alloc",		ARGV_INT,		&max_alloc,    "bytes",			"maximum allocation to test" },  { 'n',	"no-special",		ARGV_BOOL_INT,		&no_special_b,    NULL,			"do not run special tests" },  { 'p',	"max-pointers",		ARGV_INT,		&max_pointers,    "pointers",		"number of pointers to test" },  { 'r',	"random-debug",		ARGV_BOOL_INT,	       &random_debug_b,    NULL,			"randomly change debug flag" },  { 's',	"silent",		ARGV_BOOL_INT,		&silent_b,    NULL,			"do not display messages" },  { 'S',	"seed-random",		ARGV_U_INT,		&seed_random,    "number",			"seed for random function" },  { 't',	"times",		ARGV_INT,	       &default_iter_n,    "number",			"number of iterations to run" },  { 'v',	"verbose",		ARGV_BOOL_INT,		&verbose_b,    NULL,			"enables verbose messages" },  { ARGV_LAST }};/* * Hexadecimal STR to integer translation */static	long	hex_to_long(char *str){  long		ret;    /* strip off spaces */  for (; *str == ' ' || *str == '\t'; str++) {  }    /* skip a leading 0[xX] */  if (*str == '0' && (*(str + 1) == 'x' || *(str + 1) == 'X')) {    str += 2;  }    for (ret = 0;; str++) {    if (*str >= '0' && *str <= '9') {      ret = ret * 16 + (*str - '0');    }    else if (*str >= 'a' && *str <= 'f') {      ret = ret * 16 + (*str - 'a' + 10);    }    else if (*str >= 'A' && *str <= 'F') {      ret = ret * 16 + (*str - 'A' + 10);    }    else {      break;    }  }    return ret;}/* * Read an address from the user */static	void	*get_address(void){  char	line[80];  void	*pnt;    do {    (void)printf("Enter a hex address: ");    if (fgets(line, sizeof(line), stdin) == NULL) {      return NULL;    }  } while (line[0] == '\0');    pnt = (void *)hex_to_long(line);    return pnt;}/* * Free a slot from the used_p list and put it on the free list */static	void	free_slot(const int iter_c, pnt_info_t *slot_p,			  pnt_info_t **used_pp, pnt_info_t **free_pp){  pnt_info_t	*this_p, *prev_p;    if (verbose_b) {    (void)printf("%d: free'd %d bytes from slot %d (%#lx)\n",		 iter_c + 1, slot_p->pi_size, slot_p - pointer_grid,		 (long)slot_p->pi_pnt);  }    slot_p->pi_pnt = NULL;    /* find pnt in the used list */  for (this_p = *used_pp, prev_p = NULL;       this_p != NULL;       prev_p = this_p, this_p = this_p->pi_next) {    if (this_p == slot_p) {      break;    }  }  if (prev_p == NULL) {    *used_pp = slot_p->pi_next;  }  else {    prev_p->pi_next = slot_p->pi_next;  }    slot_p->pi_next = *free_pp;  *free_pp = slot_p;}/* * Try ITER_N random program iterations, returns 1 on success else 0 */static	int	do_random(const int iter_n){  unsigned int	flags;  int		iter_c, prev_errno, amount, max_avail, free_c;  int		final = 1;  char		*chunk_p;  pnt_info_t	*free_p, *used_p = NULL;  pnt_info_t	*pnt_p;    max_avail = max_alloc;    flags = dmalloc_debug_current();    pointer_grid = (pnt_info_t *)malloc(sizeof(pnt_info_t) * max_pointers);  if (pointer_grid == NULL) {    (void)printf("%s: problems allocating space for %d pointer slots.\n",		 argv_program, max_pointers);    return 0;  }    /* initialize free list */  free_p = pointer_grid;  for (pnt_p = pointer_grid; pnt_p < pointer_grid + max_pointers; pnt_p++) {    pnt_p->pi_size = 0;    pnt_p->pi_pnt = NULL;    pnt_p->pi_next = pnt_p + 1;  }  /* redo the last next pointer */  (pnt_p - 1)->pi_next = NULL;  free_c = max_pointers;    prev_errno = ERROR_NONE;  for (iter_c = 0; iter_c < iter_n;) {    int		which_func, which;        if (dmalloc_errno != prev_errno && ! silent_b) {      (void)printf("ERROR: iter %d, %s (err %d)\n",		   iter_c, dmalloc_strerror(dmalloc_errno), dmalloc_errno);      prev_errno = dmalloc_errno;      final = 0;    }        /* special case when doing non-linear stuff, sbrk took all memory */    if (max_avail < MIN_AVAIL && free_p == NULL) {      break;    }        if (random_debug_b) {      unsigned int	new_flag;      which = _dmalloc_rand() % (sizeof(int) * 8);      new_flag = 1 << which;      flags ^= new_flag;      if (verbose_b) {	(void)printf("%d: debug flags = %#x\n", iter_c + 1, flags);      }      dmalloc_debug(flags);    }        /* decide whether to malloc a new pointer or free/realloc an existing */    which = _dmalloc_rand() % 4;        if ((free_p == NULL	 || which == 3	 || max_avail < MIN_AVAIL	 || free_c == max_pointers)	&& used_p != NULL) {            /* choose a random slot to free */      which = _dmalloc_rand() % (max_pointers - free_c);      for (pnt_p = used_p; which > 0; which--) {	pnt_p = pnt_p->pi_next;      }            free(pnt_p->pi_pnt);      free_slot(iter_c, pnt_p, &used_p, &free_p);      free_c++;            if (verbose_b) {	(void)printf("%d: free'd %d bytes from slot %d (%#lx)\n",		     iter_c + 1, pnt_p->pi_size, pnt_p - pointer_grid,		     (long)pnt_p->pi_pnt);      }            max_avail += pnt_p->pi_size;      iter_c++;      continue;    }        /* sanity check */    if (free_p == NULL) {      (void)fprintf(stderr, "%s: problem with test program free list\n",		    argv_program);      exit(1);    }        /* rest are allocations */    amount = _dmalloc_rand() % (max_avail / 2);#if ALLOW_ALLOC_ZERO_SIZE == 0    if (amount == 0) {      amount = 1;    }#endif        which_func = _dmalloc_rand() % 7;        switch (which_func) {            /* malloc */    case 0:      pnt_p = free_p;      pnt_p->pi_pnt = malloc(amount);            if (verbose_b) {	(void)printf("%d: malloc %d of max %d into slot %d.  got %#lx\n",		     iter_c + 1, amount, max_avail, pnt_p - pointer_grid,		     (long)pnt_p->pi_pnt);      }      break;            /* calloc */    case 1:      pnt_p = free_p;      pnt_p->pi_pnt = calloc(amount, sizeof(char));            if (verbose_b) {	(void)printf("%d: calloc %d of max %d into slot %d.  got %#lx\n",		     iter_c + 1, amount, max_avail, pnt_p - pointer_grid,		     (long)pnt_p->pi_pnt);      }            /* test the returned block to make sure that is has been cleared */      if (pnt_p->pi_pnt != NULL) {	for (chunk_p = pnt_p->pi_pnt;	     chunk_p < (char *)pnt_p->pi_pnt + amount;	     chunk_p++) {	  if (*chunk_p != '\0') {	    if (! silent_b) {	      (void)printf("calloc of %d was not fully zeroed on iteration #%d\n",			   amount, iter_c + 1);	    }	    break;	  }	}      }      break;            /* realloc */    case 2:      if (free_c == max_pointers) {	continue;      }      which = _dmalloc_rand() % (max_pointers - free_c);      for (pnt_p = used_p; which > 0; which--) {	pnt_p = pnt_p->pi_next;      }            pnt_p->pi_pnt = realloc(pnt_p->pi_pnt, amount);      /*       * note that we've free the old size, we'll account for the       * alloc below       */      max_avail += pnt_p->pi_size;            if (verbose_b) {	(void)printf("%d: realloc %d from %d of max %d slot %d.  got %#lx\n",		     iter_c + 1, amount, pnt_p->pi_size, max_avail,		     pnt_p - pointer_grid, (long)pnt_p->pi_pnt);      }            if (amount == 0) {	free_slot(iter_c, pnt_p, &used_p, &free_p);	free_c++;	pnt_p = NULL;	continue;      }      break;            /* recalloc */    case 3:      if (free_c == max_pointers) {	continue;      }            which = _dmalloc_rand() % (max_pointers - free_c);      for (pnt_p = used_p; which > 0; which--) {	pnt_p = pnt_p->pi_next;      }            pnt_p->pi_pnt = recalloc(pnt_p->pi_pnt, amount);      /*       * note that we've free the old size, we'll account for the       * alloc below       */      max_avail += pnt_p->pi_size;            if (verbose_b) {	(void)printf("%d: recalloc %d from %d of max %d slot %d.  got %#lx\n",		     iter_c + 1, amount, pnt_p->pi_size, max_avail,		     pnt_p - pointer_grid, (long)pnt_p->pi_pnt);      }            /* test the returned block to make sure that is has been cleared */      if (pnt_p->pi_pnt != NULL && amount > pnt_p->pi_size) {	for (chunk_p = (char *)pnt_p->pi_pnt + pnt_p->pi_size;	     chunk_p < (char *)pnt_p->pi_pnt + amount;	     chunk_p++) {	  if (*chunk_p != '\0') {	    if (! silent_b) {	      (void)printf("recalloc %d from %d was not fully zeroed on iteration #%d\n",			   amount, pnt_p->pi_size, iter_c + 1);	    }	    break;	  }	}      }            if (amount == 0) {	free_slot(iter_c, pnt_p, &used_p, &free_p);	free_c++;	pnt_p = NULL;	continue;      }      break;            /* valloc */    case 4:      pnt_p = free_p;      pnt_p->pi_pnt = valloc(amount);            if (verbose_b) {	(void)printf("%d: valloc %d of max %d into slot %d.  got %#lx\n",		     iter_c + 1, amount, max_avail, pnt_p - pointer_grid,		     (long)pnt_p->pi_pnt);      }      break;            /* sbrk */    case 5:      /* do it less often then the other functions */      which = _dmalloc_rand() % 5;      if (which == 3 && amount > 0) {	void	*mem;		mem = _dmalloc_heap_alloc(amount);	if (verbose_b) {	  (void)printf("%d: heap alloc %d of max %d bytes.  got %#lx\n",		       iter_c + 1, amount, max_avail, (long)mem);	}	iter_c++;      }      /* don't store the memory */      continue;      break;            /* heap check in the middle */    case 6:      /* do it less often then the other functions */      which = _dmalloc_rand() % 20;      if (which == 7) {	if (dmalloc_verify(NULL /* check all heap */) != DMALLOC_NOERROR) {	  if (! silent_b) {	    (void)printf("%d: ERROR dmalloc_verify failed\n", iter_c + 1);	  }	  final = 0;	}	iter_c++;      }      continue;      break;          default:      continue;      break;    }        if (pnt_p->pi_pnt == NULL) {      if (! silent_b) {	(void)printf("%d: ERROR allocation of %d returned error\n",		     iter_c + 1, amount);      }      final = 0;      iter_c++;      continue;    }        /* set the size and take it off the free-list and put on used list */    pnt_p->pi_size = amount;        if (pnt_p == free_p) {      free_p = pnt_p->pi_next;      pnt_p->pi_next = used_p;      used_p = pnt_p;      free_c--;    }        max_avail -= amount;    iter_c++;    continue;  }    /* free used pointers */  for (pnt_p = pointer_grid; pnt_p < pointer_grid + max_pointers; pnt_p++) {    if (pnt_p->pi_pnt != NULL) {      free(pnt_p->pi_pnt);    }  }  

⌨️ 快捷键说明

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