play_testcase.py 3.6 KB

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