#include #include #include #include #include #define Smem_included_by_smem_C #include "smem.h" /* ------------------------------ SmemiteM ----------------------------- */ int Smemitem_new(item,data,size,next,hash_start,flag) struct SmemiteM **item; char *data; size_t size; struct SmemiteM *next; struct SmemiteM **hash_start; int flag; { struct SmemiteM *t; *item= t= (struct SmemiteM *) malloc(sizeof(struct SmemiteM)); if(t==NULL) return(-1); t->data= data; t->size= size; t->prev= NULL; t->next= next; #ifdef Smem_with_hasH t->hash_next= NULL; t->hash_prev= NULL; #endif /* Smem_with_hasH */ if(next!=NULL) { if(next->prev!=NULL) { t->prev= next->prev; next->prev->next= t; } next->prev= t; } #ifdef Smem_with_hasH if(hash_start!=NULL) { t->hash_next= *hash_start; if(t->hash_next!=NULL) { t->hash_next->hash_prev= t; } *hash_start= t; } #endif /* Smem_with_hasH */ return(1); } int Smemitem_destroy(in_item,hash_start,flag) struct SmemiteM **in_item; struct SmemiteM **hash_start; int flag; { struct SmemiteM *item; item= *in_item; if(item==NULL) return(0); if(item==Smem_start_iteM) Smem_start_iteM= item->next; if(item->prev!=NULL) item->prev->next= item->next; if(item->next!=NULL) item->next->prev= item->prev; #ifdef Smem_with_hasH if(hash_start!=NULL) { if(item==*hash_start) *hash_start= item->hash_next; if(item->hash_prev!=NULL) item->hash_prev->hash_next= item->hash_next; if(item->hash_next!=NULL) item->hash_next->hash_prev= item->hash_prev; } #endif /* Smem_with_hasH */ free((char *) item); *in_item= NULL; return(1); } int Smemitem_report(item,line,flag) struct SmemiteM *item; char line[1024]; int flag; { char *cpt; int i,upto; sprintf(line,"%4lu bytes at %8.8lx ",(unsigned long) item->size, (unsigned long) item->data); cpt= line+strlen(line); if(item->size<=256) upto= item->size; else upto= 256; if(item->data!=NULL) { strcpy(cpt,"= \""); cpt+= 3; for(i=0;idata[i]<32 || item->data[i]>=127 || item->data[i]=='\\') { sprintf(cpt,"\\%2.2X",(unsigned char) item->data[i]); cpt+= 3; } else { *(cpt++)= item->data[i]; } } if(isize) { sprintf(cpt,"\" [truncated]"); } else { *(cpt++)= '"'; *cpt= 0; } } return(1); } int Smemitem_stderr(item,flag) struct SmemiteM *item; int flag; { char line[1024]; Smemitem_report(item,line,0); fprintf(stderr,"%s\n",line); return(1); } /* -------------------------------- Smem ------------------------------ */ int Smem_protest(line,flag) char *line; int flag; { fprintf(stderr,"%s\n",line); return(1); } int Smem_hashindex(ptr,flag) char *ptr; int flag; { unsigned long idx; idx= (unsigned long) ptr; return((idx>>Smem_hashshifT)%(Smem_hashsizE)); } /* find a certain memory item */ struct SmemiteM *Smem_find_item(ptr,flag) char *ptr; int flag; { int misscount= 0,idx; struct SmemiteM *current; #ifdef Smem_with_hasH idx= Smem_hashindex(ptr,0); for(current= Smem_hasH[idx];current!=NULL;current= current->hash_next) { if(current->data==ptr) return(current); misscount++; } #else /* Smem_with_hasH */ for(current= Smem_start_iteM;current!=NULL;current= current->next) { if(current->data==ptr) return(current); misscount++; } #endif /* ! Smem_with_hasH */ return(NULL); } int Smem_search_and_delete(ptr,flag) char *ptr; int flag; /* bit0= revoke registration : decrement counters */ { int idx; struct SmemiteM *current; current= Smem_find_item(ptr,0); if(current==NULL) return(0); Smem_record_counT--; Smem_record_byteS-= current->size; idx= Smem_hashindex(ptr,0); Smemitem_destroy(¤t,&(Smem_hasH[idx]),0); Smem_hash_counteR[idx]-= 1.0; if(flag&1) { Smem_malloc_counT--; Smem_pending_counT--; } return(1); } char *Smem_malloc(size) size_t size; { int idx; char *cpt; if(size==0) { Smem_protest("########### smem.c : malloc(0) caught",0); return(NULL); } /* if(size==1032) cpt= NULL; / * set breakpoint here to find requests of certain size */ cpt= (char *) malloc(size); if(cpt==NULL) { char text[161]; sprintf(text,"########### smem.c : malloc( %lu ) returned NULL", (unsigned long) size); Smem_protest(text,0); return(NULL); } /* if(cpt==0x080a1e20) cpt= NULL; / * set breakpoint here to find origin of certain address */ Smem_malloc_counT++; Smem_pending_counT++; if(Smem_record_itemS) { idx= Smem_hashindex(cpt,0); Smem_hash_counteR[idx]+= 1.0; if(Smemitem_new(&Smem_start_iteM,cpt,size,Smem_start_iteM, &(Smem_hasH[idx]),0)<=0) { Smem_protest( "########### smem.c : malloc( sizeof(SmemiteM) ) returned NULL",0); return(NULL); } Smem_record_counT++; Smem_record_byteS+= size; } return(cpt); } int Smem_free(ptr) char *ptr; { if(ptr==NULL) { Smem_protest("########### smem.c : free() of NULL pointer caught",0); return(0); } if(Smem_record_itemS) { if(Smem_search_and_delete(ptr,0)<=0) { Smem_protest("########### smem.c : free() of unrecorded pointer caught",0); return(0); } } Smem_free_counT++; Smem_pending_counT--; free(ptr); return(1); } int Smem_report(line,flag) char line[1024]; int flag; { sprintf(line,"malloc= %.f , free= %.f , pending= %.f", Smem_malloc_counT,Smem_free_counT,Smem_pending_counT); if(Smem_record_itemS) { sprintf(line+strlen(line)," , bytes=%.f , records= %.f", Smem_record_byteS,Smem_record_counT); } return(1); } int Smem_stderr(flag) int flag; /* bit0= report 50 youngest pending items too bit1= do not report if nothing is pending */ { struct SmemiteM *current; char line[1024]; int i= 0; if(flag&2) if(Smem_pending_counT==0.0 && Smem_record_counT==0.0 && Smem_record_byteS==0.0) return(2); Smem_report(line,0); fprintf(stderr,"%s\n",line); if(flag&1) { for(current= Smem_start_iteM;current!=NULL;current= current->next) { Smemitem_stderr(current,0); if(++i>=50) break; } if(current!=NULL) if(current->next!=NULL) fprintf(stderr,"[list truncated]\n"); } return(1); } int Smem_set_record_items(value) int value; { int i; if(!Smem_hash_initializeD) { for(i=0;i0) { for(;current!=NULL;current= current->next) { if(step==0) return(current); step--; } } else if(step<0) { for(;current!=NULL;current= current->prev) { if(step==0) return(current); step++; } } else { return(current); } return(NULL); } int Smem_print_hash_counter() { int i; for(i=0;idata); if(ret<=0) return(0); } return(1); }