callgraph

runtime callgraph generator
git clone git://git.2f30.org/callgraph
Log | Files | Refs | README | LICENSE

commit 992805a678fb84b64f201a1d4abf8b99b47d1ac8
parent efedcd4b641ea255f9d37ca0f34c27d259ac0bdd
Author: lostd <lostd@2f30.org>
Date:   Thu, 14 Nov 2013 21:57:09 +0200

Remove original file

Diffstat:
Dcallgraph.c | 198-------------------------------------------------------------------------------
1 file changed, 0 insertions(+), 198 deletions(-)

diff --git a/callgraph.c b/callgraph.c @@ -1,198 +0,0 @@ -/* runtime callgraph generator by stateless */ - -#include <stdio.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <stdlib.h> -#include <unistd.h> -#include <errno.h> -#include <string.h> -#include <stdint.h> -#include <inttypes.h> -#include <assert.h> - -struct fnode_t { - uintptr_t addr; - struct fnode_t *next; -}; - -struct fpair_t { - uintptr_t l, r; /* l is the caller, r is the callee */ - struct fpair_t *next; -}; - -/* essentially a stack of function calls */ -static struct fnode_t *fnode_head = NULL; -static struct fnode_t *fnode_tail = NULL; - -/* a list of function pairs (caller -> callee) */ -static struct fpair_t *fpair_head = NULL; -static struct fpair_t *fpair_tail = NULL; - -static int fd = -1; -static char logbuf[BUFSIZ]; - -static void * -xmalloc(size_t size) -{ - void *p; - - p = malloc(size); - if (!p) - _Exit(EXIT_FAILURE); - return p; -} - -static ssize_t -writelog(int fildes, const void *buf, size_t nbyte) -{ - ssize_t w, r, tmp; - - w = 0; - r = nbyte; - if (r < 0) return 0; - do { -again: - tmp = write(fildes, (const char *)buf + w, r); - if (tmp <= 0) { - if (tmp) - if (errno == EINTR) - goto again; - return tmp; - } - w += tmp; - r -= tmp; - } while (r > 0); - return w; -} - -__attribute__ ((constructor)) static void -init_logging(void) -{ - char *f; - - f = getenv("CGRAPH_OUT"); - if (!f) { - fprintf(stderr, "cgraph: CGRAPH_OUT is not set!\n"); - _Exit(EXIT_FAILURE); - } - - fd = open(f, O_WRONLY | O_CREAT, 0644); - if (fd < 0 || ftruncate(fd, 0) < 0) { - perror("cgraph"); - _Exit(EXIT_FAILURE); - } -} - -__attribute__ ((destructor)) static void -deinit_logging(void) -{ - struct fpair_t *p, *tmppair; - struct fnode_t *n, *tmpnode; - - writelog(fd, "digraph G {\n", - strlen("digraph G {\n")); - p = fpair_head; - while (p) { - snprintf(logbuf, sizeof logbuf, - "\t \"%"PRIxPTR"\" -> \"%"PRIxPTR"\"\n", p->l, p->r); - writelog(fd, logbuf, strlen(logbuf)); - p = p->next; - } - writelog(fd, "}\n", 2); - - if (fd != -1) - if (close(fd) < 0) - perror("cgraph"); - - p = fpair_head; - while (p) { - tmppair = p->next; - free(p); - p = tmppair; - } - n = fnode_head; - while (n) { - tmpnode = n->next; - free(n); - n = tmpnode; - } -} - -static void -push_fnode(uintptr_t addr) -{ - if (!fnode_head) { - fnode_head = xmalloc(sizeof(struct fnode_t)); - fnode_head->addr = addr; - fnode_head->next = NULL; - fnode_tail = fnode_head; - } else { - fnode_tail->next = xmalloc(sizeof(struct fnode_t)); - fnode_tail = fnode_tail->next; - fnode_tail->next = NULL; - fnode_tail->addr = addr; - } -} - -static void -pop_fnode(void) -{ - struct fnode_t *i; - - assert(fnode_tail); - for (i = fnode_head; i; i = i->next) - if (i->next == fnode_tail) - break; - if (!i) return; - free(fnode_tail); - fnode_tail = i; - fnode_tail->next = NULL; -} - -static inline struct fnode_t * -get_top(void) { - return fnode_tail; -} - -static void -add_fpair(uintptr_t r) -{ - struct fnode_t *curfun; - - curfun = get_top(); - if (!fpair_head) { - fpair_head = xmalloc(sizeof(struct fpair_t)); - fpair_head->l = curfun->addr; - fpair_head->r = r; - fpair_head->next = NULL; - fpair_tail = fpair_head; - } else { - fpair_tail->next = xmalloc(sizeof(struct fpair_t)); - fpair_tail = fpair_tail->next; - fpair_tail->l = curfun->addr; - fpair_tail->r = r; - fpair_tail->next = NULL; - } -} - -void -__cyg_profile_func_enter(void *func_address, - __attribute__ ((unused)) void *call_site) -{ - struct fnode_t *n; - - n = get_top(); - if (n) - add_fpair((uintptr_t)func_address); - push_fnode((uintptr_t)func_address); -} - -void -__cyg_profile_func_exit ( - __attribute__ ((unused)) void *func_address, - __attribute__ ((unused)) void *call_site) -{ - pop_fnode(); -} -