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

📄 yamd.c

📁 很好用的内存泄漏检测工具。要配合linux的gcc使用,安装后将你的编译器gcc命令换成yamd-gcc就行了
💻 C
📖 第 1 页 / 共 4 页
字号:
  s = (addr )(b->block_addr + PGSZ);  e = (addr )(b->user_addr);  /* incomplete */#endif  /* The end */  s = (b->user_addr + b->user_size);  e = b->suffix_addr;  badp = magic_check_range(s, e);  if (badp)    {      handle_bad_magic(b, badp);      magic_fill_range(s, e);    }}static voidcheck_heap(void){  block *p;  /* Optimization. */  if (check_front)    return; /* Always nestled directly against a zapped page. */  if (default_alignment > 1)    for_each_block_by_alignment(p, unaligned_blocks)      check_block(p);  for_each_block_by_alignment(p, aligned_blocks)    check_block(p);}static void *lite_malloc(size_t nbytes){  block *b;  void *p;  NO_CATCH();  b = REAL(malloc)(sizeof(block));  p = REAL(malloc)(nbytes);  OK_CATCH();  if (!b || !p)    return NULL; /* FIXME: Not nice when memory low */  b->user_addr = b->block_addr = (addr)p;  b->user_size = b->block_size = nbytes;  b->who_alloced = BY_LITE;  b->who_freed = BY_NONE;  b->realloc_backlink = NULL;  /* Should be all we need to keep everyone else away from this. */  insert_block(b);  return p;}/* This is starting to get hairy. */static void *do_malloc(size_t nbytes, size_t alignment, addr orig_caller, 	  unsigned by_who, block *backlink){  block *b;  int nomem = 0; /* Might a goto actually be cleaner?? */  check_heap(); /* As long as we have control... */    if (nbytes > WAY_TOO_BIG)    {      log_event(LOG_ERR, "Ridiculous allocation");      log_detail(LOG_ERR, "At\n");      do_traceback(LOG_ERR, orig_caller);      log_detail(LOG_ERR, "attempt to %s %u bytes, which is way too big\n",		 get_entry_name(by_who), nbytes);      return NULL;    }  NO_CATCH();  b = REAL(malloc)(sizeof(block));  OK_CATCH();  if (!b)    nomem = 1;  else    {      size_t ca; /* controlling alignment, in bytes */      size_t user_piece_size; /* size of the piece not guarded */      addr user_piece_start;      user_piece_size = round_up(nbytes, PGSZ);      ca = round_up(alignment, PGSZ);      /* 1 addded for the ending guard page */      b->block_size = user_piece_size + ca + PGSZ;      b->block_addr = (addr)do_valloc(b->block_size);      if (b->block_addr)	{	  user_piece_start = round_up(b->block_addr + PGSZ, ca);	  b->suffix_addr = user_piece_start + user_piece_size;	  zap(b->block_addr, user_piece_start - b->block_addr);	  zap(b->suffix_addr, (b->block_addr + b->block_size) - b->suffix_addr);	  if (check_front)	    b->user_addr = user_piece_start;	  else	    {	      b->user_addr = (b->suffix_addr - nbytes) & ~(alignment - 1);	      magic_fill_range(b->user_addr + nbytes, b->suffix_addr);	    }#ifdef DEBUG	  assert(b->suffix_addr >= b->user_addr);	  assert((b->user_addr & (alignment - 1)) == 0);	  bzero((void *)b->user_addr, nbytes); /* make sure it's touchable */#endif	}      else /* no memory */	{	  nomem = 1;	}    }  if (nomem)    {      NO_CATCH();      if (b) REAL(free)(b);      OK_CATCH();      /* Should this be LOG_WARN? */      log_event(LOG_INFO, "Failed allocation");      log_detail(LOG_INFO, "Failed to %s %u bytes (aligned to %u) at\n", 		 get_entry_name(by_who), nbytes, alignment);      do_traceback(LOG_INFO, orig_caller);      return NULL;    }  /* Okay, set it all up. */  b->user_size = nbytes;  b->alignment = alignment;  generate_traceback(b->where_alloced, orig_caller);  b->who_alloced = by_who;  b->who_freed = BY_NONE;  b->realloc_backlink = backlink;#ifdef COMPLETE_MAGIC  if (complete_magic)    magic_fill_block(b);#endif  insert_block(b);  /* Lies, damn lies, and... */  user_currently_allocated += nbytes;  if (user_currently_allocated > max_user_allocated)    max_user_allocated = user_currently_allocated;  user_allocated += nbytes;  n_allocations++;    internal_allocated += b->block_size; /* total size allocated */  internal_mapped += (b->suffix_addr - (b->user_addr & ~PAGEMASK));  if (internal_mapped > max_internal_mapped)    max_internal_mapped = internal_mapped;  if (nbytes == 0)    {      log_event(LOG_WARN, "Zero-byte allocation");      describe_block(LOG_WARN, b);    }  else    {      log_event(LOG_INFO, "Normal allocation of this block");      describe_block(LOG_INFO, b);    }  return (void *)b->user_addr;}WRAPPER_LINKAGE void *WRAP(malloc)(size_t n ){  void *p;  MODE_VAR;  if (SHOULD_NOT_CATCH)    return REAL(malloc)(n);  ENTER();  if (WAS_LITE_MODE)    p = lite_malloc(n);  else    p = do_malloc(n, default_alignment, (addr)__builtin_return_address(0), BY_MALLOC, NULL);  LEAVE();  return p;}static inline intlog_base_2(unsigned long x){  int i;  i = -1;  while (x != 0)    {      x >>= 1;      i++;    }  return i;}#ifdef HAVE_MEMALIGNstatic void *lite_memalign(size_t alignment, size_t nbytes){  block *b;  void *p;  NO_CATCH();  b = REAL(malloc)(sizeof(block));  p = REAL(memalign)(alignment, nbytes);  OK_CATCH();  if (!b || !p)    return NULL; /* FIXME: Not nice when memory low */  b->user_addr = b->block_addr = (addr)p;  b->user_size = b->block_size = nbytes;  b->who_alloced = BY_LITE;  b->who_freed = BY_NONE;  b->realloc_backlink = NULL;  /* Should be all we need to keep everyone else away from this. */  insert_block(b);  return p;}WRAPPER_LINKAGEvoid *WRAP(memalign)(size_t alignment, size_t size ){  void *p;  int t;  MODE_VAR;  if (SHOULD_NOT_CATCH)    return REAL(memalign) (alignment, size);  ENTER();  if (WAS_LITE_MODE)    p = lite_memalign(alignment, size);  else    {      /* Check alignment for sanity */      if (alignment > WAY_TOO_BIG)	{	  log_event(LOG_ERR, "Ridiculous alignment");	  log_detail(LOG_ERR, "At\n");	  do_traceback(LOG_ERR, (addr)__builtin_return_address(0));	  log_detail(LOG_ERR, "attempt to memalign with %u byte alignment, which is way too big\n",		     alignment);	  LEAVE();	  return NULL;	}            t = log_base_2(alignment);      if (t < 0 || alignment != (1UL << t))	{	  size_t new_alignment = 1UL << (t + 1);	  log_event(LOG_ERR, "Alignment not power of 2");	  log_detail(LOG_ERR, "At\n");	  do_traceback(LOG_ERR, (addr)__builtin_return_address(0));	  log_detail(LOG_ERR, "Attempt to memalign with %u byte alignment, which is not a power of 2\n", alignment);	  log_detail(LOG_ERR,  "Using alignment of %u instead\n", new_alignment);	  if (new_alignment > WAY_TOO_BIG)	    {	      log_detail(LOG_ERR, "Oops, that's too big, giving up.\n");	      LEAVE();	      return NULL;	    }	  alignment = new_alignment;	}      p = do_malloc(size, alignment, (addr)__builtin_return_address(0), BY_MEMALIGN, NULL);    }  LEAVE();  return p;}#endif/* KLUDGE: Returns block * */static block *block_to_free(void *user, addr orig_caller, unsigned by_who){  block *b;  check_heap(); /* Got to do it sometime */    if (!user && by_who != BY_REALLOC) /* realloc(NULL, ...) is OK */    {      log_event(LOG_WARN, "Free of null pointer");      log_detail(LOG_WARN, "At\n");      do_traceback(LOG_WARN, orig_caller);      log_detail(LOG_WARN, "Attempt to %s null pointer\n",		 get_entry_name(by_who));      return NULL;    }        b = find_block_by_user_addr((addr)user);  if (!b)    {      log_event(LOG_ERR, "Free of errnoneous pointer");      log_detail(LOG_ERR, "At\n");      do_traceback(LOG_ERR, orig_caller);      log_detail(LOG_ERR, "Freeing erroneous pointer " POINTER_FORMAT "\n", user);      describe_address(LOG_ERR, (addr)user);      return NULL;    }  if (b->who_freed != BY_NONE)    {      log_event(LOG_ERR, "Multiple freeing");      log_detail(LOG_ERR, "At\n");      do_traceback(LOG_ERR, orig_caller);      log_detail(LOG_ERR, "%s of pointer already freed\n",		 get_entry_name(by_who));      describe_block(LOG_ERR, b);      return NULL;    }  return b;}static void do_free_block(block *b, addr orig_caller, unsigned by_who){  if (b->who_alloced == BY_LITE)    {      lite_free_block(b);      return;    }  zap(b->block_addr, b->block_size);  b->who_freed = by_who;  if (by_who != BY_AUTO)    generate_traceback(b->where_freed, orig_caller);  /* We make sure that the traceback of an auto-freed block isn't used. */  user_currently_allocated -= b->user_size;  internal_mapped += (b->suffix_addr - (b->user_addr & ~PAGEMASK));  log_event(LOG_INFO, "Normal deallocation of this block");  describe_block(LOG_INFO, b);}static voidlite_free_block(block *b){  b->who_freed = BY_LITE;#if 0 /* Enable this later */  if (b->who_alloced == BY_LITE)    {      NO_CATCH();      REAL(free)((void *)b->user_addr);      OK_CATCH();    }#endif}static voidlite_free(void *p){  block *b;#ifdef DEBUG  /* We don't expect any errors here, but just for paranoia... */  b = block_to_free(p, 0, BY_LITE);#else  b = find_block_by_user_addr((addr)p);#endif  if (b)    lite_free_block(b);}WRAPPER_LINKAGEvoidWRAP(free) (void *p ){  MODE_VAR;  block *b;  if (SHOULD_NOT_CATCH)    {      REAL(free)(p);      return;    }  ENTER();  if (WAS_LITE_MODE)    lite_free(p);  else if ((b = block_to_free(p, (addr)__builtin_return_address(0), BY_FREE)) != NULL)    do_free_block(b, (addr)__builtin_return_address(0), BY_FREE);  LEAVE();}static void *do_realloc(void *p, size_t s, addr orig_caller){  void *q;  block *b;  if (p)    {      b = block_to_free(p, orig_caller, BY_REALLOC);      if (!b)	b = BAD_POINTER; /* not NULL, since reallocing from NULL			    is not the same as reallocing from a bad			    pointer. */    }  else    {      b = NULL;    }  q = do_malloc(s, default_alignment, orig_caller, BY_REALLOC, b);  if (b && b != BAD_POINTER)    {      size_t ncpy;      if (s < b->user_size)	ncpy = s;      else	ncpy = b->user_size;      memcpy(q, (void *)b->user_addr, ncpy);      do_free_block(b, orig_caller, BY_REALLOC);      }  return q;}static void *lite_realloc(void *p, size_t s){  block *b;  void *q;  size_t ncpy;#ifdef DEBUG  /* We don't expect any errors here, but just for paranoia... */  b = block_to_free(p, 0, BY_LITE);#else  b = find_block_by_user_addr((addr)p);#endif  if (!b)    {      /* Hmm.  Not a good thing. */      return NULL;    }  q = lite_malloc(s);  if (!q)    {      return NULL;    }  if (s < b->user_size)    ncpy = s;  else    ncpy = b->user_size;  memcpy(q, (void *)b->user_addr, ncpy);  lite_free_block(b);    return q;}WRAPPER_LINKAGEvoid *WRAP(realloc)(void *p, size_t s){  MODE_VAR;  void *q;  if (SHOULD_NOT_CATCH)    return REAL(realloc)(p, s);  ENTER();  if (WAS_LITE_MODE)    q = lite_realloc(p, s);  else    q = do_realloc(p, s, (addr)__builtin_return_address(0));  LEAVE();  return q;}static voiddescribe_address(int level, addr a){  block *b;  b = find_block_by_any_addr(a);  if (b)    {      int ofs;      log_detail(level, "Seems to be part of this block:\n");      describe_block(level, b);      ofs = a - b->user_addr;      log_detail(level, "Address in question is at offset %d",		 ofs);      if (ofs >= 0 && ofs < (int)b->user_size)	log_detail(level, " (in bounds)\n");      else	log_detail(level, " (out of bounds)\n");    }  else

⌨️ 快捷键说明

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