Example #1
0
  def runFuzzer(self):
    self.remoteInit()

    # Ensure Fennec isn't running
    if self.isFennecRunning():
      self.stopFennec()

    # Clean all existing minidumps
    if not self.clearMinidumps():
      raise Exception("Failed to clean existing minidumps")

    # Start our HTTP server for serving the fuzzer code
    self.HTTPProcess = self.startHTTPServer()

    # Start all loggers
    self.startLoggers()

    # Start Fennec
    self.startFennec()

    # Even though the program is already running, we should grant it
    # some extra time to load the fuzzer source and start running,
    # so it isn't directly diagnosed as hanging
    time.sleep(10);
    
    logSize = 0
    hangDetected = False
    forceRestart = False
    while(self.isFennecRunning() and not self.checkLoggingThreads()):
      time.sleep(self.config.runTimeout)

      if not os.path.exists(self.logFile):
        raise Exception("Logfile not present. If you are using websockets, this could indicate a network problem.")

      # Poor man's hang detection. Yes, this is a bad
      # idea, just for the sake of proof-of-concept
      newLogSize = os.path.getsize(self.logFile)
      if (logSize == newLogSize):
        hangDetected = True
        break
      else:
        logSize = newLogSize
        if newLogSize > self.config.maxLogSize:
          forceRestart = True
          break

    if hangDetected or forceRestart:
      self.stopFennec()
      self.stopLoggers()
      print "Hang detected or running too long, restarting..."
    else:
      try:
        # Fennec died or a logger found something
        checkCrashDump = True
        crashUUID = None
        minidump = None
        
        # If Fennec is still running, stop it now
        if self.isFennecRunning():
          checkCrashDump = False
          self.stopFennec()
        
        # Terminate our logging processes first
        self.stopLoggers()
        
        if checkCrashDump:
          dumps = self.getMinidumps()
          if (len(dumps) > 1):
            raise Exception("Multiple dumps detected!")
            
          if (len(dumps) < 1):
            raise Exception("No crash dump detected!")
    
          if not self.fetchMinidump(dumps[0]):
            raise Exception("Failed to fetch minidump with UUID " + dumps[0])
  
          crashUUID = dumps[0]
  
          # Copy logfiles
          shutil.copy2(self.syslogFile, dumps[0] + ".syslog")
          shutil.copy2(self.logFile, dumps[0] + ".log")
    
          minidump = Minidump(dumps[0] + ".dmp", self.config.libDir)
        else:
          # We need to generate an arbitrary ID here
          crashUUID = str(uuid.uuid4())
          
          # Copy logfiles
          shutil.copy2(self.syslogFile, crashUUID + ".syslog")
          shutil.copy2(self.logFile, crashUUID + ".log")
  
        print "Crash detected. Reproduction logfile stored at: " + crashUUID + ".log"
        if checkCrashDump:
          crashTrace = minidump.getCrashTrace()
          crashType = minidump.getCrashType()
          print "Crash type: " + crashType
          print "Crash backtrace:"
          print ""
          print crashTrace
        else:
          print "Crash type: Abnormal behavior (e.g. Assertion violation)"
  
        self.triager.process(crashUUID, minidump, crashUUID + ".syslog", crashUUID + ".log")
      except Exception, e:
        print "Error during crash processing: "
        print traceback.format_exc()
    def runFuzzer(self):
        self.remoteInit()

        # Ensure Fennec isn't running
        if self.isFennecRunning():
            self.stopFennec()

        # Clean all existing minidumps
        if not self.clearMinidumps():
            raise Exception("Failed to clean existing minidumps")

        # Start our HTTP server for serving the fuzzer code
        self.HTTPProcess = self.startHTTPServer()

        # Start all loggers
        self.startLoggers()

        # Start Fennec
        self.startFennec()

        # Even though the program is already running, we should grant it
        # some extra time to load the fuzzer source and start running,
        # so it isn't directly diagnosed as hanging
        time.sleep(10)

        logSize = 0
        hangDetected = False
        forceRestart = False
        while (self.isFennecRunning() and not self.checkLoggingThreads()):
            time.sleep(self.config.runTimeout)

            if not os.path.exists(self.logFile):
                raise Exception(
                    "Logfile not present. If you are using websockets, this could indicate a network problem."
                )

            # Poor man's hang detection. Yes, this is a bad
            # idea, just for the sake of proof-of-concept
            newLogSize = os.path.getsize(self.logFile)
            if (logSize == newLogSize):
                hangDetected = True
                break
            else:
                logSize = newLogSize
                if newLogSize > self.config.maxLogSize:
                    forceRestart = True
                    break

        if hangDetected or forceRestart:
            self.stopFennec()
            self.stopLoggers()
            print "Hang detected or running too long, restarting..."
        else:
            try:
                # Fennec died or a logger found something
                checkCrashDump = True
                crashUUID = None
                minidump = None

                # If Fennec is still running, stop it now
                if self.isFennecRunning():
                    checkCrashDump = False
                    self.stopFennec()

                # Terminate our logging processes first
                self.stopLoggers()

                if checkCrashDump:
                    dumps = self.getMinidumps()
                    if (len(dumps) > 1):
                        raise Exception("Multiple dumps detected!")

                    if (len(dumps) < 1):
                        raise Exception("No crash dump detected!")

                    if not self.fetchMinidump(dumps[0]):
                        raise Exception("Failed to fetch minidump with UUID " +
                                        dumps[0])

                    crashUUID = dumps[0]

                    # Copy logfiles
                    shutil.copy2(self.syslogFile, dumps[0] + ".syslog")
                    shutil.copy2(self.logFile, dumps[0] + ".log")

                    minidump = Minidump(dumps[0] + ".dmp", self.config.libDir)
                else:
                    # We need to generate an arbitrary ID here
                    crashUUID = str(uuid.uuid4())

                    # Copy logfiles
                    shutil.copy2(self.syslogFile, crashUUID + ".syslog")
                    shutil.copy2(self.logFile, crashUUID + ".log")

                print "Crash detected. Reproduction logfile stored at: " + crashUUID + ".log"
                if checkCrashDump:
                    crashTrace = minidump.getCrashTrace()
                    crashType = minidump.getCrashType()
                    print "Crash type: " + crashType
                    print "Crash backtrace:"
                    print ""
                    print crashTrace
                else:
                    print "Crash type: Abnormal behavior (e.g. Assertion violation)"

                self.triager.process(crashUUID, minidump,
                                     crashUUID + ".syslog", crashUUID + ".log")
            except Exception, e:
                print "Error during crash processing: "
                print traceback.format_exc()