# -*- coding: utf-8 -*-
# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Generate minidump symbols for use by the Crash server.

Note: This should be run inside the chroot.

This produces files in the breakpad format required by minidump_stackwalk and
the crash server to dump stack information.

Basically it scans all the split .debug files in /build/$BOARD/usr/lib/debug/
and converts them over using the `dump_syms` programs.  Those plain text .sym
files are then stored in /build/$BOARD/usr/lib/debug/breakpad/.

If you want to actually upload things, see upload_symbols.py.
"""

from __future__ import print_function

import collections
import ctypes
import multiprocessing
import os
import sys

from chromite.lib import commandline
from chromite.lib import cros_build_lib
from chromite.lib import cros_logging as logging
from chromite.lib import osutils
from chromite.lib import parallel
from chromite.lib import signals


assert sys.version_info >= (3, 6), 'This module requires Python 3.6+'


SymbolHeader = collections.namedtuple('SymbolHeader',
                                      ('cpu', 'id', 'name', 'os',))


def ReadSymsHeader(sym_file):
  """Parse the header of the symbol file

  The first line of the syms file will read like:
    MODULE Linux arm F4F6FA6CCBDEF455039C8DE869C8A2F40 blkid

  https://code.google.com/p/google-breakpad/wiki/SymbolFiles

  Args:
    sym_file: The symbol file to parse

  Returns:
    A SymbolHeader object

  Raises:
    ValueError if the first line of |sym_file| is invalid
  """
  with cros_build_lib.Open(sym_file, 'rb') as f:
    header = f.readline().decode('utf-8').split()

  if header[0] != 'MODULE' or len(header) != 5:
    raise ValueError('header of sym file is invalid')

  return SymbolHeader(os=header[1], cpu=header[2], id=header[3], name=header[4])


def GenerateBreakpadSymbol(elf_file, debug_file=None, breakpad_dir=None,
                           strip_cfi=False, num_errors=None,
                           dump_syms_cmd='dump_syms'):
  """Generate the symbols for |elf_file| using |debug_file|

  Args:
    elf_file: The file to dump symbols for
    debug_file: Split debug file to use for symbol information
    breakpad_dir: The dir to store the output symbol file in
    strip_cfi: Do not generate CFI data
    num_errors: An object to update with the error count (needs a .value member)
    dump_syms_cmd: Command to use for dumping symbols.

  Returns:
    The name of symbol file written out.
  """
  assert breakpad_dir
  if num_errors is None:
    num_errors = ctypes.c_int()

  cmd_base = [dump_syms_cmd, '-v']
  if strip_cfi:
    cmd_base += ['-c']
  # Some files will not be readable by non-root (e.g. set*id /bin/su).
  needs_sudo = not os.access(elf_file, os.R_OK)

  def _DumpIt(cmd_args):
    if needs_sudo:
      run_command = cros_build_lib.sudo_run
    else:
      run_command = cros_build_lib.run
    return run_command(
        cmd_base + cmd_args, stderr=True, stdout=temp.name,
        check=False, debug_level=logging.DEBUG)

  def _CrashCheck(ret, msg):
    if ret < 0:
      logging.PrintBuildbotStepWarnings()
      logging.warning('dump_syms crashed with %s; %s',
                      signals.StrSignal(-ret), msg)

  osutils.SafeMakedirs(breakpad_dir)
  with cros_build_lib.UnbufferedNamedTemporaryFile(
      dir=breakpad_dir, delete=False) as temp:
    if debug_file:
      # Try to dump the symbols using the debug file like normal.
      cmd_args = [elf_file, os.path.dirname(debug_file)]
      result = _DumpIt(cmd_args)

      if result.returncode:
        # Sometimes dump_syms can crash because there's too much info.
        # Try dumping and stripping the extended stuff out.  At least
        # this way we'll get the extended symbols.  https://crbug.com/266064
        _CrashCheck(result.returncode, 'retrying w/out CFI')
        cmd_args = ['-c', '-r'] + cmd_args
        result = _DumpIt(cmd_args)
        _CrashCheck(result.returncode, 'retrying w/out debug')

      basic_dump = result.returncode
    else:
      basic_dump = True

    if basic_dump:
      # If that didn't work (no debug, or dump_syms still failed), try
      # dumping just the file itself directly.
      result = _DumpIt([elf_file])
      if result.returncode:
        # A lot of files (like kernel files) contain no debug information,
        # do not consider such occurrences as errors.
        logging.PrintBuildbotStepWarnings()
        _CrashCheck(result.returncode, 'giving up entirely')
        if b'file contains no debugging information' in result.stderr:
          logging.warning('no symbols found for %s', elf_file)
        else:
          num_errors.value += 1
          logging.error('dumping symbols for %s failed:\n%s', elf_file,
                        result.error)
        os.unlink(temp.name)
        return num_errors.value

    # Move the dumped symbol file to the right place:
    # /build/$BOARD/usr/lib/debug/breakpad/<module-name>/<id>/<module-name>.sym
    header = ReadSymsHeader(temp)
    logging.info('Dumped %s as %s : %s', elf_file, header.name, header.id)
    sym_file = os.path.join(breakpad_dir, header.name, header.id,
                            header.name + '.sym')
    osutils.SafeMakedirs(os.path.dirname(sym_file))
    os.rename(temp.name, sym_file)
    os.chmod(sym_file, 0o644)

  return sym_file


def GenerateBreakpadSymbols(board, breakpad_dir=None, strip_cfi=False,
                            generate_count=None, sysroot=None,
                            num_processes=None, clean_breakpad=False,
                            exclude_dirs=(), file_list=None):
  """Generate symbols for this board.

  If |file_list| is None, symbols are generated for all executables, otherwise
  only for the files included in |file_list|.

  TODO(build):
  This should be merged with buildbot_commands.GenerateBreakpadSymbols()
  once we rewrite cros_generate_breakpad_symbols in python.

  Args:
    board: The board whose symbols we wish to generate
    breakpad_dir: The full path to the breakpad directory where symbols live
    strip_cfi: Do not generate CFI data
    generate_count: If set, only generate this many symbols (meant for testing)
    sysroot: The root where to find the corresponding ELFs
    num_processes: Number of jobs to run in parallel
    clean_breakpad: Should we `rm -rf` the breakpad output dir first; note: we
      do not do any locking, so do not run more than one in parallel when True
    exclude_dirs: List of dirs (relative to |sysroot|) to not search
    file_list: Only generate symbols for files in this list. Each file must be a
      full path (including |sysroot| prefix).
      TODO(build): Support paths w/o |sysroot|.

  Returns:
    The number of errors that were encountered.
  """
  if sysroot is None:
    sysroot = cros_build_lib.GetSysroot(board=board)
  if breakpad_dir is None:
    breakpad_dir = FindBreakpadDir(board, sysroot=sysroot)
  if clean_breakpad:
    logging.info('cleaning out %s first', breakpad_dir)
    osutils.RmDir(breakpad_dir, ignore_missing=True, sudo=True)
  # Make sure non-root can write out symbols as needed.
  osutils.SafeMakedirs(breakpad_dir, sudo=True)
  if not os.access(breakpad_dir, os.W_OK):
    cros_build_lib.sudo_run(['chown', '-R', str(os.getuid()), breakpad_dir])
  debug_dir = FindDebugDir(board, sysroot=sysroot)
  exclude_paths = [os.path.join(debug_dir, x) for x in exclude_dirs]
  if file_list is None:
    file_list = []
  file_filter = dict.fromkeys([os.path.normpath(x) for x in file_list], False)

  logging.info('generating breakpad symbols using %s', debug_dir)

  # Let's locate all the debug_files and elfs first along with the debug file
  # sizes.  This way we can start processing the largest files first in parallel
  # with the small ones.
  # If |file_list| was given, ignore all other files.
  targets = []
  for root, dirs, files in os.walk(debug_dir):
    if root in exclude_paths:
      logging.info('Skipping excluded dir %s', root)
      del dirs[:]
      continue

    for debug_file in files:
      debug_file = os.path.join(root, debug_file)
      # Turn /build/$BOARD/usr/lib/debug/sbin/foo.debug into
      # /build/$BOARD/sbin/foo.
      elf_file = os.path.join(sysroot, debug_file[len(debug_dir) + 1:-6])

      if file_filter:
        if elf_file in file_filter:
          file_filter[elf_file] = True
        elif debug_file in file_filter:
          file_filter[debug_file] = True
        else:
          continue

      # Filter out files based on common issues with the debug file.
      if not debug_file.endswith('.debug'):
        continue

      elif debug_file.endswith('.ko.debug'):
        logging.debug('Skipping kernel module %s', debug_file)
        continue

      elif os.path.islink(debug_file):
        # The build-id stuff is common enough to filter out by default.
        if '/.build-id/' in debug_file:
          msg = logging.debug
        else:
          msg = logging.warning
        msg('Skipping symbolic link %s', debug_file)
        continue

      # Filter out files based on common issues with the elf file.
      if not os.path.exists(elf_file):
        # Sometimes we filter out programs from /usr/bin but leave behind
        # the .debug file.
        logging.warning('Skipping missing %s', elf_file)
        continue

      targets.append((os.path.getsize(debug_file), elf_file, debug_file))

  bg_errors = multiprocessing.Value('i')
  if file_filter:
    files_not_found = [x for x, found in file_filter.items() if not found]
    bg_errors.value += len(files_not_found)
    if files_not_found:
      logging.error('Failed to find requested files: %s', files_not_found)

  # Now start generating symbols for the discovered elfs.
  with parallel.BackgroundTaskRunner(GenerateBreakpadSymbol,
                                     breakpad_dir=breakpad_dir,
                                     strip_cfi=strip_cfi,
                                     num_errors=bg_errors,
                                     processes=num_processes) as queue:
    for _, elf_file, debug_file in sorted(targets, reverse=True):
      if generate_count == 0:
        break

      queue.put([elf_file, debug_file])
      if generate_count is not None:
        generate_count -= 1
        if generate_count == 0:
          break

  return bg_errors.value


def FindDebugDir(board, sysroot=None):
  """Given a |board|, return the path to the split debug dir for it"""
  if sysroot is None:
    sysroot = cros_build_lib.GetSysroot(board=board)
  return os.path.join(sysroot, 'usr', 'lib', 'debug')


def FindBreakpadDir(board, sysroot=None):
  """Given a |board|, return the path to the breakpad dir for it"""
  return os.path.join(FindDebugDir(board, sysroot=sysroot), 'breakpad')


def main(argv):
  parser = commandline.ArgumentParser(description=__doc__)

  parser.add_argument('--board', default=None,
                      help='board to generate symbols for')
  parser.add_argument('--breakpad_root', type='path', default=None,
                      help='root output directory for breakpad symbols')
  parser.add_argument('--sysroot', type='path', default=None,
                      help='root input directory for files')
  parser.add_argument('--exclude-dir', type=str, action='append',
                      default=[],
                      help='directory (relative to |board| root) to not search')
  parser.add_argument('--generate-count', type=int, default=None,
                      help='only generate # number of symbols')
  parser.add_argument('--noclean', dest='clean', action='store_false',
                      default=True,
                      help='do not clean out breakpad dir before running')
  parser.add_argument('--jobs', type=int, default=None,
                      help='limit number of parallel jobs')
  parser.add_argument('--strip_cfi', action='store_true', default=False,
                      help='do not generate CFI data (pass -c to dump_syms)')
  parser.add_argument('file_list', nargs='*', default=None,
                      help='generate symbols for only these files '
                           '(e.g. /build/$BOARD/usr/bin/foo)')

  opts = parser.parse_args(argv)
  opts.Freeze()

  if opts.board is None and opts.sysroot is None:
    cros_build_lib.Die('--board or --sysroot is required')

  ret = GenerateBreakpadSymbols(opts.board, breakpad_dir=opts.breakpad_root,
                                strip_cfi=opts.strip_cfi,
                                generate_count=opts.generate_count,
                                sysroot=opts.sysroot,
                                num_processes=opts.jobs,
                                clean_breakpad=opts.clean,
                                exclude_dirs=opts.exclude_dir,
                                file_list=opts.file_list)
  if ret:
    logging.error('encountered %i problem(s)', ret)
    # Since exit(status) gets masked, clamp it to 1 so we don't inadvertently
    # return 0 in case we are a multiple of the mask.
    ret = 1

  return ret
