Beispiel #1
0
    def killAndGetStack(self,
                        process,
                        utilityPath,
                        debuggerInfo,
                        dump_screen=False):
        """
    Kill the process, preferrably in a way that gets us a stack trace.
    Also attempts to obtain a screenshot before killing the process
    if specified.
    """

        if dump_screen:
            self.dumpScreen(utilityPath)

        if mozinfo.info.get('crashreporter', True) and not debuggerInfo:
            if mozinfo.isWin:
                # We should have a "crashinject" program in our utility path
                crashinject = os.path.normpath(
                    os.path.join(utilityPath, "crashinject.exe"))
                if os.path.exists(crashinject):
                    status = subprocess.Popen([crashinject,
                                               str(process.pid)]).wait()
                    printstatus(status, "crashinject")
                    if status == 0:
                        return
            else:
                try:
                    process.kill(sig=signal.SIGABRT)
                except OSError:
                    # https://bugzilla.mozilla.org/show_bug.cgi?id=921509
                    log.info(
                        "Can't trigger Breakpad, process no longer exists")
                return
        log.info("Can't trigger Breakpad, just killing process")
        process.kill()
Beispiel #2
0
  def killAndGetStack(self, process, utilityPath, debuggerInfo, dump_screen=False):
    """
    Kill the process, preferrably in a way that gets us a stack trace.
    Also attempts to obtain a screenshot before killing the process
    if specified.
    """

    if dump_screen:
      self.dumpScreen(utilityPath)

    if mozinfo.info.get('crashreporter', True) and not debuggerInfo:
      if mozinfo.isWin:
        # We should have a "crashinject" program in our utility path
        crashinject = os.path.normpath(os.path.join(utilityPath, "crashinject.exe"))
        if os.path.exists(crashinject):
          status = subprocess.Popen([crashinject, str(process.pid)]).wait()
          printstatus(status, "crashinject")
          if status == 0:
            return
      else:
        try:
          process.kill(sig=signal.SIGABRT)
        except OSError:
          # https://bugzilla.mozilla.org/show_bug.cgi?id=921509
          log.info("Can't trigger Breakpad, process no longer exists")
        return
    log.info("Can't trigger Breakpad, just killing process")
    process.kill()
Beispiel #3
0
 def killAndGetStackNoScreenshot(self, processPID, utilityPath, debuggerInfo):
     """Kill the process, preferrably in a way that gets us a stack trace."""
     if self.CRASHREPORTER and not debuggerInfo:
         if not self.IS_WIN32:
             # ABRT will get picked up by Breakpad's signal handler
             os.kill(processPID, signal.SIGABRT)
             return
         else:
             # We should have a "crashinject" program in our utility path
             crashinject = os.path.normpath(os.path.join(utilityPath, "crashinject.exe"))
             if os.path.exists(crashinject):
                 status = subprocess.Popen([crashinject, str(processPID)]).wait()
                 automationutils.printstatus(status, "crashinject")
                 if status == 0:
                     return
     self.log.info("Can't trigger Breakpad, just killing process")
     self.killPid(processPID)
Beispiel #4
0
    def waitForFinish(self, proc, utilityPath, timeout, maxTime, startTime, debuggerInfo, symbolsPath):
        """ Look for timeout or crashes and return the status after the process terminates """
        stackFixerFunction = None
        didTimeout = False
        hitMaxTime = False
        if proc.stdout is None:
            self.log.info("TEST-INFO: Not logging stdout or stderr due to debugger connection")
        else:
            logsource = proc.stdout

            if self.IS_DEBUG_BUILD and symbolsPath and os.path.exists(symbolsPath):
                # Run each line through a function in fix_stack_using_bpsyms.py (uses breakpad symbol files)
                # This method is preferred for Tinderbox builds, since native symbols may have been stripped.
                sys.path.insert(0, utilityPath)
                import fix_stack_using_bpsyms as stackFixerModule

                stackFixerFunction = lambda line: stackFixerModule.fixSymbols(line, symbolsPath)
                del sys.path[0]
            elif self.IS_DEBUG_BUILD and self.IS_MAC:
                # Run each line through a function in fix_macosx_stack.py (uses atos)
                sys.path.insert(0, utilityPath)
                import fix_macosx_stack as stackFixerModule

                stackFixerFunction = lambda line: stackFixerModule.fixSymbols(line)
                del sys.path[0]
            elif self.IS_DEBUG_BUILD and self.IS_LINUX:
                # Run each line through a function in fix_linux_stack.py (uses addr2line)
                # This method is preferred for developer machines, so we don't have to run "make buildsymbols".
                sys.path.insert(0, utilityPath)
                import fix_linux_stack as stackFixerModule

                stackFixerFunction = lambda line: stackFixerModule.fixSymbols(line)
                del sys.path[0]

            # With metro browser runs this script launches the metro test harness which launches the browser.
            # The metro test harness hands back the real browser process id via log output which we need to
            # pick up on and parse out. This variable tracks the real browser process id if we find it.
            browserProcessId = -1

            (line, didTimeout) = self.readWithTimeout(logsource, timeout)
            while line != "" and not didTimeout:
                if stackFixerFunction:
                    line = stackFixerFunction(line)
                self.log.info(line.rstrip().decode("UTF-8", "ignore"))
                if "TEST-START" in line and "|" in line:
                    self.lastTestSeen = line.split("|")[1].strip()
                if not debuggerInfo and "TEST-UNEXPECTED-FAIL" in line and "Test timed out" in line:
                    self.dumpScreen(utilityPath)

                (line, didTimeout) = self.readWithTimeout(logsource, timeout)

                if not hitMaxTime and maxTime and datetime.now() - startTime > timedelta(seconds=maxTime):
                    # Kill the application.
                    hitMaxTime = True
                    self.log.info(
                        "TEST-UNEXPECTED-FAIL | %s | application ran for longer than allowed maximum time of %d seconds",
                        self.lastTestSeen,
                        int(maxTime),
                    )
                    self.killAndGetStack(proc.pid, utilityPath, debuggerInfo)
            if didTimeout:
                if line:
                    self.log.info(line.rstrip().decode("UTF-8", "ignore"))
                self.log.info(
                    "TEST-UNEXPECTED-FAIL | %s | application timed out after %d seconds with no output",
                    self.lastTestSeen,
                    int(timeout),
                )
                if browserProcessId == -1:
                    browserProcessId = proc.pid
                self.killAndGetStack(browserProcessId, utilityPath, debuggerInfo)

        status = proc.wait()
        automationutils.printstatus(status, "Main app process")
        if status == 0:
            self.lastTestSeen = "Main app process exited normally"
        if status != 0 and not didTimeout and not hitMaxTime:
            self.log.info("TEST-UNEXPECTED-FAIL | %s | Exited with code %d during test run", self.lastTestSeen, status)
        return status