#! /usr/bin/perl # eg. cd ../src; /bin/ls *|xargs -i -t ../perl/debug.pl {} /tmp/src $Alloc = 'alloc'; $Src = $ARGV[0]; $Dst = $ARGV[1]; $Done = 0; if (!$Src || !$Dst) { print STDERR "debug.pl [file.c] [destination-directory]" . "\n"; exit 1; } if (!(-d $Dst)) { print STDERR "$Dst: Not a directory" . "\n"; exit 1; } if (!(-f $Src) || $Src =~ /\//) { print STDERR "$Src: No such file in current directory" . "\n"; exit 1; } exit 0 if ($Src eq $Alloc . '.h'); open(GREP, "grep tcb_ " . $Src . "|"); $Done = 0; while (!$Done && ) { $Done++; } close(GREP); $Dst .= '/' if (!($Dst =~ /\/$/)); $Dst .= $Src; open(SRC, $Src); open(DST, '>' . $Dst); $i = 0; while () { if (!$Done) { if (/calloc\(/) { s/calloc\(/tcb_calloc\(\042$Src:$i\042\, /; $i++; } if (/malloc\(/) { s/malloc\(/tcb_malloc\(\042$Src:$i\042\, /; $i++; } if (/strdup\(/) { s/strdup\(/tcb_strdup\(\042$Src:$i\042\, /; $i++; } if (/free\(/) { s/free\(/tcb_free\(\042$Src:$i\042\, /; $i++; } } print DST; } close (SRC); close (DST); exit 0 if ($Src ne $Alloc . '.c'); $Dst =~ s/\.c/\.h/; open(DST, '>' . $Dst); print DST < typedef struct ALLOC { char *name; u_int addr; struct { u_int type : 2; u_int size : 30; } f; struct ALLOC *next; } ALLOC; static ALLOC *hashALLOC[N_hash]; static void *incALLOC(u_int addr, int type, int size, char name[]) { ALLOC *ap; int i; if ((ap = (ALLOC*)malloc(sizeof(ALLOC)))) { ap->name = name; ap->addr = addr; ap->f.type = type; ap->f.size = size; i = addr & (N_hash-1); ap->next = hashALLOC[i]; hashALLOC[i] = ap; } return ap; } static ALLOC *decALLOC(u_int addr, char name[]) { ALLOC *ap, *ab, *a0; int i; /* delete `addr' from list */ i = addr & (N_hash-1); a0 = hashALLOC[i]; for (ab = ap = a0; ap && ap->addr != addr; ap = ap->next) ab = ap; if (ap) if (ap == a0) { hashALLOC[i] = ap->next; free(ap); } else { ab->next = ap->next; free(ap); } else incALLOC(addr, 3, addr, name); return ap; } int printALLOC(char *name) { ALLOC *ap, *ai; int i, j; save_stderr("CHECK_FREE: "); for (i = j = 0; i < N_hash; i++) { for (ap = hashALLOC[i]; ap; ) { if (!j) if (name) save_stderr("error!! (%s)\\n", name); else save_stderr("error!!\\n"); switch(ap->f.type) { case 0: save_stderr("calloc: %s=%d", ap->name, ap->f.size); break; case 1: save_stderr("malloc: %s=%d", ap->name, ap->f.size); break; case 2: save_stderr("strdup: %s=%d", ap->name, ap->f.size); break; case 3: save_stderr("free: %s=0x%x", ap->name, ap->addr); break; } if (name) save_stderr(" (%s)\\n", name); else save_stderr("\\n"); j = 1; ai = ap; ap = ap->next; free(ai); } } if (!j) if (name) save_stderr("ok. (%s)\\n", name); else save_stderr("ok. \\n"); return j; } void *TCBcalloc(char name[], int n, int size) { void *vp; if ((vp = calloc(n, size))) if (!incALLOC((u_int)vp, 0, n*size, name)) vp = NULL; return vp; } void *TCBmalloc(char name[], int size) { void *vp; if ((vp = malloc(size))) if (!incALLOC((u_int)vp, 1, size, name)) vp = NULL; return vp; } char *TCBstrdup(char name[], const char *s) { char *cp; if ((cp = strdup(s))) if (!incALLOC((u_int)cp, 2, strlen(s) + 1, name)) cp = NULL; return cp; } void TCBfree(char name[], void *vp) { if (decALLOC((u_int)vp, name)) free(vp); } void initALLOC(void) { /* for SHELL (child process) */ int i; for (i = 0; i < N_hash; i++) hashALLOC[i] = NULL; } #else int printALLOC(char *name) { return 0; } void initALLOC(void) { } #endif CHECK_FREE #endif _ALLOC_H EOF close(DST);