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

📄 profile.c

📁 debug source code under unix platform.
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * mpatrol * A library for controlling and tracing dynamic memory allocations. * Copyright (C) 1997-2002 Graeme S. Roy <graeme.roy@analog.com> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307, USA. *//* * Memory allocation profiling.  The call graphs for every memory allocation * and deallocation are recorded here along with their memory usage statistics * and are written to a file for later processing by a profiling tool. */#include "profile.h"#include "info.h"#include "diag.h"#include "utils.h"#include "version.h"#include <stdio.h>#include <string.h>#if MP_IDENT_SUPPORT#ident "$Id: profile.c,v 1.38 2002/01/08 20:13:59 graeme Exp $"#else /* MP_IDENT_SUPPORT */static MP_CONST MP_VOLATILE char *profile_id = "$Id: profile.c,v 1.38 2002/01/08 20:13:59 graeme Exp $";#endif /* MP_IDENT_SUPPORT */#ifdef __cplusplusextern "C"{#endif /* __cplusplus *//* Initialise the fields of a profhead so that the mpatrol library * is ready to profile memory allocations. */MP_GLOBALvoid__mp_newprofile(profhead *p, heaphead *h, symhead *s){    struct { char x; profdata y; } w;    struct { char x; profnode y; } z;    size_t i;    long n;    p->heap = h;    p->syms = s;    /* Determine the minimum alignment for a profdata structure and a     * profnode on this system and force the alignments to be a power     * of two.  This information is used when initialising the slot     * tables.     */    n = (char *) &w.y - &w.x;    __mp_newslots(&p->dtable, sizeof(profdata), __mp_poweroftwo(n));    n = (char *) &z.y - &z.x;    __mp_newslots(&p->ntable, sizeof(profnode), __mp_poweroftwo(n));    __mp_newlist(&p->ilist);    __mp_newlist(&p->list);    __mp_newtree(&p->tree);    p->size = 0;    for (i = 0; i < MP_BIN_SIZE; i++)        p->acounts[i] = p->dcounts[i] = 0;    p->atotals = p->dtotals = 0;    p->sbound = MP_SMALLBOUND;    p->mbound = MP_MEDIUMBOUND;    p->lbound = MP_LARGEBOUND;    p->autosave = p->autocount = 0;    p->file = __mp_proffile(&h->memory, NULL);    p->prot = MA_NOACCESS;    p->protrecur = 0;    p->profiling = 0;}/* Forget all existing profiling information. */MP_GLOBALvoid__mp_deleteprofile(profhead *p){    size_t i;    /* We don't need to explicitly free any memory as this is dealt with     * at a lower level by the heap manager.     */    p->heap = NULL;    p->syms = NULL;    p->dtable.free = NULL;    p->dtable.size = 0;    p->ntable.free = NULL;    p->ntable.size = 0;    __mp_newlist(&p->ilist);    __mp_newlist(&p->list);    __mp_newtree(&p->tree);    p->size = 0;    for (i = 0; i < MP_BIN_SIZE; i++)        p->acounts[i] = p->dcounts[i] = 0;    p->atotals = p->dtotals = 0;    p->autocount = 0;    p->file = NULL;    p->prot = MA_NOACCESS;    p->protrecur = 0;    p->profiling = 0;}/* Allocate a new profiling data structure. */staticprofdata *getprofdata(profhead *p){    profdata *d;    heapnode *h;    size_t i;    /* If we have no more profiling data structure slots left then we must     * allocate some more memory for them.  An extra MP_ALLOCFACTOR pages     * of memory should suffice.     */    if ((d = (profdata *) __mp_getslot(&p->dtable)) == NULL)    {        if ((h = __mp_heapalloc(p->heap, p->heap->memory.page * MP_ALLOCFACTOR,              p->dtable.entalign, 1)) == NULL)            return NULL;        __mp_initslots(&p->dtable, h->block, h->size);        d = (profdata *) __mp_getslot(&p->dtable);        __mp_addtail(&p->ilist, &d->index.node);        d->index.block = h->block;        d->index.size = h->size;        p->size += h->size;        d = (profdata *) __mp_getslot(&p->dtable);    }    __mp_addtail(&p->list, &d->data.node);    d->data.index = p->list.size;    for (i = 0; i < 4; i++)    {        d->data.acount[i] = d->data.dcount[i] = 0;        d->data.atotal[i] = d->data.dtotal[i] = 0;    }    return d;}/* Allocate a new profiling node. */staticprofnode *getprofnode(profhead *p){    profnode *n;    heapnode *h;    /* If we have no more profnode slots left then we must allocate     * some more memory for them.  An extra MP_ALLOCFACTOR pages of memory     * should suffice.     */    if ((n = (profnode *) __mp_getslot(&p->ntable)) == NULL)    {        if ((h = __mp_heapalloc(p->heap, p->heap->memory.page * MP_ALLOCFACTOR,              p->ntable.entalign, 1)) == NULL)            return NULL;        __mp_initslots(&p->ntable, h->block, h->size);        n = (profnode *) __mp_getslot(&p->ntable);        __mp_addtail(&p->ilist, &n->index.node);        n->index.block = h->block;        n->index.size = h->size;        p->size += h->size;        n = (profnode *) __mp_getslot(&p->ntable);    }    return n;}/* Locate or create a call site associated with a specified return address. */staticprofnode *getcallsite(profhead *p, addrnode *a){    profnode *n, *t;    addrnode *d;    if (n = (profnode *) __mp_search(p->tree.root,        (unsigned long) a->data.addr))    {        while ((t = (profnode *) __mp_predecessor(&n->data.node)) &&               (t->data.addr == a->data.addr))            n = t;        while ((n != NULL) && (n->data.addr == a->data.addr))        {            for (t = n->data.parent, d = a->data.next;                 (t != NULL) && (d != NULL);                 t = t->data.parent, d = d->data.next)                if (t->data.addr != d->data.addr)                    break;            if ((t == NULL) && (d == NULL))                return n;            n = (profnode *) __mp_successor(&n->data.node);        }    }    t = NULL;    if (((n = getprofnode(p)) == NULL) || ((a->data.next != NULL) &&         ((t = getcallsite(p, a->data.next)) == NULL)))    {        if (n != NULL)            __mp_freeslot(&p->ntable, n);        return NULL;    }    __mp_treeinsert(&p->tree, &n->data.node, (unsigned long) a->data.addr);    n->data.parent = t;    n->data.index = p->tree.size;    n->data.addr = a->data.addr;    n->data.symbol = __mp_findsymbol(p->syms, a->data.addr);    n->data.data = NULL;    return n;}/* Record a memory allocation for profiling. */MP_GLOBALint__mp_profilealloc(profhead *p, size_t l, void *d, int w){    profnode *n;    infonode *m;    size_t i;    /* Try to associate the allocation with a previous call site, or create     * a new call site if no such site exists.  This information is not     * recorded if the return address could not be determined.     */    m = (infonode *) d;    if ((m->data.stack != NULL) && (m->data.stack->data.addr != NULL))    {        if (((n = getcallsite(p, m->data.stack)) == NULL) ||            ((n->data.data == NULL) &&             ((n->data.data = getprofdata(p)) == NULL)))            return 0;        if (l <= p->sbound)            i = 0;        else if (l <= p->mbound)            i = 1;        else if (l <= p->lbound)

⌨️ 快捷键说明

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