FILE * openpfile(char *filename) { struct gmonhdr tmp; FILE *pfile; int size; int rate; if((pfile = fopen(filename, "r")) == NULL) err(1, "%s", filename); fread(&tmp, sizeof(struct gmonhdr), 1, pfile); if ( s_highpc != 0 && ( tmp.lpc != gmonhdr.lpc || tmp.hpc != gmonhdr.hpc || tmp.ncnt != gmonhdr.ncnt ) ) errx(1, "%s: incompatible with first gmon file", filename); gmonhdr = tmp; if ( gmonhdr.version == GMONVERSION ) { rate = gmonhdr.profrate; size = sizeof(struct gmonhdr); } else { fseek(pfile, sizeof(struct ophdr), SEEK_SET); size = sizeof(struct ophdr); gmonhdr.profrate = rate = hertz(); gmonhdr.version = GMONVERSION; } if (hz == 0) { hz = rate; } else if (hz != rate) errx(0, "%s: profile clock rate (%d) %s (%ld) in first gmon file", filename, rate, "incompatible with clock rate", hz); if ( gmonhdr.histcounter_type == 0 ) { /* Historical case. The type was u_short (2 bytes in practice). */ histcounter_type = 16; histcounter_size = 2; } else { histcounter_type = gmonhdr.histcounter_type; histcounter_size = abs(histcounter_type) / CHAR_BIT; } s_lowpc = (unsigned long) gmonhdr.lpc; s_highpc = (unsigned long) gmonhdr.hpc; lowpc = (unsigned long)gmonhdr.lpc / HISTORICAL_SCALE_2; highpc = (unsigned long)gmonhdr.hpc / HISTORICAL_SCALE_2; sampbytes = gmonhdr.ncnt - size; nsamples = sampbytes / histcounter_size; # ifdef DEBUG if ( debug & SAMPLEDEBUG ) { printf( "[openpfile] hdr.lpc 0x%lx hdr.hpc 0x%lx hdr.ncnt %d\n", gmonhdr.lpc , gmonhdr.hpc , gmonhdr.ncnt ); printf( "[openpfile] s_lowpc 0x%lx s_highpc 0x%lx\n" , s_lowpc , s_highpc ); printf( "[openpfile] lowpc 0x%lx highpc 0x%lx\n" , lowpc , highpc ); printf( "[openpfile] sampbytes %d nsamples %d\n" , sampbytes , nsamples ); printf( "[openpfile] sample rate %ld\n" , hz ); } # endif /* DEBUG */ return(pfile); }
FILE * openpfile(char *filename) { struct gmonhdr tmp; FILE *pfile; int size; int rate; if((pfile = fopen(filename, "r")) == NULL) { perror(filename); done(); } fread(&tmp, sizeof(struct gmonhdr), 1, pfile); if ( s_highpc != 0 && ( tmp.lpc != gmonhdr.lpc || tmp.hpc != gmonhdr.hpc || tmp.ncnt != gmonhdr.ncnt ) ) { warnx("%s: incompatible with first gmon file", filename); done(); } gmonhdr = tmp; if ( gmonhdr.version == GMONVERSION ) { rate = gmonhdr.profrate; size = sizeof(struct gmonhdr); } else { fseek(pfile, sizeof(struct ophdr), SEEK_SET); size = sizeof(struct ophdr); gmonhdr.profrate = rate = hertz(); gmonhdr.version = GMONVERSION; } if (hz == 0) { hz = rate; } else if (hz != rate) { fprintf(stderr, "%s: profile clock rate (%d) %s (%d) in first gmon file\n", filename, rate, "incompatible with clock rate", hz); done(); } s_lowpc = (unsigned long) gmonhdr.lpc; s_highpc = (unsigned long) gmonhdr.hpc; lowpc = (unsigned long)gmonhdr.lpc / sizeof(UNIT); highpc = (unsigned long)gmonhdr.hpc / sizeof(UNIT); sampbytes = gmonhdr.ncnt - size; nsamples = sampbytes / sizeof (UNIT); # ifdef DEBUG if ( debug & SAMPLEDEBUG ) { printf( "[openpfile] hdr.lpc 0x%x hdr.hpc 0x%x hdr.ncnt %d\n", gmonhdr.lpc , gmonhdr.hpc , gmonhdr.ncnt ); printf( "[openpfile] s_lowpc 0x%x s_highpc 0x%x\n" , s_lowpc , s_highpc ); printf( "[openpfile] lowpc 0x%x highpc 0x%x\n" , lowpc , highpc ); printf( "[openpfile] sampbytes %d nsamples %d\n" , sampbytes , nsamples ); printf( "[openpfile] sample rate %d\n" , hz ); } # endif /* DEBUG */ return(pfile); }
KAFFE_STD_PROF_RATE #endif #endif int enableXProfiling(void) { int retval = false; xProfilingOff(); /* Start up our profiler and set it to observe the main executable */ if( xProfFlag && enableProfileTimer() && (kaffe_memory_samples = createMemorySamples()) && observeMemory(kaffe_memory_samples, &_start, &etext - &_start) && (profiler_debug_file = createDebugFile(kaffe_syms_filename)) && !atexit(profilerAtExit) ) { #if defined(KAFFE_CPROFILER) struct gmonparam *gp = getGmonParam(); int prof_rate; #endif #if defined(KAFFE_CPROFILER) /* Turn off any other profiling */ profil(0, 0, 0, 0); #if defined(KAFFE_STD_PROF_RATE) if( !(prof_rate = kaffeStdProfRate()) ) #endif prof_rate = hertz(); /* Just guess */ if( !prof_rate ) prof_rate = 100; /* Copy the hits leading up to now into our own counters */ if( gp && gp->kcountsize > 0 ) { int lpc, len = gp->kcountsize / sizeof(HISTCOUNTER); HISTCOUNTER *hist = gp->kcount; int scale; scale = (gp->highpc - gp->lowpc) / len; for( lpc = 0; lpc < len; lpc++ ) { if( hist[lpc] ) { char *pc = ((char *)gp->lowpc) + (lpc * scale); memoryHitCount(kaffe_memory_samples, pc, (100 * hist[lpc]) / prof_rate); } } } #endif retval = true; } else { xProfFlag = 0; disableXProfiling(); } xProfilingOn(); return( retval ); }
void _mcleanup(void) { int fd; int fromindex; int endfrom; u_long frompc; int toindex; struct rawarc rawarc; struct gmonparam *p = &_gmonparam; struct gmonhdr gmonhdr, *hdr; struct clockinfo clockinfo; char outname[128]; int mib[2]; size_t size; #ifdef DEBUG int log, len; char buf[200]; #endif if (p->state == GMON_PROF_ERROR) ERR("_mcleanup: tos overflow\n"); size = sizeof(clockinfo); mib[0] = CTL_KERN; mib[1] = KERN_CLOCKRATE; if (sysctl(mib, 2, &clockinfo, &size, NULL, 0) < 0) { /* * Best guess */ clockinfo.profhz = hertz(); } else if (clockinfo.profhz == 0) { if (clockinfo.hz != 0) clockinfo.profhz = clockinfo.hz; else clockinfo.profhz = hertz(); } moncontrol(0); if (getenv("PROFIL_USE_PID")) snprintf(outname, sizeof(outname), "%s.%d.gmon", _getprogname(), getpid()); else snprintf(outname, sizeof(outname), "%s.gmon", _getprogname()); fd = _open(outname, O_CREAT|O_TRUNC|O_WRONLY|O_CLOEXEC, 0666); if (fd < 0) { _warn("_mcleanup: %s", outname); return; } #ifdef DEBUG log = _open("gmon.log", O_CREAT|O_TRUNC|O_WRONLY|O_CLOEXEC, 0664); if (log < 0) { _warn("_mcleanup: gmon.log"); return; } len = sprintf(buf, "[mcleanup1] kcount 0x%p ssiz %lu\n", p->kcount, p->kcountsize); _write(log, buf, len); #endif hdr = (struct gmonhdr *)&gmonhdr; bzero(hdr, sizeof(*hdr)); hdr->lpc = p->lowpc; hdr->hpc = p->highpc; hdr->ncnt = p->kcountsize + sizeof(gmonhdr); hdr->version = GMONVERSION; hdr->profrate = clockinfo.profhz; _write(fd, (char *)hdr, sizeof *hdr); _write(fd, p->kcount, p->kcountsize); endfrom = p->fromssize / sizeof(*p->froms); for (fromindex = 0; fromindex < endfrom; fromindex++) { if (p->froms[fromindex] == 0) continue; frompc = p->lowpc; frompc += fromindex * p->hashfraction * sizeof(*p->froms); for (toindex = p->froms[fromindex]; toindex != 0; toindex = p->tos[toindex].link) { #ifdef DEBUG len = sprintf(buf, "[mcleanup2] frompc 0x%lx selfpc 0x%lx count %lu\n" , frompc, p->tos[toindex].selfpc, p->tos[toindex].count); _write(log, buf, len); #endif rawarc.raw_frompc = frompc; rawarc.raw_selfpc = p->tos[toindex].selfpc; rawarc.raw_count = p->tos[toindex].count; _write(fd, &rawarc, sizeof rawarc); } } _close(fd); }
int main( int argc, char **argv, char **envp) { uint32_t i; char **sp; nltype **timesortnlp; progname = argv[0]; --argc; argv++; debug = 0; bflag = TRUE; while(*argv != 0 && **argv == '-'){ (*argv)++; switch(**argv){ case 'a': aflag = TRUE; break; case 'b': bflag = FALSE; break; case 'c': printf("%s: -c not supported\n", progname); /* cflag = TRUE; */ break; case 'd': dflag = TRUE; (*argv)++; debug |= atoi(*argv); debug |= ANYDEBUG; #ifdef DEBUG printf("[main] debug = %u\n", debug); #else printf("%s: -d ignored\n", progname); #endif break; case 'E': ++argv; addlist(Elist, *argv); Eflag = TRUE; addlist(elist, *argv); eflag = TRUE; break; case 'e': addlist(elist, *++argv); eflag = TRUE; break; case 'F': ++argv; addlist(Flist, *argv); Fflag = TRUE; addlist(flist, *argv); fflag = TRUE; break; case 'f': addlist(flist, *++argv); fflag = TRUE; break; case 'S': Sflag = TRUE; break; case 's': sflag = TRUE; break; case 'x': xflag = TRUE; break; case 'z': zflag = TRUE; break; } argv++; } if(*argv != 0){ a_outname = *argv; argv++; } else{ a_outname = A_OUTNAME; } if(*argv != 0){ gmonname = *argv; argv++; } else{ gmonname = GMONNAME; } /* * Turn off default functions. */ for(sp = &defaultEs[0]; *sp; sp++){ Eflag = TRUE; addlist(Elist, *sp); eflag = TRUE; addlist(elist, *sp); } /* * Get information about a.out file. */ getnfile(); if(errors != 0) exit(1); /* * Get information about mon.out file(s). */ hz = 0; do{ getpfile(gmonname); if(*argv != 0){ gmonname = *argv; } }while(*argv++ != 0); /* * How many ticks per second? If we can't tell, report time in ticks. * If this was picked up from the mon.out files use that value. */ #ifndef __OPENSTEP__ if(hz == 0) #endif hz = hertz(); if(hz == 0){ hz = 1; fprintf(stderr, "time is in ticks, not seconds\n"); } /* * Dump out a gmon.sum file if requested. */ if(sflag){ dumpsum(GMONSUM); exit(0); } /* * Assign samples to procedures. */ alignentries(); for(i = 0; i < nsample_sets; i++) asgnsamples(sample_sets + i); /* * Assemble the dynamic profile. */ timesortnlp = doarcs(); /* * Print the dynamic profile. */ printgprof(timesortnlp); /* * Print the flat profile. */ printprof(); /* * Print the index. */ printindex(); /* * Dump out the order files if requested. */ if(Sflag) printscatter(); return(0); }