예제 #1
0
 def _CreateTraceConfigFile(self, config):
     assert not self._trace_config_file
     if self._platform_backend.GetOSName() == 'android':
         self._trace_config_file = os.path.join(
             _CHROME_TRACE_CONFIG_DIR_ANDROID,
             _CHROME_TRACE_CONFIG_FILE_NAME)
         self._platform_backend.device.WriteFile(
             self._trace_config_file,
             self._CreateTraceConfigFileString(config),
             as_root=True)
         # The config file has fixed path on Android. We need to ensure it is
         # always cleaned up.
         atexit_with_log.Register(self._RemoveTraceConfigFile)
     elif self._platform_backend.GetOSName() == 'chromeos':
         self._trace_config_file = os.path.join(
             _CHROME_TRACE_CONFIG_DIR_CROS, _CHROME_TRACE_CONFIG_FILE_NAME)
         cri = self._platform_backend.cri
         cri.PushContents(self._CreateTraceConfigFileString(config),
                          self._trace_config_file)
         cri.Chown(self._trace_config_file)
         # The config file has fixed path on CrOS. We need to ensure it is
         # always cleaned up.
         atexit_with_log.Register(self._RemoveTraceConfigFile)
     elif self._platform_backend.GetOSName() in _DESKTOP_OS_NAMES:
         self._trace_config_file = os.path.join(
             tempfile.mkdtemp(), _CHROME_TRACE_CONFIG_FILE_NAME)
         with open(self._trace_config_file, 'w') as f:
             trace_config_string = self._CreateTraceConfigFileString(config)
             logging.info('Trace config file string: %s',
                          trace_config_string)
             f.write(trace_config_string)
         os.chmod(self._trace_config_file,
                  os.stat(self._trace_config_file).st_mode | stat.S_IROTH)
     else:
         raise NotImplementedError
예제 #2
0
 def CollectAgentTraceData(self, trace_data_builder):
   if not self._is_tracing_controllable:
     return
   assert not trace_event.trace_is_enabled(), 'Stop tracing before collection.'
   with open(self._trace_log, 'r') as fp:
     data = ast.literal_eval(fp.read() + ']')
   trace_data_builder.SetTraceFor(trace_data_module.TELEMETRY_PART, {
       "traceEvents": data,
       "metadata": {
           # TODO(charliea): For right now, we use "TELEMETRY" as the clock
           # domain to guarantee that Telemetry is given its own clock
           # domain. Telemetry isn't really a clock domain, though: it's a
           # system that USES a clock domain like LINUX_CLOCK_MONOTONIC or
           # WIN_QPC. However, there's a chance that a Telemetry controller
           # running on Linux (using LINUX_CLOCK_MONOTONIC) is interacting with
           # an Android phone (also using LINUX_CLOCK_MONOTONIC, but on a
           # different machine). The current logic collapses clock domains
           # based solely on the clock domain string, but we really should to
           # collapse based on some (device ID, clock domain ID) tuple. Giving
           # Telemetry its own clock domain is a work-around for this.
           "clock-domain": "TELEMETRY",
           "iteration-info": (self._iteration_info.AsDict()
               if self._iteration_info else {}),
       }
   })
   try:
     os.remove(self._trace_log)
     self._trace_log = None
   except OSError:
     logging.exception('Error when deleting %s, will try again at exit.',
                       self._trace_log)
     def DeleteAtExit(path):
       os.remove(path)
     atexit_with_log.Register(DeleteAtExit, self._trace_log)
   self._trace_log = None
예제 #3
0
  def StartServer(self):
    """Start Web Page Replay and verify that it started.

    Returns:
      A forwarders.PortSet(http, https, dns) tuple; with dns None if unused.
    Raises:
      ReplayNotStartedError: if Replay start-up fails.
    """
    is_posix = sys.platform.startswith('linux') or sys.platform == 'darwin'
    logging.info('Starting Web-Page-Replay: %s', self._cmd_line)
    self._CreateTempLogFilePath()
    with self._OpenLogFile() as log_fh:
      self.replay_process = subprocess.Popen(
          self._cmd_line, stdout=log_fh, stderr=subprocess.STDOUT,
          preexec_fn=(_ResetInterruptHandler if is_posix else None))
    try:
      util.WaitFor(self._IsStarted, 30)
      atexit_with_log.Register(self.StopServer)
      return forwarders.PortSet(
          self._started_ports['http'],
          self._started_ports['https'],
          self._started_ports.get('dns'),  # None if unused
          )
    except exceptions.TimeoutException:
      raise ReplayNotStartedError(
          'Web Page Replay failed to start. Log output:\n%s' %
          ''.join(self._LogLines()))
예제 #4
0
  def _StartMsrServerIfNeeded(self):
    if self._msr_server_handle:
      return

    _InstallWinRing0()

    pipe_name = r"\\.\pipe\msr_server_pipe_{}".format(os.getpid())
    # Try to open a named pipe to receive a msr port number from server process.
    pipe = win32pipe.CreateNamedPipe(
        pipe_name,
        win32pipe.PIPE_ACCESS_INBOUND,
        win32pipe.PIPE_TYPE_MESSAGE | win32pipe.PIPE_WAIT,
        1, 32, 32, 300, None)
    parameters = (
        os.path.join(os.path.dirname(__file__), 'msr_server_win.py'),
        pipe_name,
    )
    self._msr_server_handle = self.LaunchApplication(
        sys.executable, parameters, elevate_privilege=True)
    if pipe != win32file.INVALID_HANDLE_VALUE:
      if win32pipe.ConnectNamedPipe(pipe, None) == 0:
        self._msr_server_port = int(win32file.ReadFile(pipe, 32)[1])
      win32api.CloseHandle(pipe)
    # Wait for server to start.
    try:
      socket.create_connection(('127.0.0.1', self._msr_server_port), 5).close()
    except socket.error:
      self.CloseMsrServer()
    atexit_with_log.Register(TerminateProcess, self._msr_server_handle)
예제 #5
0
 def StartServer(self, timeout=10):
     """Start TsProxy server and verify that it started.
 """
     cmd_line = [sys.executable, _TSPROXY_PATH]
     cmd_line.extend([
         '--port=0'
     ])  # Use port 0 so tsproxy picks a random available port.
     if self._host_ip:
         cmd_line.append('--desthost=%s' % self._host_ip)
     if self._http_port:
         cmd_line.append('--mapports=443:%s,*:%s' %
                         (self._https_port, self._http_port))
     logging.info('Tsproxy commandline: %r' % cmd_line)
     self._proc = subprocess.Popen(cmd_line,
                                   stdout=subprocess.PIPE,
                                   stdin=subprocess.PIPE,
                                   stderr=subprocess.PIPE,
                                   bufsize=1)
     atexit_with_log.Register(self.StopServer)
     try:
         util.WaitFor(self._IsStarted, timeout)
         logging.info('TsProxy port: %s', self._port)
         self._is_running = True
     except exceptions.TimeoutException:
         err = self.StopServer()
         raise RuntimeError('Error starting tsproxy: %s' % err)
예제 #6
0
    def StartAgentTracing(self, config, timeout):
        """Start tracing on the BattOr.

    Args:
      config: A TracingConfig instance.
      timeout: number of seconds that this tracing agent should try to start
        tracing until timing out.

    Returns:
      True if the tracing agent started successfully.
    """
        if not config.enable_battor_trace:
            return False
        try:
            if self._battery:
                self._battery.SetCharging(False)
                atexit_with_log.Register(_ReenableChargingIfNeeded,
                                         self._battery)

            self._battor.StartShell()
            self._battor.StartTracing()
            return True
        except battor_error.BattOrError:
            if self._battery:
                self._battery.SetCharging(True)
            raise
예제 #7
0
 def __init__(self, device, port_pair):
     super(AndroidForwarder, self).__init__(port_pair)
     self._device = device
     forwarder.Forwarder.Map(
         [(port_pair.remote_port, port_pair.local_port)], self._device)
     self._port_pair = (forwarders.PortPair(
         port_pair.local_port,
         forwarder.Forwarder.DevicePortForHostPort(port_pair.local_port)))
     atexit_with_log.Register(self.Close)
예제 #8
0
 def __init__(self, device, port_pairs):
     super(AndroidForwarder, self).__init__(port_pairs)
     self._device = device
     forwarder.Forwarder.Map([(p.remote_port, p.local_port)
                              for p in port_pairs if p], self._device)
     self._port_pairs = forwarders.PortPairs(*[
         forwarders.
         PortPair(p.local_port,
                  forwarder.Forwarder.DevicePortForHostPort(p.local_port)
                  ) if p else None for p in port_pairs
     ])
     atexit_with_log.Register(self.Close)
    def CollectAgentTraceData(self, trace_data_builder):
        if not self._is_tracing_controllable:
            return
        assert not trace_event.trace_is_enabled(
        ), 'Stop tracing before collection.'
        with open(self._trace_log, 'r') as fp:
            data = ast.literal_eval(fp.read() + ']')
        trace_data_builder.AddEventsTo(trace_data_module.TELEMETRY_PART, data)
        try:
            os.remove(self._trace_log)
            self._trace_log = None
        except OSError:
            logging.exception(
                'Error when deleting %s, will try again at exit.',
                self._trace_log)

            def DeleteAtExit(path):
                os.remove(path)

            atexit_with_log.Register(DeleteAtExit, self._trace_log)
        self._trace_log = None
예제 #10
0
def EnableListingStrayProcessesUponExitHook():
  def _ListAllSubprocesses():
    try:
      import psutil
    except ImportError:
      logging.warning(
          'psutil is not installed on the system. Not listing possible '
          'leaked processes. To install psutil, see: '
          'https://pypi.python.org/pypi/psutil')
      return
    telemetry_pid = os.getpid()
    parent = psutil.Process(telemetry_pid)
    if hasattr(parent, 'children'):
      children = parent.children(recursive=True)
    else:  # Some old version of psutil use get_children instead children.
      children = parent.get_children()
    if children:
      leak_processes_info = []
      for p in children:
        if inspect.ismethod(p.name):
          name = p.name()
        else:  # Process.name is a property in old versions of psutil.
          name = p.name
        process_info = '%s (%s)' % (name, p.pid)
        try:
          if inspect.ismethod(p.cmdline):
            cmdline = p.cmdline()
          else:
            cmdline = p.cmdline
          process_info += ' - %s' % cmdline
        except Exception as e: # pylint: disable=broad-except
          logging.warning(str(e))
        leak_processes_info.append(process_info)
      logging.warning('Telemetry leaks these processes: %s',
                      ', '.join(leak_processes_info))

  atexit_with_log.Register(_ListAllSubprocesses)
 def __init__(self, power_monitors, battery):
     super(AndroidPowerMonitorController, self).__init__()
     self._candidate_power_monitors = power_monitors
     self._active_monitors = []
     self._battery = battery
     atexit_with_log.Register(_ReenableChargingIfNeeded, self._battery)