Beispiel #1
0
def _filter_cflags_for_chromium_org(vars):
  append_cflags = []
  # TODO(http://crbug.com/509945): Use Gold once it's ready.
  strip_flags = ['-fuse-ld=gold', '-march=pentium4', '-finline-limit=64']
  if OPTIONS.is_arm():
    # ARM clang does not support these flags.
    strip_flags.extend(['-fno-partial-inlining', '-fno-early-inlining',
                        '-fno-tree-copy-prop', '-fno-tree-loop-optimize',
                        '-fno-move-loop-invariants',
                        '-Wa,-mimplicit-it=always'])
  if not OPTIONS.is_bare_metal_build():
    # nacl-clang supports -Oz, which is more aggressive than -Os.
    strip_flags.append('-Os')
  # TODO(crbug.com/346783): Remove this once we NaCl'ize PageAllocator.cpp.
  # It is only necessary for NaCl, but we do this for linux as well
  # to minimize platform differences.
  append_cflags.append('-DMEMORY_TOOL_REPLACES_ALLOCATOR')
  _update_flags(vars, append_cflags, strip_flags)
  # -finline-limit=32 experimentally provides the smallest binary across
  # the ni and nx targets.  Also specify -finline-functions so all functions
  # are candidates for inlining.
  size_opts = ['-finline-limit=32', '-finline-functions']
  if not OPTIONS.is_bare_metal_build():
    # -Oz is not valid for asmflags, so just add it for C and C++.
    vars.get_conlyflags().append('-Oz')
    vars.get_cxxflags().append('-Oz')
  # With these flags, compilers will not emit .eh_frame* sections and
  # the size of libwebviewchromium.so reduces from 84MB to 75MB on L.
  # As these options disables libgcc's _Unwind_Backtrace, we keep
  # using them for non-production build. Note GDB and breakpad can
  # produce backtraces without .eh_frame.
  #
  # It is intentional this condition is inconsistent with
  # ninja_generator.py and make_to_ninja.py. Removing .eh_frame from
  # production binary did not make a significant difference for file
  # size of L. We would rather prefer keeping .eh_frame for
  # _Unwind_Backtrace.
  if not OPTIONS.is_debug_code_enabled():
    size_opts += ['-fno-unwind-tables', '-fno-asynchronous-unwind-tables']
  vars.get_cflags()[:] = vars.get_cflags() + size_opts
  # dlopen fails for the following undefined reference without -mthumb
  # _ZN7WebCore26feLightingConstantsForNeonEv
  # TODO(crbug.com/358333): Investigate if this is actually needed.
  if OPTIONS.is_arm():
    vars.get_cflags().append('-mthumb')
  # OpenSSL makes wrong assumption that sizeof(long) == 8 under x86_64.
  # Remove the x86_64-specific include path to fall back to x86 config.
  # Note that this include path is set in many modules depending on OpenSSL,
  # not limited to third_party_openssl_openssl_gyp.a itself.
  if OPTIONS.is_nacl_x86_64():
    openssl_x64_include = (
        'android/external/chromium_org/third_party/openssl/config/x64')
    includes = vars.get_includes()
    if openssl_x64_include in includes:
      includes.remove(openssl_x64_include)
Beispiel #2
0
    def run_with_filter(self, cmd, cwd=None):
        if cwd is None:
            cwd = self.get_remote_arc_root()
        cmd = 'cd %s && %s' % (cwd, cmd)

        handler = minidump_filter.MinidumpFilter(
            concurrent_subprocess.RedirectOutputHandler())
        if self._attach_nacl_gdb_type:
            if OPTIONS.is_nacl_build():
                handler = gdb_util.NaClGdbHandlerAdapter(
                    handler,
                    None,
                    self._attach_nacl_gdb_type,
                    remote_executor=self)
            elif OPTIONS.is_bare_metal_build():
                handler = gdb_util.BareMetalGdbHandlerAdapter(
                    handler,
                    self._nacl_helper_nonsfi_binary,
                    self._attach_nacl_gdb_type,
                    host=self._remote,
                    ssh_options=self.get_ssh_options(),
                    remote_executor=self)
        if self._jdb_type and self._jdb_port:
            handler = jdb_util.JdbHandlerAdapter(handler, self._jdb_port,
                                                 self._jdb_type, self)
        return run_command_with_filter(self._build_ssh_command(cmd),
                                       output_handler=handler)
Beispiel #3
0
def get_target_runner(bin_dir=None, extra_library_paths=None, extra_envs=None):
  if OPTIONS.is_bare_metal_build():
    return get_bare_metal_runner(bin_dir=bin_dir,
                                 extra_library_paths=extra_library_paths,
                                 extra_envs=extra_envs)
  else:
    return get_nacl_runner(OPTIONS.get_target_bitsize(), bin_dir=bin_dir,
                           extra_library_paths=extra_library_paths,
                           extra_envs=extra_envs)
Beispiel #4
0
def _cleanup_output(raw):
  if OPTIONS.is_nacl_build():
    filter_pattern = _NACL_FILTER_PATTERN
  elif OPTIONS.is_bare_metal_build():
    filter_pattern = _BARE_METAL_FILTER_PATTERN
  else:
    assert False, 'Must not reach here'
  lines = [line for line in raw.split('\n') if not filter_pattern.match(line)]
  return '\n'.join(lines)
Beispiel #5
0
def get_target_runner(bin_dir=None, extra_library_paths=None, extra_envs=None):
    if OPTIONS.is_bare_metal_build():
        return get_bare_metal_runner(bin_dir=bin_dir,
                                     extra_library_paths=extra_library_paths,
                                     extra_envs=extra_envs)
    else:
        return get_nacl_runner(OPTIONS.get_target_bitsize(),
                               bin_dir=bin_dir,
                               extra_library_paths=extra_library_paths,
                               extra_envs=extra_envs)
Beispiel #6
0
def launch_remote_chrome(parsed_args, argv):
    try:
        attach_nacl_gdb_type = None
        nacl_helper_nonsfi_binary = None
        need_copy_nacl_helper_nonsfi_binary = False
        jdb_port = None
        jdb_type = None

        if 'plugin' in parsed_args.gdb:
            attach_nacl_gdb_type = parsed_args.gdb_type
            if OPTIONS.is_bare_metal_build():
                nacl_helper_nonsfi_binary = parsed_args.nacl_helper_nonsfi_binary
                if not nacl_helper_nonsfi_binary:
                    # We decide the path here, but the binary can be copied after
                    # RemoteExecutor is constructed.
                    nacl_helper_nonsfi_binary = os.path.join(
                        remote_executor_util.get_remote_binaries_dir(),
                        os.path.basename(_REMOTE_NACL_HELPER_NONSFI_BINARY))
                    need_copy_nacl_helper_nonsfi_binary = True

        if 'jdb_port' in vars(parsed_args) and 'jdb_type' in vars(parsed_args):
            jdb_port = parsed_args.jdb_port
            jdb_type = parsed_args.jdb_type

        executor = _create_remote_executor(
            parsed_args,
            attach_nacl_gdb_type=attach_nacl_gdb_type,
            nacl_helper_nonsfi_binary=nacl_helper_nonsfi_binary,
            arc_dir_name=parsed_args.remote_arc_dir_name,
            jdb_port=jdb_port,
            jdb_type=jdb_type)

        copied_files = remote_executor_util.get_launch_chrome_deps(parsed_args)
        _setup_remote_environment(parsed_args, executor, copied_files)

        if need_copy_nacl_helper_nonsfi_binary:
            remote_binaries = [_REMOTE_NACL_HELPER_NONSFI_BINARY]
            executor.copy_remote_files(
                remote_binaries,
                remote_executor_util.get_remote_binaries_dir())

        if nacl_helper_nonsfi_binary:
            # This should not happen, but for just in case.
            assert os.path.exists(nacl_helper_nonsfi_binary)
            # -v: show the killed process, -w: wait for the killed process to die.
            executor.run('sudo killall -vw gdbserver', ignore_failure=True)

        command = ' '.join(
            ['sudo', '-u', 'chronos',
             executor.get_remote_env()] +
            launch_chrome_util.get_launch_chrome_command(
                remote_executor_util.create_launch_remote_chrome_param(argv)))
        executor.run_with_filter(command)
    except subprocess.CalledProcessError as e:
        sys.exit(e.returncode)
Beispiel #7
0
    def get_crash_report(self):
        assert self._crash_addr is not None
        for binary_name, start_addr, end_addr in self._text_segments:
            if start_addr > self._crash_addr or self._crash_addr >= end_addr:
                continue

            addr = self._crash_addr
            # For PIC or PIE, we need to subtract the load bias.
            if binary_name.endswith('.so') or OPTIONS.is_bare_metal_build():
                addr -= start_addr

            if os.path.exists(binary_name):
                binary_filename = binary_name
            else:
                self.init_binary_map()
                if binary_name not in self._binary_map:
                    return '%s %x (binary file not found)\n' % (binary_name,
                                                                addr)
                binary_filename = self._binary_map[binary_name]

            pipe = subprocess.Popen([
                toolchain.get_tool(OPTIONS.target(), 'addr2line'), '-e',
                binary_filename
            ],
                                    stdin=subprocess.PIPE,
                                    stdout=subprocess.PIPE,
                                    stderr=subprocess.STDOUT)
            addr2line_result = pipe.communicate('%x\n' % addr)[0]

            # We can always get clean result using 32 byte aligned start
            # address as NaCl binary does never overlap 32 byte boundary.
            objdump_start_addr = (addr & ~31) - 32
            objdump_end_addr = addr + 64
            pipe = subprocess.Popen([
                toolchain.get_tool(OPTIONS.target(), 'objdump'), '-SC',
                binary_filename, '--start-address',
                '0x%x' % objdump_start_addr, '--stop-address',
                '0x%x' % objdump_end_addr
            ],
                                    stdout=subprocess.PIPE,
                                    stderr=subprocess.STDOUT)
            objdump_result = pipe.communicate('%x\n' % addr)[0]

            if self._is_annotating:
                report = ('[[ %s 0x%x %s ]]' %
                          (binary_filename, addr, addr2line_result.strip()))
                # The result of objdump is too verbose for annotation.
            else:
                report = '%s 0x%x\n' % (binary_filename, addr)
                report += addr2line_result
                report += objdump_result

            return report
        return 'Failed to retrieve a crash report\n'
def launch_remote_chrome(parsed_args, argv):
    try:
        attach_nacl_gdb_type = None
        nacl_helper_nonsfi_binary = None
        need_copy_nacl_helper_nonsfi_binary = False
        jdb_port = None
        jdb_type = None

        if "plugin" in parsed_args.gdb:
            attach_nacl_gdb_type = parsed_args.gdb_type
            if OPTIONS.is_bare_metal_build():
                nacl_helper_nonsfi_binary = parsed_args.nacl_helper_nonsfi_binary
                if not nacl_helper_nonsfi_binary:
                    # We decide the path here, but the binary can be copied after
                    # RemoteExecutor is constructed.
                    nacl_helper_nonsfi_binary = os.path.join(
                        remote_executor_util.get_remote_binaries_dir(),
                        os.path.basename(_REMOTE_NACL_HELPER_NONSFI_BINARY),
                    )
                    need_copy_nacl_helper_nonsfi_binary = True

        if "jdb_port" in vars(parsed_args) and "jdb_type" in vars(parsed_args):
            jdb_port = parsed_args.jdb_port
            jdb_type = parsed_args.jdb_type

        executor = _create_remote_executor(
            parsed_args,
            attach_nacl_gdb_type=attach_nacl_gdb_type,
            nacl_helper_nonsfi_binary=nacl_helper_nonsfi_binary,
            arc_dir_name=parsed_args.remote_arc_dir_name,
            jdb_port=jdb_port,
            jdb_type=jdb_type,
        )

        copied_files = remote_executor_util.get_launch_chrome_deps(parsed_args)
        _setup_remote_environment(parsed_args, executor, copied_files)

        if need_copy_nacl_helper_nonsfi_binary:
            remote_binaries = [_REMOTE_NACL_HELPER_NONSFI_BINARY]
            executor.copy_remote_files(remote_binaries, remote_executor_util.get_remote_binaries_dir())

        if nacl_helper_nonsfi_binary:
            # This should not happen, but for just in case.
            assert os.path.exists(nacl_helper_nonsfi_binary)
            # -v: show the killed process, -w: wait for the killed process to die.
            executor.run("sudo killall -vw gdbserver", ignore_failure=True)

        command = " ".join(
            ["sudo", "-u", "chronos", executor.get_remote_env()]
            + launch_chrome_util.get_launch_chrome_command(remote_executor_util.create_launch_remote_chrome_param(argv))
        )
        executor.run_with_filter(command)
    except subprocess.CalledProcessError as e:
        sys.exit(e.returncode)
Beispiel #9
0
  def get_crash_report(self):
    assert self._crash_addr is not None
    for binary_name, start_addr, end_addr in self._text_segments:
      if start_addr > self._crash_addr or self._crash_addr >= end_addr:
        continue

      addr = self._crash_addr
      # For PIC or PIE, we need to subtract the load bias.
      if binary_name.endswith('.so') or OPTIONS.is_bare_metal_build():
        addr -= start_addr

      if os.path.exists(binary_name):
        binary_filename = binary_name
      else:
        self.init_binary_map()
        if binary_name not in self._binary_map:
          return '%s %x (binary file not found)\n' % (binary_name, addr)
        binary_filename = self._binary_map[binary_name]

      pipe = subprocess.Popen([toolchain.get_tool(OPTIONS.target(),
                                                  'addr2line'),
                               '-e', binary_filename],
                              stdin=subprocess.PIPE,
                              stdout=subprocess.PIPE,
                              stderr=subprocess.STDOUT)
      addr2line_result = pipe.communicate('%x\n' % addr)[0]

      # We can always get clean result using 32 byte aligned start
      # address as NaCl binary does never overlap 32 byte boundary.
      objdump_start_addr = (addr & ~31) - 32
      objdump_end_addr = addr + 64
      pipe = subprocess.Popen([toolchain.get_tool(OPTIONS.target(),
                                                  'objdump'),
                               '-SC', binary_filename,
                               '--start-address', '0x%x' % objdump_start_addr,
                               '--stop-address', '0x%x' % objdump_end_addr],
                              stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
      objdump_result = pipe.communicate('%x\n' % addr)[0]

      if self._is_annotating:
        report = ('[[ %s 0x%x %s ]]' %
                  (binary_filename, addr, addr2line_result.strip()))
        # The result of objdump is too verbose for annotation.
      else:
        report = '%s 0x%x\n' % (binary_filename, addr)
        report += addr2line_result
        report += objdump_result

      return report
    return 'Failed to retrieve a crash report\n'
Beispiel #10
0
def is_no_sandbox_needed(gdb_target_list):
    """Returns whether --no-sandbox is needed to run Chrome with GDB properly.
  """
    # Chrome uses getpid() to print the PID of the renderer/gpu process to be
    # debugged, which is parsed by launch_chrome.  If the sandbox is enabled,
    # fake PIDs are returned from getpid().
    if 'renderer' in gdb_target_list or 'gpu' in gdb_target_list:
        return True

    # To suspend at the very beginning of the loader, we use a lock file.
    # no-sandox option is necessary to access the file.
    # TODO(crbug.com/354290): Remove this when GDB is properly supported.
    if OPTIONS.is_bare_metal_build() and 'plugin' in gdb_target_list:
        return True

    return False
Beispiel #11
0
def is_no_sandbox_needed(gdb_target_list):
  """Returns whether --no-sandbox is needed to run Chrome with GDB properly.
  """
  # Chrome uses getpid() to print the PID of the renderer/gpu process to be
  # debugged, which is parsed by launch_chrome.  If the sandbox is enabled,
  # fake PIDs are returned from getpid().
  if 'renderer' in gdb_target_list or 'gpu' in gdb_target_list:
    return True

  # To suspend at the very beginning of the loader, we use a lock file.
  # no-sandox option is necessary to access the file.
  # TODO(crbug.com/354290): Remove this when GDB is properly supported.
  if OPTIONS.is_bare_metal_build() and 'plugin' in gdb_target_list:
    return True

  return False
Beispiel #12
0
def _select_output_handler(parsed_args, stats, chrome_process, **kwargs):
  if parsed_args.mode == 'atftest':
    handler = output_handler.AtfTestHandler()
  elif parsed_args.mode == 'perftest':
    handler = output_handler.PerfTestHandler(
        parsed_args, stats, chrome_process, **kwargs)
  else:
    handler = concurrent_subprocess.RedirectOutputHandler(
        *['.*' + re.escape(suppress) for suppress in _SUPPRESS_LIST])

  if 'gpu' in parsed_args.gdb or 'renderer' in parsed_args.gdb:
    handler = gdb_util.GdbHandlerAdapter(
        handler, parsed_args.gdb, parsed_args.gdb_type)

  if 'plugin' in parsed_args.gdb:
    if OPTIONS.is_nacl_build():
      handler = gdb_util.NaClGdbHandlerAdapter(
          handler, _get_nacl_irt_path(parsed_args), parsed_args.gdb_type)
    elif OPTIONS.is_bare_metal_build():
      handler = gdb_util.BareMetalGdbHandlerAdapter(
          handler, _get_nacl_helper_nonsfi_path(parsed_args),
          parsed_args.gdb_type)

  if (parsed_args.enable_arc_strace and
      parsed_args.arc_strace_output != 'stderr'):
    handler = output_handler.ArcStraceFilter(
        handler, parsed_args.arc_strace_output)

  handler = output_handler.CrashAddressFilter(handler)

  if not platform_util.is_running_on_remote_host():
    # Filters that need to run on local host.
    # See remote_executor_util.run_with_filter
    handler = minidump_filter.MinidumpFilter(handler)

    if parsed_args.jdb_port:
      handler = jdb_util.JdbHandlerAdapter(
          handler, parsed_args.jdb_port, parsed_args.jdb_type)

  if parsed_args.chrome_flakiness_retry:
    handler = output_handler.ChromeFlakinessHandler(handler, chrome_process)

  return output_handler.ChromeStatusCodeHandler(handler)
Beispiel #13
0
def _compute_chrome_plugin_params(parsed_args):
  params = []
  params.append(
      '--load-extension=' +
      remote_executor.resolve_path(build_common.get_runtime_out_dir()))

  # Do not use user defined data directory if user name for remote host is
  # provided. The mounted cryptohome directory is used instead.
  if not parsed_args.login_user:
    params.append(
        '--user-data-dir=' + remote_executor.resolve_path(_USER_DATA_DIR))

  # Force-enable nonsfi mode on targets that do not allow it by default
  # (for example, non-ChromeOS Linux) for testing purposes.
  if (OPTIONS.is_bare_metal_build() and
      not platform_util.is_running_on_chromeos()):
    params.append('--enable-nacl-nonsfi-mode')

  return params
Beispiel #14
0
def _compute_chrome_sandbox_params(parsed_args):
  params = []
  if _is_no_sandbox_needed(parsed_args):
    params.append('--no-sandbox')
    if OPTIONS.is_bare_metal_build():
      # Non-SFI NaCl helper, which heavily depends on seccomp-bpf,
      # does not start without seccomp sandbox initialized unless we
      # specify this flag explicitly.
      params.append('--nacl-dangerous-no-sandbox-nonsfi')

  # Environment variables to pass through to nacl_helper.
  passthrough_env_vars = []

  if OPTIONS.is_nacl_build() and parsed_args.disable_nacl_sandbox:
    os.environ['NACL_DANGEROUS_ENABLE_FILE_ACCESS'] = '1'
    passthrough_env_vars.append('NACL_DANGEROUS_ENABLE_FILE_ACCESS')
  if OPTIONS.is_nacl_build() and parsed_args.enable_nacl_list_mappings:
    os.environ['NACL_DANGEROUS_ENABLE_LIST_MAPPINGS'] = '1'
    passthrough_env_vars.append('NACL_DANGEROUS_ENABLE_LIST_MAPPINGS')
  if passthrough_env_vars:
    os.environ['NACL_ENV_PASSTHROUGH'] = ','.join(passthrough_env_vars)
  return params
Beispiel #15
0
def _filter_ldflags_for_libwebviewchromium(vars):
  if OPTIONS.is_bare_metal_build() or OPTIONS.is_nacl_build():
    # We need to pass in --no-keep-memory or ld runs out of memory linking.
    vars.get_ldflags().append('-Wl,--no-keep-memory')
  # --no-undefined allows undefined symbols to be present in the linked .so
  # without errors, which is what we want so they are resolved at runtime.
  vars.get_ldflags().remove('-Wl,--no-undefined')

  # TODO(crbug.com/489972): Suppress warnings caused by hidden skia symbols.
  vars.get_ldflags().remove('-Wl,--fatal-warnings')

  for idx, flag in enumerate(vars.get_ldflags()):
    if 'android_exports.lst' in flag:
      version_script = os.path.join(build_common.get_target_common_dir(),
                                    'android_gen_sources/GYP',
                                    'shared_intermediates/android_exports.lst')
      vars.get_ldflags()[idx] = '-Wl,--version-script=' + version_script

  if OPTIONS.is_nacl_build():
    # This causes libdl.so to be dropped for some reason, even when it provides
    # the reference to the required dlerror function. Remove it.
    vars.get_ldflags().remove('-Wl,--as-needed')
Beispiel #16
0
  def run_with_filter(self, cmd, cwd=None):
    if cwd is None:
      cwd = self.get_remote_arc_root()
    cmd = 'cd %s && %s' % (cwd, cmd)

    handler = minidump_filter.MinidumpFilter(
        concurrent_subprocess.RedirectOutputHandler())
    if self._attach_nacl_gdb_type:
      if OPTIONS.is_nacl_build():
        handler = gdb_util.NaClGdbHandlerAdapter(
            handler, None, self._attach_nacl_gdb_type,
            remote_executor=self)
      elif OPTIONS.is_bare_metal_build():
        handler = gdb_util.BareMetalGdbHandlerAdapter(
            handler, self._nacl_helper_nonsfi_binary,
            self._attach_nacl_gdb_type, host=self._remote,
            ssh_options=self.get_ssh_options(),
            remote_executor=self)
    if self._jdb_type and self._jdb_port:
      handler = jdb_util.JdbHandlerAdapter(
          handler, self._jdb_port, self._jdb_type, self)
    return run_command_with_filter(self._build_ssh_command(cmd),
                                   output_handler=handler)
Beispiel #17
0
def use_ndk_direct_execution():
    # On -t=ba, we always use NDK direct execution. On -t=bi, it is dynamically
    # enabled/disabled at runtime. When --ndk-abi=x86 is passed, it is enabled.
    # Otherwise it is not.
    return OPTIONS.is_bare_metal_build()
Beispiel #18
0
 def _filter(vars):
     # -fstack-protector emits undefined symbols.
     if not OPTIONS.is_bare_metal_build():
         vars.get_cflags().append("-fno-stack-protector")
     return True
Beispiel #19
0
def create_or_remove_bare_metal_gdb_lock_dir(gdb_target_list):
    file_util.rmtree(_BARE_METAL_GDB_LOCK_DIR, ignore_errors=True)
    if 'plugin' in gdb_target_list and OPTIONS.is_bare_metal_build():
        file_util.makedirs_safely(_BARE_METAL_GDB_LOCK_DIR)
Beispiel #20
0
 def _filter(vars):
   # -fstack-protector emits undefined symbols.
   if not OPTIONS.is_bare_metal_build():
     vars.get_cflags().append('-fno-stack-protector')
   return True
Beispiel #21
0
def create_or_remove_bare_metal_gdb_lock_dir(gdb_target_list):
  file_util.rmtree(_BARE_METAL_GDB_LOCK_DIR, ignore_errors=True)
  if 'plugin' in gdb_target_list and OPTIONS.is_bare_metal_build():
    file_util.makedirs_safely(_BARE_METAL_GDB_LOCK_DIR)
Beispiel #22
0
def use_ndk_direct_execution():
    # On -t=ba, we always use NDK direct execution. On -t=bi, it is dynamically
    # enabled/disabled at runtime. When --ndk-abi=x86 is passed, it is enabled.
    # Otherwise it is not.
    return OPTIONS.is_bare_metal_build()