void leaky::open() { LoadMap(); setupSymbols(progFile); // open up the log file mappedLogFile = ::open(logFile, O_RDONLY); if (mappedLogFile < 0) { perror("open"); exit(-1); } off_t size; firstLogEntry = (malloc_log_entry*) mapFile(mappedLogFile, PROT_READ, &size); lastLogEntry = (malloc_log_entry*)((char*)firstLogEntry + size); analyze(); exit(0); }
void leaky::open(char *logFile) { int threadArray[100]; // should auto-expand int last_thread = -1; int numThreads = 0; int section = -1; bool collecting = false; LoadMap(); setupSymbols(progFile); // open up the log file if (mappedLogFile) ::close(mappedLogFile); mappedLogFile = ::open(logFile, O_RDONLY); if (mappedLogFile < 0) { perror("open"); exit(-1); } off_t size; firstLogEntry = (malloc_log_entry*) mapFile(mappedLogFile, PROT_READ, &size); lastLogEntry = (malloc_log_entry*)((char*)firstLogEntry + size); if (!collect_last || collect_start < 0) { collecting = true; } // First, restrict it to the capture sections specified (all, last, start/end) // This loop walks through all the call stacks we recorded for (malloc_log_entry* lep=firstLogEntry; lep < lastLogEntry; lep = reinterpret_cast<malloc_log_entry*>(&lep->pcs[lep->numpcs])) { if (lep->flags & JP_FIRST_AFTER_PAUSE) { section++; if (collect_last) { firstLogEntry = lep; numThreads = 0; collecting = true; } if (collect_start == section) { collecting = true; firstLogEntry = lep; } if (collect_end == section) { collecting = false; lastLogEntry = lep; } if (!quiet) fprintf(stderr,"New section %d: first=%p, last=%p, collecting=%d\n", section,(void*)firstLogEntry,(void*)lastLogEntry,collecting); } // Capture thread info at the same time // Find all the threads captured // pthread/linux docs say the signal can be delivered to any thread in // the process. In practice, it appears in Linux that it's always // delivered to the thread that called setitimer(), and each thread can // have a separate itimer. There's a support library for gprof that // overlays pthread_create() to set timers in any threads you spawn. if (showThreads && collecting) { if (lep->thread != last_thread) { int i; for (i=0; i<numThreads; i++) { if (lep->thread == threadArray[i]) break; } if (i == numThreads && i < (int) (sizeof(threadArray)/sizeof(threadArray[0]))) { threadArray[i] = lep->thread; numThreads++; if (!quiet) fprintf(stderr,"new thread %d\n",lep->thread); } } } } if (!quiet) fprintf(stderr,"Done collecting: sections %d: first=%p, last=%p, numThreads=%d\n", section,(void*)firstLogEntry,(void*)lastLogEntry,numThreads); if (!cleo) { fprintf(outputfd,"<html><head><title>Jprof Profile Report</title></head><body>\n"); fprintf(outputfd,"<h1><center>Jprof Profile Report</center></h1>\n"); } if (showThreads) { fprintf(stderr,"Num threads %d\n",numThreads); if (!cleo) { fprintf(outputfd,"<hr>Threads:<p><pre>\n"); for (int i=0; i<numThreads; i++) { fprintf(outputfd," <a href=\"#thread_%d\">%d</a> ", threadArray[i],threadArray[i]); if ((i+1)%10 == 0) fprintf(outputfd,"<br>\n"); } fprintf(outputfd,"</pre>"); } for (int i=0; i<numThreads; i++) { if (!onlyThread || onlyThread == threadArray[i]) analyze(threadArray[i]); } } else { analyze(0); } if (!cleo) fprintf(outputfd,"</pre></body></html>\n"); }
void leaky::open() { int threadArray[100]; // should auto-expand int last_thread = -1; int numThreads=0; LoadMap(); setupSymbols(progFile); // open up the log file mappedLogFile = ::open(logFile, O_RDONLY); if (mappedLogFile < 0) { perror("open"); exit(-1); } off_t size; firstLogEntry = (malloc_log_entry*) mapFile(mappedLogFile, PROT_READ, &size); lastLogEntry = (malloc_log_entry*)((char*)firstLogEntry + size); fprintf(stdout,"<html><head><title>Jprof Profile Report</title></head><body>\n"); fprintf(stdout,"<h1><center>Jprof Profile Report</center></h1>\n"); if (showThreads) { // Find all the threads captured // pthread/linux docs say the signal can be delivered to any thread in // the process. In practice, it appears in Linux that it's always // delivered to the thread that called setitimer(), and each thread can // have a separate itimer. There's a support library for gprof that // overlays pthread_create() to set timers in any threads you spawn. // This loop walks through all the call stacks we recorded for (malloc_log_entry* lep=firstLogEntry; lep < lastLogEntry; lep = reinterpret_cast<malloc_log_entry*>(&lep->pcs[lep->numpcs])) { if (lep->thread != last_thread) { int i; for (i=0; i<numThreads; i++) { if (lep->thread == threadArray[i]) break; } if (i == numThreads && i < (int) (sizeof(threadArray)/sizeof(threadArray[0]))) { threadArray[i] = lep->thread; numThreads++; fprintf(stderr,"new thread %d\n",lep->thread); } } } fprintf(stderr,"Num threads %d\n",numThreads); fprintf(stdout,"<hr>Threads:<p><pre>\n"); for (int i=0; i<numThreads; i++) { fprintf(stdout," <a href=\"thread_%d\">%d</a><p>\n", threadArray[i],threadArray[i]); } fprintf(stdout,"</pre><hr>"); for (int i=0; i<numThreads; i++) { analyze(threadArray[i]); } } else { analyze(0); } fprintf(stdout,"</pre></body></html>\n"); exit(0); }