# Copyright 2015 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""
Manages a debugging session with GDB.

This module is meant to be imported from inside GDB. Once loaded, the
|DebugSession| attaches GDB to a running Mojo Shell process on an Android
device using a remote gdbserver.

At startup and each time the execution stops, |DebugSession| associates
debugging symbols for every frame. For more information, see |DebugSession|
documentation.
"""

import gdb
import glob
import itertools
import logging
import os
import os.path
import shutil
import subprocess
import sys
import tempfile
import traceback
import urllib2

sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import android_gdb.config as config
from android_gdb.remote_file_connection import RemoteFileConnection
from android_gdb.signatures import get_signature


logging.getLogger().setLevel(logging.INFO)


def _gdb_execute(command):
  """Executes a GDB command."""
  return gdb.execute(command, to_string=True)


class Mapping(object):
  """Represents a mapped memory region."""
  def __init__(self, line):
    self.start = int(line[0], 16)
    self.end = int(line[1], 16)
    self.size = int(line[2], 16)
    self.offset = int(line[3], 16)
    self.filename = line[4]


def _get_mapped_files():
  """Retrieves all the files mapped into the debugged process memory.

  Returns:
    List of mapped memory regions grouped by files.
  """
  # info proc map returns a space-separated table with the following fields:
  # start address, end address, size, offset, file path.
  mappings = [Mapping(x) for x in
              [x.split() for x in
               _gdb_execute("info proc map").split('\n')]
              if len(x) == 5 and x[4][0] == '/']
  res = {}
  for m in mappings:
    libname = m.filename[m.filename.rfind('/') + 1:]
    res[libname] = res.get(libname, []) + [m]
  return res.values()


class DebugSession(object):
  def __init__(self, build_directory, package_name, pyelftools_dir=None,
               adb='adb'):
    self._build_directory = build_directory
    if not os.path.exists(self._build_directory):
      logging.fatal("Please pass a valid build directory")
      sys.exit(1)
    self._package_name = package_name
    self._adb = adb
    self._remote_file_cache = os.path.join(os.getenv('HOME'), '.mojosymbols')

    if pyelftools_dir != None:
      sys.path.append(pyelftools_dir)
    try:
      import elftools.elf.elffile as elffile
    except ImportError:
      logging.fatal("Unable to find elftools module; please install it "
                    "(for example, using 'pip install pyelftools')")
      sys.exit(1)

    self._elffile_module = elffile

    self._libraries = self._find_libraries(build_directory)
    self._rfc = RemoteFileConnection('localhost', 10000)
    self._remote_file_reader_process = None
    if not os.path.exists(self._remote_file_cache):
      os.makedirs(self._remote_file_cache)
    self._done_mapping = set()
    self._downloaded_files = []

  def __del__(self):
    # Note that, per python interpreter documentation, __del__ is not
    # guaranteed to be called when the interpreter (GDB, in our case) quits.
    # Also, most (all?) globals are no longer available at this time (launching
    # a subprocess does not work).
    self.stop()

  def stop(self, _unused_return_value=None):
    if self._remote_file_reader_process != None:
      self._remote_file_reader_process.kill()

  def _find_libraries(self, lib_dir):
    """Finds all libraries in |lib_dir| and key them by their signatures.
    """
    res = {}
    for fn in glob.glob('%s/*.so' % lib_dir):
      with open(fn, 'r') as f:
        s = get_signature(f, self._elffile_module)
        if s is not None:
          res[s] = fn
    return res

  def _associate_symbols(self, mapping, local_file):
    with open(local_file, "r") as f:
      elf = self._elffile_module.ELFFile(f)
      s = elf.get_section_by_name(".text")
      text_address = mapping[0].start + s['sh_offset']
      _gdb_execute("add-symbol-file %s 0x%x" % (local_file, text_address))

  def _download_file(self, signature, remote):
    """Downloads a remote file either from the cloud or through GDB connection.

    Returns:
      The filename of the downloaded file
    """
    temp_file = tempfile.NamedTemporaryFile()
    logging.info("Trying to download symbols from the cloud.")
    symbols_url = "http://storage.googleapis.com/mojo/symbols/%s" % signature
    try:
      symbol_file = urllib2.urlopen(symbols_url)
      try:
        with open(temp_file.name, "w") as dst:
          shutil.copyfileobj(symbol_file, dst)
          logging.info("Getting symbols for %s at %s." % (remote, symbols_url))
          # This allows the deletion of temporary files on disk when the
          # debugging session terminates.
          self._downloaded_files.append(temp_file)
          return temp_file.name
      finally:
        symbol_file.close()
    except urllib2.HTTPError:
      pass
    logging.info("Downloading file %s" % remote)
    _gdb_execute("remote get %s %s" % (remote, temp_file.name))
    # This allows the deletion of temporary files on disk when the debugging
    # session terminates.
    self._downloaded_files.append(temp_file)
    return temp_file.name

  def _find_mapping_for_address(self, mappings, address):
    """Returns the list of all mappings of the file occupying the |address|
    memory address.
    """
    for file_mappings in mappings:
      for mapping in file_mappings:
        if address >= mapping.start and address <= mapping.end:
          return file_mappings
    return None

  def _try_to_map(self, mapping):
    remote_file = mapping[0].filename
    if remote_file in self._done_mapping:
      return False
    self._done_mapping.add(remote_file)
    self._rfc.open(remote_file)
    signature = get_signature(self._rfc, self._elffile_module)
    if signature is not None:
      if signature in self._libraries:
        self._associate_symbols(mapping, self._libraries[signature])
      else:
        # This library file is not known locally. Download it from the device or
        # the cloud and put it in cache so, if it got symbols, we can see them.
        local_file = os.path.join(self._remote_file_cache, signature)
        if not os.path.exists(local_file):
          tmp_output = self._download_file(signature, remote_file)
          shutil.move(tmp_output, local_file)
        self._associate_symbols(mapping, local_file)
      return True
    return False

  def _update_symbols(self):
    """Updates the mapping between symbols as seen from GDB and local library
    files."""
    logging.info("Updating symbols")
    mapped_files = _get_mapped_files()
    _gdb_execute("info threads")
    nb_threads = len(_gdb_execute("info threads").split("\n")) - 2
    # Map all symbols from native libraries packages with the APK.
    for file_mappings in mapped_files:
      filename = file_mappings[0].filename
      if ((filename.startswith('/data/data/') or
           filename.startswith('/data/app')) and
          not filename.endswith('.apk') and
          not filename.endswith('.dex')):
        logging.info('Pre-mapping: %s' % file_mappings[0].filename)
        self._try_to_map(file_mappings)
    for i in xrange(nb_threads):
      try:
        _gdb_execute("thread %d" % (i + 1))
        frame = gdb.newest_frame()
        while frame and frame.is_valid():
          if frame.name() is None:
            m = self._find_mapping_for_address(mapped_files, frame.pc())
            if m is not None and self._try_to_map(m):
              # Force gdb to recompute its frames.
              _gdb_execute("info threads")
              frame = gdb.newest_frame()
              assert frame.is_valid()
          if (frame.older() is not None and
              frame.older().is_valid() and
              frame.older().pc() != frame.pc()):
            frame = frame.older()
          else:
            frame = None
      except gdb.error:
        traceback.print_exc()

  def _get_device_application_pid(self, application):
    """Gets the PID of an application running on a device."""
    output = subprocess.check_output([self._adb, 'shell', 'ps'])
    for line in output.split('\n'):
      elements = line.split()
      if len(elements) > 0 and elements[-1] == application:
        return elements[1]
    return None

  def start(self):
    """Starts a debugging session."""
    gdbserver_pid = self._get_device_application_pid('gdbserver')
    if gdbserver_pid is not None:
      subprocess.check_call([self._adb, 'shell', 'kill', gdbserver_pid])
    shell_pid = self._get_device_application_pid(self._package_name)
    if shell_pid is None:
      raise Exception('Unable to find a running mojo shell.')
    subprocess.check_call([self._adb, 'forward', 'tcp:9999', 'tcp:9999'])
    subprocess.Popen(
        [self._adb, 'shell', 'gdbserver', '--attach', ':9999', shell_pid],
        # os.setpgrp ensures signals passed to this file (such as SIGINT) are
        # not propagated to child processes.
        preexec_fn = os.setpgrp)

    # Kill stray remote reader processes. See __del__ comment for more info.
    remote_file_reader_pid = self._get_device_application_pid(
        config.REMOTE_FILE_READER_DEVICE_PATH)
    if remote_file_reader_pid is not None:
      subprocess.check_call([self._adb, 'shell', 'kill',
                             remote_file_reader_pid])
    self._remote_file_reader_process = subprocess.Popen(
        [self._adb, 'shell', config.REMOTE_FILE_READER_DEVICE_PATH],
        stdout=subprocess.PIPE, preexec_fn = os.setpgrp)
    port = int(self._remote_file_reader_process.stdout.readline())
    subprocess.check_call([self._adb, 'forward', 'tcp:10000', 'tcp:%d' % port])
    self._rfc.connect()

    _gdb_execute('target remote localhost:9999')

    self._update_symbols()
    def on_stop(_):
      self._update_symbols()
    gdb.events.stop.connect(on_stop)
    gdb.events.exited.connect(self.stop)
