def runTest(self):
     mock_backend_1 = MockBackend('mock-backend-1')
     mock_backend_2 = MockBackend('mock-backend-2')
     self.assertEqual(mock_backend_1.settings['key_1'], 'key descritpion 1')
     backends.Register(mock_backend_1)
     backends.Register(mock_backend_2)
     devices = list(backends.ListDevices())
     self.assertEqual(len(devices), 4)
     self.assertIsNotNone(backends.GetDevice('mock-backend-1', 'device-1'))
     self.assertIsNotNone(backends.GetDevice('mock-backend-1', 'device-2'))
     self.assertIsNotNone(backends.GetDevice('mock-backend-2', 'device-1'))
     self.assertIsNotNone(backends.GetDevice('mock-backend-2', 'device-1'))
     self.assertTrue('key_1' in mock_backend_1.settings)
Beispiel #2
0
def TracerMain_(log, storage_path, backend_name, device_id, pid, interval,
    count, trace_native_heap):
  """Entry point for the background periodic tracer task."""
  # Initialize storage.
  storage = file_storage.Storage(storage_path)

  # Initialize the backend.
  backend = backends.GetBackend(backend_name)
  for k, v in storage.LoadSettings(backend_name).iteritems():
    backend.settings[k] = v

  # Initialize the device.
  device = backends.GetDevice(backend_name, device_id)
  for k, v in storage.LoadSettings(device_id).iteritems():
    device.settings[k] = v

  # Start periodic tracing.
  process = device.GetProcess(pid)
  log.put((1, 'Starting trace (%d dumps x %s s.). Device: %s, process: %s' % (
      count, interval, device.name, process.name)))
  datetime_str = datetime.datetime.now().strftime('%Y-%m-%d_%H-%M')
  archive_name = '%s - %s - %s' % (datetime_str, device.name, process.name)
  archive = storage.OpenArchive(archive_name, create=True)
  heaps_to_symbolize = []

  for i in xrange(1, count + 1):  # [1, count] range is easier to handle.
    process = device.GetProcess(pid)
    if not process:
      log.put((100, 'Process %d died.' % pid))
      return 1
    # Calculate the completion rate proportionally to 80%. We keep the remaining
    # 20% for the final symbolization step (just an approximate estimation).
    completion = 80 * i / count
    log.put((completion, 'Dumping trace %d of %d' % (i, count)))
    archive.StartNewSnapshot()
    mmaps = process.DumpMemoryMaps()
    log.put((completion, 'Dumped %d memory maps' % len(mmaps)))
    archive.StoreMemMaps(mmaps)
    if trace_native_heap:
      nheap = process.DumpNativeHeap()
      log.put((completion, 'Dumped %d native allocs' % len(nheap.allocations)))
      archive.StoreNativeHeap(nheap)
      heaps_to_symbolize += [nheap]

    if i < count:
      time.sleep(interval)

  log.put((90, 'Symbolizing'))
  symbols = backend.ExtractSymbols(heaps_to_symbolize,
                                   device.settings['native_symbol_paths'] or '')

  expected_symbols_count = len(set.union(
      *[set(x.stack_frames.iterkeys()) for x in heaps_to_symbolize]))
  log.put((99, 'Symbolization complete. Got %d symbols (%.1f%%).' % (
      len(symbols), 100.0 * len(symbols) / expected_symbols_count)))

  archive.StoreSymbols(symbols)

  log.put((100, 'Trace complete.'))
  return 0
Beispiel #3
0
def _ListProcesses(backend_name, device_id, filter_process_name):
    device = backends.GetDevice(backend_name, device_id)
    if not device:
        print 'Device', device_id, 'does not exist'
    else:
        if not filter_process_name:
            print 'Listing all processes'
        else:
            print 'Listing processes matching ' + filter_process_name.lower()
        print ''
        device.Initialize()
        _PrintProcessStatsHeadingLine()
        for process in device.ListProcesses():
            if (not filter_process_name
                    or filter_process_name.lower() in process.name.lower()):
                stats = process.GetStats()
                _PrintProcessStats(process, stats)
Beispiel #4
0
def _ListProcessStats(backend_name, device_id, process_id):
    """Prints process stats periodically and displays an error if the
     process or device does not exist
  """
    device = backends.GetDevice(backend_name, device_id)
    if not device:
        print 'Device', device_id, 'does not exist'
    else:
        device.Initialize()
        process = device.GetProcess(process_id)
        if not process:
            print 'Cannot find process [%d] on device %s' % (process_id,
                                                             device_id)
            return
        print 'Stats for process: [%d] %s' % (process_id, process.name)
        _PrintProcessStatsHeadingLine()
        while True:
            stats = process.GetStats()
            _PrintProcessStats(process, stats)
            time.sleep(1)
Beispiel #5
0
def _GetDevice(args):
    """Returns a |backends.Device| instance from a /backend/device URI."""
    assert (len(args) >= 2), 'Malformed request. Expecting /backend/device'
    return backends.GetDevice(backend_name=args[0], device_id=args[1])
Beispiel #6
0
def main():
    COMMANDS = ['devices', 'ps', 'stats', 'mmaps', 'classified_mmaps']
    usage = ('%prog [options] ' + ' | '.join(COMMANDS))
    parser = optparse.OptionParser(usage=usage)
    parser.add_option('-b',
                      '--backend',
                      help='Backend name '
                      '(e.g., Android)',
                      type='string',
                      default='Android')
    parser.add_option('-s',
                      '--device_id',
                      help='Device '
                      'id (e.g., Android serial)',
                      type='string')
    parser.add_option('-p',
                      '--process_id',
                      help='Target process id',
                      type='int')
    parser.add_option('-m',
                      '--filter_process_name',
                      help='Process '
                      'name to match',
                      type='string')
    parser.add_option('-r',
                      '--mmap_rule',
                      help='mmap rule',
                      type='string',
                      default=os.path.join(constants.CLASSIFICATION_RULES_PATH,
                                           'default', 'mmap-android.py'))
    (options, args) = parser.parse_args()

    memory_inspector.RegisterAllBackends()

    if not args or args[0] not in COMMANDS:
        parser.print_help()
        return -1

    if args[0] == 'devices':
        _ListDevices(options.backend)
        return 0

    number_of_devices = 0
    if options.device_id:
        device_id = options.device_id
        number_of_devices = 1
    else:
        for device in backends.ListDevices():
            if device.backend.name == options.backend:
                number_of_devices += 1
                device_id = device.id

    if number_of_devices == 0:
        print "No devices connected"
        return -1

    if number_of_devices > 1:
        print(
            'More than 1 device connected. You need to provide'
            ' --device_id')
        return -1

    device = backends.GetDevice(options.backend, device_id)
    if not device:
        print 'Device', device_id, 'does not exist'
        return -1

    device.Initialize()
    if args[0] == 'ps':
        if not options.filter_process_name:
            print 'Listing all processes'
        else:
            print('Listing processes matching ' +
                  options.filter_process_name.lower())
        print ''
        print '%-10s : %-50s : %12s %12s %12s' % (
            'Process ID', 'Process Name', 'RUN_TIME', 'THREADS', 'MEM_RSS_KB')
        print ''
        for process in device.ListProcesses():
            if (not options.filter_process_name
                    or options.filter_process_name.lower()
                    in process.name.lower()):
                stats = process.GetStats()
                run_time_min, run_time_sec = divmod(stats.run_time, 60)
                print '%10s : %-50s : %6s m %2s s %8s %12s' % (
                    process.pid, _Truncate(process.name, 50), run_time_min,
                    run_time_sec, stats.threads, stats.vm_rss)
        return 0

    if not options.process_id:
        print 'You need to provide --process_id'
        return -1

    process = device.GetProcess(options.process_id)

    if not process:
        print 'Cannot find process [%d] on device %s' % (options.process_id,
                                                         device.id)
        return -1
    elif args[0] == 'stats':
        _ListProcessStats(process)
        return 0
    elif args[0] == 'mmaps':
        _ListProcessMmaps(process)
        return 0
    elif args[0] == 'classified_mmaps':
        _ListProcessClassifiedMmaps(process, options.mmap_rule)
        return 0