2014-11-19 00:25:21 +08:00
|
|
|
#include "lib_acl.h"
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
char name[256];
|
|
|
|
int ncalloc;
|
|
|
|
int nmalloc;
|
|
|
|
int nstrdup;
|
|
|
|
int nfree;
|
|
|
|
} FNAME;
|
|
|
|
|
|
|
|
static ACL_HTABLE *__table = NULL;
|
|
|
|
|
|
|
|
static FNAME *fname_new(const char *name)
|
|
|
|
{
|
|
|
|
FNAME *fname = (FNAME*) acl_mycalloc(1, sizeof(FNAME));
|
|
|
|
|
|
|
|
ACL_SAFE_STRNCPY(fname->name, name, sizeof(fname->name));
|
|
|
|
return (fname);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void fname_free(FNAME *fname)
|
|
|
|
{
|
|
|
|
acl_myfree(fname);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void run(const char *path)
|
|
|
|
{
|
|
|
|
ACL_FILE *fp = acl_fopen(path, "r");
|
|
|
|
FNAME *fname;
|
|
|
|
char buf[4096];
|
|
|
|
ACL_ITER iter;
|
|
|
|
int nfree = 0, nmalloc = 0, ncalloc = 0, nstrdup = 0;
|
|
|
|
|
|
|
|
if (fp == NULL) {
|
|
|
|
printf("open file(%s) error(%s)\n", path, acl_last_serror());
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
__table = acl_htable_create(100, 0);
|
|
|
|
|
|
|
|
while (acl_fgets_nonl(buf, sizeof(buf), fp) != NULL) {
|
|
|
|
ACL_ARGV *argv = acl_argv_split(buf, " ");
|
|
|
|
const char *oper, *name;
|
|
|
|
|
|
|
|
if (argv->argc != 8) {
|
|
|
|
acl_argv_free(argv);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
oper = argv->argv[5];
|
|
|
|
name = argv->argv[6];
|
|
|
|
if (strcmp(oper, "free:") == 0) {
|
|
|
|
fname = (FNAME*) acl_htable_find(__table, name);
|
|
|
|
if (fname == NULL) {
|
|
|
|
fname = fname_new(name);
|
|
|
|
acl_htable_enter(__table, name, fname);
|
|
|
|
}
|
|
|
|
fname->nfree++;
|
|
|
|
} else if (strcmp(oper, "malloc:") == 0) {
|
|
|
|
fname = (FNAME*) acl_htable_find(__table, name);
|
|
|
|
if (fname == NULL) {
|
|
|
|
fname = fname_new(name);
|
|
|
|
acl_htable_enter(__table, name, fname);
|
|
|
|
}
|
|
|
|
fname->nmalloc++;
|
|
|
|
} else if (strcmp(oper, "calloc:") == 0) {
|
|
|
|
fname = (FNAME*) acl_htable_find(__table, name);
|
|
|
|
if (fname == NULL) {
|
|
|
|
fname = fname_new(name);
|
|
|
|
acl_htable_enter(__table, name, fname);
|
|
|
|
}
|
|
|
|
fname->ncalloc++;
|
|
|
|
} else if (strcmp(oper, "strdup:") == 0) {
|
|
|
|
fname = (FNAME*) acl_htable_find(__table, name);
|
|
|
|
if (fname == NULL) {
|
|
|
|
fname = fname_new(name);
|
|
|
|
acl_htable_enter(__table, name, fname);
|
|
|
|
}
|
|
|
|
fname->nstrdup++;
|
|
|
|
}
|
|
|
|
acl_argv_free(argv);
|
|
|
|
}
|
|
|
|
|
|
|
|
acl_foreach(iter, __table) {
|
|
|
|
fname = (FNAME*) iter.data;
|
|
|
|
nmalloc += fname->nmalloc;
|
|
|
|
ncalloc += fname->ncalloc;
|
|
|
|
nstrdup += fname->nstrdup;
|
|
|
|
nfree += fname->nfree;
|
|
|
|
if (fname->nmalloc + fname->ncalloc + fname->nstrdup == fname->nfree)
|
|
|
|
continue;
|
|
|
|
printf(">>>%s: total free: %d, total alloc: %d (malloc: %d, calloc: %d, strdup: %d)\n",
|
|
|
|
fname->name, fname->nfree, fname->nmalloc + fname->ncalloc + fname->nstrdup,
|
|
|
|
fname->nmalloc, fname->ncalloc, fname->nstrdup);
|
|
|
|
}
|
|
|
|
|
|
|
|
printf(">>> total free: %d, total alloc: %d (malloc: %d, calloc: %d, strdup: %d)\n",
|
|
|
|
nfree, nmalloc + ncalloc + nstrdup, nmalloc, ncalloc, nstrdup);
|
|
|
|
|
|
|
|
acl_htable_free(__table, (void (*)(void*)) fname_free);
|
|
|
|
acl_fclose(fp);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void usage(const char *procname)
|
|
|
|
{
|
|
|
|
printf("usage: %s -h [help] -f log_path\n", procname);
|
|
|
|
}
|
|
|
|
|
|
|
|
int main(int argc, char *argv[])
|
|
|
|
{
|
|
|
|
char ch, path[256] = "";
|
|
|
|
|
|
|
|
while ((ch = getopt(argc, argv, "hf:")) > 0) {
|
|
|
|
switch (ch) {
|
|
|
|
case 'f':
|
|
|
|
snprintf(path, sizeof(path), "%s", optarg);
|
|
|
|
break;
|
|
|
|
case 'h':
|
|
|
|
default:
|
|
|
|
usage(argv[0]);
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (path[0] == 0) {
|
|
|
|
usage(argv[0]);
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
|
|
|
run(path);
|
|
|
|
|
|
|
|
return (0);
|
|
|
|
}
|