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

📄 hooks.c

📁 MPI stands for the Message Passing Interface. Written by the MPI Forum (a large committee comprising
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Malloc implementation for multiple threads without lock contention.   Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.   This file is part of the GNU C Library.   Contributed by Wolfram Gloger <wg@malloc.de>, 2001.   The GNU C Library is free software; you can redistribute it and/or   modify it under the terms of the GNU Library General Public License as   published by the Free Software Foundation; either version 2 of the   License, or (at your option) any later version.   The GNU C Library is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU   Library General Public License for more details.   You should have received a copy of the GNU Library General Public   License along with the GNU C Library; see the file COPYING.LIB.  If not,   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,   Boston, MA 02111-1307, USA.  *//* $Id: hooks.c,v 1.12 2004/11/05 14:42:32 wg Exp $ */#ifndef DEFAULT_CHECK_ACTION#define DEFAULT_CHECK_ACTION 1#endif/* What to do if the standard debugging hooks are in place and a   corrupt pointer is detected: do nothing (0), print an error message   (1), or call abort() (2). *//* Hooks for debugging versions.  The initial hooks just call the   initialization routine, then do the normal work. */#if !(USE_STARTER & 2)static Void_t*#if __STD_Cmalloc_hook_ini(size_t sz, const __malloc_ptr_t caller)#elsemalloc_hook_ini(sz, caller)     size_t sz; const __malloc_ptr_t caller;#endif{  __malloc_hook = NULL;  ptmalloc_init();  return public_mALLOc(sz);}static Void_t*#if __STD_Crealloc_hook_ini(Void_t* ptr, size_t sz, const __malloc_ptr_t caller)#elserealloc_hook_ini(ptr, sz, caller)     Void_t* ptr; size_t sz; const __malloc_ptr_t caller;#endif{  __malloc_hook = NULL;  __realloc_hook = NULL;  ptmalloc_init();  return public_rEALLOc(ptr, sz);}static Void_t*#if __STD_Cmemalign_hook_ini(size_t alignment, size_t sz, const __malloc_ptr_t caller)#elsememalign_hook_ini(alignment, sz, caller)     size_t alignment; size_t sz; const __malloc_ptr_t caller;#endif{  __memalign_hook = NULL;  ptmalloc_init();  return public_mEMALIGn(alignment, sz);}#endif /* !(USE_STARTER & 2) */static int check_action = DEFAULT_CHECK_ACTION;/* Whether we are using malloc checking.  */static int using_malloc_checking;/* A flag that is set by malloc_set_state, to signal that malloc checking   must not be enabled on the request from the user (via the MALLOC_CHECK_   environment variable).  It is reset by __malloc_check_init to tell   malloc_set_state that the user has requested malloc checking.   The purpose of this flag is to make sure that malloc checking is not   enabled when the heap to be restored was constructed without malloc   checking, and thus does not contain the required magic bytes.   Otherwise the heap would be corrupted by calls to free and realloc.  If   it turns out that the heap was created with malloc checking and the   user has requested it malloc_set_state just calls __malloc_check_init   again to enable it.  On the other hand, reusing such a heap without   further malloc checking is safe.  */static int disallow_malloc_check;/* Activate a standard set of debugging hooks. */void__malloc_check_init(){  if (disallow_malloc_check) {    disallow_malloc_check = 0;    return;  }  using_malloc_checking = 1;  __malloc_hook = malloc_check;  __free_hook = free_check;  __realloc_hook = realloc_check;  __memalign_hook = memalign_check;  if(check_action & 1)    fprintf(stderr, "malloc: using debugging hooks\n");}/* A simple, standard set of debugging hooks.  Overhead is `only' one   byte per chunk; still this will catch most cases of double frees or   overruns.  The goal here is to avoid obscure crashes due to invalid   usage, unlike in the MALLOC_DEBUG code. */#define MAGICBYTE(p) ( ( ((size_t)p >> 3) ^ ((size_t)p >> 11)) & 0xFF )/* Instrument a chunk with overrun detector byte(s) and convert it   into a user pointer with requested size sz. */static Void_t*internal_function#if __STD_Cmem2mem_check(Void_t *ptr, size_t sz)#elsemem2mem_check(ptr, sz) Void_t *ptr; size_t sz;#endif{  mchunkptr p;  unsigned char* m_ptr = (unsigned char*)BOUNDED_N(ptr, sz);  size_t i;  if (!ptr)    return ptr;  p = mem2chunk(ptr);  for(i = chunksize(p) - (chunk_is_mmapped(p) ? 2*SIZE_SZ+1 : SIZE_SZ+1);      i > sz;      i -= 0xFF) {    if(i-sz < 0x100) {      m_ptr[i] = (unsigned char)(i-sz);      break;    }    m_ptr[i] = 0xFF;  }  m_ptr[sz] = MAGICBYTE(p);  return (Void_t*)m_ptr;}/* Convert a pointer to be free()d or realloc()ed to a valid chunk   pointer.  If the provided pointer is not valid, return NULL. */static mchunkptrinternal_function#if __STD_Cmem2chunk_check(Void_t* mem)#elsemem2chunk_check(mem) Void_t* mem;#endif{  mchunkptr p;  INTERNAL_SIZE_T sz, c;  unsigned char magic;  if(!aligned_OK(mem)) return NULL;  p = mem2chunk(mem);  if (!chunk_is_mmapped(p)) {    /* Must be a chunk in conventional heap memory. */    int contig = contiguous(&main_arena);    sz = chunksize(p);    if((contig &&	((char*)p<mp_.sbrk_base ||	 ((char*)p + sz)>=(mp_.sbrk_base+main_arena.system_mem) )) ||       sz<MINSIZE || sz&MALLOC_ALIGN_MASK || !inuse(p) ||       ( !prev_inuse(p) && (p->prev_size&MALLOC_ALIGN_MASK ||                            (contig && (char*)prev_chunk(p)<mp_.sbrk_base) ||                            next_chunk(prev_chunk(p))!=p) ))      return NULL;    magic = MAGICBYTE(p);    for(sz += SIZE_SZ-1; (c = ((unsigned char*)p)[sz]) != magic; sz -= c) {      if(c<=0 || sz<(c+2*SIZE_SZ)) return NULL;    }    ((unsigned char*)p)[sz] ^= 0xFF;  } else {    unsigned long offset, page_mask = malloc_getpagesize-1;    /* mmap()ed chunks have MALLOC_ALIGNMENT or higher power-of-two       alignment relative to the beginning of a page.  Check this       first. */    offset = (unsigned long)mem & page_mask;    if((offset!=MALLOC_ALIGNMENT && offset!=0 && offset!=0x10 &&        offset!=0x20 && offset!=0x40 && offset!=0x80 && offset!=0x100 &&        offset!=0x200 && offset!=0x400 && offset!=0x800 && offset!=0x1000 &&        offset<0x2000) ||       !chunk_is_mmapped(p) || (p->size & PREV_INUSE) ||       ( (((unsigned long)p - p->prev_size) & page_mask) != 0 ) ||       ( (sz = chunksize(p)), ((p->prev_size + sz) & page_mask) != 0 ) )      return NULL;    magic = MAGICBYTE(p);    for(sz -= 1; (c = ((unsigned char*)p)[sz]) != magic; sz -= c) {      if(c<=0 || sz<(c+2*SIZE_SZ)) return NULL;    }    ((unsigned char*)p)[sz] ^= 0xFF;  }  return p;}/* Check for corruption of the top chunk, and try to recover if   necessary. */static intinternal_function#if __STD_Ctop_check(void)#elsetop_check()#endif{  mchunkptr t = top(&main_arena);  char* brk, * new_brk;  INTERNAL_SIZE_T front_misalign, sbrk_size;  unsigned long pagesz = malloc_getpagesize;  if (t == initial_top(&main_arena) ||      (!chunk_is_mmapped(t) &&       chunksize(t)>=MINSIZE &&       prev_inuse(t) &&       (!contiguous(&main_arena) ||	(char*)t + chunksize(t) == mp_.sbrk_base + main_arena.system_mem)))    return 0;  if(check_action & 1)    fprintf(stderr, "malloc: top chunk is corrupt\n");  if(check_action & 2)    abort();  /* Try to set up a new top chunk. */  brk = MORECORE(0);  front_misalign = (unsigned long)chunk2mem(brk) & MALLOC_ALIGN_MASK;  if (front_misalign > 0)    front_misalign = MALLOC_ALIGNMENT - front_misalign;  sbrk_size = front_misalign + mp_.top_pad + MINSIZE;  sbrk_size += pagesz - ((unsigned long)(brk + sbrk_size) & (pagesz - 1));  new_brk = (char*)(MORECORE (sbrk_size));  if (new_brk == (char*)(MORECORE_FAILURE)) return -1;  /* Call the `morecore' hook if necessary.  */  if (__after_morecore_hook)    (*__after_morecore_hook) ();  main_arena.system_mem = (new_brk - mp_.sbrk_base) + sbrk_size;  top(&main_arena) = (mchunkptr)(brk + front_misalign);  set_head(top(&main_arena), (sbrk_size - front_misalign) | PREV_INUSE);  return 0;}static Void_t*#if __STD_Cmalloc_check(size_t sz, const Void_t *caller)#elsemalloc_check(sz, caller) size_t sz; const Void_t *caller;#endif{  Void_t *victim;  (void)mutex_lock(&main_arena.mutex);  victim = (top_check() >= 0) ? _int_malloc(&main_arena, sz+1) : NULL;  (void)mutex_unlock(&main_arena.mutex);  return mem2mem_check(victim, sz);}static void#if __STD_Cfree_check(Void_t* mem, const Void_t *caller)#elsefree_check(mem, caller) Void_t* mem; const Void_t *caller;#endif{  mchunkptr p;  if(!mem) return;  (void)mutex_lock(&main_arena.mutex);  p = mem2chunk_check(mem);  if(!p) {    (void)mutex_unlock(&main_arena.mutex);    if(check_action & 1)      fprintf(stderr, "free(): invalid pointer %p!\n", mem);    if(check_action & 2)      abort();    return;  }#if HAVE_MMAP  if (chunk_is_mmapped(p)) {    (void)mutex_unlock(&main_arena.mutex);    munmap_chunk(p);    return;  }#endif#if 0 /* Erase freed memory. */  memset(mem, 0, chunksize(p) - (SIZE_SZ+1));#endif  _int_free(&main_arena, mem);  (void)mutex_unlock(&main_arena.mutex);}static Void_t*#if __STD_Crealloc_check(Void_t* oldmem, size_t bytes, const Void_t *caller)#elserealloc_check(oldmem, bytes, caller)     Void_t* oldmem; size_t bytes; const Void_t *caller;#endif{  mchunkptr oldp;  INTERNAL_SIZE_T nb, oldsize;  Void_t* newmem = 0;  if (oldmem == 0) return malloc_check(bytes, NULL);

⌨️ 快捷键说明

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