Home | History | Annotate | Download | only in ipc_fuzzer
      1 #!/usr/bin/env python
      2 # Copyright 2013 The Chromium Authors. All rights reserved.
      3 # Use of this source code is governed by a BSD-style license that can be
      4 # found in the LICENSE file.
      5 
      6 """Wrapper around chrome.
      7 
      8 Replaces all the child processes (renderer, GPU, plugins and utility) with the
      9 IPC fuzzer. The fuzzer will then play back a specified testcase.
     10 
     11 Depends on ipc_fuzzer being available on the same directory as chrome.
     12 """
     13 
     14 import argparse
     15 import os
     16 import platform
     17 import subprocess
     18 import sys
     19 
     20 def main():
     21   desc = 'Wrapper to run chrome with child processes replaced by IPC fuzzers'
     22   parser = argparse.ArgumentParser(description=desc)
     23   parser.add_argument('--out-dir', dest='out_dir', default='out',
     24                       help='output directory under src/ directory')
     25   parser.add_argument('--build-type', dest='build_type', default='Release',
     26                       help='Debug vs. Release build')
     27   parser.add_argument('--gdb-browser', dest='gdb_browser', default=False,
     28                       action='store_true',
     29                       help='run browser process inside gdb')
     30   parser.add_argument('testcase',
     31                       help='IPC file to be replayed')
     32   parser.add_argument('chrome_args',
     33                       nargs=argparse.REMAINDER,
     34                       help='any additional arguments are passed to chrome')
     35   args = parser.parse_args()
     36 
     37   chrome_binary = 'chrome'
     38   fuzzer_binary = 'ipc_fuzzer_replay'
     39 
     40   script_path = os.path.realpath(__file__)
     41   ipc_fuzzer_dir = os.path.dirname(script_path)
     42   src_dir = os.path.abspath(os.path.join(ipc_fuzzer_dir, os.pardir, os.pardir))
     43   out_dir =  os.path.join(src_dir, args.out_dir)
     44   build_dir = os.path.join(out_dir, args.build_type)
     45 
     46   chrome_path = os.path.join(build_dir, chrome_binary)
     47   if not os.path.exists(chrome_path):
     48     print 'chrome executable not found at ', chrome_path
     49     return 1
     50 
     51   fuzzer_path = os.path.join(build_dir, fuzzer_binary)
     52   if not os.path.exists(fuzzer_path):
     53     print 'fuzzer executable not found at ', fuzzer_path
     54     print ('ensure GYP_DEFINES="enable_ipc_fuzzer=1" and build target ' +
     55            fuzzer_binary + '.')
     56     return 1
     57 
     58   prefixes = {
     59     '--renderer-cmd-prefix',
     60     '--gpu-launcher',
     61     '--plugin-launcher',
     62     '--ppapi-plugin-launcher',
     63     '--utility-cmd-prefix',
     64   }
     65 
     66   chrome_command = [
     67     chrome_path,
     68     '--ipc-fuzzer-testcase=' + args.testcase,
     69     '--no-sandbox',
     70     '--disable-kill-after-bad-ipc',
     71   ]
     72 
     73   if args.gdb_browser:
     74     chrome_command = ['gdb', '--args'] + chrome_command
     75 
     76   launchers = {}
     77   for prefix in prefixes:
     78     launchers[prefix] = fuzzer_path
     79 
     80   for arg in args.chrome_args:
     81     if arg.find('=') != -1:
     82       switch, value = arg.split('=', 1)
     83       if switch in prefixes:
     84         launchers[switch] = value + ' ' + launchers[switch]
     85         continue
     86     chrome_command.append(arg)
     87 
     88   for switch, value in launchers.items():
     89     chrome_command.append(switch + '=' + value)
     90 
     91   command_line = ' '.join(['\'' + arg + '\'' for arg in chrome_command])
     92   print 'Executing: ' + command_line
     93 
     94   return subprocess.call(chrome_command)
     95 
     96 
     97 if __name__ == "__main__":
     98   sys.exit(main())
     99