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

📄 mprof.c

📁 debug source code under unix platform.
💻 C
📖 第 1 页 / 共 3 页
字号:
    {        if ((nodes = (profilenode *) malloc(nodesize * sizeof(profilenode))) ==            NULL)        {            fprintf(stderr, "%s: Out of memory\n", progname);            exit(EXIT_FAILURE);        }        for (i = 0; i < nodesize; i++)        {            getentry(&n, sizeof(unsigned long), 1, b);            p = &nodes[n - 1];            getentry(&p->parent, sizeof(unsigned long), 1, b);            getentry(&p->addr, sizeof(void *), 1, b);            getentry(&p->symbol, sizeof(unsigned long), 1, b);            getentry(&p->name, sizeof(unsigned long), 1, b);            getentry(&p->data, sizeof(unsigned long), 1, b);            __mp_treeinsert(&proftree, &p->node, (unsigned long) p->addr);            cleardata(&p->tdata);            p->flags = 0;        }    }    /* Read the table containing the symbol addresses.     */    getentry(&i, sizeof(size_t), 1, b);    if (i > 0)    {        if ((addrs = (void **) malloc(i * sizeof(void *))) == NULL)        {            fprintf(stderr, "%s: Out of memory\n", progname);            exit(EXIT_FAILURE);        }        getentry(addrs, sizeof(void *), i, b);    }    /* Read the string table containing the symbol names.     */    getentry(&i, sizeof(size_t), 1, b);    if (i > 0)    {        if ((symbols = (char *) malloc(i * sizeof(char))) == NULL)        {            fprintf(stderr, "%s: Out of memory\n", progname);            exit(EXIT_FAILURE);        }        getentry(symbols, sizeof(char), i, 0);    }    getentry(s, sizeof(char), 4, 0);    if (memcmp(s, MP_PROFMAGIC, 4) != 0)    {        fprintf(stderr, "%s: Invalid file format\n", progname);        exit(EXIT_FAILURE);    }}/* Count the number of decimal digits in a number. */staticunsigned charcountdigits(unsigned long n){    unsigned char d;    for (d = 1; n /= 10; d++);    return d;}/* Display a character a specified number of times. */staticvoidprintchar(char c, size_t n){    size_t i;    for (i = 0; i < n; i++)        fputc(c, stdout);}/* Display a set of profiling data. */staticvoidprintdata(size_t *d, size_t t){    size_t i;    double n;    for (i = 0; i < 4; i++)        if ((d[i] == 0) || (t == 0))            fputs("   ", stdout);        else        {            n = ((double) d[i] / (double) t) * 100.0;            if (n <= 0.5)                fputs("  .", stdout);            else if (n >= 99.5)                fputs(" %%", stdout);            else                fprintf(stdout, " %2.0f", n);        }}/* Display the symbol associated with a particular call site. */staticvoidprintsymbol(FILE *f, profilenode *n){    ptrdiff_t o;    if (n->name == 0)        fprintf(f, MP_POINTER, n->addr);    else    {        fputs(symbols + n->name, f);        if (useaddresses && (n->symbol != 0) &&            ((o = (char *) n->addr - (char *) addrs[n->symbol - 1]) != 0))            fprintf(f, "%+ld", o);    }}/* Add a new vertex to the allocation call graph. */staticvertex *addvertex(profilenode *n){    vertex *v;    if ((v = (vertex *) malloc(sizeof(vertex))) == NULL)    {        fprintf(stderr, "%s: Out of memory\n", progname);        exit(EXIT_FAILURE);    }    if (useaddresses || (n->symbol == 0))        __mp_treeinsert(&temptree, &v->node, (unsigned long) n->addr);    else        __mp_treeinsert(&temptree, &v->node, n->symbol);    __mp_addnode(&graph, &v->gnode);    v->pnode = n;    v->index = 0;    return v;}/* Add a new edge to the allocation call graph. */staticedge *addedge(graphnode *p, graphnode *c){    edge *e;    if ((e = (edge *) malloc(sizeof(edge))) == NULL)    {        fprintf(stderr, "%s: Out of memory\n", progname);        exit(EXIT_FAILURE);    }    __mp_addtail(&edgelist, &e->node);    __mp_addedge(&graph, &e->gnode, p, c);    cleardata(&e->data);    e->flags = 0;    return e;}/* Build the allocation call graph. */staticvoidbuildgraph(void){    profilenode *n, *p;    vertex *u, *v;    edge *e;    graphedge *g;    profiledata d;    for (n = (profilenode *) __mp_minimum(proftree.root); n != NULL;         n = (profilenode *) __mp_successor(&n->node))        if ((n->data != 0) && !(n->flags & 1))        {            cleardata(&d);            sumdata(&d, &data[n->data - 1]);            p = (profilenode *) __mp_successor(&n->node);            while ((p != NULL) && ((p->addr == n->addr) || (!useaddresses &&                     (p->symbol != 0) && (p->symbol == n->symbol))))            {                if ((p->data != 0) && !(p->flags & 1) && comparestack(n, p, 1))                {                    sumdata(&d, &data[p->data - 1]);                    p->flags |= 1;                }                p = (profilenode *) __mp_successor(&p->node);            }            p = n;            if (useaddresses || (p->symbol == 0))                u = (vertex *) __mp_search(temptree.root,                                           (unsigned long) p->addr);            else                u = (vertex *) __mp_search(temptree.root, p->symbol);            if (u == NULL)                u = addvertex(p);            if ((g = __mp_findedge(&graph, &u->gnode, &graph.end)) == NULL)                e = addedge(&u->gnode, &graph.end);            else                e = (edge *) ((char *) g - offsetof(edge, gnode));            sumdata(&e->data, &d);            u->pnode->flags |= 2;            for (v = u; p->parent != 0; u = v)            {                p = &nodes[p->parent - 1];                if (useaddresses || (p->symbol == 0))                    v = (vertex *) __mp_search(temptree.root,                                               (unsigned long) p->addr);                else                    v = (vertex *) __mp_search(temptree.root, p->symbol);                if (v == NULL)                    v = addvertex(p);                if ((g = __mp_findedge(&graph, &v->gnode, &u->gnode)) == NULL)                    e = addedge(&v->gnode, &u->gnode);                else                    e = (edge *) ((char *) g - offsetof(edge, gnode));                /* Find out if we've been here before.  If we have then we have                 * detected a cycle in the call graph and we should not                 * contribute anything to the current edge since we have done so                 * already.  However, we mark the edge as being part of a cycle                 * since it is useful to know this later on.                 */                if (v->pnode->flags & 2)                    e->flags |= 2;                else                {                    sumdata(&e->data, &d);                    v->pnode->flags |= 2;                }            }            if ((g = __mp_findedge(&graph, &graph.start, &v->gnode)) == NULL)                e = addedge(&graph.start, &v->gnode);            else                e = (edge *) ((char *) g - offsetof(edge, gnode));            sumdata(&e->data, &d);            /* Clear all of the flags from the current call stack that we used             * to determine cycles in the call graph.             */            p = n;            do            {                if (useaddresses || (p->symbol == 0))                    v = (vertex *) __mp_search(temptree.root,                                               (unsigned long) p->addr);                else                    v = (vertex *) __mp_search(temptree.root, p->symbol);                v->pnode->flags &= ~2;                if (p->parent != 0)                    p = &nodes[p->parent - 1];                else                    p = NULL;            }            while (p != NULL);        }    for (n = (profilenode *) __mp_minimum(proftree.root); n != NULL;         n = (profilenode *) __mp_successor(&n->node))        n->flags = 0;}/* Delete the allocation call graph. */staticvoiddeletegraph(void){    vertex *n, *v;    edge *e, *m;    /* Remove the nodes from the graph and free up the memory that they     * inhabit.  This is done by traversing the tree rather than the graph     * in order to avoid deleting nodes that result in other nodes being     * inaccessible.     */    for (v = (vertex *) __mp_minimum(temptree.root); v != NULL; v = n)    {        n = (vertex *) __mp_successor(&v->node);        __mp_treeremove(&temptree, &v->node);        __mp_removenode(&graph, &v->gnode);        free(v);    }    /* Remove the edges from the graph.  The graph is now empty following     * the removal of the nodes in the previous loop, so we just need to     * free the memory that each edge uses.     */    for (e = (edge *) edgelist.head; m = (edge *) e->node.next; e = m)    {        __mp_remove(&edgelist, &e->node);        free(e);    }}/* Display the allocation bin table. */staticvoidbintable(void){    size_t i;    unsigned long a, b, c, d;    double e, f, g, h;    int p;    p = 0;    printchar(' ', 32);    fputs("ALLOCATION BINS\n\n", stdout);    printchar(' ', 29);    fprintf(stdout, "(number of bins: %lu)\n\n", binsize);    printchar(' ', 21);    fputs("allocated", stdout);    printchar(' ', 26);    fputs("unfreed\n", stdout);    printchar(' ', 10);    printchar('-', 32);    fputs("  ", stdout);    printchar('-', 32);    fputs("\n    size   count       %     bytes       %   "          "count       %     bytes       %\n\n", stdout);    for (i = 0; i < binsize; i++)        if (acounts[i] != 0)        {            a = acounts[i];            b = a - dcounts[i];            if (i == binsize - 1)            {                c = atotals;                d = c - dtotals;            }            else            {                c = a * (i + 1);                d = b * (i + 1);            }            e = ((double) a / (double) acount) * 100.0;            if (acount != dcount)                f = ((double) b / (double) (acount - dcount)) * 100.0;            else                f = 0.0;            g = ((double) c / (double) atotal) * 100.0;            if (atotal != dtotal)                h = ((double) d / (double) (atotal - dtotal)) * 100.0;            else                h = 0.0;            fprintf(stdout, " %s %4lu  %6lu  %6.2f  %8lu  %6.2f  "                    "%6lu  %6.2f  %8lu  %6.2f\n",                    (i == binsize - 1) ? ">=" : "  ",                    i + 1, a, e, c, g, b, f, d, h);            p = 1;        }    if (p == 1)        fputc('\n', stdout);    fprintf(stdout, "   total  %6lu          %8lu          "            "%6lu          %8lu\n", acount, atotal,            acount - dcount, atotal - dtotal);}/* Display the direct allocation table. */staticvoiddirecttable(void){    profiledata *d;    profilenode *n, *p;    treenode *t;    profiledata m;    size_t i;    unsigned long a, b, c;    double e, f;    cleardata(&m);    printchar(' ', 31);    fputs("DIRECT ALLOCATIONS\n\n", stdout);    printchar(' ', 20);    fprintf(stdout, "(0 < s <= %lu < m <= %lu < l <= %lu < x)\n\n",            sbound, mbound, lbound);    if (showcounts)    {        printchar(' ', 9);        fputs("allocated", stdout);        printchar(' ', 21);        fputs("unfreed\n", stdout);        printchar('-', 27);        fputs("  ", stdout);        printchar('-', 27);        fputs("\n count       %   s  m  l  x   "              "count       %   s  m  l  x     bytes  function\n\n", stdout);    }    else    {        printchar(' ', 10);        fputs("allocated", stdout);        printchar(' ', 23);        fputs("unfreed\n", stdout);        printchar('-', 29);        fputs("  ", stdout);        printchar('-', 29);        fputs("\n   bytes       %   s  m  l  x     "              "bytes       %   s  m  l  x   count  function\n\n", stdout);    }    for (n = (profilenode *) __mp_minimum(proftree.root); n != NULL; n = p)    {        p = (profilenode *) __mp_successor(&n->node);        if (n->data != 0)        {            d = &n->tdata;            sumdata(d, &data[n->data - 1]);            while ((p != NULL) && ((p->addr == n->addr) || (!useaddresses &&                     (p->symbol != 0) && (p->symbol == n->symbol))))            {                if (p->data != 0)                    sumdata(d, &data[p->data - 1]);                p = (profilenode *) __mp_successor(&p->node);            }            a = 0;            for (i = 0; i < 4; i++)                if (showcounts)                    a += d->acount[i];                else                    a += d->atotal[i];            __mp_treeinsert(&temptree, &n->tnode, a);            sumdata(&m, d);        }    }    for (t = __mp_maximum(temptree.root); t != NULL; t = __mp_predecessor(t))    {        n = (profilenode *) ((char *) t - offsetof(profilenode, tnode));        d = &n->tdata;        a = t->key;        b = c = 0;        for (i = 0; i < 4; i++)        {            if (showcounts)            {                b += d->dcount[i];                c += d->atotal[i];            }            else            {                b += d->dtotal[i];                c += d->acount[i];            }            d->dcount[i] = d->acount[i] - d->dcount[i];            d->dtotal[i] = d->atotal[i] - d->dtotal[i];        }        b = a - b;        if (showcounts)        {            e = ((double) a / (double) acount) * 100.0;            if (acount != dcount)                f = ((double) b / (double) (acount - dcount)) * 100.0;            else                f = 0.0;            fprintf(stdout, "%6lu  %6.2f ", a, e);            printdata(d->acount, acount);            fprintf(stdout, "  %6lu  %6.2f ", b, f);            printdata(d->dcount, acount - dcount);            fprintf(stdout, "  %8lu  ", c);        }        else        {            e = ((double) a / (double) atotal) * 100.0;            if (atotal != dtotal)                f = ((double) b / (double) (atotal - dtotal)) * 100.0;            else                f = 0.0;            fprintf(stdout, "%8lu  %6.2f ", a, e);            printdata(d->atotal, atotal);            fprintf(stdout, "  %8lu  %6.2f ", b, f);            printdata(d->dtotal, atotal - dtotal);            fprintf(stdout, "  %6lu  ", c);        }        printsymbol(stdout, n);        fputc('\n', stdout);        cleardata(d);    }    for (i = 0; i < 4; i++)    {        m.dcount[i] = m.acount[i] - m.dcount[i];        m.dtotal[i] = m.atotal[i] - m.dtotal[i];    }    if (temptree.size != 0)        fputc('\n', stdout);    if (showcounts)    {        fprintf(stdout, "%6lu         ", acount);        printdata(m.acount, acount);        fprintf(stdout, "  %6lu         ", acount - dcount);        printdata(m.dcount, acount - dcount);        fprintf(stdout, "  %8lu  total\n", atotal);    }    else    {        fprintf(stdout, "%8lu         ", atotal);        printdata(m.atotal, atotal);        fprintf(stdout, "  %8lu         ", atotal - dtotal);        printdata(m.dtotal, atotal - dtotal);        fprintf(stdout, "  %6lu  total\n", acount);    }    __mp_newtree(&temptree);}/* Display the memory leak table. */

⌨️ 快捷键说明

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