Reformat malloc to gnu style.

This commit is contained in:
Ondřej Bílka 2014-01-02 09:38:18 +01:00
parent 9a3c6a6ff6
commit 6c8dbf00f5
18 changed files with 3843 additions and 3559 deletions

View File

@ -1,3 +1,37 @@
2013-01-02 Ondřej Bílka <neleai@seznam.cz>
* malloc/arena.c (malloc_atfork, free_atfork, ptmalloc_lock_all,
ptmalloc_unlock_all, ptmalloc_unlock_all2, next_env_entry,
__failing_morecore, ptmalloc_init, dump_heap, new_heap, grow_heap,
heap_trim, _int_new_arena, get_free_list, reused_arena, arena_get2):
Convert to GNU style.
* malloc/hooks.c (memalign_hook_ini, __malloc_check_init,
mem2mem_check, mem2chunk_check, top_check, realloc_check,
memalign_check, __malloc_set_state): Likewise.
* malloc/mallocbug.c (main): Likewise.
* malloc/malloc.c (__malloc_assert, malloc_init_state, free_perturb,
do_check_malloced_chunk, do_check_malloc_state, sysmalloc, systrim,
mremap_chunk, __libc_malloc, __libc_free, __libc_realloc, _mid_memalign,
_int_malloc, malloc_consolidate, _int_realloc, _int_memalign, mtrim,
musable, __libc_mallopt, __posix_memalign, malloc_info): Likewise.
* malloc/malloc.h: Likewise.
* malloc/mcheck.c (checkhdr, unlink_blk, link_blk, freehook, mallochook,
memalignhook, reallochook, mabort): Likewise.
* malloc/mcheck.h: Likewise.
* malloc/memusage.c (update_data, me, malloc, realloc, calloc, free, mmap,
mmap64, mremap, munmap, dest): Likewise.
* malloc/memusagestat.c (main, parse_opt, more_help): Likewise.
* malloc/morecore.c (__default_morecore): Likewise.
* malloc/mtrace.c (tr_break, lock_and_info, mtrace): Likewise.
* malloc/obstack.c (_obstack_begin, _obstack_newchunk,
_obstack_allocated_p, obstack_free, _obstack_memory_used,
print_and_abort): Likewise.
* malloc/obstack.h: Likewise.
* malloc/set-freeres.c (__libc_freeres): Likewise.
* malloc/tst-mallocstate.c (main): Likewise.
* malloc/tst-mtrace.c (main): Likewise.
* malloc/tst-realloc.c (do_test): Likewise.
2013-01-02 Siddhesh Poyarekar <siddhesh@redhat.com>
[BZ #16366]

File diff suppressed because it is too large Load Diff

View File

@ -24,29 +24,29 @@
/* Hooks for debugging versions. The initial hooks just call the
initialization routine, then do the normal work. */
static void*
malloc_hook_ini(size_t sz, const void *caller)
static void *
malloc_hook_ini (size_t sz, const void *caller)
{
__malloc_hook = NULL;
ptmalloc_init();
return __libc_malloc(sz);
ptmalloc_init ();
return __libc_malloc (sz);
}
static void*
realloc_hook_ini(void* ptr, size_t sz, const void *caller)
static void *
realloc_hook_ini (void *ptr, size_t sz, const void *caller)
{
__malloc_hook = NULL;
__realloc_hook = NULL;
ptmalloc_init();
return __libc_realloc(ptr, sz);
ptmalloc_init ();
return __libc_realloc (ptr, sz);
}
static void*
memalign_hook_ini(size_t alignment, size_t sz, const void *caller)
static void *
memalign_hook_ini (size_t alignment, size_t sz, const void *caller)
{
__memalign_hook = NULL;
ptmalloc_init();
return __libc_memalign(alignment, sz);
ptmalloc_init ();
return __libc_memalign (alignment, sz);
}
/* Whether we are using malloc checking. */
@ -71,10 +71,11 @@ static int disallow_malloc_check;
void
__malloc_check_init (void)
{
if (disallow_malloc_check) {
disallow_malloc_check = 0;
return;
}
if (disallow_malloc_check)
{
disallow_malloc_check = 0;
return;
}
using_malloc_checking = 1;
__malloc_hook = malloc_check;
__free_hook = free_check;
@ -87,7 +88,7 @@ __malloc_check_init (void)
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 )
#define MAGICBYTE(p) ((((size_t) p >> 3) ^ ((size_t) p >> 11)) & 0xFF)
/* Visualize the chunk as being partitioned into blocks of 256 bytes from the
highest address of the chunk, downwards. The beginning of each block tells
@ -96,53 +97,58 @@ __malloc_check_init (void)
must reach it with this iteration, otherwise we have witnessed a memory
corruption. */
static size_t
malloc_check_get_size(mchunkptr p)
malloc_check_get_size (mchunkptr p)
{
size_t size;
unsigned char c;
unsigned char magic = MAGICBYTE(p);
unsigned char magic = MAGICBYTE (p);
assert(using_malloc_checking == 1);
assert (using_malloc_checking == 1);
for (size = chunksize(p) - 1 + (chunk_is_mmapped(p) ? 0 : SIZE_SZ);
(c = ((unsigned char*)p)[size]) != magic;
size -= c) {
if(c<=0 || size<(c+2*SIZE_SZ)) {
malloc_printerr(check_action, "malloc_check_get_size: memory corruption",
chunk2mem(p));
return 0;
for (size = chunksize (p) - 1 + (chunk_is_mmapped (p) ? 0 : SIZE_SZ);
(c = ((unsigned char *) p)[size]) != magic;
size -= c)
{
if (c <= 0 || size < (c + 2 * SIZE_SZ))
{
malloc_printerr (check_action, "malloc_check_get_size: memory corruption",
chunk2mem (p));
return 0;
}
}
}
/* chunk2mem size. */
return size - 2*SIZE_SZ;
return size - 2 * SIZE_SZ;
}
/* Instrument a chunk with overrun detector byte(s) and convert it
into a user pointer with requested size sz. */
static void*
static void *
internal_function
mem2mem_check(void *ptr, size_t sz)
mem2mem_check (void *ptr, size_t sz)
{
mchunkptr p;
unsigned char* m_ptr = ptr;
unsigned char *m_ptr = ptr;
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;
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[i] = 0xFF;
}
m_ptr[sz] = MAGICBYTE(p);
return (void*)m_ptr;
m_ptr[sz] = MAGICBYTE (p);
return (void *) m_ptr;
}
/* Convert a pointer to be free()d or realloc()ed to a valid chunk
@ -150,53 +156,64 @@ mem2mem_check(void *ptr, size_t sz)
static mchunkptr
internal_function
mem2chunk_check(void* mem, unsigned char **magic_p)
mem2chunk_check (void *mem, unsigned char **magic_p)
{
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;
}
} else {
unsigned long offset, page_mask = GLRO(dl_pagesize)-1;
if (!aligned_OK (mem))
return NULL;
/* 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;
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 = GLRO (dl_pagesize) - 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;
if (magic_p)
*magic_p = (unsigned char *)p + sz;
*magic_p = (unsigned char *) p + sz;
return p;
}
@ -205,32 +222,32 @@ mem2chunk_check(void* mem, unsigned char **magic_p)
static int
internal_function
top_check(void)
top_check (void)
{
mchunkptr t = top(&main_arena);
char* brk, * new_brk;
mchunkptr t = top (&main_arena);
char *brk, *new_brk;
INTERNAL_SIZE_T front_misalign, sbrk_size;
unsigned long pagesz = GLRO(dl_pagesize);
unsigned long pagesz = GLRO (dl_pagesize);
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)))
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;
malloc_printerr (check_action, "malloc: top chunk is corrupt", t);
/* Try to set up a new top chunk. */
brk = MORECORE(0);
front_misalign = (unsigned long)chunk2mem(brk) & MALLOC_ALIGN_MASK;
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))
sbrk_size += pagesz - ((unsigned long) (brk + sbrk_size) & (pagesz - 1));
new_brk = (char *) (MORECORE (sbrk_size));
if (new_brk == (char *) (MORECORE_FAILURE))
{
__set_errno (ENOMEM);
return -1;
@ -238,128 +255,148 @@ top_check(void)
/* Call the `morecore' hook if necessary. */
void (*hook) (void) = atomic_forced_read (__after_morecore_hook);
if (hook)
(*hook) ();
(*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);
top (&main_arena) = (mchunkptr) (brk + front_misalign);
set_head (top (&main_arena), (sbrk_size - front_misalign) | PREV_INUSE);
return 0;
}
static void*
malloc_check(size_t sz, const void *caller)
static void *
malloc_check (size_t sz, const void *caller)
{
void *victim;
if (sz+1 == 0) {
__set_errno (ENOMEM);
return NULL;
}
if (sz + 1 == 0)
{
__set_errno (ENOMEM);
return NULL;
}
(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);
(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
free_check(void* mem, const void *caller)
free_check (void *mem, const void *caller)
{
mchunkptr p;
if(!mem) return;
(void)mutex_lock(&main_arena.mutex);
p = mem2chunk_check(mem, NULL);
if(!p) {
(void)mutex_unlock(&main_arena.mutex);
if (!mem)
return;
malloc_printerr(check_action, "free(): invalid pointer", mem);
return;
}
if (chunk_is_mmapped(p)) {
(void)mutex_unlock(&main_arena.mutex);
munmap_chunk(p);
return;
}
_int_free(&main_arena, p, 1);
(void)mutex_unlock(&main_arena.mutex);
(void) mutex_lock (&main_arena.mutex);
p = mem2chunk_check (mem, NULL);
if (!p)
{
(void) mutex_unlock (&main_arena.mutex);
malloc_printerr (check_action, "free(): invalid pointer", mem);
return;
}
if (chunk_is_mmapped (p))
{
(void) mutex_unlock (&main_arena.mutex);
munmap_chunk (p);
return;
}
_int_free (&main_arena, p, 1);
(void) mutex_unlock (&main_arena.mutex);
}
static void*
realloc_check(void* oldmem, size_t bytes, const void *caller)
static void *
realloc_check (void *oldmem, size_t bytes, const void *caller)
{
INTERNAL_SIZE_T nb;
void* newmem = 0;
void *newmem = 0;
unsigned char *magic_p;
if (bytes+1 == 0) {
__set_errno (ENOMEM);
return NULL;
}
if (oldmem == 0) return malloc_check(bytes, NULL);
if (bytes == 0) {
free_check (oldmem, NULL);
return NULL;
}
(void)mutex_lock(&main_arena.mutex);
const mchunkptr oldp = mem2chunk_check(oldmem, &magic_p);
(void)mutex_unlock(&main_arena.mutex);
if(!oldp) {
malloc_printerr(check_action, "realloc(): invalid pointer", oldmem);
return malloc_check(bytes, NULL);
}
const INTERNAL_SIZE_T oldsize = chunksize(oldp);
checked_request2size(bytes+1, nb);
(void)mutex_lock(&main_arena.mutex);
if (chunk_is_mmapped(oldp)) {
#if HAVE_MREMAP
mchunkptr newp = mremap_chunk(oldp, nb);
if(newp)
newmem = chunk2mem(newp);
else
#endif
if (bytes + 1 == 0)
{
/* 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) {
memcpy(newmem, oldmem, oldsize - 2*SIZE_SZ);
munmap_chunk(oldp);
}
__set_errno (ENOMEM);
return NULL;
}
if (oldmem == 0)
return malloc_check (bytes, NULL);
if (bytes == 0)
{
free_check (oldmem, NULL);
return NULL;
}
(void) mutex_lock (&main_arena.mutex);
const mchunkptr oldp = mem2chunk_check (oldmem, &magic_p);
(void) mutex_unlock (&main_arena.mutex);
if (!oldp)
{
malloc_printerr (check_action, "realloc(): invalid pointer", oldmem);
return malloc_check (bytes, NULL);
}
const INTERNAL_SIZE_T oldsize = chunksize (oldp);
checked_request2size (bytes + 1, nb);
(void) mutex_lock (&main_arena.mutex);
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)
{
memcpy (newmem, oldmem, oldsize - 2 * SIZE_SZ);
munmap_chunk (oldp);
}
}
}
}
} else {
if (top_check() >= 0) {
INTERNAL_SIZE_T nb;
checked_request2size(bytes + 1, nb);
newmem = _int_realloc(&main_arena, oldp, oldsize, nb);
else
{
if (top_check () >= 0)
{
INTERNAL_SIZE_T nb;
checked_request2size (bytes + 1, nb);
newmem = _int_realloc (&main_arena, oldp, oldsize, nb);
}
}
}
/* mem2chunk_check changed the magic byte in the old chunk.
If newmem is NULL, then the old chunk will still be used though,
so we need to invert that change here. */
if (newmem == NULL) *magic_p ^= 0xFF;
if (newmem == NULL)
*magic_p ^= 0xFF;
(void)mutex_unlock(&main_arena.mutex);
(void) mutex_unlock (&main_arena.mutex);
return mem2mem_check(newmem, bytes);
return mem2mem_check (newmem, bytes);
}
static void*
memalign_check(size_t alignment, size_t bytes, const void *caller)
static void *
memalign_check (size_t alignment, size_t bytes, const void *caller)
{
void* mem;
void *mem;
if (alignment <= MALLOC_ALIGNMENT) return malloc_check(bytes, NULL);
if (alignment < MINSIZE) alignment = MINSIZE;
if (alignment <= MALLOC_ALIGNMENT)
return malloc_check (bytes, NULL);
if (alignment < MINSIZE)
alignment = MINSIZE;
/* If the alignment is greater than SIZE_MAX / 2 + 1 it cannot be a
power of 2 and will cause overflow in the check below. */
@ -377,17 +414,19 @@ memalign_check(size_t alignment, size_t bytes, const void *caller)
}
/* Make sure alignment is power of 2. */
if (!powerof2(alignment)) {
size_t a = MALLOC_ALIGNMENT * 2;
while (a < alignment) a <<= 1;
alignment = a;
}
if (!powerof2 (alignment))
{
size_t a = MALLOC_ALIGNMENT * 2;
while (a < alignment)
a <<= 1;
alignment = a;
}
(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);
(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);
}
@ -408,59 +447,63 @@ memalign_check(size_t alignment, size_t bytes, const void *caller)
then the hooks are reset to 0. */
#define MALLOC_STATE_MAGIC 0x444c4541l
#define MALLOC_STATE_VERSION (0*0x100l + 4l) /* major*0x100 + minor */
#define MALLOC_STATE_VERSION (0 * 0x100l + 4l) /* major*0x100 + minor */
struct malloc_save_state {
long magic;
long version;
mbinptr av[NBINS * 2 + 2];
char* sbrk_base;
int sbrked_mem_bytes;
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 int n_mmaps_max;
unsigned long mmap_threshold;
int check_action;
int check_action;
unsigned long max_sbrked_mem;
unsigned long max_total_mem;
unsigned int n_mmaps;
unsigned int max_n_mmaps;
unsigned int n_mmaps;
unsigned int max_n_mmaps;
unsigned long mmapped_mem;
unsigned long max_mmapped_mem;
int using_malloc_checking;
int using_malloc_checking;
unsigned long max_fast;
unsigned long arena_test;
unsigned long arena_max;
unsigned long narenas;
};
void*
__malloc_get_state(void)
void *
__malloc_get_state (void)
{
struct malloc_save_state* ms;
struct malloc_save_state *ms;
int i;
mbinptr b;
ms = (struct malloc_save_state*)__libc_malloc(sizeof(*ms));
ms = (struct malloc_save_state *) __libc_malloc (sizeof (*ms));
if (!ms)
return 0;
(void)mutex_lock(&main_arena.mutex);
malloc_consolidate(&main_arena);
(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[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);
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;
@ -475,78 +518,92 @@ __malloc_get_state(void)
ms->mmapped_mem = mp_.mmapped_mem;
ms->max_mmapped_mem = mp_.max_mmapped_mem;
ms->using_malloc_checking = using_malloc_checking;
ms->max_fast = get_max_fast();
ms->max_fast = get_max_fast ();
ms->arena_test = mp_.arena_test;
ms->arena_max = mp_.arena_max;
ms->narenas = narenas;
(void)mutex_unlock(&main_arena.mutex);
return (void*)ms;
(void) mutex_unlock (&main_arena.mutex);
return (void *) ms;
}
int
__malloc_set_state(void* msptr)
__malloc_set_state (void *msptr)
{
struct malloc_save_state* ms = (struct malloc_save_state*)msptr;
struct malloc_save_state *ms = (struct malloc_save_state *) msptr;
size_t i;
mbinptr b;
disallow_malloc_check = 1;
ptmalloc_init();
if(ms->magic != MALLOC_STATE_MAGIC) return -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);
if ((ms->version & ~0xffl) > (MALLOC_STATE_VERSION & ~0xffl))
return -2;
(void) mutex_lock (&main_arena.mutex);
/* There are no fastchunks. */
clear_fastchunks(&main_arena);
clear_fastchunks (&main_arena);
if (ms->version >= 4)
set_max_fast(ms->max_fast);
set_max_fast (ms->max_fast);
else
set_max_fast(64); /* 64 used to be the value we always used. */
for (i=0; i<NFASTBINS; ++i)
set_max_fast (64); /* 64 used to be the value we always used. */
for (i = 0; i < NFASTBINS; ++i)
fastbin (&main_arena, i) = 0;
for (i=0; i<BINMAPSIZE; ++i)
for (i = 0; i < BINMAPSIZE; ++i)
main_arena.binmap[i] = 0;
top(&main_arena) = ms->av[2];
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(ms->version >= 3 &&
(i<NSMALLBINS || (largebin_index(chunksize(ms->av[2*i+2]))==i &&
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];
}
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 (ms->version >= 3 &&
(i < NSMALLBINS || (largebin_index (chunksize (ms->av[2 * i + 2])) == i &&
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];
}
}
}
}
if (ms->version < 3) {
/* Clear fd_nextsize and bk_nextsize fields. */
b = unsorted_chunks(&main_arena)->fd;
while (b != unsorted_chunks(&main_arena)) {
if (!in_smallbin_range(chunksize(b))) {
b->fd_nextsize = NULL;
b->bk_nextsize = NULL;
}
b = b->fd;
if (ms->version < 3)
{
/* Clear fd_nextsize and bk_nextsize fields. */
b = unsorted_chunks (&main_arena)->fd;
while (b != unsorted_chunks (&main_arena))
{
if (!in_smallbin_range (chunksize (b)))
{
b->fd_nextsize = NULL;
b->bk_nextsize = NULL;
}
b = b->fd;
}
}
}
mp_.sbrk_base = ms->sbrk_base;
main_arena.system_mem = ms->sbrked_mem_bytes;
mp_.trim_threshold = ms->trim_threshold;
@ -560,28 +617,31 @@ __malloc_set_state(void* msptr)
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 = NULL;
__free_hook = NULL;
__realloc_hook = NULL;
__memalign_hook = NULL;
using_malloc_checking = 0;
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 = NULL;
__free_hook = NULL;
__realloc_hook = NULL;
__memalign_hook = NULL;
using_malloc_checking = 0;
}
}
}
if (ms->version >= 4) {
mp_.arena_test = ms->arena_test;
mp_.arena_max = ms->arena_max;
narenas = ms->narenas;
}
check_malloc_state(&main_arena);
if (ms->version >= 4)
{
mp_.arena_test = ms->arena_test;
mp_.arena_max = ms->arena_max;
narenas = ms->narenas;
}
check_malloc_state (&main_arena);
(void)mutex_unlock(&main_arena.mutex);
(void) mutex_unlock (&main_arena.mutex);
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@ -39,7 +39,7 @@ extern void *malloc (size_t __size) __THROW __attribute_malloc__ __wur;
/* Allocate NMEMB elements of SIZE bytes each, all initialized to 0. */
extern void *calloc (size_t __nmemb, size_t __size)
__THROW __attribute_malloc__ __wur;
__THROW __attribute_malloc__ __wur;
/* Re-allocate the previously allocated block in __ptr, making the new
block SIZE bytes long. */
@ -47,7 +47,7 @@ extern void *calloc (size_t __nmemb, size_t __size)
the same pointer that was passed to it, aliasing needs to be allowed
between objects pointed by the old and new pointers. */
extern void *realloc (void *__ptr, size_t __size)
__THROW __attribute_warn_unused_result__;
__THROW __attribute_warn_unused_result__;
/* Free a block allocated by `malloc', `realloc' or `calloc'. */
extern void free (void *__ptr) __THROW;
@ -57,14 +57,14 @@ extern void cfree (void *__ptr) __THROW;
/* Allocate SIZE bytes allocated to ALIGNMENT bytes. */
extern void *memalign (size_t __alignment, size_t __size)
__THROW __attribute_malloc__ __wur;
__THROW __attribute_malloc__ __wur;
/* Allocate SIZE bytes on a page boundary. */
extern void *valloc (size_t __size) __THROW __attribute_malloc__ __wur;
/* Equivalent to valloc(minimum-page-that-holds(n)), that is, round up
__size to nearest pagesize. */
extern void * pvalloc (size_t __size) __THROW __attribute_malloc__ __wur;
extern void *pvalloc (size_t __size) __THROW __attribute_malloc__ __wur;
/* Underlying allocation function; successive calls should return
contiguous pieces of memory. */
@ -72,7 +72,7 @@ extern void *(*__morecore) (ptrdiff_t __size);
/* Default value of `__morecore'. */
extern void *__default_morecore (ptrdiff_t __size)
__THROW __attribute_malloc__;
__THROW __attribute_malloc__;
/* SVID2/XPG mallinfo structure */
@ -95,16 +95,16 @@ extern struct mallinfo mallinfo (void) __THROW;
/* SVID2/XPG mallopt options */
#ifndef M_MXFAST
# define M_MXFAST 1 /* maximum request size for "fastbins" */
# define M_MXFAST 1 /* maximum request size for "fastbins" */
#endif
#ifndef M_NLBLKS
# define M_NLBLKS 2 /* UNUSED in this malloc */
# define M_NLBLKS 2 /* UNUSED in this malloc */
#endif
#ifndef M_GRAIN
# define M_GRAIN 3 /* UNUSED in this malloc */
# define M_GRAIN 3 /* UNUSED in this malloc */
#endif
#ifndef M_KEEP
# define M_KEEP 4 /* UNUSED in this malloc */
# define M_KEEP 4 /* UNUSED in this malloc */
#endif
/* mallopt options that actually do something */
@ -113,9 +113,9 @@ extern struct mallinfo mallinfo (void) __THROW;
#define M_MMAP_THRESHOLD -3
#define M_MMAP_MAX -4
#define M_CHECK_ACTION -5
#define M_PERTURB -6
#define M_ARENA_TEST -7
#define M_ARENA_MAX -8
#define M_PERTURB -6
#define M_ARENA_TEST -7
#define M_ARENA_MAX -8
/* General SVID/XPG interface to tunable parameters. */
extern int mallopt (int __param, int __val) __THROW;
@ -145,22 +145,22 @@ extern int malloc_set_state (void *__ptr) __THROW;
the application provides the preferred way to set up the hook
pointers. */
extern void (*__MALLOC_HOOK_VOLATILE __malloc_initialize_hook) (void)
__MALLOC_DEPRECATED;
__MALLOC_DEPRECATED;
/* Hooks for debugging and user-defined versions. */
extern void (*__MALLOC_HOOK_VOLATILE __free_hook) (void *__ptr,
const void *)
__MALLOC_DEPRECATED;
extern void *(*__MALLOC_HOOK_VOLATILE __malloc_hook) (size_t __size,
const void *)
__MALLOC_DEPRECATED;
extern void *(*__MALLOC_HOOK_VOLATILE __realloc_hook) (void *__ptr,
size_t __size,
const void *)
__MALLOC_DEPRECATED;
extern void *(*__MALLOC_HOOK_VOLATILE __memalign_hook) (size_t __alignment,
size_t __size,
const void *)
__MALLOC_DEPRECATED;
const void *)
__MALLOC_DEPRECATED;
extern void *(*__MALLOC_HOOK_VOLATILE __malloc_hook)(size_t __size,
const void *)
__MALLOC_DEPRECATED;
extern void *(*__MALLOC_HOOK_VOLATILE __realloc_hook)(void *__ptr,
size_t __size,
const void *)
__MALLOC_DEPRECATED;
extern void *(*__MALLOC_HOOK_VOLATILE __memalign_hook)(size_t __alignment,
size_t __size,
const void *)
__MALLOC_DEPRECATED;
extern void (*__MALLOC_HOOK_VOLATILE __after_morecore_hook) (void);
/* Activate a standard set of debugging hooks. */
@ -168,5 +168,4 @@ extern void __malloc_check_init (void) __THROW __MALLOC_DEPRECATED;
__END_DECLS
#endif /* malloc.h */

View File

@ -22,14 +22,14 @@ main (int argc, char *argv[])
size_t i;
/* Here's what memory is supposed to look like (hex):
size contents
3000 original_info_table, later fill_info_table1
size contents
3000 original_info_table, later fill_info_table1
3fa000 dummy0
3fa000 dummy1
6000 info_table_2
3000 over_top
6000 info_table_2
3000 over_top
*/
*/
/* mem: original_info_table */
dummy0 = malloc (0x3fa000);
/* mem: original_info_table, dummy0 */
@ -54,15 +54,15 @@ main (int argc, char *argv[])
for (i = 0; i < over_top_size; ++i)
if (over_top[i] != 0)
{
printf ("FAIL: malloc expands info table\n");
return 0;
printf ("FAIL: malloc expands info table\n");
return 0;
}
for (i = 0; i < over_top_dup_size; ++i)
if (over_top_dup[i] != 1)
{
printf ("FAIL: malloc expands info table\n");
return 0;
printf ("FAIL: malloc expands info table\n");
return 0;
}
printf ("PASS: malloc expands info table\n");

View File

@ -17,7 +17,7 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#ifndef _MALLOC_INTERNAL
#ifndef _MALLOC_INTERNAL
# define _MALLOC_INTERNAL
# include <malloc.h>
# include <mcheck.h>
@ -28,32 +28,32 @@
#endif
/* Old hook values. */
static void (*old_free_hook) (__ptr_t ptr, const __ptr_t);
static void (*old_free_hook)(__ptr_t ptr, const __ptr_t);
static __ptr_t (*old_malloc_hook) (size_t size, const __ptr_t);
static __ptr_t (*old_memalign_hook) (size_t alignment, size_t size,
const __ptr_t);
const __ptr_t);
static __ptr_t (*old_realloc_hook) (__ptr_t ptr, size_t size,
const __ptr_t);
const __ptr_t);
/* Function to call when something awful happens. */
static void (*abortfunc) (enum mcheck_status);
/* Arbitrary magical numbers. */
#define MAGICWORD 0xfedabeeb
#define MAGICFREE 0xd8675309
#define MAGICBYTE ((char) 0xd7)
#define MALLOCFLOOD ((char) 0x93)
#define FREEFLOOD ((char) 0x95)
#define MAGICWORD 0xfedabeeb
#define MAGICFREE 0xd8675309
#define MAGICBYTE ((char) 0xd7)
#define MALLOCFLOOD ((char) 0x93)
#define FREEFLOOD ((char) 0x95)
struct hdr
{
size_t size; /* Exact size requested by user. */
unsigned long int magic; /* Magic number to check header integrity. */
struct hdr *prev;
struct hdr *next;
__ptr_t block; /* Real block allocated, for memalign. */
unsigned long int magic2; /* Extra, keeps us doubleword aligned. */
};
{
size_t size; /* Exact size requested by user. */
unsigned long int magic; /* Magic number to check header integrity. */
struct hdr *prev;
struct hdr *next;
__ptr_t block; /* Real block allocated, for memalign. */
unsigned long int magic2; /* Extra, keeps us doubleword aligned. */
};
/* This is the beginning of the list of all memory blocks allocated.
It is only constructed if the pedantic testing is requested. */
@ -69,11 +69,10 @@ static int pedantic;
# define flood memset
#else
static void flood (__ptr_t, int, size_t);
static void
flood (ptr, val, size)
__ptr_t ptr;
int val;
size_t size;
static void flood (ptr, val, size)
__ptr_t ptr;
int val;
size_t size;
{
char *cp = ptr;
while (size--)
@ -101,11 +100,11 @@ checkhdr (const struct hdr *hdr)
break;
case MAGICWORD:
if (((char *) &hdr[1])[hdr->size] != MAGICBYTE)
status = MCHECK_TAIL;
status = MCHECK_TAIL;
else if ((hdr->magic2 ^ (uintptr_t) hdr->block) != MAGICWORD)
status = MCHECK_HEAD;
status = MCHECK_HEAD;
else
status = MCHECK_OK;
status = MCHECK_OK;
break;
}
if (status != MCHECK_OK)
@ -148,13 +147,13 @@ unlink_blk (struct hdr *ptr)
{
ptr->next->prev = ptr->prev;
ptr->next->magic = MAGICWORD ^ ((uintptr_t) ptr->next->prev
+ (uintptr_t) ptr->next->next);
+ (uintptr_t) ptr->next->next);
}
if (ptr->prev != NULL)
{
ptr->prev->next = ptr->next;
ptr->prev->magic = MAGICWORD ^ ((uintptr_t) ptr->prev->prev
+ (uintptr_t) ptr->prev->next);
+ (uintptr_t) ptr->prev->next);
}
else
root = ptr->next;
@ -173,7 +172,7 @@ link_blk (struct hdr *hdr)
{
hdr->next->prev = hdr;
hdr->next->magic = MAGICWORD ^ ((uintptr_t) hdr
+ (uintptr_t) hdr->next->next);
+ (uintptr_t) hdr->next->next);
}
}
static void
@ -194,7 +193,7 @@ freehook (__ptr_t ptr, const __ptr_t caller)
}
__free_hook = old_free_hook;
if (old_free_hook != NULL)
(*old_free_hook) (ptr, caller);
(*old_free_hook)(ptr, caller);
else
free (ptr);
__free_hook = freehook;
@ -216,8 +215,8 @@ mallochook (size_t size, const __ptr_t caller)
__malloc_hook = old_malloc_hook;
if (old_malloc_hook != NULL)
hdr = (struct hdr *) (*old_malloc_hook) (sizeof (struct hdr) + size + 1,
caller);
hdr = (struct hdr *) (*old_malloc_hook)(sizeof (struct hdr) + size + 1,
caller);
else
hdr = (struct hdr *) malloc (sizeof (struct hdr) + size + 1);
__malloc_hook = mallochook;
@ -235,7 +234,7 @@ mallochook (size_t size, const __ptr_t caller)
static __ptr_t
memalignhook (size_t alignment, size_t size,
const __ptr_t caller)
const __ptr_t caller)
{
struct hdr *hdr;
size_t slop;
@ -244,7 +243,7 @@ memalignhook (size_t alignment, size_t size,
if (pedantic)
mcheck_check_all ();
slop = (sizeof *hdr + alignment - 1) & -alignment;
slop = (sizeof *hdr + alignment - 1) & - alignment;
if (size > ~((size_t) 0) - (slop + 1))
{
@ -254,7 +253,7 @@ memalignhook (size_t alignment, size_t size,
__memalign_hook = old_memalign_hook;
if (old_memalign_hook != NULL)
block = (*old_memalign_hook) (alignment, slop + size + 1, caller);
block = (*old_memalign_hook)(alignment, slop + size + 1, caller);
else
block = memalign (alignment, slop + size + 1);
__memalign_hook = memalignhook;
@ -301,7 +300,7 @@ reallochook (__ptr_t ptr, size_t size, const __ptr_t caller)
checkhdr (hdr);
unlink_blk (hdr);
if (size < osize)
flood ((char *) ptr + size, FREEFLOOD, osize - size);
flood ((char *) ptr + size, FREEFLOOD, osize - size);
}
else
{
@ -313,12 +312,12 @@ reallochook (__ptr_t ptr, size_t size, const __ptr_t caller)
__memalign_hook = old_memalign_hook;
__realloc_hook = old_realloc_hook;
if (old_realloc_hook != NULL)
hdr = (struct hdr *) (*old_realloc_hook) ((__ptr_t) hdr,
sizeof (struct hdr) + size + 1,
caller);
hdr = (struct hdr *) (*old_realloc_hook)((__ptr_t) hdr,
sizeof (struct hdr) + size + 1,
caller);
else
hdr = (struct hdr *) realloc ((__ptr_t) hdr,
sizeof (struct hdr) + size + 1);
sizeof (struct hdr) + size + 1);
__free_hook = freehook;
__malloc_hook = mallochook;
__memalign_hook = memalignhook;
@ -344,19 +343,19 @@ mabort (enum mcheck_status status)
switch (status)
{
case MCHECK_OK:
msg = _("memory is consistent, library is buggy\n");
msg = _ ("memory is consistent, library is buggy\n");
break;
case MCHECK_HEAD:
msg = _("memory clobbered before allocated block\n");
msg = _ ("memory clobbered before allocated block\n");
break;
case MCHECK_TAIL:
msg = _("memory clobbered past end of allocated block\n");
msg = _ ("memory clobbered past end of allocated block\n");
break;
case MCHECK_FREE:
msg = _("block freed twice\n");
msg = _ ("block freed twice\n");
break;
default:
msg = _("bogus mcheck_status, library is buggy\n");
msg = _ ("bogus mcheck_status, library is buggy\n");
break;
}
#ifdef _LIBC
@ -370,11 +369,10 @@ mabort (enum mcheck_status status)
/* Memory barrier so that GCC does not optimize out the argument. */
#define malloc_opt_barrier(x) \
({ __typeof (x) __x = x; __asm ("" : "+m" (__x)); __x; })
({ __typeof (x) __x = x; __asm ("" : "+m" (__x)); __x; })
int
mcheck (func)
void (*func) (enum mcheck_status);
int mcheck (func)
void (*func)(enum mcheck_status);
{
abortfunc = (func != NULL) ? func : &mabort;
@ -404,9 +402,8 @@ mcheck (func)
libc_hidden_def (mcheck)
#endif
int
mcheck_pedantic (func)
void (*func) (enum mcheck_status);
int mcheck_pedantic (func)
void (*func)(enum mcheck_status);
{
int res = mcheck (func);
if (res == 0)

View File

@ -16,7 +16,7 @@
<http://www.gnu.org/licenses/>. */
#ifndef _MCHECK_H
#define _MCHECK_H 1
#define _MCHECK_H 1
#include <features.h>
@ -25,24 +25,24 @@ __BEGIN_DECLS
/* Return values for `mprobe': these are the kinds of inconsistencies that
`mcheck' enables detection of. */
enum mcheck_status
{
MCHECK_DISABLED = -1, /* Consistency checking is not turned on. */
MCHECK_OK, /* Block is fine. */
MCHECK_FREE, /* Block freed twice. */
MCHECK_HEAD, /* Memory before the block was clobbered. */
MCHECK_TAIL /* Memory after the block was clobbered. */
};
{
MCHECK_DISABLED = -1, /* Consistency checking is not turned on. */
MCHECK_OK, /* Block is fine. */
MCHECK_FREE, /* Block freed twice. */
MCHECK_HEAD, /* Memory before the block was clobbered. */
MCHECK_TAIL /* Memory after the block was clobbered. */
};
/* Activate a standard collection of debugging hooks. This must be called
before `malloc' is ever called. ABORTFUNC is called with an error code
(see enum above) when an inconsistency is detected. If ABORTFUNC is
null, the standard function prints on stderr and then calls `abort'. */
extern int mcheck (void (*__abortfunc) (enum mcheck_status)) __THROW;
extern int mcheck (void (*__abortfunc)(enum mcheck_status)) __THROW;
/* Similar to `mcheck' but performs checks for all block whenever one of
the memory handling functions is called. This can be very slow. */
extern int mcheck_pedantic (void (*__abortfunc) (enum mcheck_status)) __THROW;
extern int mcheck_pedantic (void (*__abortfunc)(enum mcheck_status)) __THROW;
/* Force check of all blocks now. */
extern void mcheck_check_all (void);
@ -57,5 +57,4 @@ extern void mtrace (void) __THROW;
extern void muntrace (void) __THROW;
__END_DECLS
#endif /* mcheck.h */

View File

@ -38,7 +38,7 @@
/* Pointer to the real functions. These are determined used `dlsym'
when really needed. */
static void *(*mallocp) (size_t);
static void *(*mallocp)(size_t);
static void *(*reallocp) (void *, size_t);
static void *(*callocp) (size_t, size_t);
static void (*freep) (void *);
@ -89,11 +89,11 @@ static memusage_size_t peak_use[3];
static __thread uintptr_t start_sp;
/* A few macros to make the source more readable. */
#define peak_heap peak_use[0]
#define peak_stack peak_use[1]
#define peak_total peak_use[2]
#define peak_heap peak_use[0]
#define peak_stack peak_use[1]
#define peak_total peak_use[2]
#define DEFAULT_BUFFER_SIZE 32768
#define DEFAULT_BUFFER_SIZE 32768
static size_t buffer_size;
static int fd = -1;
@ -164,16 +164,16 @@ update_data (struct header *result, size_t len, size_t old_len)
{
uatomic32_t idx = catomic_exchange_and_add (&buffer_cnt, 1);
if (idx + 1 >= 2 * buffer_size)
{
/* We try to reset the counter to the correct range. If
this fails because of another thread increasing the
counter it does not matter since that thread will take
care of the correction. */
uatomic32_t reset = (idx + 1) % (2 * buffer_size);
catomic_compare_and_exchange_val_acq (&buffer_cnt, reset, idx + 1);
if (idx >= 2 * buffer_size)
idx = reset - 1;
}
{
/* We try to reset the counter to the correct range. If
this fails because of another thread increasing the
counter it does not matter since that thread will take
care of the correction. */
uatomic32_t reset = (idx + 1) % (2 * buffer_size);
catomic_compare_and_exchange_val_acq (&buffer_cnt, reset, idx + 1);
if (idx >= 2 * buffer_size)
idx = reset - 1;
}
assert (idx < 2 * DEFAULT_BUFFER_SIZE);
buffer[idx].heap = current_heap;
@ -182,9 +182,9 @@ update_data (struct header *result, size_t len, size_t old_len)
/* Write out buffer if it is full. */
if (idx + 1 == buffer_size)
write (fd, buffer, buffer_size * sizeof (struct entry));
write (fd, buffer, buffer_size * sizeof (struct entry));
else if (idx + 1 == 2 * buffer_size)
write (fd, &buffer[buffer_size], buffer_size * sizeof (struct entry));
write (fd, &buffer[buffer_size], buffer_size * sizeof (struct entry));
}
}
@ -221,19 +221,19 @@ me (void)
size_t prog_len = strlen (__progname);
initialized = -1;
mallocp = (void *(*) (size_t)) dlsym (RTLD_NEXT, "malloc");
reallocp = (void *(*) (void *, size_t)) dlsym (RTLD_NEXT, "realloc");
callocp = (void *(*) (size_t, size_t)) dlsym (RTLD_NEXT, "calloc");
freep = (void (*) (void *)) dlsym (RTLD_NEXT, "free");
mallocp = (void *(*)(size_t))dlsym (RTLD_NEXT, "malloc");
reallocp = (void *(*)(void *, size_t))dlsym (RTLD_NEXT, "realloc");
callocp = (void *(*)(size_t, size_t))dlsym (RTLD_NEXT, "calloc");
freep = (void (*)(void *))dlsym (RTLD_NEXT, "free");
mmapp = (void *(*) (void *, size_t, int, int, int, off_t)) dlsym (RTLD_NEXT,
"mmap");
mmapp = (void *(*)(void *, size_t, int, int, int, off_t))dlsym (RTLD_NEXT,
"mmap");
mmap64p =
(void *(*) (void *, size_t, int, int, int, off64_t)) dlsym (RTLD_NEXT,
"mmap64");
mremapp = (void *(*) (void *, size_t, size_t, int, void *)) dlsym (RTLD_NEXT,
"mremap");
munmapp = (int (*) (void *, size_t)) dlsym (RTLD_NEXT, "munmap");
(void *(*)(void *, size_t, int, int, int, off64_t))dlsym (RTLD_NEXT,
"mmap64");
mremapp = (void *(*)(void *, size_t, size_t, int, void *))dlsym (RTLD_NEXT,
"mremap");
munmapp = (int (*)(void *, size_t))dlsym (RTLD_NEXT, "munmap");
initialized = 1;
if (env != NULL)
@ -241,8 +241,8 @@ me (void)
/* Check for program name. */
size_t len = strlen (env);
if (len > prog_len || strcmp (env, &__progname[prog_len - len]) != 0
|| (prog_len != len && __progname[prog_len - len - 1] != '/'))
not_me = true;
|| (prog_len != len && __progname[prog_len - len - 1] != '/'))
not_me = true;
}
/* Only open the file if it's really us. */
@ -251,62 +251,62 @@ me (void)
const char *outname;
if (!start_sp)
start_sp = GETSP ();
start_sp = GETSP ();
outname = getenv ("MEMUSAGE_OUTPUT");
if (outname != NULL && outname[0] != '\0'
&& (access (outname, R_OK | W_OK) == 0 || errno == ENOENT))
{
fd = creat64 (outname, 0666);
&& (access (outname, R_OK | W_OK) == 0 || errno == ENOENT))
{
fd = creat64 (outname, 0666);
if (fd == -1)
/* Don't do anything in future calls if we cannot write to
the output file. */
not_me = true;
else
{
/* Write the first entry. */
first.heap = 0;
first.stack = 0;
GETTIME (first.time_low, first.time_high);
/* Write it two times since we need the starting and end time. */
write (fd, &first, sizeof (first));
write (fd, &first, sizeof (first));
if (fd == -1)
/* Don't do anything in future calls if we cannot write to
the output file. */
not_me = true;
else
{
/* Write the first entry. */
first.heap = 0;
first.stack = 0;
GETTIME (first.time_low, first.time_high);
/* Write it two times since we need the starting and end time. */
write (fd, &first, sizeof (first));
write (fd, &first, sizeof (first));
/* Determine the buffer size. We use the default if the
environment variable is not present. */
buffer_size = DEFAULT_BUFFER_SIZE;
if (getenv ("MEMUSAGE_BUFFER_SIZE") != NULL)
{
buffer_size = atoi (getenv ("MEMUSAGE_BUFFER_SIZE"));
if (buffer_size == 0 || buffer_size > DEFAULT_BUFFER_SIZE)
buffer_size = DEFAULT_BUFFER_SIZE;
}
/* Determine the buffer size. We use the default if the
environment variable is not present. */
buffer_size = DEFAULT_BUFFER_SIZE;
if (getenv ("MEMUSAGE_BUFFER_SIZE") != NULL)
{
buffer_size = atoi (getenv ("MEMUSAGE_BUFFER_SIZE"));
if (buffer_size == 0 || buffer_size > DEFAULT_BUFFER_SIZE)
buffer_size = DEFAULT_BUFFER_SIZE;
}
/* Possibly enable timer-based stack pointer retrieval. */
if (getenv ("MEMUSAGE_NO_TIMER") == NULL)
{
struct sigaction act;
/* Possibly enable timer-based stack pointer retrieval. */
if (getenv ("MEMUSAGE_NO_TIMER") == NULL)
{
struct sigaction act;
act.sa_handler = (sighandler_t) &int_handler;
act.sa_flags = SA_RESTART;
sigfillset (&act.sa_mask);
act.sa_handler = (sighandler_t) &int_handler;
act.sa_flags = SA_RESTART;
sigfillset (&act.sa_mask);
if (sigaction (SIGPROF, &act, NULL) >= 0)
{
struct itimerval timer;
if (sigaction (SIGPROF, &act, NULL) >= 0)
{
struct itimerval timer;
timer.it_value.tv_sec = 0;
timer.it_value.tv_usec = 1;
timer.it_interval = timer.it_value;
setitimer (ITIMER_PROF, &timer, NULL);
}
}
}
}
timer.it_value.tv_sec = 0;
timer.it_value.tv_usec = 1;
timer.it_interval = timer.it_value;
setitimer (ITIMER_PROF, &timer, NULL);
}
}
}
}
if (!not_me && getenv ("MEMUSAGE_TRACE_MMAP") != NULL)
trace_mmap = true;
trace_mmap = true;
}
}
@ -317,7 +317,7 @@ __attribute__ ((constructor))
init (void)
{
start_sp = GETSP ();
if (! initialized)
if (!initialized)
me ();
}
@ -333,13 +333,14 @@ malloc (size_t len)
if (__builtin_expect (initialized <= 0, 0))
{
if (initialized == -1)
return NULL;
return NULL;
me ();
}
/* If this is not the correct program just use the normal function. */
if (not_me)
return (*mallocp) (len);
return (*mallocp)(len);
/* Keep track of number of calls. */
catomic_increment (&calls[idx_malloc]);
@ -356,7 +357,7 @@ malloc (size_t len)
catomic_increment (&calls_total);
/* Do the real work. */
result = (struct header *) (*mallocp) (len + sizeof (struct header));
result = (struct header *) (*mallocp)(len + sizeof (struct header));
if (result == NULL)
{
catomic_increment (&failed[idx_malloc]);
@ -384,13 +385,14 @@ realloc (void *old, size_t len)
if (__builtin_expect (initialized <= 0, 0))
{
if (initialized == -1)
return NULL;
return NULL;
me ();
}
/* If this is not the correct program just use the normal function. */
if (not_me)
return (*reallocp) (old, len);
return (*reallocp)(old, len);
if (old == NULL)
{
@ -402,8 +404,9 @@ realloc (void *old, size_t len)
{
real = ((struct header *) old) - 1;
if (real->magic != MAGIC)
/* This is no memory allocated here. */
return (*reallocp) (old, len);
/* This is no memory allocated here. */
return (*reallocp)(old, len);
old_len = real->length;
}
@ -442,7 +445,7 @@ realloc (void *old, size_t len)
catomic_increment (&calls_total);
/* Do the real work. */
result = (struct header *) (*reallocp) (real, len + sizeof (struct header));
result = (struct header *) (*reallocp)(real, len + sizeof (struct header));
if (result == NULL)
{
catomic_increment (&failed[idx_realloc]);
@ -476,13 +479,14 @@ calloc (size_t n, size_t len)
if (__builtin_expect (initialized <= 0, 0))
{
if (initialized == -1)
return NULL;
return NULL;
me ();
}
/* If this is not the correct program just use the normal function. */
if (not_me)
return (*callocp) (n, len);
return (*callocp)(n, len);
/* Keep track of number of calls. */
catomic_increment (&calls[idx_calloc]);
@ -499,7 +503,7 @@ calloc (size_t n, size_t len)
++calls_total;
/* Do the real work. */
result = (struct header *) (*mallocp) (size + sizeof (struct header));
result = (struct header *) (*mallocp)(size + sizeof (struct header));
if (result == NULL)
{
catomic_increment (&failed[idx_calloc]);
@ -525,7 +529,8 @@ free (void *ptr)
if (__builtin_expect (initialized <= 0, 0))
{
if (initialized == -1)
return;
return;
me ();
}
@ -576,17 +581,18 @@ mmap (void *start, size_t len, int prot, int flags, int fd, off_t offset)
if (__builtin_expect (initialized <= 0, 0))
{
if (initialized == -1)
return NULL;
return NULL;
me ();
}
/* Always get a block. We don't need extra memory. */
result = (*mmapp) (start, len, prot, flags, fd, offset);
result = (*mmapp)(start, len, prot, flags, fd, offset);
if (!not_me && trace_mmap)
{
int idx = (flags & MAP_ANON
? idx_mmap_a : prot & PROT_WRITE ? idx_mmap_w : idx_mmap_r);
? idx_mmap_a : prot & PROT_WRITE ? idx_mmap_w : idx_mmap_r);
/* Keep track of number of calls. */
catomic_increment (&calls[idx]);
@ -596,20 +602,20 @@ mmap (void *start, size_t len, int prot, int flags, int fd, off_t offset)
catomic_add (&grand_total, len);
/* Remember the size of the request. */
if (len < 65536)
catomic_increment (&histogram[len / 16]);
catomic_increment (&histogram[len / 16]);
else
catomic_increment (&large);
catomic_increment (&large);
/* Total number of calls of any of the functions. */
catomic_increment (&calls_total);
/* Check for failures. */
if (result == NULL)
catomic_increment (&failed[idx]);
catomic_increment (&failed[idx]);
else if (idx == idx_mmap_w)
/* Update the allocation data and write out the records if
necessary. Note the first parameter is NULL which means
the size is not tracked. */
update_data (NULL, len, 0);
/* Update the allocation data and write out the records if
necessary. Note the first parameter is NULL which means
the size is not tracked. */
update_data (NULL, len, 0);
}
/* Return the pointer to the user buffer. */
@ -628,17 +634,18 @@ mmap64 (void *start, size_t len, int prot, int flags, int fd, off64_t offset)
if (__builtin_expect (initialized <= 0, 0))
{
if (initialized == -1)
return NULL;
return NULL;
me ();
}
/* Always get a block. We don't need extra memory. */
result = (*mmap64p) (start, len, prot, flags, fd, offset);
result = (*mmap64p)(start, len, prot, flags, fd, offset);
if (!not_me && trace_mmap)
{
int idx = (flags & MAP_ANON
? idx_mmap_a : prot & PROT_WRITE ? idx_mmap_w : idx_mmap_r);
? idx_mmap_a : prot & PROT_WRITE ? idx_mmap_w : idx_mmap_r);
/* Keep track of number of calls. */
catomic_increment (&calls[idx]);
@ -648,20 +655,20 @@ mmap64 (void *start, size_t len, int prot, int flags, int fd, off64_t offset)
catomic_add (&grand_total, len);
/* Remember the size of the request. */
if (len < 65536)
catomic_increment (&histogram[len / 16]);
catomic_increment (&histogram[len / 16]);
else
catomic_increment (&large);
catomic_increment (&large);
/* Total number of calls of any of the functions. */
catomic_increment (&calls_total);
/* Check for failures. */
if (result == NULL)
catomic_increment (&failed[idx]);
catomic_increment (&failed[idx]);
else if (idx == idx_mmap_w)
/* Update the allocation data and write out the records if
necessary. Note the first parameter is NULL which means
the size is not tracked. */
update_data (NULL, len, 0);
/* Update the allocation data and write out the records if
necessary. Note the first parameter is NULL which means
the size is not tracked. */
update_data (NULL, len, 0);
}
/* Return the pointer to the user buffer. */
@ -672,7 +679,7 @@ mmap64 (void *start, size_t len, int prot, int flags, int fd, off64_t offset)
/* `mremap' replacement. We do not have to keep track of the size since
`munmap' will get it as a parameter. */
void *
mremap (void *start, size_t old_len, size_t len, int flags, ...)
mremap (void *start, size_t old_len, size_t len, int flags, ...)
{
void *result = NULL;
va_list ap;
@ -685,49 +692,50 @@ mremap (void *start, size_t old_len, size_t len, int flags, ...)
if (__builtin_expect (initialized <= 0, 0))
{
if (initialized == -1)
return NULL;
return NULL;
me ();
}
/* Always get a block. We don't need extra memory. */
result = (*mremapp) (start, old_len, len, flags, newaddr);
result = (*mremapp)(start, old_len, len, flags, newaddr);
if (!not_me && trace_mmap)
{
/* Keep track of number of calls. */
catomic_increment (&calls[idx_mremap]);
if (len > old_len)
{
/* Keep track of total memory consumption for `malloc'. */
catomic_add (&total[idx_mremap], len - old_len);
/* Keep track of total memory requirement. */
catomic_add (&grand_total, len - old_len);
}
{
/* Keep track of total memory consumption for `malloc'. */
catomic_add (&total[idx_mremap], len - old_len);
/* Keep track of total memory requirement. */
catomic_add (&grand_total, len - old_len);
}
/* Remember the size of the request. */
if (len < 65536)
catomic_increment (&histogram[len / 16]);
catomic_increment (&histogram[len / 16]);
else
catomic_increment (&large);
catomic_increment (&large);
/* Total number of calls of any of the functions. */
catomic_increment (&calls_total);
/* Check for failures. */
if (result == NULL)
catomic_increment (&failed[idx_mremap]);
catomic_increment (&failed[idx_mremap]);
else
{
/* Record whether the reduction/increase happened in place. */
if (start == result)
catomic_increment (&inplace_mremap);
/* Was the buffer increased? */
if (old_len > len)
catomic_increment (&decreasing_mremap);
{
/* Record whether the reduction/increase happened in place. */
if (start == result)
catomic_increment (&inplace_mremap);
/* Was the buffer increased? */
if (old_len > len)
catomic_increment (&decreasing_mremap);
/* Update the allocation data and write out the records if
necessary. Note the first parameter is NULL which means
the size is not tracked. */
update_data (NULL, len, old_len);
}
/* Update the allocation data and write out the records if
necessary. Note the first parameter is NULL which means
the size is not tracked. */
update_data (NULL, len, old_len);
}
}
/* Return the pointer to the user buffer. */
@ -745,12 +753,13 @@ munmap (void *start, size_t len)
if (__builtin_expect (initialized <= 0, 0))
{
if (initialized == -1)
return -1;
return -1;
me ();
}
/* Do the real work. */
result = (*munmapp) (start, len);
result = (*munmapp)(start, len);
if (!not_me && trace_mmap)
{
@ -758,16 +767,16 @@ munmap (void *start, size_t len)
catomic_increment (&calls[idx_munmap]);
if (__builtin_expect (result == 0, 1))
{
/* Keep track of total memory freed using `free'. */
catomic_add (&total[idx_munmap], len);
{
/* Keep track of total memory freed using `free'. */
catomic_add (&total[idx_munmap], len);
/* Update the allocation data and write out the records if
necessary. */
update_data (NULL, 0, len);
}
/* Update the allocation data and write out the records if
necessary. */
update_data (NULL, 0, len);
}
else
catomic_increment (&failed[idx_munmap]);
catomic_increment (&failed[idx_munmap]);
}
return result;
@ -785,6 +794,7 @@ dest (void)
/* If we haven't done anything here just return. */
if (not_me)
return;
/* If we should call any of the memory functions don't do any profiling. */
not_me = true;
@ -793,13 +803,13 @@ dest (void)
{
/* Write the partially filled buffer. */
if (buffer_cnt > buffer_size)
write (fd, buffer + buffer_size,
(buffer_cnt - buffer_size) * sizeof (struct entry));
write (fd, buffer + buffer_size,
(buffer_cnt - buffer_size) * sizeof (struct entry));
else
write (fd, buffer, buffer_cnt * sizeof (struct entry));
write (fd, buffer, buffer_cnt * sizeof (struct entry));
/* Go back to the beginning of the file. We allocated two records
here when we opened the file. */
here when we opened the file. */
lseek (fd, 0, SEEK_SET);
/* Write out a record containing the total size. */
first.stack = peak_total;
@ -824,25 +834,25 @@ dest (void)
\e[00;34mrealloc|\e[0m %10lu %12llu %s%12lu\e[00;00m (nomove:%ld, dec:%ld, free:%ld)\n\
\e[00;34m calloc|\e[0m %10lu %12llu %s%12lu\e[00;00m\n\
\e[00;34m free|\e[0m %10lu %12llu\n",
(unsigned long long int) grand_total, (unsigned long int) peak_heap,
(unsigned long int) peak_stack,
(unsigned long int) calls[idx_malloc],
(unsigned long long int) total[idx_malloc],
failed[idx_malloc] ? "\e[01;41m" : "",
(unsigned long int) failed[idx_malloc],
(unsigned long int) calls[idx_realloc],
(unsigned long long int) total[idx_realloc],
failed[idx_realloc] ? "\e[01;41m" : "",
(unsigned long int) failed[idx_realloc],
(unsigned long int) inplace,
(unsigned long int) decreasing,
(unsigned long int) realloc_free,
(unsigned long int) calls[idx_calloc],
(unsigned long long int) total[idx_calloc],
failed[idx_calloc] ? "\e[01;41m" : "",
(unsigned long int) failed[idx_calloc],
(unsigned long int) calls[idx_free],
(unsigned long long int) total[idx_free]);
(unsigned long long int) grand_total, (unsigned long int) peak_heap,
(unsigned long int) peak_stack,
(unsigned long int) calls[idx_malloc],
(unsigned long long int) total[idx_malloc],
failed[idx_malloc] ? "\e[01;41m" : "",
(unsigned long int) failed[idx_malloc],
(unsigned long int) calls[idx_realloc],
(unsigned long long int) total[idx_realloc],
failed[idx_realloc] ? "\e[01;41m" : "",
(unsigned long int) failed[idx_realloc],
(unsigned long int) inplace,
(unsigned long int) decreasing,
(unsigned long int) realloc_free,
(unsigned long int) calls[idx_calloc],
(unsigned long long int) total[idx_calloc],
failed[idx_calloc] ? "\e[01;41m" : "",
(unsigned long int) failed[idx_calloc],
(unsigned long int) calls[idx_free],
(unsigned long long int) total[idx_free]);
if (trace_mmap)
fprintf (stderr, "\
@ -851,28 +861,28 @@ dest (void)
\e[00;34mmmap(a)|\e[0m %10lu %12llu %s%12lu\e[00;00m\n\
\e[00;34m mremap|\e[0m %10lu %12llu %s%12lu\e[00;00m (nomove: %ld, dec:%ld)\n\
\e[00;34m munmap|\e[0m %10lu %12llu %s%12lu\e[00;00m\n",
(unsigned long int) calls[idx_mmap_r],
(unsigned long long int) total[idx_mmap_r],
failed[idx_mmap_r] ? "\e[01;41m" : "",
(unsigned long int) failed[idx_mmap_r],
(unsigned long int) calls[idx_mmap_w],
(unsigned long long int) total[idx_mmap_w],
failed[idx_mmap_w] ? "\e[01;41m" : "",
(unsigned long int) failed[idx_mmap_w],
(unsigned long int) calls[idx_mmap_a],
(unsigned long long int) total[idx_mmap_a],
failed[idx_mmap_a] ? "\e[01;41m" : "",
(unsigned long int) failed[idx_mmap_a],
(unsigned long int) calls[idx_mremap],
(unsigned long long int) total[idx_mremap],
failed[idx_mremap] ? "\e[01;41m" : "",
(unsigned long int) failed[idx_mremap],
(unsigned long int) inplace_mremap,
(unsigned long int) decreasing_mremap,
(unsigned long int) calls[idx_munmap],
(unsigned long long int) total[idx_munmap],
failed[idx_munmap] ? "\e[01;41m" : "",
(unsigned long int) failed[idx_munmap]);
(unsigned long int) calls[idx_mmap_r],
(unsigned long long int) total[idx_mmap_r],
failed[idx_mmap_r] ? "\e[01;41m" : "",
(unsigned long int) failed[idx_mmap_r],
(unsigned long int) calls[idx_mmap_w],
(unsigned long long int) total[idx_mmap_w],
failed[idx_mmap_w] ? "\e[01;41m" : "",
(unsigned long int) failed[idx_mmap_w],
(unsigned long int) calls[idx_mmap_a],
(unsigned long long int) total[idx_mmap_a],
failed[idx_mmap_a] ? "\e[01;41m" : "",
(unsigned long int) failed[idx_mmap_a],
(unsigned long int) calls[idx_mremap],
(unsigned long long int) total[idx_mremap],
failed[idx_mremap] ? "\e[01;41m" : "",
(unsigned long int) failed[idx_mremap],
(unsigned long int) inplace_mremap,
(unsigned long int) decreasing_mremap,
(unsigned long int) calls[idx_munmap],
(unsigned long long int) total[idx_munmap],
failed[idx_munmap] ? "\e[01;41m" : "",
(unsigned long int) failed[idx_munmap]);
/* Write out a histoogram of the sizes of the allocations. */
fprintf (stderr, "\e[01;32mHistogram for block sizes:\e[0;0m\n");
@ -887,20 +897,20 @@ dest (void)
/* Only write out the nonzero entries. */
if (histogram[cnt / 16] != 0)
{
percent = (histogram[cnt / 16] * 100) / calls_total;
fprintf (stderr, "%5d-%-5d%12lu ", cnt, cnt + 15,
(unsigned long int) histogram[cnt / 16]);
if (percent == 0)
fputs (" <1% \e[41;37m", stderr);
else
fprintf (stderr, "%3d%% \e[41;37m", percent);
percent = (histogram[cnt / 16] * 100) / calls_total;
fprintf (stderr, "%5d-%-5d%12lu ", cnt, cnt + 15,
(unsigned long int) histogram[cnt / 16]);
if (percent == 0)
fputs (" <1% \e[41;37m", stderr);
else
fprintf (stderr, "%3d%% \e[41;37m", percent);
/* Draw a bar with a length corresponding to the current
/* Draw a bar with a length corresponding to the current
percentage. */
percent = (histogram[cnt / 16] * 50) / maxcalls;
while (percent-- > 0)
fputc ('=', stderr);
fputs ("\e[0;0m\n", stderr);
percent = (histogram[cnt / 16] * 50) / maxcalls;
while (percent-- > 0)
fputc ('=', stderr);
fputs ("\e[0;0m\n", stderr);
}
if (large != 0)
@ -908,9 +918,9 @@ dest (void)
percent = (large * 100) / calls_total;
fprintf (stderr, " large %12lu ", (unsigned long int) large);
if (percent == 0)
fputs (" <1% \e[41;37m", stderr);
fputs (" <1% \e[41;37m", stderr);
else
fprintf (stderr, "%3d%% \e[41;37m", percent);
fprintf (stderr, "%3d%% \e[41;37m", percent);
percent = (large * 50) / maxcalls;
while (percent-- > 0)
fputc ('=', stderr);

View File

@ -53,24 +53,24 @@
/* Definitions of arguments for argp functions. */
static const struct argp_option options[] =
{
{ "output", 'o', N_("FILE"), 0, N_("Name output file") },
{ "string", 's', N_("STRING"), 0, N_("Title string used in output graphic") },
{ "time", 't', NULL, 0, N_("\
{ "output", 'o', N_ ("FILE"), 0, N_ ("Name output file") },
{ "string", 's', N_ ("STRING"), 0, N_ ("Title string used in output graphic") },
{ "time", 't', NULL, 0, N_ (" \
Generate output linear to time (default is linear to number of function calls)\
") },
{ "total", 'T', NULL, 0,
N_("Also draw graph for total memory consumption") },
{ "x-size", 'x', N_("VALUE"), 0,
N_("Make output graphic VALUE pixels wide") },
{ "y-size", 'y', "VALUE", 0, N_("Make output graphic VALUE pixels high") },
N_ ("Also draw graph for total memory consumption") },
{ "x-size", 'x', N_ ("VALUE"), 0,
N_ ("Make output graphic VALUE pixels wide") },
{ "y-size", 'y', "VALUE", 0, N_ ("Make output graphic VALUE pixels high") },
{ NULL, 0, NULL, 0, NULL }
};
/* Short description of program. */
static const char doc[] = N_("Generate graphic from memory profiling data");
static const char doc[] = N_ ("Generate graphic from memory profiling data");
/* Strings for arguments in help texts. */
static const char args_doc[] = N_("DATAFILE [OUTFILE]");
static const char args_doc[] = N_ ("DATAFILE [OUTFILE]");
/* Prototype for option handler. */
static error_t parse_opt (int key, char *arg, struct argp_state *state);
@ -152,7 +152,7 @@ main (int argc, char *argv[])
if (remaining >= argc || remaining + 2 < argc)
{
argp_help (&argp, stdout, ARGP_HELP_SEE | ARGP_HELP_EXIT_ERR,
program_invocation_short_name);
program_invocation_short_name);
exit (1);
}
@ -197,21 +197,21 @@ main (int argc, char *argv[])
if (maxsize_heap == 0 && maxsize_stack == 0)
{
/* The program aborted before memusage was able to write the
information about the maximum heap and stack use. Repair
the file now. */
information about the maximum heap and stack use. Repair
the file now. */
struct entry next;
while (1)
{
if (read (fd, &next, sizeof (next)) == 0)
break;
if (next.heap > maxsize_heap)
maxsize_heap = next.heap;
if (next.stack > maxsize_stack)
maxsize_stack = next.stack;
if (maxsize_heap + maxsize_stack > maxsize_total)
maxsize_total = maxsize_heap + maxsize_stack;
}
{
if (read (fd, &next, sizeof (next)) == 0)
break;
if (next.heap > maxsize_heap)
maxsize_heap = next.heap;
if (next.stack > maxsize_stack)
maxsize_stack = next.stack;
if (maxsize_heap + maxsize_stack > maxsize_total)
maxsize_total = maxsize_heap + maxsize_stack;
}
headent[0].stack = maxsize_total;
headent[1].heap = maxsize_heap;
@ -227,7 +227,7 @@ main (int argc, char *argv[])
if (also_total)
{
/* We use one scale and since we also draw the total amount of
memory used we have to adapt the maximum. */
memory used we have to adapt the maximum. */
maxsize_heap = maxsize_total;
maxsize_stack = maxsize_total;
}
@ -292,145 +292,145 @@ main (int argc, char *argv[])
}
gdImageString (im_out, gdFontSmall, 38, ysize - 14, (unsigned char *) "0",
blue);
blue);
snprintf (buf, sizeof (buf), heap_format, 0);
gdImageString (im_out, gdFontSmall, maxsize_heap < 1024 ? 32 : 26,
ysize - 26, (unsigned char *) buf, red);
ysize - 26, (unsigned char *) buf, red);
snprintf (buf, sizeof (buf), stack_format, 0);
gdImageString (im_out, gdFontSmall, xsize - 37, ysize - 26,
(unsigned char *) buf, green);
(unsigned char *) buf, green);
if (string != NULL)
gdImageString (im_out, gdFontLarge, (xsize - strlen (string) * 8) / 2,
2, (unsigned char *) string, green);
2, (unsigned char *) string, green);
gdImageStringUp (im_out, gdFontSmall, 1, ysize / 2 - 10,
(unsigned char *) "allocated", red);
(unsigned char *) "allocated", red);
gdImageStringUp (im_out, gdFontSmall, 11, ysize / 2 - 10,
(unsigned char *) "memory", red);
(unsigned char *) "memory", red);
gdImageStringUp (im_out, gdFontSmall, xsize - 39, ysize / 2 - 10,
(unsigned char *) "used", green);
(unsigned char *) "used", green);
gdImageStringUp (im_out, gdFontSmall, xsize - 27, ysize / 2 - 10,
(unsigned char *) "stack", green);
(unsigned char *) "stack", green);
snprintf (buf, sizeof (buf), heap_format, maxsize_heap / heap_scale);
gdImageString (im_out, gdFontSmall, 39 - strlen (buf) * 6, 14,
(unsigned char *) buf, red);
(unsigned char *) buf, red);
snprintf (buf, sizeof (buf), stack_format, maxsize_stack / stack_scale);
gdImageString (im_out, gdFontSmall, xsize - 37, 14,
(unsigned char *) buf, green);
(unsigned char *) buf, green);
for (line = 1; line <= 3; ++line)
{
if (maxsize_heap > 0)
{
cnt = (((ysize - 40) * (maxsize_heap / 4 * line / heap_scale))
/ (maxsize_heap / heap_scale));
gdImageDashedLine (im_out, 40, ysize - 20 - cnt, xsize - 40,
ysize - 20 - cnt, red);
snprintf (buf, sizeof (buf), heap_format,
maxsize_heap / 4 * line / heap_scale);
gdImageString (im_out, gdFontSmall, 39 - strlen (buf) * 6,
ysize - 26 - cnt, (unsigned char *) buf, red);
}
{
cnt = (((ysize - 40) * (maxsize_heap / 4 * line / heap_scale))
/ (maxsize_heap / heap_scale));
gdImageDashedLine (im_out, 40, ysize - 20 - cnt, xsize - 40,
ysize - 20 - cnt, red);
snprintf (buf, sizeof (buf), heap_format,
maxsize_heap / 4 * line / heap_scale);
gdImageString (im_out, gdFontSmall, 39 - strlen (buf) * 6,
ysize - 26 - cnt, (unsigned char *) buf, red);
}
else
cnt = 0;
cnt = 0;
if (maxsize_stack > 0)
cnt2 = (((ysize - 40) * (maxsize_stack / 4 * line / stack_scale))
/ (maxsize_stack / stack_scale));
cnt2 = (((ysize - 40) * (maxsize_stack / 4 * line / stack_scale))
/ (maxsize_stack / stack_scale));
else
cnt2 = 0;
cnt2 = 0;
if (cnt != cnt2)
gdImageDashedLine (im_out, 40, ysize - 20 - cnt2, xsize - 40,
ysize - 20 - cnt2, green);
gdImageDashedLine (im_out, 40, ysize - 20 - cnt2, xsize - 40,
ysize - 20 - cnt2, green);
snprintf (buf, sizeof (buf), stack_format, maxsize_stack / 4 * line /
stack_scale);
stack_scale);
gdImageString (im_out, gdFontSmall, xsize - 37, ysize - 26 - cnt2,
(unsigned char *) buf, green);
(unsigned char *) buf, green);
}
snprintf (buf, sizeof (buf), "%llu", (unsigned long long) total);
gdImageString (im_out, gdFontSmall, xsize - 50, ysize - 14,
(unsigned char *) buf, blue);
(unsigned char *) buf, blue);
if (!time_based)
{
uint64_t previously = start_time;
gdImageString (im_out, gdFontSmall, 40 + (xsize - 32 * 6 - 80) / 2,
ysize - 12,
(unsigned char *) "# memory handling function calls",
blue);
ysize - 12,
(unsigned char *) "# memory handling function calls",
blue);
last_stack = last_heap = last_total = ysize - 20;
for (cnt = 1; cnt <= total; ++cnt)
{
struct entry entry;
size_t new[2];
uint64_t now;
{
struct entry entry;
size_t new[2];
uint64_t now;
read (fd, &entry, sizeof (entry));
read (fd, &entry, sizeof (entry));
now = ((uint64_t) entry.time_high) << 32 | entry.time_low;
now = ((uint64_t) entry.time_high) << 32 | entry.time_low;
if ((((previously - start_time) * 100) / total_time) % 10 < 5)
gdImageFilledRectangle (im_out,
40 + ((cnt - 1) * (xsize - 80)) / total,
ysize - 19,
39 + (cnt * (xsize - 80)) / total,
ysize - 14, yellow);
previously = now;
if ((((previously - start_time) * 100) / total_time) % 10 < 5)
gdImageFilledRectangle (im_out,
40 + ((cnt - 1) * (xsize - 80)) / total,
ysize - 19,
39 + (cnt * (xsize - 80)) / total,
ysize - 14, yellow);
previously = now;
if (also_total && maxsize_heap > 0)
{
size_t new3;
if (also_total && maxsize_heap > 0)
{
size_t new3;
new3 = (ysize - 20) - ((((unsigned long long int) (ysize - 40))
* (entry.heap + entry.stack))
/ maxsize_heap);
gdImageLine (im_out, 40 + ((xsize - 80) * (cnt - 1)) / total,
last_total,
40 + ((xsize - 80) * cnt) / total, new3,
black);
last_total = new3;
}
new3 = (ysize - 20) - ((((unsigned long long int) (ysize - 40))
* (entry.heap + entry.stack))
/ maxsize_heap);
gdImageLine (im_out, 40 + ((xsize - 80) * (cnt - 1)) / total,
last_total,
40 + ((xsize - 80) * cnt) / total, new3,
black);
last_total = new3;
}
if (maxsize_heap > 0)
{
new[0] = ((ysize - 20)
- ((((unsigned long long int) (ysize - 40))
* entry.heap) / maxsize_heap));
gdImageLine (im_out, 40 + ((xsize - 80) * (cnt - 1)) / total,
last_heap, 40 + ((xsize - 80) * cnt) / total,
new[0], red);
last_heap = new[0];
}
if (maxsize_heap > 0)
{
new[0] = ((ysize - 20)
- ((((unsigned long long int) (ysize - 40))
* entry.heap) / maxsize_heap));
gdImageLine (im_out, 40 + ((xsize - 80) * (cnt - 1)) / total,
last_heap, 40 + ((xsize - 80) * cnt) / total,
new[0], red);
last_heap = new[0];
}
if (maxsize_stack > 0)
{
new[1] = ((ysize - 20)
- ((((unsigned long long int) (ysize - 40))
* entry.stack) / maxsize_stack));
gdImageLine (im_out, 40 + ((xsize - 80) * (cnt - 1)) / total,
last_stack, 40 + ((xsize - 80) * cnt) / total,
new[1], green);
last_stack = new[1];
}
}
if (maxsize_stack > 0)
{
new[1] = ((ysize - 20)
- ((((unsigned long long int) (ysize - 40))
* entry.stack) / maxsize_stack));
gdImageLine (im_out, 40 + ((xsize - 80) * (cnt - 1)) / total,
last_stack, 40 + ((xsize - 80) * cnt) / total,
new[1], green);
last_stack = new[1];
}
}
cnt = 0;
while (cnt < total)
{
gdImageLine (im_out, 40 + ((xsize - 80) * cnt) / total, ysize - 20,
40 + ((xsize - 80) * cnt) / total, ysize - 15, blue);
cnt += MAX (1, total / 20);
}
{
gdImageLine (im_out, 40 + ((xsize - 80) * cnt) / total, ysize - 20,
40 + ((xsize - 80) * cnt) / total, ysize - 15, blue);
cnt += MAX (1, total / 20);
}
gdImageLine (im_out, xsize - 40, ysize - 20, xsize - 40, ysize - 15,
blue);
blue);
}
else
{
@ -438,67 +438,67 @@ main (int argc, char *argv[])
size_t last_xpos = 40;
gdImageString (im_out, gdFontSmall, 40 + (xsize - 39 * 6 - 80) / 2,
ysize - 12,
(unsigned char *) "\
ysize - 12,
(unsigned char *) " \
# memory handling function calls / time", blue);
for (cnt = 0; cnt < 20; cnt += 2)
gdImageFilledRectangle (im_out,
40 + (cnt * (xsize - 80)) / 20, ysize - 19,
39 + ((cnt + 1) * (xsize - 80)) / 20,
ysize - 14, yellow);
gdImageFilledRectangle (im_out,
40 + (cnt * (xsize - 80)) / 20, ysize - 19,
39 + ((cnt + 1) * (xsize - 80)) / 20,
ysize - 14, yellow);
last_stack = last_heap = last_total = ysize - 20;
for (cnt = 1; cnt <= total; ++cnt)
{
struct entry entry;
size_t new[2];
size_t xpos;
uint64_t now;
{
struct entry entry;
size_t new[2];
size_t xpos;
uint64_t now;
read (fd, &entry, sizeof (entry));
read (fd, &entry, sizeof (entry));
now = ((uint64_t) entry.time_high) << 32 | entry.time_low;
xpos = 40 + ((xsize - 80) * (now - start_time)) / total_time;
now = ((uint64_t) entry.time_high) << 32 | entry.time_low;
xpos = 40 + ((xsize - 80) * (now - start_time)) / total_time;
if (cnt == next_tick)
{
gdImageLine (im_out, xpos, ysize - 20, xpos, ysize - 15, blue);
next_tick += MAX (1, total / 20);
}
if (cnt == next_tick)
{
gdImageLine (im_out, xpos, ysize - 20, xpos, ysize - 15, blue);
next_tick += MAX (1, total / 20);
}
if (also_total && maxsize_heap > 0)
{
size_t new3;
if (also_total && maxsize_heap > 0)
{
size_t new3;
new3 = (ysize - 20) - ((((unsigned long long int) (ysize - 40))
* (entry.heap + entry.stack))
/ maxsize_heap);
gdImageLine (im_out, last_xpos, last_total, xpos, new3, black);
last_total = new3;
}
new3 = (ysize - 20) - ((((unsigned long long int) (ysize - 40))
* (entry.heap + entry.stack))
/ maxsize_heap);
gdImageLine (im_out, last_xpos, last_total, xpos, new3, black);
last_total = new3;
}
if (maxsize_heap > 0)
{
new[0] = ((ysize - 20)
- ((((unsigned long long int) (ysize - 40))
* entry.heap) / maxsize_heap));
gdImageLine (im_out, last_xpos, last_heap, xpos, new[0], red);
last_heap = new[0];
}
if (maxsize_heap > 0)
{
new[0] = ((ysize - 20)
- ((((unsigned long long int) (ysize - 40))
* entry.heap) / maxsize_heap));
gdImageLine (im_out, last_xpos, last_heap, xpos, new[0], red);
last_heap = new[0];
}
if (maxsize_stack > 0)
{
new[1] = ((ysize - 20)
- ((((unsigned long long int) (ysize - 40))
* entry.stack) / maxsize_stack));
gdImageLine (im_out, last_xpos, last_stack, xpos, new[1],
green);
last_stack = new[1];
}
if (maxsize_stack > 0)
{
new[1] = ((ysize - 20)
- ((((unsigned long long int) (ysize - 40))
* entry.stack) / maxsize_stack));
gdImageLine (im_out, last_xpos, last_stack, xpos, new[1],
green);
last_stack = new[1];
}
last_xpos = xpos;
}
last_xpos = xpos;
}
}
/* Write out the result. */
@ -537,12 +537,12 @@ parse_opt (int key, char *arg, struct argp_state *state)
case 'x':
xsize = atoi (arg);
if (xsize == 0)
xsize = XSIZE;
xsize = XSIZE;
break;
case 'y':
ysize = atoi (arg);
if (ysize == 0)
ysize = XSIZE;
ysize = XSIZE;
break;
default:
return ARGP_ERR_UNKNOWN;
@ -563,8 +563,10 @@ more_help (int key, const char *text, void *input)
if (asprintf (&tp, gettext ("\
For bug reporting instructions, please see:\n\
%s.\n"), REPORT_BUGS_TO) < 0)
return NULL;
return NULL;
return tp;
default:
break;
}

View File

@ -15,27 +15,27 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#ifndef _MALLOC_INTERNAL
#define _MALLOC_INTERNAL
#include <malloc.h>
#ifndef _MALLOC_INTERNAL
# define _MALLOC_INTERNAL
# include <malloc.h>
#endif
#ifndef __GNU_LIBRARY__
#define __sbrk sbrk
#ifndef __GNU_LIBRARY__
# define __sbrk sbrk
#endif
#ifdef __GNU_LIBRARY__
/* It is best not to declare this and cast its result on foreign operating
systems with potentially hostile include files. */
#include <stddef.h>
#include <stdlib.h>
# include <stddef.h>
# include <stdlib.h>
extern void *__sbrk (ptrdiff_t increment) __THROW;
libc_hidden_proto (__sbrk)
#endif
#ifndef NULL
#define NULL 0
# define NULL 0
#endif
/* Allocate INCREMENT more bytes of data space,
@ -47,6 +47,7 @@ __default_morecore (ptrdiff_t increment)
void *result = (void *) __sbrk (increment);
if (result == (void *) -1)
return NULL;
return result;
}
libc_hidden_def (__default_morecore)

View File

@ -1,8 +1,8 @@
/* More debugging hooks for `malloc'.
Copyright (C) 1991-2014 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Written April 2, 1991 by John Gilmore of Cygnus Support.
Based on mcheck.c by Mike Haertel.
Written April 2, 1991 by John Gilmore of Cygnus Support.
Based on mcheck.c by Mike Haertel.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@ -18,11 +18,11 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#ifndef _MALLOC_INTERNAL
#define _MALLOC_INTERNAL
#include <malloc.h>
#include <mcheck.h>
#include <bits/libc-lock.h>
#ifndef _MALLOC_INTERNAL
# define _MALLOC_INTERNAL
# include <malloc.h>
# include <mcheck.h>
# include <bits/libc-lock.h>
#endif
#include <dlfcn.h>
@ -48,7 +48,7 @@
#define TRACE_BUFFER_SIZE 512
static FILE *mallstream;
static const char mallenv[]= "MALLOC_TRACE";
static const char mallenv[] = "MALLOC_TRACE";
static char *malloc_trace_buffer;
__libc_lock_define_initialized (static, lock);
@ -60,9 +60,9 @@ __ptr_t mallwatch;
static void (*tr_old_free_hook) (__ptr_t ptr, const __ptr_t);
static __ptr_t (*tr_old_malloc_hook) (size_t size, const __ptr_t);
static __ptr_t (*tr_old_realloc_hook) (__ptr_t ptr, size_t size,
const __ptr_t);
const __ptr_t);
static __ptr_t (*tr_old_memalign_hook) (size_t __alignment, size_t __size,
const __ptr_t);
const __ptr_t);
/* This function is called when the block being alloc'd, realloc'd, or
freed has an address matching the variable "mallwatch". In a debugger,
@ -79,39 +79,38 @@ libc_hidden_def (tr_break)
static void tr_where (const __ptr_t, Dl_info *) __THROW internal_function;
static void
internal_function
tr_where (caller, info)
const __ptr_t caller;
Dl_info *info;
internal_function tr_where (caller, info)
const __ptr_t caller;
Dl_info *info;
{
if (caller != NULL)
{
if (info != NULL)
{
char *buf = (char *) "";
if (info->dli_sname != NULL)
{
size_t len = strlen (info->dli_sname);
buf = alloca (len + 6 + 2 * sizeof (void *));
{
char *buf = (char *) "";
if (info->dli_sname != NULL)
{
size_t len = strlen (info->dli_sname);
buf = alloca (len + 6 + 2 * sizeof (void *));
buf[0] = '(';
__stpcpy (_fitoa (caller >= (const __ptr_t) info->dli_saddr
? caller - (const __ptr_t) info->dli_saddr
: (const __ptr_t) info->dli_saddr - caller,
__stpcpy (__mempcpy (buf + 1, info->dli_sname,
len),
caller >= (__ptr_t) info->dli_saddr
? "+0x" : "-0x"),
16, 0),
")");
}
buf[0] = '(';
__stpcpy (_fitoa (caller >= (const __ptr_t) info->dli_saddr
? caller - (const __ptr_t) info->dli_saddr
: (const __ptr_t) info->dli_saddr - caller,
__stpcpy (__mempcpy (buf + 1, info->dli_sname,
len),
caller >= (__ptr_t) info->dli_saddr
? "+0x" : "-0x"),
16, 0),
")");
}
fprintf (mallstream, "@ %s%s%s[%p] ",
info->dli_fname ?: "", info->dli_fname ? ":" : "",
buf, caller);
}
fprintf (mallstream, "@ %s%s%s[%p] ",
info->dli_fname ? : "", info->dli_fname ? ":" : "",
buf, caller);
}
else
fprintf (mallstream, "@ [%p] ", caller);
fprintf (mallstream, "@ [%p] ", caller);
}
}
@ -131,10 +130,9 @@ lock_and_info (const __ptr_t caller, Dl_info *mem)
static void tr_freehook (__ptr_t, const __ptr_t) __THROW;
static void
tr_freehook (ptr, caller)
__ptr_t ptr;
const __ptr_t caller;
static void tr_freehook (ptr, caller)
__ptr_t ptr;
const __ptr_t caller;
{
if (ptr == NULL)
return;
@ -152,7 +150,7 @@ tr_freehook (ptr, caller)
}
__free_hook = tr_old_free_hook;
if (tr_old_free_hook != NULL)
(*tr_old_free_hook) (ptr, caller);
(*tr_old_free_hook)(ptr, caller);
else
free (ptr);
__free_hook = tr_freehook;
@ -160,10 +158,9 @@ tr_freehook (ptr, caller)
}
static __ptr_t tr_mallochook (size_t, const __ptr_t) __THROW;
static __ptr_t
tr_mallochook (size, caller)
size_t size;
const __ptr_t caller;
static __ptr_t tr_mallochook (size, caller)
size_t size;
const __ptr_t caller;
{
__ptr_t hdr;
@ -172,7 +169,7 @@ tr_mallochook (size, caller)
__malloc_hook = tr_old_malloc_hook;
if (tr_old_malloc_hook != NULL)
hdr = (__ptr_t) (*tr_old_malloc_hook) (size, caller);
hdr = (__ptr_t) (*tr_old_malloc_hook)(size, caller);
else
hdr = (__ptr_t) malloc (size);
__malloc_hook = tr_mallochook;
@ -190,12 +187,11 @@ tr_mallochook (size, caller)
}
static __ptr_t tr_reallochook (__ptr_t, size_t, const __ptr_t)
__THROW;
static __ptr_t
tr_reallochook (ptr, size, caller)
__ptr_t ptr;
size_t size;
const __ptr_t caller;
__THROW;
static __ptr_t tr_reallochook (ptr, size, caller)
__ptr_t ptr;
size_t size;
const __ptr_t caller;
{
__ptr_t hdr;
@ -209,7 +205,7 @@ tr_reallochook (ptr, size, caller)
__malloc_hook = tr_old_malloc_hook;
__realloc_hook = tr_old_realloc_hook;
if (tr_old_realloc_hook != NULL)
hdr = (__ptr_t) (*tr_old_realloc_hook) (ptr, size, caller);
hdr = (__ptr_t) (*tr_old_realloc_hook)(ptr, size, caller);
else
hdr = (__ptr_t) realloc (ptr, size);
__free_hook = tr_freehook;
@ -220,10 +216,10 @@ tr_reallochook (ptr, size, caller)
if (hdr == NULL)
{
if (size != 0)
/* Failed realloc. */
fprintf (mallstream, "! %p %#lx\n", ptr, (unsigned long int) size);
/* Failed realloc. */
fprintf (mallstream, "! %p %#lx\n", ptr, (unsigned long int) size);
else
fprintf (mallstream, "- %p\n", ptr);
fprintf (mallstream, "- %p\n", ptr);
}
else if (ptr == NULL)
fprintf (mallstream, "+ %p %#lx\n", hdr, (unsigned long int) size);
@ -243,11 +239,10 @@ tr_reallochook (ptr, size, caller)
}
static __ptr_t tr_memalignhook (size_t, size_t,
const __ptr_t) __THROW;
static __ptr_t
tr_memalignhook (alignment, size, caller)
size_t alignment, size;
const __ptr_t caller;
const __ptr_t) __THROW;
static __ptr_t tr_memalignhook (alignment, size, caller)
size_t alignment, size;
const __ptr_t caller;
{
__ptr_t hdr;
@ -257,7 +252,7 @@ tr_memalignhook (alignment, size, caller)
__memalign_hook = tr_old_memalign_hook;
__malloc_hook = tr_old_malloc_hook;
if (tr_old_memalign_hook != NULL)
hdr = (__ptr_t) (*tr_old_memalign_hook) (alignment, size, caller);
hdr = (__ptr_t) (*tr_old_memalign_hook)(alignment, size, caller);
else
hdr = (__ptr_t) memalign (alignment, size);
__memalign_hook = tr_memalignhook;
@ -321,44 +316,44 @@ mtrace (void)
{
char *mtb = malloc (TRACE_BUFFER_SIZE);
if (mtb == NULL)
return;
return;
mallstream = fopen (mallfile != NULL ? mallfile : "/dev/null", "wce");
if (mallstream != NULL)
{
{
#ifndef __ASSUME_O_CLOEXEC
/* Make sure we close the file descriptor on exec. */
int flags = __fcntl (fileno (mallstream), F_GETFD, 0);
if (flags >= 0)
{
flags |= FD_CLOEXEC;
__fcntl (fileno (mallstream), F_SETFD, flags);
}
/* Make sure we close the file descriptor on exec. */
int flags = __fcntl (fileno (mallstream), F_GETFD, 0);
if (flags >= 0)
{
flags |= FD_CLOEXEC;
__fcntl (fileno (mallstream), F_SETFD, flags);
}
#endif
/* Be sure it doesn't malloc its buffer! */
malloc_trace_buffer = mtb;
setvbuf (mallstream, malloc_trace_buffer, _IOFBF, TRACE_BUFFER_SIZE);
fprintf (mallstream, "= Start\n");
tr_old_free_hook = __free_hook;
__free_hook = tr_freehook;
tr_old_malloc_hook = __malloc_hook;
__malloc_hook = tr_mallochook;
tr_old_realloc_hook = __realloc_hook;
__realloc_hook = tr_reallochook;
tr_old_memalign_hook = __memalign_hook;
__memalign_hook = tr_memalignhook;
/* Be sure it doesn't malloc its buffer! */
malloc_trace_buffer = mtb;
setvbuf (mallstream, malloc_trace_buffer, _IOFBF, TRACE_BUFFER_SIZE);
fprintf (mallstream, "= Start\n");
tr_old_free_hook = __free_hook;
__free_hook = tr_freehook;
tr_old_malloc_hook = __malloc_hook;
__malloc_hook = tr_mallochook;
tr_old_realloc_hook = __realloc_hook;
__realloc_hook = tr_reallochook;
tr_old_memalign_hook = __memalign_hook;
__memalign_hook = tr_memalignhook;
#ifdef _LIBC
if (!added_atexit_handler)
{
extern void *__dso_handle __attribute__ ((__weak__));
added_atexit_handler = 1;
__cxa_atexit ((void (*) (void *)) release_libc_mem, NULL,
&__dso_handle ? __dso_handle : NULL);
}
if (!added_atexit_handler)
{
extern void *__dso_handle __attribute__ ((__weak__));
added_atexit_handler = 1;
__cxa_atexit ((void (*)(void *))release_libc_mem, NULL,
&__dso_handle ? __dso_handle : NULL);
}
#endif
}
}
else
free (mtb);
free (mtb);
}
}

View File

@ -42,7 +42,7 @@
program understand `configure --with-gnu-libc' and omit the object
files, it is simpler to just do this in the source for each such file. */
#include <stdio.h> /* Random thing to get __GNU_LIBRARY__. */
#include <stdio.h> /* Random thing to get __GNU_LIBRARY__. */
#if !defined _LIBC && defined __GNU_LIBRARY__ && __GNU_LIBRARY__ > 1
# include <gnu-versions.h>
# if _GNU_OBSTACK_INTERFACE_VERSION == OBSTACK_INTERFACE_VERSION
@ -78,10 +78,10 @@ struct fooalign
But in fact it might be less smart and round addresses to as much as
DEFAULT_ROUNDING. So we prepare for it to do that. */
enum
{
DEFAULT_ALIGNMENT = offsetof (struct fooalign, u),
DEFAULT_ROUNDING = sizeof (union fooround)
};
{
DEFAULT_ALIGNMENT = offsetof (struct fooalign, u),
DEFAULT_ROUNDING = sizeof (union fooround)
};
/* When we copy a long block of data, this is the unit to do it with.
On some machines, copying successive ints does not work;
@ -127,19 +127,19 @@ compat_symbol (libc, _obstack_compat, _obstack, GLIBC_2_0);
do not allow (expr) ? void : void. */
# define CALL_CHUNKFUN(h, size) \
(((h) -> use_extra_arg) \
? (*(h)->chunkfun) ((h)->extra_arg, (size)) \
: (*(struct _obstack_chunk *(*) (long)) (h)->chunkfun) ((size)))
(((h)->use_extra_arg) \
? (*(h)->chunkfun)((h)->extra_arg, (size)) \
: (*(struct _obstack_chunk *(*)(long))(h)->chunkfun)((size)))
# define CALL_FREEFUN(h, old_chunk) \
do { \
if ((h) -> use_extra_arg) \
(*(h)->freefun) ((h)->extra_arg, (old_chunk)); \
else \
(*(void (*) (void *)) (h)->freefun) ((old_chunk)); \
} while (0)
if ((h)->use_extra_arg) \
(*(h)->freefun)((h)->extra_arg, (old_chunk)); \
else \
(*(void (*)(void *))(h)->freefun)((old_chunk)); \
} while (0)
/* Initialize an obstack H for use. Specify chunk size SIZE (0 means default).
Objects start on multiples of ALIGNMENT (0 means use default).
CHUNKFUN is the function to use to allocate chunks,
@ -150,44 +150,44 @@ compat_symbol (libc, _obstack_compat, _obstack, GLIBC_2_0);
int
_obstack_begin (struct obstack *h,
int size, int alignment,
void *(*chunkfun) (long),
void (*freefun) (void *))
int size, int alignment,
void *(*chunkfun)(long),
void (*freefun)(void *))
{
struct _obstack_chunk *chunk; /* points to new chunk */
if (alignment == 0)
alignment = DEFAULT_ALIGNMENT;
if (size == 0)
/* Default size is what GNU malloc can fit in a 4096-byte block. */
/* Default size is what GNU malloc can fit in a 4096-byte block. */
{
/* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc.
Use the values for range checking, because if range checking is off,
the extra bytes won't be missed terribly, but if range checking is on
and we used a larger request, a whole extra 4096 bytes would be
allocated.
Use the values for range checking, because if range checking is off,
the extra bytes won't be missed terribly, but if range checking is on
and we used a larger request, a whole extra 4096 bytes would be
allocated.
These number are irrelevant to the new GNU malloc. I suspect it is
less sensitive to the size of the request. */
These number are irrelevant to the new GNU malloc. I suspect it is
less sensitive to the size of the request. */
int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1))
+ 4 + DEFAULT_ROUNDING - 1)
& ~(DEFAULT_ROUNDING - 1));
+ 4 + DEFAULT_ROUNDING - 1)
& ~(DEFAULT_ROUNDING - 1));
size = 4096 - extra;
}
h->chunkfun = (struct _obstack_chunk * (*)(void *, long)) chunkfun;
h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun;
h->chunkfun = (struct _obstack_chunk * (*)(void *, long))chunkfun;
h->freefun = (void (*)(void *, struct _obstack_chunk *))freefun;
h->chunk_size = size;
h->alignment_mask = alignment - 1;
h->use_extra_arg = 0;
chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size);
chunk = h->chunk = CALL_CHUNKFUN (h, h->chunk_size);
if (!chunk)
(*obstack_alloc_failed_handler) ();
(*obstack_alloc_failed_handler)();
h->next_free = h->object_base = __PTR_ALIGN ((char *) chunk, chunk->contents,
alignment - 1);
alignment - 1);
h->chunk_limit = chunk->limit
= (char *) chunk + h->chunk_size;
= (char *) chunk + h->chunk_size;
chunk->prev = 0;
/* The initial chunk now contains no empty object. */
h->maybe_empty_object = 0;
@ -197,45 +197,45 @@ _obstack_begin (struct obstack *h,
int
_obstack_begin_1 (struct obstack *h, int size, int alignment,
void *(*chunkfun) (void *, long),
void (*freefun) (void *, void *),
void *arg)
void *(*chunkfun)(void *, long),
void (*freefun)(void *, void *),
void *arg)
{
struct _obstack_chunk *chunk; /* points to new chunk */
if (alignment == 0)
alignment = DEFAULT_ALIGNMENT;
if (size == 0)
/* Default size is what GNU malloc can fit in a 4096-byte block. */
/* Default size is what GNU malloc can fit in a 4096-byte block. */
{
/* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc.
Use the values for range checking, because if range checking is off,
the extra bytes won't be missed terribly, but if range checking is on
and we used a larger request, a whole extra 4096 bytes would be
allocated.
Use the values for range checking, because if range checking is off,
the extra bytes won't be missed terribly, but if range checking is on
and we used a larger request, a whole extra 4096 bytes would be
allocated.
These number are irrelevant to the new GNU malloc. I suspect it is
less sensitive to the size of the request. */
These number are irrelevant to the new GNU malloc. I suspect it is
less sensitive to the size of the request. */
int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1))
+ 4 + DEFAULT_ROUNDING - 1)
& ~(DEFAULT_ROUNDING - 1));
+ 4 + DEFAULT_ROUNDING - 1)
& ~(DEFAULT_ROUNDING - 1));
size = 4096 - extra;
}
h->chunkfun = (struct _obstack_chunk * (*)(void *,long)) chunkfun;
h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun;
h->chunkfun = (struct _obstack_chunk * (*)(void *, long))chunkfun;
h->freefun = (void (*)(void *, struct _obstack_chunk *))freefun;
h->chunk_size = size;
h->alignment_mask = alignment - 1;
h->extra_arg = arg;
h->use_extra_arg = 1;
chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size);
chunk = h->chunk = CALL_CHUNKFUN (h, h->chunk_size);
if (!chunk)
(*obstack_alloc_failed_handler) ();
(*obstack_alloc_failed_handler)();
h->next_free = h->object_base = __PTR_ALIGN ((char *) chunk, chunk->contents,
alignment - 1);
alignment - 1);
h->chunk_limit = chunk->limit
= (char *) chunk + h->chunk_size;
= (char *) chunk + h->chunk_size;
chunk->prev = 0;
/* The initial chunk now contains no empty object. */
h->maybe_empty_object = 0;
@ -254,7 +254,7 @@ _obstack_newchunk (struct obstack *h, int length)
{
struct _obstack_chunk *old_chunk = h->chunk;
struct _obstack_chunk *new_chunk;
long new_size;
long new_size;
long obj_size = h->next_free - h->object_base;
long i;
long already;
@ -268,7 +268,7 @@ _obstack_newchunk (struct obstack *h, int length)
/* Allocate and initialize the new chunk. */
new_chunk = CALL_CHUNKFUN (h, new_size);
if (!new_chunk)
(*obstack_alloc_failed_handler) ();
(*obstack_alloc_failed_handler)();
h->chunk = new_chunk;
new_chunk->prev = old_chunk;
new_chunk->limit = h->chunk_limit = (char *) new_chunk + new_size;
@ -283,12 +283,12 @@ _obstack_newchunk (struct obstack *h, int length)
if (h->alignment_mask + 1 >= DEFAULT_ALIGNMENT)
{
for (i = obj_size / sizeof (COPYING_UNIT) - 1;
i >= 0; i--)
((COPYING_UNIT *)object_base)[i]
= ((COPYING_UNIT *)h->object_base)[i];
i >= 0; i--)
((COPYING_UNIT *) object_base)[i]
= ((COPYING_UNIT *) h->object_base)[i];
/* We used to copy the odd few remaining bytes as one extra COPYING_UNIT,
but that can cross a page boundary on a machine
which does not do strict alignment for COPYING_UNITS. */
but that can cross a page boundary on a machine
which does not do strict alignment for COPYING_UNITS. */
already = obj_size / sizeof (COPYING_UNIT) * sizeof (COPYING_UNIT);
}
else
@ -300,10 +300,10 @@ _obstack_newchunk (struct obstack *h, int length)
/* If the object just copied was the only data in OLD_CHUNK,
free that chunk and remove it from the chain.
But not if that chunk might contain an empty object. */
if (! h->maybe_empty_object
if (!h->maybe_empty_object
&& (h->object_base
== __PTR_ALIGN ((char *) old_chunk, old_chunk->contents,
h->alignment_mask)))
== __PTR_ALIGN ((char *) old_chunk, old_chunk->contents,
h->alignment_mask)))
{
new_chunk->prev = old_chunk->prev;
CALL_FREEFUN (h, old_chunk);
@ -329,8 +329,8 @@ int _obstack_allocated_p (struct obstack *h, void *obj);
int
_obstack_allocated_p (struct obstack *h, void *obj)
{
struct _obstack_chunk *lp; /* below addr of any objects in this chunk */
struct _obstack_chunk *plp; /* point to previous chunk if any */
struct _obstack_chunk *lp; /* below addr of any objects in this chunk */
struct _obstack_chunk *plp; /* point to previous chunk if any */
lp = (h)->chunk;
/* We use >= rather than > since the object cannot be exactly at
@ -343,7 +343,7 @@ _obstack_allocated_p (struct obstack *h, void *obj)
}
return lp != 0;
}
/* Free objects in obstack H, including OBJ and everything allocate
more recently than OBJ. If OBJ is zero, free everything in H. */
@ -352,8 +352,8 @@ _obstack_allocated_p (struct obstack *h, void *obj)
void
obstack_free (struct obstack *h, void *obj)
{
struct _obstack_chunk *lp; /* below addr of any objects in this chunk */
struct _obstack_chunk *plp; /* point to previous chunk if any */
struct _obstack_chunk *lp; /* below addr of any objects in this chunk */
struct _obstack_chunk *plp; /* point to previous chunk if any */
lp = h->chunk;
/* We use >= because there cannot be an object at the beginning of a chunk.
@ -365,7 +365,7 @@ obstack_free (struct obstack *h, void *obj)
CALL_FREEFUN (h, lp);
lp = plp;
/* If we switch chunks, we can't tell whether the new current
chunk contains an empty object, so assume that it may. */
chunk contains an empty object, so assume that it may. */
h->maybe_empty_object = 1;
}
if (lp)
@ -384,11 +384,11 @@ obstack_free (struct obstack *h, void *obj)
called by non-GCC compilers. */
strong_alias (obstack_free, _obstack_free)
# endif
int
_obstack_memory_used (struct obstack *h)
{
struct _obstack_chunk* lp;
struct _obstack_chunk *lp;
int nbytes = 0;
for (lp = h->chunk; lp != 0; lp = lp->prev)
@ -397,7 +397,7 @@ _obstack_memory_used (struct obstack *h)
}
return nbytes;
}
/* Define the error handler. */
# ifdef _LIBC
# include <libintl.h>
@ -429,11 +429,10 @@ print_and_abort (void)
like this and the translation should be reused instead of creating
a very similar string which requires a separate translation. */
# ifdef _LIBC
(void) __fxprintf (NULL, "%s\n", _("memory exhausted"));
(void) __fxprintf (NULL, "%s\n", _ ("memory exhausted"));
# else
fprintf (stderr, "%s\n", _("memory exhausted"));
fprintf (stderr, "%s\n", _ ("memory exhausted"));
# endif
exit (obstack_exit_failure);
}
#endif /* !ELIDE_CODE */
#endif /* !ELIDE_CODE */

View File

@ -18,85 +18,85 @@
/* Summary:
All the apparent functions defined here are macros. The idea
is that you would use these pre-tested macros to solve a
very specific set of problems, and they would run fast.
Caution: no side-effects in arguments please!! They may be
evaluated MANY times!!
All the apparent functions defined here are macros. The idea
is that you would use these pre-tested macros to solve a
very specific set of problems, and they would run fast.
Caution: no side-effects in arguments please!! They may be
evaluated MANY times!!
These macros operate a stack of objects. Each object starts life
small, and may grow to maturity. (Consider building a word syllable
by syllable.) An object can move while it is growing. Once it has
been "finished" it never changes address again. So the "top of the
stack" is typically an immature growing object, while the rest of the
stack is of mature, fixed size and fixed address objects.
These macros operate a stack of objects. Each object starts life
small, and may grow to maturity. (Consider building a word syllable
by syllable.) An object can move while it is growing. Once it has
been "finished" it never changes address again. So the "top of the
stack" is typically an immature growing object, while the rest of the
stack is of mature, fixed size and fixed address objects.
These routines grab large chunks of memory, using a function you
supply, called `obstack_chunk_alloc'. On occasion, they free chunks,
by calling `obstack_chunk_free'. You must define them and declare
them before using any obstack macros.
These routines grab large chunks of memory, using a function you
supply, called `obstack_chunk_alloc'. On occasion, they free chunks,
by calling `obstack_chunk_free'. You must define them and declare
them before using any obstack macros.
Each independent stack is represented by a `struct obstack'.
Each of the obstack macros expects a pointer to such a structure
as the first argument.
Each independent stack is represented by a `struct obstack'.
Each of the obstack macros expects a pointer to such a structure
as the first argument.
One motivation for this package is the problem of growing char strings
in symbol tables. Unless you are "fascist pig with a read-only mind"
--Gosper's immortal quote from HAKMEM item 154, out of context--you
would not like to put any arbitrary upper limit on the length of your
symbols.
One motivation for this package is the problem of growing char strings
in symbol tables. Unless you are "fascist pig with a read-only mind"
--Gosper's immortal quote from HAKMEM item 154, out of context--you
would not like to put any arbitrary upper limit on the length of your
symbols.
In practice this often means you will build many short symbols and a
few long symbols. At the time you are reading a symbol you don't know
how long it is. One traditional method is to read a symbol into a
buffer, realloc()ating the buffer every time you try to read a symbol
that is longer than the buffer. This is beaut, but you still will
want to copy the symbol from the buffer to a more permanent
symbol-table entry say about half the time.
In practice this often means you will build many short symbols and a
few long symbols. At the time you are reading a symbol you don't know
how long it is. One traditional method is to read a symbol into a
buffer, realloc()ating the buffer every time you try to read a symbol
that is longer than the buffer. This is beaut, but you still will
want to copy the symbol from the buffer to a more permanent
symbol-table entry say about half the time.
With obstacks, you can work differently. Use one obstack for all symbol
names. As you read a symbol, grow the name in the obstack gradually.
When the name is complete, finalize it. Then, if the symbol exists already,
free the newly read name.
With obstacks, you can work differently. Use one obstack for all symbol
names. As you read a symbol, grow the name in the obstack gradually.
When the name is complete, finalize it. Then, if the symbol exists already,
free the newly read name.
The way we do this is to take a large chunk, allocating memory from
low addresses. When you want to build a symbol in the chunk you just
add chars above the current "high water mark" in the chunk. When you
have finished adding chars, because you got to the end of the symbol,
you know how long the chars are, and you can create a new object.
Mostly the chars will not burst over the highest address of the chunk,
because you would typically expect a chunk to be (say) 100 times as
long as an average object.
The way we do this is to take a large chunk, allocating memory from
low addresses. When you want to build a symbol in the chunk you just
add chars above the current "high water mark" in the chunk. When you
have finished adding chars, because you got to the end of the symbol,
you know how long the chars are, and you can create a new object.
Mostly the chars will not burst over the highest address of the chunk,
because you would typically expect a chunk to be (say) 100 times as
long as an average object.
In case that isn't clear, when we have enough chars to make up
the object, THEY ARE ALREADY CONTIGUOUS IN THE CHUNK (guaranteed)
so we just point to it where it lies. No moving of chars is
needed and this is the second win: potentially long strings need
never be explicitly shuffled. Once an object is formed, it does not
change its address during its lifetime.
In case that isn't clear, when we have enough chars to make up
the object, THEY ARE ALREADY CONTIGUOUS IN THE CHUNK (guaranteed)
so we just point to it where it lies. No moving of chars is
needed and this is the second win: potentially long strings need
never be explicitly shuffled. Once an object is formed, it does not
change its address during its lifetime.
When the chars burst over a chunk boundary, we allocate a larger
chunk, and then copy the partly formed object from the end of the old
chunk to the beginning of the new larger chunk. We then carry on
accreting characters to the end of the object as we normally would.
When the chars burst over a chunk boundary, we allocate a larger
chunk, and then copy the partly formed object from the end of the old
chunk to the beginning of the new larger chunk. We then carry on
accreting characters to the end of the object as we normally would.
A special macro is provided to add a single char at a time to a
growing object. This allows the use of register variables, which
break the ordinary 'growth' macro.
A special macro is provided to add a single char at a time to a
growing object. This allows the use of register variables, which
break the ordinary 'growth' macro.
Summary:
We allocate large chunks.
We carve out one object at a time from the current chunk.
Once carved, an object never moves.
We are free to append data of any size to the currently
growing object.
Exactly one object is growing in an obstack at any one time.
You can run one obstack per control block.
You may have as many control blocks as you dare.
Because of the way we do it, you can `unwind' an obstack
back to a previous state. (You may remove objects much
as you would with a stack.)
*/
Summary:
We allocate large chunks.
We carve out one object at a time from the current chunk.
Once carved, an object never moves.
We are free to append data of any size to the currently
growing object.
Exactly one object is growing in an obstack at any one time.
You can run one obstack per control block.
You may have as many control blocks as you dare.
Because of the way we do it, you can `unwind' an obstack
back to a previous state. (You may remove objects much
as you would with a stack.)
*/
/* Don't do the contents of this file more than once. */
@ -107,7 +107,7 @@ Summary:
#ifdef __cplusplus
extern "C" {
#endif
/* We need the type of a pointer subtraction. If __PTRDIFF_TYPE__ is
defined, as with GNU C, use that; that way we don't pollute the
namespace with <stddef.h>'s symbols. Otherwise, include <stddef.h>
@ -124,7 +124,7 @@ extern "C" {
aligning P to the next multiple of A + 1. B and P must be of type
char *. A + 1 must be a power of 2. */
#define __BPTR_ALIGN(B, P, A) ((B) + (((P) - (B) + (A)) & ~(A)))
#define __BPTR_ALIGN(B, P, A) ((B) + (((P) -(B) + (A)) & ~(A)))
/* Similiar to _BPTR_ALIGN (B, P, A), except optimize the common case
where pointers can be converted to integers, aligned as integers,
@ -133,61 +133,61 @@ extern "C" {
relative to B. Otherwise, use the faster strategy of computing the
alignment relative to 0. */
#define __PTR_ALIGN(B, P, A) \
#define __PTR_ALIGN(B, P, A) \
__BPTR_ALIGN (sizeof (PTR_INT_TYPE) < sizeof (void *) ? (B) : (char *) 0, \
P, A)
P, A)
#include <string.h>
struct _obstack_chunk /* Lives at front of each chunk. */
struct _obstack_chunk /* Lives at front of each chunk. */
{
char *limit; /* 1 past end of this chunk */
struct _obstack_chunk *prev; /* address of prior chunk or NULL */
char contents[4]; /* objects begin here */
char *limit; /* 1 past end of this chunk */
struct _obstack_chunk *prev; /* address of prior chunk or NULL */
char contents[4]; /* objects begin here */
};
struct obstack /* control current object in current chunk */
struct obstack /* control current object in current chunk */
{
long chunk_size; /* preferred size to allocate chunks in */
struct _obstack_chunk *chunk; /* address of current struct obstack_chunk */
char *object_base; /* address of object we are building */
char *next_free; /* where to add next char to current object */
char *chunk_limit; /* address of char after current chunk */
long chunk_size; /* preferred size to allocate chunks in */
struct _obstack_chunk *chunk; /* address of current struct obstack_chunk */
char *object_base; /* address of object we are building */
char *next_free; /* where to add next char to current object */
char *chunk_limit; /* address of char after current chunk */
union
{
PTR_INT_TYPE tempint;
void *tempptr;
} temp; /* Temporary for some macros. */
int alignment_mask; /* Mask of alignment for each object. */
} temp; /* Temporary for some macros. */
int alignment_mask; /* Mask of alignment for each object. */
/* These prototypes vary based on `use_extra_arg', and we use
casts to the prototypeless function type in all assignments,
but having prototypes here quiets -Wstrict-prototypes. */
struct _obstack_chunk *(*chunkfun) (void *, long);
void (*freefun) (void *, struct _obstack_chunk *);
void *extra_arg; /* first arg for chunk alloc/dealloc funcs */
unsigned use_extra_arg:1; /* chunk alloc/dealloc funcs take extra arg */
unsigned maybe_empty_object:1;/* There is a possibility that the current
chunk contains a zero-length object. This
prevents freeing the chunk if we allocate
a bigger chunk to replace it. */
unsigned alloc_failed:1; /* No longer used, as we now call the failed
handler on error, but retained for binary
compatibility. */
void *extra_arg; /* first arg for chunk alloc/dealloc funcs */
unsigned use_extra_arg : 1; /* chunk alloc/dealloc funcs take extra arg */
unsigned maybe_empty_object : 1; /* There is a possibility that the current
chunk contains a zero-length object. This
prevents freeing the chunk if we allocate
a bigger chunk to replace it. */
unsigned alloc_failed : 1; /* No longer used, as we now call the failed
handler on error, but retained for binary
compatibility. */
};
/* Declare the external functions we use; they are in obstack.c. */
extern void _obstack_newchunk (struct obstack *, int);
extern int _obstack_begin (struct obstack *, int, int,
void *(*) (long), void (*) (void *));
void *(*)(long), void (*)(void *));
extern int _obstack_begin_1 (struct obstack *, int, int,
void *(*) (void *, long),
void (*) (void *, void *), void *);
void *(*)(void *, long),
void (*)(void *, void *), void *);
extern int _obstack_memory_used (struct obstack *);
void obstack_free (struct obstack *__obstack, void *__glibc_block);
/* Error handler called when `obstack_chunk_alloc' failed to allocate
more memory. This can be set to a user defined function which
should either abort gracefully or use longjump - but shouldn't
@ -196,7 +196,7 @@ extern void (*obstack_alloc_failed_handler) (void);
/* Exit value used when `print_and_abort' is used. */
extern int obstack_exit_failure;
/* Pointer to beginning of object being allocated or to be allocated next.
Note that this might not be the final address of the object
because a new chunk might be needed to hold the final size. */
@ -209,45 +209,45 @@ extern int obstack_exit_failure;
/* Pointer to next byte not yet allocated in current chunk. */
#define obstack_next_free(h) ((h)->next_free)
#define obstack_next_free(h) ((h)->next_free)
/* Mask specifying low bits that should be clear in address of an object. */
#define obstack_alignment_mask(h) ((h)->alignment_mask)
/* To prevent prototype warnings provide complete argument list. */
#define obstack_init(h) \
_obstack_begin ((h), 0, 0, \
(void *(*) (long)) obstack_chunk_alloc, \
(void (*) (void *)) obstack_chunk_free)
#define obstack_init(h) \
_obstack_begin ((h), 0, 0, \
(void *(*)(long))obstack_chunk_alloc, \
(void (*)(void *))obstack_chunk_free)
#define obstack_begin(h, size) \
_obstack_begin ((h), (size), 0, \
(void *(*) (long)) obstack_chunk_alloc, \
(void (*) (void *)) obstack_chunk_free)
#define obstack_begin(h, size) \
_obstack_begin ((h), (size), 0, \
(void *(*)(long))obstack_chunk_alloc, \
(void (*)(void *))obstack_chunk_free)
#define obstack_specify_allocation(h, size, alignment, chunkfun, freefun) \
_obstack_begin ((h), (size), (alignment), \
(void *(*) (long)) (chunkfun), \
(void (*) (void *)) (freefun))
_obstack_begin ((h), (size), (alignment), \
(void *(*)(long))(chunkfun), \
(void (*)(void *))(freefun))
#define obstack_specify_allocation_with_arg(h, size, alignment, chunkfun, freefun, arg) \
_obstack_begin_1 ((h), (size), (alignment), \
(void *(*) (void *, long)) (chunkfun), \
(void (*) (void *, void *)) (freefun), (arg))
_obstack_begin_1 ((h), (size), (alignment), \
(void *(*)(void *, long))(chunkfun), \
(void (*)(void *, void *))(freefun), (arg))
#define obstack_chunkfun(h, newchunkfun) \
((h) -> chunkfun = (struct _obstack_chunk *(*)(void *, long)) (newchunkfun))
((h)->chunkfun = (struct _obstack_chunk *(*)(void *, long))(newchunkfun))
#define obstack_freefun(h, newfreefun) \
((h) -> freefun = (void (*)(void *, struct _obstack_chunk *)) (newfreefun))
((h)->freefun = (void (*)(void *, struct _obstack_chunk *))(newfreefun))
#define obstack_1grow_fast(h,achar) (*((h)->next_free)++ = (achar))
#define obstack_1grow_fast(h, achar) (*((h)->next_free)++ = (achar))
#define obstack_blank_fast(h,n) ((h)->next_free += (n))
#define obstack_blank_fast(h, n) ((h)->next_free += (n))
#define obstack_memory_used(h) _obstack_memory_used (h)
#if defined __GNUC__
/* NextStep 2.0 cc is really gcc 1.93 but it defines __GNUC__ = 2 and
does not implement __extension__. But that compiler doesn't define
@ -261,158 +261,158 @@ extern int obstack_exit_failure;
without using a global variable.
Also, we can avoid using the `temp' slot, to make faster code. */
# define obstack_object_size(OBSTACK) \
__extension__ \
({ struct obstack const *__o = (OBSTACK); \
(unsigned) (__o->next_free - __o->object_base); })
# define obstack_object_size(OBSTACK) \
__extension__ \
({ struct obstack const *__o = (OBSTACK); \
(unsigned) (__o->next_free - __o->object_base); })
# define obstack_room(OBSTACK) \
__extension__ \
({ struct obstack const *__o = (OBSTACK); \
(unsigned) (__o->chunk_limit - __o->next_free); })
# define obstack_room(OBSTACK) \
__extension__ \
({ struct obstack const *__o = (OBSTACK); \
(unsigned) (__o->chunk_limit - __o->next_free); })
# define obstack_make_room(OBSTACK,length) \
__extension__ \
({ struct obstack *__o = (OBSTACK); \
int __len = (length); \
if (__o->chunk_limit - __o->next_free < __len) \
_obstack_newchunk (__o, __len); \
(void) 0; })
# define obstack_make_room(OBSTACK, length) \
__extension__ \
({ struct obstack *__o = (OBSTACK); \
int __len = (length); \
if (__o->chunk_limit - __o->next_free < __len) \
_obstack_newchunk (__o, __len); \
(void) 0; })
# define obstack_empty_p(OBSTACK) \
__extension__ \
({ struct obstack const *__o = (OBSTACK); \
(__o->chunk->prev == 0 \
&& __o->next_free == __PTR_ALIGN ((char *) __o->chunk, \
__o->chunk->contents, \
__o->alignment_mask)); })
# define obstack_empty_p(OBSTACK) \
__extension__ \
({ struct obstack const *__o = (OBSTACK); \
(__o->chunk->prev == 0 \
&& __o->next_free == __PTR_ALIGN ((char *) __o->chunk, \
__o->chunk->contents, \
__o->alignment_mask)); })
# define obstack_grow(OBSTACK,where,length) \
__extension__ \
({ struct obstack *__o = (OBSTACK); \
int __len = (length); \
if (__o->next_free + __len > __o->chunk_limit) \
_obstack_newchunk (__o, __len); \
memcpy (__o->next_free, where, __len); \
__o->next_free += __len; \
(void) 0; })
# define obstack_grow(OBSTACK, where, length) \
__extension__ \
({ struct obstack *__o = (OBSTACK); \
int __len = (length); \
if (__o->next_free + __len > __o->chunk_limit) \
_obstack_newchunk (__o, __len); \
memcpy (__o->next_free, where, __len); \
__o->next_free += __len; \
(void) 0; })
# define obstack_grow0(OBSTACK,where,length) \
__extension__ \
({ struct obstack *__o = (OBSTACK); \
int __len = (length); \
if (__o->next_free + __len + 1 > __o->chunk_limit) \
_obstack_newchunk (__o, __len + 1); \
memcpy (__o->next_free, where, __len); \
__o->next_free += __len; \
*(__o->next_free)++ = 0; \
(void) 0; })
# define obstack_grow0(OBSTACK, where, length) \
__extension__ \
({ struct obstack *__o = (OBSTACK); \
int __len = (length); \
if (__o->next_free + __len + 1 > __o->chunk_limit) \
_obstack_newchunk (__o, __len + 1); \
memcpy (__o->next_free, where, __len); \
__o->next_free += __len; \
*(__o->next_free)++ = 0; \
(void) 0; })
# define obstack_1grow(OBSTACK,datum) \
__extension__ \
({ struct obstack *__o = (OBSTACK); \
if (__o->next_free + 1 > __o->chunk_limit) \
_obstack_newchunk (__o, 1); \
obstack_1grow_fast (__o, datum); \
(void) 0; })
# define obstack_1grow(OBSTACK, datum) \
__extension__ \
({ struct obstack *__o = (OBSTACK); \
if (__o->next_free + 1 > __o->chunk_limit) \
_obstack_newchunk (__o, 1); \
obstack_1grow_fast (__o, datum); \
(void) 0; })
/* These assume that the obstack alignment is good enough for pointers
or ints, and that the data added so far to the current object
shares that much alignment. */
# define obstack_ptr_grow(OBSTACK,datum) \
__extension__ \
({ struct obstack *__o = (OBSTACK); \
if (__o->next_free + sizeof (void *) > __o->chunk_limit) \
_obstack_newchunk (__o, sizeof (void *)); \
obstack_ptr_grow_fast (__o, datum); }) \
# define obstack_ptr_grow(OBSTACK, datum) \
__extension__ \
({ struct obstack *__o = (OBSTACK); \
if (__o->next_free + sizeof (void *) > __o->chunk_limit) \
_obstack_newchunk (__o, sizeof (void *)); \
obstack_ptr_grow_fast (__o, datum); }) \
# define obstack_int_grow(OBSTACK,datum) \
__extension__ \
({ struct obstack *__o = (OBSTACK); \
if (__o->next_free + sizeof (int) > __o->chunk_limit) \
_obstack_newchunk (__o, sizeof (int)); \
obstack_int_grow_fast (__o, datum); })
# define obstack_int_grow(OBSTACK, datum) \
__extension__ \
({ struct obstack *__o = (OBSTACK); \
if (__o->next_free + sizeof (int) > __o->chunk_limit) \
_obstack_newchunk (__o, sizeof (int)); \
obstack_int_grow_fast (__o, datum); })
# define obstack_ptr_grow_fast(OBSTACK,aptr) \
__extension__ \
({ struct obstack *__o1 = (OBSTACK); \
*(const void **) __o1->next_free = (aptr); \
__o1->next_free += sizeof (const void *); \
(void) 0; })
# define obstack_ptr_grow_fast(OBSTACK, aptr) \
__extension__ \
({ struct obstack *__o1 = (OBSTACK); \
*(const void **) __o1->next_free = (aptr); \
__o1->next_free += sizeof (const void *); \
(void) 0; })
# define obstack_int_grow_fast(OBSTACK,aint) \
__extension__ \
({ struct obstack *__o1 = (OBSTACK); \
*(int *) __o1->next_free = (aint); \
__o1->next_free += sizeof (int); \
(void) 0; })
# define obstack_int_grow_fast(OBSTACK, aint) \
__extension__ \
({ struct obstack *__o1 = (OBSTACK); \
*(int *) __o1->next_free = (aint); \
__o1->next_free += sizeof (int); \
(void) 0; })
# define obstack_blank(OBSTACK,length) \
__extension__ \
({ struct obstack *__o = (OBSTACK); \
int __len = (length); \
if (__o->chunk_limit - __o->next_free < __len) \
_obstack_newchunk (__o, __len); \
obstack_blank_fast (__o, __len); \
(void) 0; })
# define obstack_blank(OBSTACK, length) \
__extension__ \
({ struct obstack *__o = (OBSTACK); \
int __len = (length); \
if (__o->chunk_limit - __o->next_free < __len) \
_obstack_newchunk (__o, __len); \
obstack_blank_fast (__o, __len); \
(void) 0; })
# define obstack_alloc(OBSTACK,length) \
__extension__ \
({ struct obstack *__h = (OBSTACK); \
obstack_blank (__h, (length)); \
obstack_finish (__h); })
# define obstack_alloc(OBSTACK, length) \
__extension__ \
({ struct obstack *__h = (OBSTACK); \
obstack_blank (__h, (length)); \
obstack_finish (__h); })
# define obstack_copy(OBSTACK,where,length) \
__extension__ \
({ struct obstack *__h = (OBSTACK); \
obstack_grow (__h, (where), (length)); \
obstack_finish (__h); })
# define obstack_copy(OBSTACK, where, length) \
__extension__ \
({ struct obstack *__h = (OBSTACK); \
obstack_grow (__h, (where), (length)); \
obstack_finish (__h); })
# define obstack_copy0(OBSTACK,where,length) \
__extension__ \
({ struct obstack *__h = (OBSTACK); \
obstack_grow0 (__h, (where), (length)); \
obstack_finish (__h); })
# define obstack_copy0(OBSTACK, where, length) \
__extension__ \
({ struct obstack *__h = (OBSTACK); \
obstack_grow0 (__h, (where), (length)); \
obstack_finish (__h); })
/* The local variable is named __o1 to avoid a name conflict
when obstack_blank is called. */
# define obstack_finish(OBSTACK) \
__extension__ \
({ struct obstack *__o1 = (OBSTACK); \
void *__value = (void *) __o1->object_base; \
if (__o1->next_free == __value) \
__o1->maybe_empty_object = 1; \
__o1->next_free \
= __PTR_ALIGN (__o1->object_base, __o1->next_free, \
__o1->alignment_mask); \
if (__o1->next_free - (char *)__o1->chunk \
> __o1->chunk_limit - (char *)__o1->chunk) \
__o1->next_free = __o1->chunk_limit; \
__o1->object_base = __o1->next_free; \
__value; })
# define obstack_finish(OBSTACK) \
__extension__ \
({ struct obstack *__o1 = (OBSTACK); \
void *__value = (void *) __o1->object_base; \
if (__o1->next_free == __value) \
__o1->maybe_empty_object = 1; \
__o1->next_free \
= __PTR_ALIGN (__o1->object_base, __o1->next_free, \
__o1->alignment_mask); \
if (__o1->next_free - (char *) __o1->chunk \
> __o1->chunk_limit - (char *) __o1->chunk) \
__o1->next_free = __o1->chunk_limit; \
__o1->object_base = __o1->next_free; \
__value; })
# define obstack_free(OBSTACK, OBJ) \
__extension__ \
({ struct obstack *__o = (OBSTACK); \
void *__obj = (OBJ); \
if (__obj > (void *) __o->chunk && __obj < (void *) __o->chunk_limit) \
__o->next_free = __o->object_base = (char *) __obj; \
else (obstack_free) (__o, __obj); })
# define obstack_free(OBSTACK, OBJ) \
__extension__ \
({ struct obstack *__o = (OBSTACK); \
void *__obj = (OBJ); \
if (__obj > (void *)__o->chunk && __obj < (void *)__o->chunk_limit) \
__o->next_free = __o->object_base = (char *)__obj; \
else (obstack_free) (__o, __obj); })
#else /* not __GNUC__ */
# define obstack_object_size(h) \
(unsigned) ((h)->next_free - (h)->object_base)
(unsigned) ((h)->next_free - (h)->object_base)
# define obstack_room(h) \
(unsigned) ((h)->chunk_limit - (h)->next_free)
# define obstack_room(h) \
(unsigned) ((h)->chunk_limit - (h)->next_free)
# define obstack_empty_p(h) \
((h)->chunk->prev == 0 \
&& (h)->next_free == __PTR_ALIGN ((char *) (h)->chunk, \
(h)->chunk->contents, \
(h)->alignment_mask))
((h)->chunk->prev == 0 \
&& (h)->next_free == __PTR_ALIGN ((char *) (h)->chunk, \
(h)->chunk->contents, \
(h)->alignment_mask))
/* Note that the call to _obstack_newchunk is enclosed in (..., 0)
so that we can avoid having void expressions
@ -420,88 +420,86 @@ __extension__ \
Casting the third operand to void was tried before,
but some compilers won't accept it. */
# define obstack_make_room(h,length) \
( (h)->temp.tempint = (length), \
(((h)->next_free + (h)->temp.tempint > (h)->chunk_limit) \
# define obstack_make_room(h, length) \
((h)->temp.tempint = (length), \
(((h)->next_free + (h)->temp.tempint > (h)->chunk_limit) \
? (_obstack_newchunk ((h), (h)->temp.tempint), 0) : 0))
# define obstack_grow(h,where,length) \
( (h)->temp.tempint = (length), \
(((h)->next_free + (h)->temp.tempint > (h)->chunk_limit) \
? (_obstack_newchunk ((h), (h)->temp.tempint), 0) : 0), \
memcpy ((h)->next_free, where, (h)->temp.tempint), \
(h)->next_free += (h)->temp.tempint)
# define obstack_grow(h, where, length) \
((h)->temp.tempint = (length), \
(((h)->next_free + (h)->temp.tempint > (h)->chunk_limit) \
? (_obstack_newchunk ((h), (h)->temp.tempint), 0) : 0), \
memcpy ((h)->next_free, where, (h)->temp.tempint), \
(h)->next_free += (h)->temp.tempint)
# define obstack_grow0(h,where,length) \
( (h)->temp.tempint = (length), \
(((h)->next_free + (h)->temp.tempint + 1 > (h)->chunk_limit) \
? (_obstack_newchunk ((h), (h)->temp.tempint + 1), 0) : 0), \
memcpy ((h)->next_free, where, (h)->temp.tempint), \
(h)->next_free += (h)->temp.tempint, \
*((h)->next_free)++ = 0)
# define obstack_grow0(h, where, length) \
((h)->temp.tempint = (length), \
(((h)->next_free + (h)->temp.tempint + 1 > (h)->chunk_limit) \
? (_obstack_newchunk ((h), (h)->temp.tempint + 1), 0) : 0), \
memcpy ((h)->next_free, where, (h)->temp.tempint), \
(h)->next_free += (h)->temp.tempint, \
*((h)->next_free)++ = 0)
# define obstack_1grow(h,datum) \
( (((h)->next_free + 1 > (h)->chunk_limit) \
? (_obstack_newchunk ((h), 1), 0) : 0), \
obstack_1grow_fast (h, datum))
# define obstack_1grow(h, datum) \
((((h)->next_free + 1 > (h)->chunk_limit) \
? (_obstack_newchunk ((h), 1), 0) : 0), \
obstack_1grow_fast (h, datum))
# define obstack_ptr_grow(h,datum) \
( (((h)->next_free + sizeof (char *) > (h)->chunk_limit) \
? (_obstack_newchunk ((h), sizeof (char *)), 0) : 0), \
obstack_ptr_grow_fast (h, datum))
# define obstack_ptr_grow(h, datum) \
((((h)->next_free + sizeof (char *) > (h)->chunk_limit) \
? (_obstack_newchunk ((h), sizeof (char *)), 0) : 0), \
obstack_ptr_grow_fast (h, datum))
# define obstack_int_grow(h,datum) \
( (((h)->next_free + sizeof (int) > (h)->chunk_limit) \
? (_obstack_newchunk ((h), sizeof (int)), 0) : 0), \
obstack_int_grow_fast (h, datum))
# define obstack_int_grow(h, datum) \
((((h)->next_free + sizeof (int) > (h)->chunk_limit) \
? (_obstack_newchunk ((h), sizeof (int)), 0) : 0), \
obstack_int_grow_fast (h, datum))
# define obstack_ptr_grow_fast(h,aptr) \
# define obstack_ptr_grow_fast(h, aptr) \
(((const void **) ((h)->next_free += sizeof (void *)))[-1] = (aptr))
# define obstack_int_grow_fast(h,aint) \
# define obstack_int_grow_fast(h, aint) \
(((int *) ((h)->next_free += sizeof (int)))[-1] = (aint))
# define obstack_blank(h,length) \
( (h)->temp.tempint = (length), \
(((h)->chunk_limit - (h)->next_free < (h)->temp.tempint) \
? (_obstack_newchunk ((h), (h)->temp.tempint), 0) : 0), \
obstack_blank_fast (h, (h)->temp.tempint))
# define obstack_blank(h, length) \
((h)->temp.tempint = (length), \
(((h)->chunk_limit - (h)->next_free < (h)->temp.tempint) \
? (_obstack_newchunk ((h), (h)->temp.tempint), 0) : 0), \
obstack_blank_fast (h, (h)->temp.tempint))
# define obstack_alloc(h,length) \
(obstack_blank ((h), (length)), obstack_finish ((h)))
# define obstack_alloc(h, length) \
(obstack_blank ((h), (length)), obstack_finish ((h)))
# define obstack_copy(h,where,length) \
(obstack_grow ((h), (where), (length)), obstack_finish ((h)))
# define obstack_copy(h, where, length) \
(obstack_grow ((h), (where), (length)), obstack_finish ((h)))
# define obstack_copy0(h,where,length) \
(obstack_grow0 ((h), (where), (length)), obstack_finish ((h)))
# define obstack_copy0(h, where, length) \
(obstack_grow0 ((h), (where), (length)), obstack_finish ((h)))
# define obstack_finish(h) \
( ((h)->next_free == (h)->object_base \
? (((h)->maybe_empty_object = 1), 0) \
: 0), \
(h)->temp.tempptr = (h)->object_base, \
(h)->next_free \
= __PTR_ALIGN ((h)->object_base, (h)->next_free, \
(h)->alignment_mask), \
(((h)->next_free - (char *) (h)->chunk \
> (h)->chunk_limit - (char *) (h)->chunk) \
? ((h)->next_free = (h)->chunk_limit) : 0), \
(h)->object_base = (h)->next_free, \
(h)->temp.tempptr)
# define obstack_finish(h) \
(((h)->next_free == (h)->object_base \
? (((h)->maybe_empty_object = 1), 0) \
: 0), \
(h)->temp.tempptr = (h)->object_base, \
(h)->next_free \
= __PTR_ALIGN ((h)->object_base, (h)->next_free, \
(h)->alignment_mask), \
(((h)->next_free - (char *) (h)->chunk \
> (h)->chunk_limit - (char *) (h)->chunk) \
? ((h)->next_free = (h)->chunk_limit) : 0), \
(h)->object_base = (h)->next_free, \
(h)->temp.tempptr)
# define obstack_free(h,obj) \
( (h)->temp.tempint = (char *) (obj) - (char *) (h)->chunk, \
((((h)->temp.tempint > 0 \
&& (h)->temp.tempint < (h)->chunk_limit - (char *) (h)->chunk)) \
? (((h)->next_free = (h)->object_base \
= (h)->temp.tempint + (char *) (h)->chunk), 0) \
# define obstack_free(h, obj) \
((h)->temp.tempint = (char *) (obj) - (char *) (h)->chunk, \
((((h)->temp.tempint > 0 \
&& (h)->temp.tempint < (h)->chunk_limit - (char *) (h)->chunk)) \
? (((h)->next_free = (h)->object_base \
= (h)->temp.tempint + (char *) (h)->chunk), 0) \
: ((obstack_free) ((h), (h)->temp.tempint + (char *) (h)->chunk), 0)))
#endif /* not __GNUC__ */
#ifdef __cplusplus
} /* C++ */
} /* C++ */
#endif
#endif /* obstack.h */

View File

@ -33,17 +33,17 @@ __libc_freeres (void)
protect for multiple executions since these are fatal. */
static long int already_called;
if (! atomic_compare_and_exchange_bool_acq (&already_called, 1, 0))
if (!atomic_compare_and_exchange_bool_acq (&already_called, 1, 0))
{
void * const *p;
void *const *p;
_IO_cleanup ();
RUN_HOOK (__libc_subfreeres, ());
for (p = symbol_set_first_element (__libc_freeres_ptrs);
! symbol_set_end_p (__libc_freeres_ptrs, p); ++p)
free (*p);
!symbol_set_end_p (__libc_freeres_ptrs, p); ++p)
free (*p);
}
}
libc_hidden_def (__libc_freeres)

View File

@ -48,19 +48,19 @@ main (void)
free (malloc (10));
for (i=0; i<100; ++i)
for (i = 0; i < 100; ++i)
{
save_state = malloc_get_state ();
if (save_state == NULL)
{
merror ("malloc_get_state () failed.");
break;
}
{
merror ("malloc_get_state () failed.");
break;
}
/*free (malloc (10)); This could change the top chunk! */
malloc_set_state (save_state);
p1 = realloc (p1, i*4 + 4);
p1 = realloc (p1, i * 4 + 4);
if (p1 == NULL)
merror ("realloc (i*4) failed.");
merror ("realloc (i*4) failed.");
free (save_state);
}

View File

@ -55,20 +55,20 @@ main (void)
ssize_t n = getline (&line, &linelen, fp);
if (n < 0)
break;
break;
if (n == 0)
continue;
continue;
copy = strdup (line);
if (copy == NULL)
abort ();
abort ();
p = (char **) tsearch (copy, &root,
(int (*) (const void *, const void *)) strcmp);
(int (*)(const void *, const void *))strcmp);
if (*p != copy)
/* This line wasn't added. */
free (copy);
/* This line wasn't added. */
free (copy);
}
fclose (fp);

View File

@ -79,11 +79,11 @@ do_test (void)
for (i = 0; i < 20; i++)
{
if (c[i] != 0)
ok = 0;
ok = 0;
}
if (ok == 0)
merror ("first 20 bytes were not cleared");
merror ("first 20 bytes were not cleared");
free (p);
@ -104,11 +104,11 @@ do_test (void)
for (i = 0; i < 16; i++)
{
if (c[i] != 0xff)
ok = 0;
ok = 0;
}
if (ok == 0)
merror ("first 16 bytes were not correct");
merror ("first 16 bytes were not correct");
/* Check failed realloc leaves original untouched (C89). */
c = realloc (p, -1);
@ -121,11 +121,11 @@ do_test (void)
for (i = 0; i < 16; i++)
{
if (c[i] != 0xff)
ok = 0;
ok = 0;
}
if (ok == 0)
merror ("first 16 bytes were not correct after failed realloc");
merror ("first 16 bytes were not correct after failed realloc");
/* realloc (p, 0) frees p (C89) and returns NULL (glibc). */
p = realloc (p, 0);