diff -urN v22/mem.c v23/mem.c --- v22/mem.c 2018-09-14 21:50:19.000000000 +0900 +++ v23/mem.c 2018-09-14 21:53:22.000000000 +0900 @@ -78,6 +78,40 @@ free(p); } +struct callback{ + struct callback *prev, *next; + + const char *func; + void (*f)(void *p); +}; + +static struct callback *top_cb = NULL; + +void +mem_add_callback(const char *func, void (*f)(void *p)) +{ + struct callback *cb = malloc( sizeof(*cb) ); + cb->func = func; + cb->f = f; + top_cb = chain_add_tail(top_cb, cb); +} + +static void +call_cb(struct node *nd) +{ + struct callback *cb = top_cb; + + while(cb){ + if( strcmp(cb->func, nd->func) == 0 ){ + break; + } + cb = cb->next == top_cb ? NULL : cb->next; + } + if(cb){ + (*cb->f)(nd->p); + } +} + void mem_show(void) { @@ -87,6 +121,9 @@ while(nd){ fprintf(stderr, "%p %d %s %s %d %s()\n", nd->p, nd->sz, nd->kind, nd->filename, nd->line, nd->func); + + call_cb(nd); + nd = nd->next == top ? NULL : nd->next; } fprintf(stderr, "\n"); diff -urN v22/mem.h v23/mem.h --- v22/mem.h 2018-09-14 21:50:19.000000000 +0900 +++ v23/mem.h 2018-09-14 21:53:22.000000000 +0900 @@ -6,6 +6,7 @@ char *mem_strndup(const char *s, int n, const char *filename, int line, const char *func); void mem_free(void *p, const char *filename, int line, const char *func); +void mem_add_callback(const char *func, void (*f)(void *p)); void mem_show(void); #ifdef MEM_DBG @@ -15,6 +16,7 @@ #define free(p) mem_free(p, __FILE__, __LINE__, __func__) #else #define mem_show() +#define mem_add_callback(func, f) #endif #endif diff -urN v22/objs.c v23/objs.c --- v22/objs.c 2018-09-14 21:50:19.000000000 +0900 +++ v23/objs.c 2018-09-14 21:53:22.000000000 +0900 @@ -98,11 +98,85 @@ } } +#ifdef MEM_DBG + +static char * +typ_name(int typ) +{ + struct{ + int typ; + char *name; + } lst[]= { + { OBJ_TYP_INT, "int" }, + { OBJ_TYP_DOUBLE, "double" }, + { OBJ_TYP_PTR, "ptr" }, + { OBJ_TYP_OBJS, "objs" }, + { OBJ_TYP_BOOL, "bool" }, + { OBJ_TYP_LIST, "list" }, + { OBJ_TYP_DICT, "dict" }, + { OBJ_TYP_STR, "str" }, + { OBJ_TYP_BUF, "buf" }, + }; + int n = sizeof(lst) / sizeof(*lst), i; + + for(i=0; ityp) ); + + switch(obj->typ){ + case OBJ_TYP_INT: + fprintf( stderr, "i=%d\n", obj->any.i ); + break; + case OBJ_TYP_BOOL: + fprintf( stderr, "bool=%s\n", obj->any.i ? "True" : "False" ); + break; + case OBJ_TYP_DOUBLE: + fprintf( stderr, "d=%g\n", obj->any.d ); + break; + + case OBJ_TYP_PTR: + fprintf( stderr, "p=%p\n", obj_ptr(obj) ); + break; + case OBJ_TYP_STR: + fprintf( stderr, "str='%s'\n", obj_ptr(obj) ? (char *) obj_ptr(obj) : "(NULL)" ); + break; + case OBJ_TYP_BUF: + fprintf( stderr, "p=%p sz=%d n=%d\n", obj_ptr(obj), obj->sz, obj->n ); + break; + } + + if( OBJ_TYP_BASE(obj->typ) == OBJ_TYP_OBJS ){ + fprintf( stderr, "objs.n=%d\n", obj->any.objs.n ); + } +} + +#endif + struct obj * obj_new(int typ, void *vp) { struct obj *obj = malloc( sizeof(*obj) ); + +#ifdef MEM_DBG + static int done = 0; + if(!done){ + mem_add_callback(__func__, dbg_obj_new); + done++; + } +#endif obj_init(obj, typ, vp); + return obj; }