static void print_unfree_stats(const mtabent *mtabs) { /* print some information about where unfreed blocks were allocated */ Unfreed *unf=NULL; int nlocs=0; const mtabent *mtp; mtp= mtabs; /* first build table of files */ do { char *myname= mtp->file; int myline= mtp->line; int ind; if ((ind=lookup_loc(myname,myline,unf,nlocs))<0) { /* extend table of pointers */ if(unf) unf= (Unfreed *)realloc((void *)unf, (unsigned)sizeof(Unfreed)*(nlocs+1)); else unf= (Unfreed *)malloc((unsigned)sizeof(Unfreed)); unf[nlocs].file= mtp->file; /* just a reference, no copying */ unf[nlocs].line= mtp->line; unf[nlocs].bytes= mtp->size; unf[nlocs].count= 1; nlocs++; } else { /* found entry, got index back */ unf[ind].bytes+= mtp->size; unf[ind].count++; } } while ( (mtp= mtp->next) ); /* at this point, unf contains an array of "Unfreed" structures, nlocs has size */ qsort(unf,(unsigned)nlocs,sizeof(Unfreed),ltbytes); { int i; (void)fprintf(stderr,"\n\n Summary of unfreed blocks by file and line\n"); (void)fprintf(stderr, " ==========================================================\n"); for (i=0; i<_MYMALLOC_MAX_UNFREE_PRINT && i<nlocs; i++) fprintf(stderr,"%16s:%4d %10d bytes (%6d block%s)\n", unf[i].file,unf[i].line,unf[i].bytes,unf[i].count, (unf[i].count==1)?"":"s"); if(nlocs>_MYMALLOC_MAX_UNFREE_PRINT) (void)fprintf(stderr,"(more... %d total locations) \n",nlocs); } }
void erts_lookup_function_info(FunctionInfo* fi, BeamInstr* pc, int full_info) { BeamInstr** low; BeamInstr** high; BeamInstr** mid; Range* rp; fi->current = NULL; fi->needed = 5; fi->loc = LINE_INVALID_LOCATION; rp = find_range(range_tables, pc); #ifdef ERTS_SLAVE_EMU_ENABLED if (slave_initialised && rp == 0) rp = find_range(slave_range_tables, pc); #endif if (rp == 0) { return; } low = (BeamInstr **) (rp->start + MI_FUNCTIONS); high = low + rp->start[MI_NUM_FUNCTIONS]; while (low < high) { mid = low + (high-low) / 2; if (pc < mid[0]) { high = mid; } else if (pc < mid[1]) { fi->current = mid[0]+2; if (full_info) { BeamInstr** fp = (BeamInstr **) (rp->start + MI_FUNCTIONS); int idx = mid - fp; lookup_loc(fi, pc, rp->start, idx); } return; } else { low = mid + 1; } } }
void erts_lookup_function_info(FunctionInfo* fi, BeamInstr* pc, int full_info) { ErtsCodeInfo** low; ErtsCodeInfo** high; ErtsCodeInfo** mid; Range* rp; BeamCodeHeader* hdr; fi->mfa = NULL; fi->needed = 5; fi->loc = LINE_INVALID_LOCATION; rp = find_range(pc); if (rp == 0) { return; } hdr = (BeamCodeHeader*) rp->start; low = hdr->functions; high = low + hdr->num_functions; while (low < high) { mid = low + (high-low) / 2; if (pc < (BeamInstr*)(mid[0])) { high = mid; } else if (pc < (BeamInstr*)(mid[1])) { fi->mfa = &mid[0]->mfa; if (full_info) { ErtsCodeInfo** fp = hdr->functions; int idx = mid - fp; lookup_loc(fi, pc, hdr, idx); } return; } else { low = mid + 1; } } }