示例#1
0
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);
}
示例#2
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");
}
示例#3
0
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);
}