📄 hooks.c
字号:
(void)mutex_lock(&main_arena.mutex); oldp = mem2chunk_check(oldmem); (void)mutex_unlock(&main_arena.mutex); if(!oldp) { if(check_action & 1) fprintf(stderr, "realloc(): invalid pointer %p!\n", oldmem); if(check_action & 2) abort(); return malloc_check(bytes, NULL); } oldsize = chunksize(oldp); checked_request2size(bytes+1, nb); (void)mutex_lock(&main_arena.mutex);#if HAVE_MMAP if (chunk_is_mmapped(oldp)) {#if HAVE_MREMAP mchunkptr newp = mremap_chunk(oldp, nb); if(newp) newmem = chunk2mem(newp); else#endif { /* Note the extra SIZE_SZ overhead. */ if(oldsize - SIZE_SZ >= nb) newmem = oldmem; /* do nothing */ else { /* Must alloc, copy, free. */ if (top_check() >= 0) newmem = _int_malloc(&main_arena, bytes+1); if (newmem) { MALLOC_COPY(BOUNDED_N(newmem, bytes+1), oldmem, oldsize - 2*SIZE_SZ); munmap_chunk(oldp); } } } } else {#endif /* HAVE_MMAP */ if (top_check() >= 0) newmem = _int_realloc(&main_arena, oldmem, bytes+1);#if 0 /* Erase freed memory. */ if(newmem) newp = mem2chunk(newmem); nb = chunksize(newp); if(oldp<newp || oldp>=chunk_at_offset(newp, nb)) { memset((char*)oldmem + 2*sizeof(mbinptr), 0, oldsize - (2*sizeof(mbinptr)+2*SIZE_SZ+1)); } else if(nb > oldsize+SIZE_SZ) { memset((char*)BOUNDED_N(chunk2mem(newp), bytes) + oldsize, 0, nb - (oldsize+SIZE_SZ)); }#endif#if HAVE_MMAP }#endif (void)mutex_unlock(&main_arena.mutex); return mem2mem_check(newmem, bytes);}static Void_t*#if __STD_Cmemalign_check(size_t alignment, size_t bytes, const Void_t *caller)#elsememalign_check(alignment, bytes, caller) size_t alignment; size_t bytes; const Void_t *caller;#endif{ INTERNAL_SIZE_T nb; Void_t* mem; if (alignment <= MALLOC_ALIGNMENT) return malloc_check(bytes, NULL); if (alignment < MINSIZE) alignment = MINSIZE; checked_request2size(bytes+1, nb); (void)mutex_lock(&main_arena.mutex); mem = (top_check() >= 0) ? _int_memalign(&main_arena, alignment, bytes+1) : NULL; (void)mutex_unlock(&main_arena.mutex); return mem2mem_check(mem, bytes);}#if !defined NO_THREADS && USE_STARTER/* The following hooks are used when the global initialization in ptmalloc_init() hasn't completed yet. */static Void_t*#if __STD_Cmalloc_starter(size_t sz, const Void_t *caller)#elsemalloc_starter(sz, caller) size_t sz; const Void_t *caller;#endif{ Void_t* victim; ptmalloc_init_minimal(); victim = _int_malloc(&main_arena, sz); return victim ? BOUNDED_N(victim, sz) : 0;}static Void_t*#if __STD_Cmemalign_starter(size_t align, size_t sz, const Void_t *caller)#elsememalign_starter(align, sz, caller) size_t align, sz; const Void_t *caller;#endif{ Void_t* victim; ptmalloc_init_minimal(); victim = _int_memalign(&main_arena, align, sz); return victim ? BOUNDED_N(victim, sz) : 0;}static void#if __STD_Cfree_starter(Void_t* mem, const Void_t *caller)#elsefree_starter(mem, caller) Void_t* mem; const Void_t *caller;#endif{ mchunkptr p; if(!mem) return; p = mem2chunk(mem);#if HAVE_MMAP if (chunk_is_mmapped(p)) { munmap_chunk(p); return; }#endif _int_free(&main_arena, mem);}#endif /* !defined NO_THREADS && USE_STARTER *//* Get/set state: malloc_get_state() records the current state of all malloc variables (_except_ for the actual heap contents and `hook' function pointers) in a system dependent, opaque data structure. This data structure is dynamically allocated and can be free()d after use. malloc_set_state() restores the state of all malloc variables to the previously obtained state. This is especially useful when using this malloc as part of a shared library, and when the heap contents are saved/restored via some other method. The primary example for this is GNU Emacs with its `dumping' procedure. `Hook' function pointers are never saved or restored by these functions, with two exceptions: If malloc checking was in use when malloc_get_state() was called, then malloc_set_state() calls __malloc_check_init() if possible; if malloc checking was not in use in the recorded state but the user requested malloc checking, then the hooks are reset to 0. */#define MALLOC_STATE_MAGIC 0x444c4541l#define MALLOC_STATE_VERSION (0*0x100l + 2l) /* major*0x100 + minor */struct malloc_save_state { long magic; long version; mbinptr av[NBINS * 2 + 2]; char* sbrk_base; int sbrked_mem_bytes; unsigned long trim_threshold; unsigned long top_pad; unsigned int n_mmaps_max; unsigned long mmap_threshold; int check_action; unsigned long max_sbrked_mem; unsigned long max_total_mem; unsigned int n_mmaps; unsigned int max_n_mmaps; unsigned long mmapped_mem; unsigned long max_mmapped_mem; int using_malloc_checking;};Void_t*public_gET_STATe(void){ struct malloc_save_state* ms; int i; mbinptr b; ms = (struct malloc_save_state*)public_mALLOc(sizeof(*ms)); if (!ms) return 0; (void)mutex_lock(&main_arena.mutex); malloc_consolidate(&main_arena); ms->magic = MALLOC_STATE_MAGIC; ms->version = MALLOC_STATE_VERSION; ms->av[0] = 0; ms->av[1] = 0; /* used to be binblocks, now no longer used */ ms->av[2] = top(&main_arena); ms->av[3] = 0; /* used to be undefined */ for(i=1; i<NBINS; i++) { b = bin_at(&main_arena, i); if(first(b) == b) ms->av[2*i+2] = ms->av[2*i+3] = 0; /* empty bin */ else { ms->av[2*i+2] = first(b); ms->av[2*i+3] = last(b); } } ms->sbrk_base = mp_.sbrk_base; ms->sbrked_mem_bytes = main_arena.system_mem; ms->trim_threshold = mp_.trim_threshold; ms->top_pad = mp_.top_pad; ms->n_mmaps_max = mp_.n_mmaps_max; ms->mmap_threshold = mp_.mmap_threshold; ms->check_action = check_action; ms->max_sbrked_mem = main_arena.max_system_mem;#ifdef NO_THREADS ms->max_total_mem = mp_.max_total_mem;#else ms->max_total_mem = 0;#endif ms->n_mmaps = mp_.n_mmaps; ms->max_n_mmaps = mp_.max_n_mmaps; ms->mmapped_mem = mp_.mmapped_mem; ms->max_mmapped_mem = mp_.max_mmapped_mem; ms->using_malloc_checking = using_malloc_checking; (void)mutex_unlock(&main_arena.mutex); return (Void_t*)ms;}intpublic_sET_STATe(Void_t* msptr){ struct malloc_save_state* ms = (struct malloc_save_state*)msptr; int i; mbinptr b; disallow_malloc_check = 1; ptmalloc_init(); if(ms->magic != MALLOC_STATE_MAGIC) return -1; /* Must fail if the major version is too high. */ if((ms->version & ~0xffl) > (MALLOC_STATE_VERSION & ~0xffl)) return -2; (void)mutex_lock(&main_arena.mutex); /* There are no fastchunks. */ clear_fastchunks(&main_arena); set_max_fast(&main_arena, DEFAULT_MXFAST); for (i=0; i<(int)NFASTBINS; ++i) main_arena.fastbins[i] = 0; for (i=0; i<(int)BINMAPSIZE; ++i) main_arena.binmap[i] = 0; top(&main_arena) = ms->av[2]; main_arena.last_remainder = 0; for(i=1; i<NBINS; i++) { b = bin_at(&main_arena, i); if(ms->av[2*i+2] == 0) { assert(ms->av[2*i+3] == 0); first(b) = last(b) = b; } else { if(i<(int)NSMALLBINS || ((int)largebin_index(chunksize(ms->av[2*i+2]))==i && (int)largebin_index(chunksize(ms->av[2*i+3]))==i)) { first(b) = ms->av[2*i+2]; last(b) = ms->av[2*i+3]; /* Make sure the links to the bins within the heap are correct. */ first(b)->bk = b; last(b)->fd = b; /* Set bit in binblocks. */ mark_bin(&main_arena, i); } else { /* Oops, index computation from chunksize must have changed. Link the whole list into unsorted_chunks. */ first(b) = last(b) = b; b = unsorted_chunks(&main_arena); ms->av[2*i+2]->bk = b; ms->av[2*i+3]->fd = b->fd; b->fd->bk = ms->av[2*i+3]; b->fd = ms->av[2*i+2]; } } } mp_.sbrk_base = ms->sbrk_base; main_arena.system_mem = ms->sbrked_mem_bytes; mp_.trim_threshold = ms->trim_threshold; mp_.top_pad = ms->top_pad; mp_.n_mmaps_max = ms->n_mmaps_max; mp_.mmap_threshold = ms->mmap_threshold; check_action = ms->check_action; main_arena.max_system_mem = ms->max_sbrked_mem;#ifdef NO_THREADS mp_.max_total_mem = ms->max_total_mem;#endif mp_.n_mmaps = ms->n_mmaps; mp_.max_n_mmaps = ms->max_n_mmaps; mp_.mmapped_mem = ms->mmapped_mem; mp_.max_mmapped_mem = ms->max_mmapped_mem; /* add version-dependent code here */ if (ms->version >= 1) { /* Check whether it is safe to enable malloc checking, or whether it is necessary to disable it. */ if (ms->using_malloc_checking && !using_malloc_checking && !disallow_malloc_check) __malloc_check_init (); else if (!ms->using_malloc_checking && using_malloc_checking) { __malloc_hook = 0; __free_hook = 0; __realloc_hook = 0; __memalign_hook = 0; using_malloc_checking = 0; } } check_malloc_state(&main_arena); (void)mutex_unlock(&main_arena.mutex); return 0;}/* * Local variables: * c-basic-offset: 2 * End: */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -