Esempio n. 1
0
MP_GLOBAL
void
__mp_deleteheap(heaphead *h)
{
    heapnode *n, *p;

    /* Free up the memory pointed to by the heap nodes first, since the
     * heap nodes themselves are freed in the second loop.
     */
    for (n = (heapnode *) __mp_minimum(h->dtree.root); n != NULL; n = p)
    {
        p = (heapnode *) __mp_successor(&n->node);
        __mp_heapfree(h, n);
    }
    for (n = (heapnode *) __mp_minimum(h->itree.root); n != NULL; n = p)
    {
        p = (heapnode *) __mp_successor(&n->node);
        __mp_treeremove(&h->itree, &n->node);
        __mp_memfree(&h->memory, n->block, n->size);
    }
    __mp_endmemory(&h->memory);
    h->table.free = NULL;
    h->table.size = 0;
    h->isize = 0;
    h->prot = MA_NOACCESS;
    h->protrecur = 0;
    h->tracing = 0;
}
Esempio n. 2
0
static
void
deletegraph(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) != NULL; e = m)
    {
        __mp_remove(&edgelist, &e->node);
        free(e);
    }
}
Esempio n. 3
0
MP_GLOBAL
int
__mp_heapprotect(heaphead *h, memaccess a)
{
    heapnode *n;

    /* The library already knows what its protection status is so we don't
     * need to do anything if the request has already been done.
     */
    if (h->prot == a)
    {
        h->protrecur++;
        return 1;
    }
    else if (h->protrecur > 0)
    {
        h->protrecur--;
        return 1;
    }
    h->prot = a;
    for (n = (heapnode *) __mp_minimum(h->itree.root); n != NULL;
         n = (heapnode *) __mp_successor(&n->node))
        if (!__mp_memprotect(&h->memory, n->block, n->size, a))
            return 0;
    return 1;
}
Esempio n. 4
0
MP_GLOBAL
int
__mp_protectalloc(allochead *h, memaccess a)
{
    allocnode *n;
    treenode *t;

    if (!__mp_heapprotect(&h->heap, a))
        return 0;
    /* The library already knows what its protection status is so we don't
     * need to do anything if the request has already been done.
     */
    if (h->prot == a)
    {
        h->protrecur++;
        return 1;
    }
    else if (h->protrecur > 0)
    {
        h->protrecur--;
        return 1;
    }
    h->prot = a;
    for (t = __mp_minimum(h->itree.root); t != NULL; t = __mp_successor(t))
    {
        n = (allocnode *) ((char *) t - offsetof(allocnode, tnode));
        if (!__mp_memprotect(&h->heap.memory, n->block, n->size, a))
            return 0;
    }
    return 1;
}
Esempio n. 5
0
static
void
freeallocs(void)
{
    allocation *n, *p;

    for (n = (allocation *) __mp_minimum(alloctree.root); n != NULL; n = p)
    {
        p = (allocation *) __mp_successor(&n->node);
        __mp_treeremove(&alloctree, &n->node);
        free(n);
    }
}
Esempio n. 6
0
static
void
directtable(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);
}
Esempio n. 7
0
static
void
buildgraph(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;
}
Esempio n. 8
0
static
void
callgraph(void)
{
    size_t d[4];
    listnode *l;
    vertex *u, *v;
    edge *e;
    graphedge *g;
    size_t i, s, t;

    i = 1;
    printchar(' ', 29);
    fputs("ALLOCATION CALL GRAPH\n\n", stdout);
    printchar(' ', 28);
    fprintf(stdout, "(number of vertices: %lu)\n\n", temptree.size);
    if (showcounts)
    {
        printchar(' ', 10);
        fputs("allocated", stdout);
        printchar(' ', 13);
        fputs("unfreed\n", stdout);
        printchar(' ', 5);
        printchar('-', 19);
        fputs("  ", stdout);
        printchar('-', 19);
        fputs("\nindex count   s  m  l  x   count   s  m  l  x  function\n",
              stdout);
    }
    else
    {
        printchar(' ', 11);
        fputs("allocated", stdout);
        printchar(' ', 15);
        fputs("unfreed\n", stdout);
        printchar(' ', 5);
        printchar('-', 21);
        fputs("  ", stdout);
        printchar('-', 21);
        fputs("\nindex   bytes   s  m  l  x     bytes   s  m  l  x  function\n",
              stdout);
    }
    /* Compute the index for each vertex in the graph.  This is currently
     * done after the graph has been completely constructed so that the
     * ordering can be done by code address.  It has to be done before we
     * start displaying the graph since each vertex will contain forward
     * references to its parents and children.
     */
    for (v = (vertex *) __mp_minimum(temptree.root); v != NULL;
         v = (vertex *) __mp_successor(&v->node))
        v->index = i++;
    for (v = (vertex *) __mp_minimum(temptree.root); v != NULL;
         v = (vertex *) __mp_successor(&v->node))
    {
        if (showcounts)
            printchar('-', 45);
        else
            printchar('-', 49);
        fputc('\n', stdout);
        /* Calculate the details of the parents.
         */
        for (l = v->gnode.parents.head; l->next != NULL; l = l->next)
        {
            /* The following three lines are a bit excessive and result from
             * using class-based programming in C.  These conversions would be
             * automatically calculated by the compiler if we were using C++
             * classes.
             */
            g = (graphedge *) ((char *) l - offsetof(graphedge, pnode));
            e = (edge *) ((char *) g - offsetof(edge, gnode));
            u = (vertex *) ((char *) e->gnode.parent - offsetof(vertex, gnode));
            if (&u->gnode != &graph.start)
            {
                for (i = s = t = 0; i < 4; i++)
                {
                    if (showcounts)
                    {
                        t += e->data.acount[i];
                        d[i] = e->data.acount[i] - e->data.dcount[i];
                    }
                    else
                    {
                        t += e->data.atotal[i];
                        d[i] = e->data.atotal[i] - e->data.dtotal[i];
                    }
                    s += d[i];
                }
                if (e->flags & 2)
                    fputs(" (*) ", stdout);
                else
                    printchar(' ', 5);
                if (showcounts)
                {
                    fprintf(stdout, "%6lu ", t);
                    printdata(e->data.acount, t);
                    fprintf(stdout, "  %6lu ", s);
                }
                else
                {
                    fprintf(stdout, "%8lu ", t);
                    printdata(e->data.atotal, t);
                    fprintf(stdout, "  %8lu ", s);
                }
                printdata(d, s);
                printchar(' ', 6);
                printsymbol(stdout, u->pnode);
                fprintf(stdout, " [%lu]\n", u->index);
            }
        }
        fprintf(stdout, "[%lu] ", v->index);
        if (showcounts)
            printchar(' ', 44 - countdigits(v->index));
        else
            printchar(' ', 48 - countdigits(v->index));
        printsymbol(stdout, v->pnode);
        fprintf(stdout, " [%lu]\n", v->index);
        /* Calculate the details of the children.
         */
        for (l = v->gnode.children.head; l->next != NULL; l = l->next)
        {
            /* The following three lines are a bit excessive and result from
             * using class-based programming in C.  These conversions would be
             * automatically calculated by the compiler if we were using C++
             * classes.
             */
            g = (graphedge *) ((char *) l - offsetof(graphedge, cnode));
            e = (edge *) ((char *) g - offsetof(edge, gnode));
            u = (vertex *) ((char *) e->gnode.child - offsetof(vertex, gnode));
            if (&u->gnode != &graph.end)
            {
                for (i = s = t = 0; i < 4; i++)
                {
                    if (showcounts)
                    {
                        t += e->data.acount[i];
                        d[i] = e->data.acount[i] - e->data.dcount[i];
                    }
                    else
                    {
                        t += e->data.atotal[i];
                        d[i] = e->data.atotal[i] - e->data.dtotal[i];
                    }
                    s += d[i];
                }
                if (e->flags & 2)
                    fputs(" (*) ", stdout);
                else
                    printchar(' ', 5);
                if (showcounts)
                {
                    fprintf(stdout, "%6lu ", t);
                    printdata(e->data.acount, t);
                    fprintf(stdout, "  %6lu ", s);
                }
                else
                {
                    fprintf(stdout, "%8lu ", t);
                    printdata(e->data.atotal, t);
                    fprintf(stdout, "  %8lu ", s);
                }
                printdata(d, s);
                printchar(' ', 6);
                printsymbol(stdout, u->pnode);
                fprintf(stdout, " [%lu]\n", u->index);
            }
        }
    }
}
Esempio n. 9
0
static
void
leaktable(void)
{
    profiledata *d;
    profilenode *n, *p;
    treenode *t;
    size_t i;
    unsigned long a, b, j, k;
    double e, f, g;

    printchar(' ', 34);
    fputs("MEMORY LEAKS\n\n", stdout);
    printchar(' ', 28);
    fprintf(stdout, "(maximum stack depth: %lu)\n\n", maxstack);
    printchar(' ', 16);
    fputs("unfreed", stdout);
    printchar(' ', 22);
    fputs("allocated\n", stdout);
    printchar('-', 40);
    fputs("  ", stdout);
    printchar('-', 16);
    if (showcounts)
        fputs("\n     %   count       %     bytes       %   "
              "count     bytes  function\n\n", stdout);
    else
        fputs("\n     %     bytes       %   count       %     "
              "bytes   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) && !n->flags)
        {
            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) && !p->flags && comparestack(n, p, 0))
                {
                    sumdata(d, &data[p->data - 1]);
                    p->flags = 1;
                }
                p = (profilenode *) __mp_successor(&p->node);
            }
            p = (profilenode *) __mp_successor(&n->node);
            a = 0;
            for (i = 0; i < 4; i++)
                if (showcounts)
                    a += d->acount[i] - d->dcount[i];
                else
                    a += d->atotal[i] - d->dtotal[i];
            if (a > 0)
                __mp_treeinsert(&temptree, &n->tnode, a);
        }
    }
    for (n = (profilenode *) __mp_minimum(proftree.root); n != NULL;
         n = (profilenode *) __mp_successor(&n->node))
        n->flags = 0;
    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 = j = k = 0;
        for (i = 0; i < 4; i++)
            if (showcounts)
            {
                b += d->dtotal[i];
                j += d->acount[i];
                k += d->atotal[i];
            }
            else
            {
                b += d->dcount[i];
                j += d->atotal[i];
                k += d->acount[i];
            }
        b = k - b;
        e = ((double) a / (double) j) * 100.0;
        f = ((double) b / (double) k) * 100.0;
        if (showcounts)
        {
            g = ((double) a / (double) (acount - dcount)) * 100.0;
            fprintf(stdout, "%6.2f  %6lu  %6.2f  %8lu  %6.2f  %6lu  %8lu  ",
                    g, a, e, b, f, j, k);
        }
        else
        {
            g = ((double) a / (double) (atotal - dtotal)) * 100.0;
            fprintf(stdout, "%6.2f  %8lu  %6.2f  %6lu  %6.2f  %8lu  %6lu  ",
                    g, a, e, b, f, j, k);
        }
        printsymbol(stdout, n);
        fputc('\n', stdout);
        p = n;
        for (i = 1; (maxstack == 0) || (i < maxstack); i++)
        {
            if (p->parent == 0)
                break;
            p = &nodes[p->parent - 1];
            printchar(' ', 60);
            printsymbol(stdout, p);
            fputc('\n', stdout);
        }
        cleardata(d);
    }
    if (acount != 0)
        e = ((double) (acount - dcount) / (double) acount) * 100.0;
    else
        e = 0.0;
    if (atotal != 0)
        f = ((double) (atotal - dtotal) / (double) atotal) * 100.0;
    else
        f = 0.0;
    if (temptree.size != 0)
        fputc('\n', stdout);
    if (showcounts)
        fprintf(stdout, "        %6lu  %6.2f  %8lu  %6.2f  %6lu  %8lu  total\n",
                acount - dcount, e, atotal - dtotal, f, acount, atotal);
    else
        fprintf(stdout, "        %8lu  %6.2f  %6lu  %6.2f  %8lu  %6lu  total\n",
                atotal - dtotal, f, acount - dcount, e, atotal, acount);
    __mp_newtree(&temptree);
}