Commit 7315d7b3 authored by Vadim Gorbachev (bmsdave)'s avatar Vadim Gorbachev (bmsdave) Committed by Commit Bot

Preparing v8 to use with python3 /tools

There are now less that 400 days until the end of life
of Python 2(aka _legacy_ Python) https://pythonclock.org/ .
The code compatibility check for python2 and python3
used the following tools: futurize, flake8
You can see the reports here: https://travis-ci.com/bmsdave/v8/builds

This CL was uploaded by git cl split.

Bug: v8:8594
Change-Id: I661c52a70527e8ddde841fee6d4dcba282b4a938
Reviewed-on: https://chromium-review.googlesource.com/c/1470123
Commit-Queue: Sergiy Belozorov <sergiyb@chromium.org>
Reviewed-by: 's avatarSergiy Belozorov <sergiyb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#59675}
parent ab2180cd
...@@ -165,6 +165,7 @@ Tiancheng "Timothy" Gu <timothygu99@gmail.com> ...@@ -165,6 +165,7 @@ Tiancheng "Timothy" Gu <timothygu99@gmail.com>
Tobias Burnus <burnus@net-b.de> Tobias Burnus <burnus@net-b.de>
Tobias Nießen <tniessen@tnie.de> Tobias Nießen <tniessen@tnie.de>
Ujjwal Sharma <usharma1998@gmail.com> Ujjwal Sharma <usharma1998@gmail.com>
Vadim Gorbachev <bmsdave@gmail.com>
Victor Costan <costan@gmail.com> Victor Costan <costan@gmail.com>
Vlad Burlik <vladbph@gmail.com> Vlad Burlik <vladbph@gmail.com>
Vladimir Krivosheev <develar@gmail.com> Vladimir Krivosheev <develar@gmail.com>
......
...@@ -35,6 +35,9 @@ ...@@ -35,6 +35,9 @@
# and output special error string in case of non-zero exit code. # and output special error string in case of non-zero exit code.
# Then we parse the output of 'adb shell' and look for that error string. # Then we parse the output of 'adb shell' and look for that error string.
# for py2/py3 compatibility
from __future__ import print_function
import os import os
from os.path import join, dirname, abspath from os.path import join, dirname, abspath
import subprocess import subprocess
...@@ -58,8 +61,8 @@ def Execute(cmdline): ...@@ -58,8 +61,8 @@ def Execute(cmdline):
exit_code = process.wait() exit_code = process.wait()
os.close(fd_out) os.close(fd_out)
os.close(fd_err) os.close(fd_err)
output = file(outname).read() output = open(outname).read()
errors = file(errname).read() errors = open(errname).read()
os.unlink(outname) os.unlink(outname)
os.unlink(errname) os.unlink(errname)
sys.stdout.write(output) sys.stdout.write(output)
......
#!/usr/bin/env python3 #!/usr/bin/env python
# Copyright 2018 the V8 project authors. All rights reserved. # Copyright 2018 the V8 project authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can # Use of this source code is governed by a BSD-style license that can
# be found in the LICENSE file. # be found in the LICENSE file.
...@@ -22,6 +23,9 @@ will output ...@@ -22,6 +23,9 @@ will output
[10/10] [default] : avg 22,885.80 stddev 1,941.80 ( 17,584.00 - 24,266.00) Kps [10/10] [default] : avg 22,885.80 stddev 1,941.80 ( 17,584.00 - 24,266.00) Kps
""" """
# for py2/py3 compatibility
from __future__ import print_function
import argparse import argparse
import math import math
import re import re
......
...@@ -3,6 +3,9 @@ ...@@ -3,6 +3,9 @@
# Use of this source code is governed by a BSD-style license that can be # Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file. # found in the LICENSE file.
# for py2/py3 compatibility
from __future__ import print_function
import argparse import argparse
import math import math
import multiprocessing import multiprocessing
...@@ -294,7 +297,7 @@ def WrapRunOne(args): ...@@ -294,7 +297,7 @@ def WrapRunOne(args):
return RunOne(*args) return RunOne(*args)
def RunAll(args): def RunAll(args):
for op in args.op: for op in args.op:
for r in xrange(args.runs): for r in range(args.runs):
yield (op, args.num_inputs, args.binary) yield (op, args.num_inputs, args.binary)
def Main(): def Main():
......
...@@ -17,6 +17,9 @@ Commands: ...@@ -17,6 +17,9 @@ Commands:
For each command, you can try ./runtime-call-stats.py help command. For each command, you can try ./runtime-call-stats.py help command.
''' '''
# for py2/py3 compatibility
from __future__ import print_function
import argparse import argparse
import json import json
import os import os
...@@ -46,7 +49,7 @@ def print_command(cmd_args): ...@@ -46,7 +49,7 @@ def print_command(cmd_args):
elif ' ' in arg: elif ' ' in arg:
arg = "'{}'".format(arg) arg = "'{}'".format(arg)
return arg return arg
print " ".join(map(fix_for_printing, cmd_args)) print(" ".join(map(fix_for_printing, cmd_args)))
def start_replay_server(args, sites, discard_output=True): def start_replay_server(args, sites, discard_output=True):
...@@ -66,15 +69,15 @@ def start_replay_server(args, sites, discard_output=True): ...@@ -66,15 +69,15 @@ def start_replay_server(args, sites, discard_output=True):
"--inject_scripts=deterministic.js,{}".format(injection), "--inject_scripts=deterministic.js,{}".format(injection),
args.replay_wpr, args.replay_wpr,
] ]
print "=" * 80 print("=" * 80)
print_command(cmd_args) print_command(cmd_args)
if discard_output: if discard_output:
with open(os.devnull, 'w') as null: with open(os.devnull, 'w') as null:
server = subprocess.Popen(cmd_args, stdout=null, stderr=null) server = subprocess.Popen(cmd_args, stdout=null, stderr=null)
else: else:
server = subprocess.Popen(cmd_args) server = subprocess.Popen(cmd_args)
print "RUNNING REPLAY SERVER: %s with PID=%s" % (args.replay_bin, server.pid) print("RUNNING REPLAY SERVER: %s with PID=%s" % (args.replay_bin, server.pid))
print "=" * 80 print("=" * 80)
return {'process': server, 'injection': injection} return {'process': server, 'injection': injection}
...@@ -85,7 +88,7 @@ def stop_replay_server(server): ...@@ -85,7 +88,7 @@ def stop_replay_server(server):
def generate_injection(f, sites, refreshes=0): def generate_injection(f, sites, refreshes=0):
print >> f, """\ print("""\
(function() { (function() {
var s = window.sessionStorage.getItem("refreshCounter"); var s = window.sessionStorage.getItem("refreshCounter");
var refreshTotal = """, refreshes, """; var refreshTotal = """, refreshes, """;
...@@ -127,7 +130,7 @@ def generate_injection(f, sites, refreshes=0): ...@@ -127,7 +130,7 @@ def generate_injection(f, sites, refreshes=0):
var sites = var sites =
""", json.dumps(sites), """; """, json.dumps(sites), """;
onLoad(window.location.href); onLoad(window.location.href);
})();""" })();""", file=f)
def get_chrome_flags(js_flags, user_data_dir, arg_delimiter=""): def get_chrome_flags(js_flags, user_data_dir, arg_delimiter=""):
return [ return [
...@@ -161,9 +164,9 @@ def get_chrome_replay_flags(args, arg_delimiter=""): ...@@ -161,9 +164,9 @@ def get_chrome_replay_flags(args, arg_delimiter=""):
] ]
def run_site(site, domain, args, timeout=None): def run_site(site, domain, args, timeout=None):
print "="*80 print("="*80)
print "RUNNING DOMAIN %s" % domain print("RUNNING DOMAIN %s" % domain)
print "="*80 print("="*80)
result_template = "{domain}#{count}.txt" if args.repeat else "{domain}.txt" result_template = "{domain}#{count}.txt" if args.repeat else "{domain}.txt"
count = 0 count = 0
if timeout is None: timeout = args.timeout if timeout is None: timeout = args.timeout
...@@ -196,9 +199,9 @@ def run_site(site, domain, args, timeout=None): ...@@ -196,9 +199,9 @@ def run_site(site, domain, args, timeout=None):
"timeout", str(timeout), "timeout", str(timeout),
args.with_chrome args.with_chrome
] + chrome_flags + [ site ] ] + chrome_flags + [ site ]
print "- " * 40 print("- " * 40)
print_command(cmd_args) print_command(cmd_args)
print "- " * 40 print("- " * 40)
with open(result, "wt") as f: with open(result, "wt") as f:
with open(args.log_stderr or os.devnull, 'at') as err: with open(args.log_stderr or os.devnull, 'at') as err:
status = subprocess.call(cmd_args, stdout=f, stderr=err) status = subprocess.call(cmd_args, stdout=f, stderr=err)
...@@ -212,8 +215,8 @@ def run_site(site, domain, args, timeout=None): ...@@ -212,8 +215,8 @@ def run_site(site, domain, args, timeout=None):
if os.path.isfile(result) and os.path.getsize(result) > 0: if os.path.isfile(result) and os.path.getsize(result) > 0:
if args.print_url: if args.print_url:
with open(result, "at") as f: with open(result, "at") as f:
print >> f print(file=f)
print >> f, "URL: {}".format(site) print("URL: {}".format(site), file=f)
retries_since_good_run = 0 retries_since_good_run = 0
break break
if retries_since_good_run > MAX_NOF_RETRIES: if retries_since_good_run > MAX_NOF_RETRIES:
...@@ -294,7 +297,7 @@ def do_run(args): ...@@ -294,7 +297,7 @@ def do_run(args):
# Run them. # Run them.
for site, domain, count, timeout in L: for site, domain, count, timeout in L:
if count is not None: domain = "{}%{}".format(domain, count) if count is not None: domain = "{}%{}".format(domain, count)
print(site, domain, timeout) print((site, domain, timeout))
run_site(site, domain, args, timeout) run_site(site, domain, args, timeout)
finally: finally:
if replay_server: if replay_server:
...@@ -459,11 +462,11 @@ def print_stats(S, args): ...@@ -459,11 +462,11 @@ def print_stats(S, args):
def stats(s, units=""): def stats(s, units=""):
conf = "{:0.1f}({:0.2f}%)".format(s['ci']['abs'], s['ci']['perc']) conf = "{:0.1f}({:0.2f}%)".format(s['ci']['abs'], s['ci']['perc'])
return "{:8.1f}{} +/- {:15s}".format(s['average'], units, conf) return "{:8.1f}{} +/- {:15s}".format(s['average'], units, conf)
print "{:>50s} {} {}".format( print("{:>50s} {} {}".format(
key, key,
stats(value['time_stat'], units="ms"), stats(value['time_stat'], units="ms"),
stats(value['count_stat']) stats(value['count_stat'])
) ))
# Print and calculate partial sums, if necessary. # Print and calculate partial sums, if necessary.
for i in range(low, high): for i in range(low, high):
print_entry(*L[i]) print_entry(*L[i])
...@@ -479,7 +482,7 @@ def print_stats(S, args): ...@@ -479,7 +482,7 @@ def print_stats(S, args):
partial['count_list'][j] += v partial['count_list'][j] += v
# Print totals, if necessary. # Print totals, if necessary.
if args.totals: if args.totals:
print '-' * 80 print('-' * 80)
if args.limit != 0 and not args.aggregate: if args.limit != 0 and not args.aggregate:
partial['time_stat'] = statistics(partial['time_list']) partial['time_stat'] = statistics(partial['time_list'])
partial['count_stat'] = statistics(partial['count_list']) partial['count_stat'] = statistics(partial['count_list'])
...@@ -500,9 +503,9 @@ def do_stats(args): ...@@ -500,9 +503,9 @@ def do_stats(args):
create_total_page_stats(domains, args) create_total_page_stats(domains, args)
for i, domain in enumerate(sorted(domains)): for i, domain in enumerate(sorted(domains)):
if len(domains) > 1: if len(domains) > 1:
if i > 0: print if i > 0: print()
print "{}:".format(domain) print("{}:".format(domain))
print '=' * 80 print('=' * 80)
domain_stats = domains[domain] domain_stats = domains[domain]
for key in domain_stats: for key in domain_stats:
domain_stats[key]['time_stat'] = \ domain_stats[key]['time_stat'] = \
...@@ -575,7 +578,7 @@ def do_json(args): ...@@ -575,7 +578,7 @@ def do_json(args):
entry.append(round(s['ci']['perc'], 2)) entry.append(round(s['ci']['perc'], 2))
stats.append(entry) stats.append(entry)
domains[domain] = stats domains[domain] = stats
print json.dumps(versions, separators=(',', ':')) print(json.dumps(versions, separators=(',', ':')))
# Help. # Help.
......
...@@ -2,7 +2,10 @@ ...@@ -2,7 +2,10 @@
# Use of this source code is governed by a BSD-style license that can be # Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file. # found in the LICENSE file.
print """ # for py2/py3 compatibility
from __future__ import print_function
print("""
1 1
v8-foozzie source: name/to/a/file.js v8-foozzie source: name/to/a/file.js
2 2
...@@ -11,4 +14,4 @@ v8-foozzie source: name/to/file.js ...@@ -11,4 +14,4 @@ v8-foozzie source: name/to/file.js
^ ^
3 3
unknown unknown
""" """)
...@@ -2,7 +2,10 @@ ...@@ -2,7 +2,10 @@
# Use of this source code is governed by a BSD-style license that can be # Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file. # found in the LICENSE file.
print """ # for py2/py3 compatibility
from __future__ import print_function
print("""
1 1
v8-foozzie source: name/to/a/file.js v8-foozzie source: name/to/a/file.js
2 2
...@@ -11,4 +14,4 @@ v8-foozzie source: name/to/file.js ...@@ -11,4 +14,4 @@ v8-foozzie source: name/to/file.js
^ ^
3 3
unknown unknown
""" """)
...@@ -2,7 +2,10 @@ ...@@ -2,7 +2,10 @@
# Use of this source code is governed by a BSD-style license that can be # Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file. # found in the LICENSE file.
print """ # for py2/py3 compatibility
from __future__ import print_function
print("""
1 1
v8-foozzie source: name/to/a/file.js v8-foozzie source: name/to/a/file.js
2 2
...@@ -11,4 +14,4 @@ v8-foozzie source: name/to/file.js ...@@ -11,4 +14,4 @@ v8-foozzie source: name/to/file.js
^ ^
3 3
not unknown not unknown
""" """)
...@@ -7,6 +7,9 @@ ...@@ -7,6 +7,9 @@
V8 correctness fuzzer launcher script. V8 correctness fuzzer launcher script.
""" """
# for py2/py3 compatibility
from __future__ import print_function
import argparse import argparse
import hashlib import hashlib
import itertools import itertools
...@@ -227,8 +230,8 @@ def content_bailout(content, ignore_fun): ...@@ -227,8 +230,8 @@ def content_bailout(content, ignore_fun):
"""Print failure state and return if ignore_fun matches content.""" """Print failure state and return if ignore_fun matches content."""
bug = (ignore_fun(content) or '').strip() bug = (ignore_fun(content) or '').strip()
if bug: if bug:
print FAILURE_HEADER_TEMPLATE % dict( print(FAILURE_HEADER_TEMPLATE % dict(
configs='', source_key='', suppression=bug) configs='', source_key='', suppression=bug))
return True return True
return False return False
...@@ -238,10 +241,10 @@ def pass_bailout(output, step_number): ...@@ -238,10 +241,10 @@ def pass_bailout(output, step_number):
if output.HasTimedOut(): if output.HasTimedOut():
# Dashed output, so that no other clusterfuzz tools can match the # Dashed output, so that no other clusterfuzz tools can match the
# words timeout or crash. # words timeout or crash.
print '# V8 correctness - T-I-M-E-O-U-T %d' % step_number print('# V8 correctness - T-I-M-E-O-U-T %d' % step_number)
return True return True
if output.HasCrashed(): if output.HasCrashed():
print '# V8 correctness - C-R-A-S-H %d' % step_number print('# V8 correctness - C-R-A-S-H %d' % step_number)
return True return True
return False return False
...@@ -250,8 +253,8 @@ def fail_bailout(output, ignore_by_output_fun): ...@@ -250,8 +253,8 @@ def fail_bailout(output, ignore_by_output_fun):
"""Print failure state and return if ignore_by_output_fun matches output.""" """Print failure state and return if ignore_by_output_fun matches output."""
bug = (ignore_by_output_fun(output.stdout) or '').strip() bug = (ignore_by_output_fun(output.stdout) or '').strip()
if bug: if bug:
print FAILURE_HEADER_TEMPLATE % dict( print(FAILURE_HEADER_TEMPLATE % dict(
configs='', source_key='', suppression=bug) configs='', source_key='', suppression=bug))
return True return True
return False return False
...@@ -289,7 +292,7 @@ def main(): ...@@ -289,7 +292,7 @@ def main():
if options.first_arch != options.second_arch: if options.first_arch != options.second_arch:
preamble.append(ARCH_MOCKS) preamble.append(ARCH_MOCKS)
args = [d8] + config_flags + preamble + [options.testcase] args = [d8] + config_flags + preamble + [options.testcase]
print " ".join(args) print(" ".join(args))
if d8.endswith('.py'): if d8.endswith('.py'):
# Wrap with python in tests. # Wrap with python in tests.
args = [sys.executable] + args args = [sys.executable] + args
...@@ -333,7 +336,7 @@ def main(): ...@@ -333,7 +336,7 @@ def main():
# will require changes on the clusterfuzz side. # will require changes on the clusterfuzz side.
first_config_label = '%s,%s' % (options.first_arch, options.first_config) first_config_label = '%s,%s' % (options.first_arch, options.first_config)
second_config_label = '%s,%s' % (options.second_arch, options.second_config) second_config_label = '%s,%s' % (options.second_arch, options.second_config)
print (FAILURE_TEMPLATE % dict( print((FAILURE_TEMPLATE % dict(
configs='%s:%s' % (first_config_label, second_config_label), configs='%s:%s' % (first_config_label, second_config_label),
source_key=source_key, source_key=source_key,
suppression='', # We can't tie bugs to differences. suppression='', # We can't tie bugs to differences.
...@@ -347,14 +350,14 @@ def main(): ...@@ -347,14 +350,14 @@ def main():
second_config_output.stdout.decode('utf-8', 'replace'), second_config_output.stdout.decode('utf-8', 'replace'),
source=source, source=source,
difference=difference.decode('utf-8', 'replace'), difference=difference.decode('utf-8', 'replace'),
)).encode('utf-8', 'replace') )).encode('utf-8', 'replace'))
return RETURN_FAIL return RETURN_FAIL
# TODO(machenbach): Figure out if we could also return a bug in case there's # TODO(machenbach): Figure out if we could also return a bug in case there's
# no difference, but one of the line suppressions has matched - and without # no difference, but one of the line suppressions has matched - and without
# the match there would be a difference. # the match there would be a difference.
print '# V8 correctness - pass' print('# V8 correctness - pass')
return RETURN_PASS return RETURN_PASS
...@@ -364,17 +367,17 @@ if __name__ == "__main__": ...@@ -364,17 +367,17 @@ if __name__ == "__main__":
except SystemExit: except SystemExit:
# Make sure clusterfuzz reports internal errors and wrong usage. # Make sure clusterfuzz reports internal errors and wrong usage.
# Use one label for all internal and usage errors. # Use one label for all internal and usage errors.
print FAILURE_HEADER_TEMPLATE % dict( print(FAILURE_HEADER_TEMPLATE % dict(
configs='', source_key='', suppression='wrong_usage') configs='', source_key='', suppression='wrong_usage'))
result = RETURN_FAIL result = RETURN_FAIL
except MemoryError: except MemoryError:
# Running out of memory happens occasionally but is not actionable. # Running out of memory happens occasionally but is not actionable.
print '# V8 correctness - pass' print('# V8 correctness - pass')
result = RETURN_PASS result = RETURN_PASS
except Exception as e: except Exception as e:
print FAILURE_HEADER_TEMPLATE % dict( print(FAILURE_HEADER_TEMPLATE % dict(
configs='', source_key='', suppression='internal_error') configs='', source_key='', suppression='internal_error'))
print '# Internal error: %s' % e print('# Internal error: %s' % e)
traceback.print_exc(file=sys.stdout) traceback.print_exc(file=sys.stdout)
result = RETURN_FAIL result = RETURN_FAIL
......
...@@ -35,6 +35,9 @@ ...@@ -35,6 +35,9 @@
# on all supported build platforms, but Python is, and hence this provides # on all supported build platforms, but Python is, and hence this provides
# us with an easy and uniform way of doing this on all platforms. # us with an easy and uniform way of doing this on all platforms.
# for py2/py3 compatibility
from __future__ import print_function
import optparse import optparse
...@@ -49,7 +52,7 @@ def Concatenate(filenames): ...@@ -49,7 +52,7 @@ def Concatenate(filenames):
True, if the operation was successful. True, if the operation was successful.
""" """
if len(filenames) < 2: if len(filenames) < 2:
print "An error occurred generating %s:\nNothing to do." % filenames[-1] print("An error occurred generating %s:\nNothing to do." % filenames[-1])
return False return False
try: try:
...@@ -59,7 +62,7 @@ def Concatenate(filenames): ...@@ -59,7 +62,7 @@ def Concatenate(filenames):
target.write(current.read()) target.write(current.read())
return True return True
except IOError as e: except IOError as e:
print "An error occurred when writing %s:\n%s" % (filenames[-1], e) print("An error occurred when writing %s:\n%s" % (filenames[-1], e))
return False return False
......
...@@ -3,6 +3,9 @@ ...@@ -3,6 +3,9 @@
# Use of this source code is governed by a BSD-style license that can be # Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file. # found in the LICENSE file.
# for py2/py3 compatibility
from __future__ import print_function
import argparse import argparse
from datetime import datetime from datetime import datetime
import re import re
......
...@@ -15,6 +15,10 @@ The example usage is as follows: ...@@ -15,6 +15,10 @@ The example usage is as follows:
If no <arch> is given, it generates tags file for all arches: If no <arch> is given, it generates tags file for all arches:
$ tools/dev/gen-tags.py $ tools/dev/gen-tags.py
""" """
# for py2/py3 compatibility
from __future__ import print_function
import os import os
import subprocess import subprocess
import sys import sys
......
...@@ -38,6 +38,9 @@ v8gen.py list ...@@ -38,6 +38,9 @@ v8gen.py list
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
""" """
# for py2/py3 compatibility
from __future__ import print_function
import argparse import argparse
import os import os
import re import re
...@@ -144,8 +147,8 @@ class GenerateGnArgs(object): ...@@ -144,8 +147,8 @@ class GenerateGnArgs(object):
# Check for builder/config in mb config. # Check for builder/config in mb config.
if self._options.builder not in self._mbw.masters[self._options.master]: if self._options.builder not in self._mbw.masters[self._options.master]:
print '%s does not exist in %s for %s' % ( print('%s does not exist in %s for %s' % (
self._options.builder, CONFIG, self._options.master) self._options.builder, CONFIG, self._options.master))
return 1 return 1
# TODO(machenbach): Check if the requested configurations has switched to # TODO(machenbach): Check if the requested configurations has switched to
...@@ -186,19 +189,19 @@ class GenerateGnArgs(object): ...@@ -186,19 +189,19 @@ class GenerateGnArgs(object):
return 0 return 0
def cmd_list(self): def cmd_list(self):
print '\n'.join(sorted(self._mbw.masters[self._options.master])) print('\n'.join(sorted(self._mbw.masters[self._options.master])))
return 0 return 0
def verbose_print_1(self, text): def verbose_print_1(self, text):
if self._options.verbosity >= 1: if self._options.verbosity >= 1:
print '#' * 80 print('#' * 80)
print text print(text)
def verbose_print_2(self, text): def verbose_print_2(self, text):
if self._options.verbosity >= 2: if self._options.verbosity >= 2:
indent = ' ' * 2 indent = ' ' * 2
for l in text.splitlines(): for l in text.splitlines():
print indent + l print(indent + l)
def _call_cmd(self, args): def _call_cmd(self, args):
self.verbose_print_1(' '.join(args)) self.verbose_print_1(' '.join(args))
...@@ -290,9 +293,9 @@ class GenerateGnArgs(object): ...@@ -290,9 +293,9 @@ class GenerateGnArgs(object):
self._mbw.ReadConfigFile() self._mbw.ReadConfigFile()
if not self._options.master in self._mbw.masters: if not self._options.master in self._mbw.masters:
print '%s not found in %s\n' % (self._options.master, CONFIG) print('%s not found in %s\n' % (self._options.master, CONFIG))
print 'Choose one of:\n%s\n' % ( print('Choose one of:\n%s\n' % (
'\n'.join(sorted(self._mbw.masters.keys()))) '\n'.join(sorted(self._mbw.masters.keys()))))
return 1 return 1
return self._options.func() return self._options.func()
......
...@@ -6,6 +6,9 @@ ...@@ -6,6 +6,9 @@
# This script executes dumpcpp.js, collects all dumped C++ symbols, # This script executes dumpcpp.js, collects all dumped C++ symbols,
# and merges them back into v8 log. # and merges them back into v8 log.
# for py2/py3 compatibility
from __future__ import print_function
import os import os
import platform import platform
import re import re
...@@ -44,10 +47,10 @@ if __name__ == '__main__': ...@@ -44,10 +47,10 @@ if __name__ == '__main__':
if d8_line: if d8_line:
d8_exec = d8_line.group(1) d8_exec = d8_line.group(1)
if not is_file_executable(d8_exec): if not is_file_executable(d8_exec):
print 'd8 binary path found in {} is not executable.'.format(log_file) print('d8 binary path found in {} is not executable.'.format(log_file))
sys.exit(-1) sys.exit(-1)
else: else:
print 'No d8 binary path found in {}.'.format(log_file) print('No d8 binary path found in {}.'.format(log_file))
sys.exit(-1) sys.exit(-1)
args = [d8_exec] + JS_FILES + ['--'] + args args = [d8_exec] + JS_FILES + ['--'] + args
...@@ -57,9 +60,9 @@ if __name__ == '__main__': ...@@ -57,9 +60,9 @@ if __name__ == '__main__':
stdin=f) stdin=f)
out, err = sp.communicate() out, err = sp.communicate()
if debug: if debug:
print err print(err)
if sp.returncode != 0: if sp.returncode != 0:
print out print(out)
exit(-1) exit(-1)
if on_windows and out: if on_windows and out:
......
...@@ -7,10 +7,14 @@ ...@@ -7,10 +7,14 @@
"""This script is used to analyze GCTracer's NVP output.""" """This script is used to analyze GCTracer's NVP output."""
# for py2/py3 compatibility
from __future__ import print_function
from argparse import ArgumentParser from argparse import ArgumentParser
from copy import deepcopy from copy import deepcopy
from gc_nvp_common import split_nvp from gc_nvp_common import split_nvp
from math import ceil,log from math import ceil, log
from sys import stdin from sys import stdin
......
...@@ -3,6 +3,9 @@ ...@@ -3,6 +3,9 @@
# Use of this source code is governed by a BSD-style license that can be # Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file. # found in the LICENSE file.
# for py2/py3 compatibility
from __future__ import print_function
import argparse import argparse
import subprocess import subprocess
import sys import sys
......
...@@ -4,6 +4,9 @@ ...@@ -4,6 +4,9 @@
"""Small utility function to find depot_tools and add it to the python path. """Small utility function to find depot_tools and add it to the python path.
""" """
# for py2/py3 compatibility
from __future__ import print_function
import os import os
import sys import sys
...@@ -36,5 +39,5 @@ def add_depot_tools_to_path(): ...@@ -36,5 +39,5 @@ def add_depot_tools_to_path():
return i return i
previous_dir = root_dir previous_dir = root_dir
root_dir = os.path.dirname(root_dir) root_dir = os.path.dirname(root_dir)
print >> sys.stderr, 'Failed to find depot_tools' print('Failed to find depot_tools', file=sys.stderr)
return None return None
...@@ -11,20 +11,25 @@ ...@@ -11,20 +11,25 @@
# Usage: gc-nvp-to-csv.py <GC-trace-filename> # Usage: gc-nvp-to-csv.py <GC-trace-filename>
# #
# for py2/py3 compatibility
from __future__ import print_function
import sys import sys
import gc_nvp_common import gc_nvp_common
def process_trace(filename): def process_trace(filename):
trace = gc_nvp_common.parse_gc_trace(filename) trace = gc_nvp_common.parse_gc_trace(filename)
if len(trace): if len(trace):
keys = trace[0].keys() keys = trace[0].keys()
print ', '.join(keys) print(', '.join(keys))
for entry in trace: for entry in trace:
print ', '.join(map(lambda key: str(entry[key]), keys)) print(', '.join(map(lambda key: str(entry[key]), keys)))
if len(sys.argv) != 2: if len(sys.argv) != 2:
print "Usage: %s <GC-trace-filename>" % sys.argv[0] print("Usage: %s <GC-trace-filename>" % sys.argv[0])
sys.exit(1) sys.exit(1)
process_trace(sys.argv[1]) process_trace(sys.argv[1])
...@@ -37,10 +37,21 @@ ...@@ -37,10 +37,21 @@
# #
# for py2/py3 compatibility
from __future__ import with_statement from __future__ import with_statement
from __future__ import print_function
from functools import reduce
import sys, types, subprocess, math import sys, types, subprocess, math
import gc_nvp_common import gc_nvp_common
try:
long # Python 2
except NameError:
long = int # Python 3
def flatten(l): def flatten(l):
flat = [] flat = []
for i in l: flat.extend(i) for i in l: flat.extend(i)
...@@ -62,7 +73,7 @@ class Item(object): ...@@ -62,7 +73,7 @@ class Item(object):
self.title = title self.title = title
self.axis = axis self.axis = axis
self.props = keywords self.props = keywords
if type(field) is types.ListType: if type(field) is list:
self.field = field self.field = field
else: else:
self.field = [field] self.field = [field]
...@@ -135,7 +146,7 @@ def is_y2_used(plot): ...@@ -135,7 +146,7 @@ def is_y2_used(plot):
def get_field(trace_line, field): def get_field(trace_line, field):
t = type(field) t = type(field)
if t is types.StringType: if t is bytes:
return trace_line[field] return trace_line[field]
elif t is types.FunctionType: elif t is types.FunctionType:
return field(trace_line) return field(trace_line)
...@@ -177,7 +188,7 @@ def plot_all(plots, trace, prefix): ...@@ -177,7 +188,7 @@ def plot_all(plots, trace, prefix):
outfilename = "%s_%d.png" % (prefix, len(charts)) outfilename = "%s_%d.png" % (prefix, len(charts))
charts.append(outfilename) charts.append(outfilename)
script = generate_script_and_datafile(plot, trace, '~datafile', outfilename) script = generate_script_and_datafile(plot, trace, '~datafile', outfilename)
print 'Plotting %s...' % outfilename print('Plotting %s...' % outfilename)
gnuplot(script) gnuplot(script)
return charts return charts
...@@ -350,10 +361,10 @@ def process_trace(filename): ...@@ -350,10 +361,10 @@ def process_trace(filename):
out.write('<img src="%s">' % chart) out.write('<img src="%s">' % chart)
out.write('</body></html>') out.write('</body></html>')
print "%s generated." % (filename + '.html') print("%s generated." % (filename + '.html'))
if len(sys.argv) != 2: if len(sys.argv) != 2:
print "Usage: %s <GC-trace-filename>" % sys.argv[0] print("Usage: %s <GC-trace-filename>" % sys.argv[0])
sys.exit(1) sys.exit(1)
process_trace(sys.argv[1]) process_trace(sys.argv[1])
...@@ -20,6 +20,9 @@ ______________ file2 ...@@ -20,6 +20,9 @@ ______________ file2
______________ finish <exit code of clang --opt file2> ______________ ______________ finish <exit code of clang --opt file2> ______________
""" """
# for py2/py3 compatibility
from __future__ import print_function
import itertools import itertools
import multiprocessing import multiprocessing
import subprocess import subprocess
...@@ -39,6 +42,6 @@ if __name__ == '__main__': ...@@ -39,6 +42,6 @@ if __name__ == '__main__':
cmdlines = ["%s %s" % (sys.argv[1], filename) for filename in sys.argv[2:]] cmdlines = ["%s %s" % (sys.argv[1], filename) for filename in sys.argv[2:]]
for filename, result in itertools.izip( for filename, result in itertools.izip(
sys.argv[2:], pool.imap(invoke, cmdlines)): sys.argv[2:], pool.imap(invoke, cmdlines)):
print "______________ %s" % filename print("______________ %s" % filename)
print result[0] print(result[0])
print "______________ finish %d ______________" % result[1] print("______________ finish %d ______________" % result[1])
...@@ -3,6 +3,9 @@ ...@@ -3,6 +3,9 @@
# Use of this source code is governed by a BSD-style license that can be # Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file. # found in the LICENSE file.
# for py2/py3 compatibility
from __future__ import print_function
import os import os
import os.path import os.path
import signal import signal
...@@ -19,8 +22,8 @@ BASE_PATH = os.path.dirname(os.path.dirname(GCMOLE_PATH)) ...@@ -19,8 +22,8 @@ BASE_PATH = os.path.dirname(os.path.dirname(GCMOLE_PATH))
assert len(sys.argv) == 2 assert len(sys.argv) == 2
if not os.path.isfile("out/Release/gen/torque-generated/builtin-definitions-from-dsl.h"): if not os.path.isfile("out/Release/gen/torque-generated/builtin-definitions-from-dsl.h"):
print "Expected generated headers in out/Release/gen." print("Expected generated headers in out/Release/gen.")
print "Either build v8 in out/Release or change gcmole.lua:115" print("Either build v8 in out/Release or change gcmole.lua:115")
sys.exit(-1) sys.exit(-1)
proc = subprocess.Popen( proc = subprocess.Popen(
......
...@@ -25,12 +25,15 @@ ...@@ -25,12 +25,15 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# for py2/py3 compatibility
from __future__ import print_function
import re import re
import tempfile import tempfile
import os import os
import subprocess import subprocess
import time import time
import gdb
kSmiTag = 0 kSmiTag = 0
kSmiTagSize = 1 kSmiTagSize = 1
......
#!/usr/bin/env python3 #!/usr/bin/env python
# Copyright 2016 the V8 project authors. All rights reserved. # Copyright 2016 the V8 project authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be # Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file. # found in the LICENSE file.
# for py2/py3 compatibility
from __future__ import print_function
from collections import namedtuple from collections import namedtuple
import textwrap import textwrap
......
...@@ -46,6 +46,9 @@ ...@@ -46,6 +46,9 @@
# the generated libv8 binary. # the generated libv8 binary.
# #
# for py2/py3 compatibility
from __future__ import print_function
import re import re
import sys import sys
...@@ -628,7 +631,7 @@ def emit_set(out, consts): ...@@ -628,7 +631,7 @@ def emit_set(out, consts):
# Emit the whole output file. # Emit the whole output file.
# #
def emit_config(): def emit_config():
out = file(sys.argv[1], 'w'); out = open(sys.argv[1], 'w');
out.write(header); out.write(header);
......
...@@ -3,6 +3,9 @@ ...@@ -3,6 +3,9 @@
# Use of this source code is governed by a BSD-style license that can be # Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file. # found in the LICENSE file.
# for py2/py3 compatibility
from __future__ import print_function
import json import json
import optparse import optparse
import os import os
......
...@@ -13,6 +13,9 @@ BUILD.gn. Just compile to check whether there are any violations to the rule ...@@ -13,6 +13,9 @@ BUILD.gn. Just compile to check whether there are any violations to the rule
that each header must be includable in isolation. that each header must be includable in isolation.
""" """
# for py2/py3 compatibility
from __future__ import print_function
import argparse import argparse
import os import os
import os.path import os.path
...@@ -58,7 +61,7 @@ def parse_args(): ...@@ -58,7 +61,7 @@ def parse_args():
def printv(line): def printv(line):
if args.verbose: if args.verbose:
print line print(line)
def find_all_headers(): def find_all_headers():
......
...@@ -8,6 +8,9 @@ This file emits the list of reasons why a particular build needs to be clobbered ...@@ -8,6 +8,9 @@ This file emits the list of reasons why a particular build needs to be clobbered
(or a list of 'landmines'). (or a list of 'landmines').
""" """
# for py2/py3 compatibility
from __future__ import print_function
import sys import sys
...@@ -21,23 +24,23 @@ def print_landmines(): # pylint: disable=invalid-name ...@@ -21,23 +24,23 @@ def print_landmines(): # pylint: disable=invalid-name
# dependency problems, fix the dependency problems instead of adding a # dependency problems, fix the dependency problems instead of adding a
# landmine. # landmine.
# See the Chromium version in src/build/get_landmines.py for usage examples. # See the Chromium version in src/build/get_landmines.py for usage examples.
print 'Need to clobber after ICU52 roll.' print('Need to clobber after ICU52 roll.')
print 'Landmines test.' print('Landmines test.')
print 'Activating MSVS 2013.' print('Activating MSVS 2013.')
print 'Revert activation of MSVS 2013.' print('Revert activation of MSVS 2013.')
print 'Activating MSVS 2013 again.' print('Activating MSVS 2013 again.')
print 'Clobber after ICU roll.' print('Clobber after ICU roll.')
print 'Moar clobbering...' print('Moar clobbering...')
print 'Remove build/android.gypi' print('Remove build/android.gypi')
print 'Cleanup after windows ninja switch attempt.' print('Cleanup after windows ninja switch attempt.')
print 'Switching to pinned msvs toolchain.' print('Switching to pinned msvs toolchain.')
print 'Clobbering to hopefully resolve problem with mksnapshot' print('Clobbering to hopefully resolve problem with mksnapshot')
print 'Clobber after ICU roll.' print('Clobber after ICU roll.')
print 'Clobber after Android NDK update.' print('Clobber after Android NDK update.')
print 'Clober to fix windows build problems.' print('Clober to fix windows build problems.')
print 'Clober again to fix windows build problems.' print('Clober again to fix windows build problems.')
print 'Clobber to possibly resolve failure on win-32 bot.' print('Clobber to possibly resolve failure on win-32 bot.')
print 'Clobber for http://crbug.com/668958.' print('Clobber for http://crbug.com/668958.')
return 0 return 0
......
...@@ -27,6 +27,12 @@ ...@@ -27,6 +27,12 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# flake8: noqa # https://bugs.chromium.org/p/v8/issues/detail?id=8784
# for py2/py3 compatibility
from __future__ import print_function
import BaseHTTPServer import BaseHTTPServer
import bisect import bisect
import cgi import cgi
...@@ -69,7 +75,7 @@ DEBUG=False ...@@ -69,7 +75,7 @@ DEBUG=False
def DebugPrint(s): def DebugPrint(s):
if not DEBUG: return if not DEBUG: return
print s print(s)
class Descriptor(object): class Descriptor(object):
...@@ -120,7 +126,7 @@ class Descriptor(object): ...@@ -120,7 +126,7 @@ class Descriptor(object):
def FullDump(reader, heap): def FullDump(reader, heap):
"""Dump all available memory regions.""" """Dump all available memory regions."""
def dump_region(reader, start, size, location): def dump_region(reader, start, size, location):
print print()
while start & 3 != 0: while start & 3 != 0:
start += 1 start += 1
size -= 1 size -= 1
...@@ -131,17 +137,17 @@ def FullDump(reader, heap): ...@@ -131,17 +137,17 @@ def FullDump(reader, heap):
if is_executable is not False: if is_executable is not False:
lines = reader.GetDisasmLines(start, size) lines = reader.GetDisasmLines(start, size)
for line in lines: for line in lines:
print FormatDisasmLine(start, heap, line) print(FormatDisasmLine(start, heap, line))
print print()
if is_ascii is not False: if is_ascii is not False:
# Output in the same format as the Unix hd command # Output in the same format as the Unix hd command
addr = start addr = start
for i in xrange(0, size, 16): for i in range(0, size, 16):
slot = i + location slot = i + location
hex_line = "" hex_line = ""
asc_line = "" asc_line = ""
for i in xrange(16): for i in range(16):
if slot + i < location + size: if slot + i < location + size:
byte = ctypes.c_uint8.from_buffer(reader.minidump, slot + i).value byte = ctypes.c_uint8.from_buffer(reader.minidump, slot + i).value
if byte >= 0x20 and byte < 0x7f: if byte >= 0x20 and byte < 0x7f:
...@@ -153,24 +159,24 @@ def FullDump(reader, heap): ...@@ -153,24 +159,24 @@ def FullDump(reader, heap):
hex_line += " " hex_line += " "
if i == 7: if i == 7:
hex_line += " " hex_line += " "
print "%s %s |%s|" % (reader.FormatIntPtr(addr), print("%s %s |%s|" % (reader.FormatIntPtr(addr),
hex_line, hex_line,
asc_line) asc_line))
addr += 16 addr += 16
if is_executable is not True and is_ascii is not True: if is_executable is not True and is_ascii is not True:
print "%s - %s" % (reader.FormatIntPtr(start), print("%s - %s" % (reader.FormatIntPtr(start),
reader.FormatIntPtr(start + size)) reader.FormatIntPtr(start + size)))
print start + size + 1; print(start + size + 1);
for i in xrange(0, size, reader.PointerSize()): for i in range(0, size, reader.PointerSize()):
slot = start + i slot = start + i
maybe_address = reader.ReadUIntPtr(slot) maybe_address = reader.ReadUIntPtr(slot)
heap_object = heap.FindObject(maybe_address) heap_object = heap.FindObject(maybe_address)
print "%s: %s" % (reader.FormatIntPtr(slot), print("%s: %s" % (reader.FormatIntPtr(slot),
reader.FormatIntPtr(maybe_address)) reader.FormatIntPtr(maybe_address)))
if heap_object: if heap_object:
heap_object.Print(Printer()) heap_object.Print(Printer())
print print()
reader.ForEachMemoryRegion(dump_region) reader.ForEachMemoryRegion(dump_region)
...@@ -611,11 +617,11 @@ class MinidumpReader(object): ...@@ -611,11 +617,11 @@ class MinidumpReader(object):
self.minidump = mmap.mmap(self.minidump_file.fileno(), 0, mmap.MAP_PRIVATE) self.minidump = mmap.mmap(self.minidump_file.fileno(), 0, mmap.MAP_PRIVATE)
self.header = MINIDUMP_HEADER.Read(self.minidump, 0) self.header = MINIDUMP_HEADER.Read(self.minidump, 0)
if self.header.signature != MinidumpReader._HEADER_MAGIC: if self.header.signature != MinidumpReader._HEADER_MAGIC:
print >>sys.stderr, "Warning: Unsupported minidump header magic!" print("Warning: Unsupported minidump header magic!", file=sys.stderr)
DebugPrint(self.header) DebugPrint(self.header)
directories = [] directories = []
offset = self.header.stream_directories_rva offset = self.header.stream_directories_rva
for _ in xrange(self.header.stream_count): for _ in range(self.header.stream_count):
directories.append(MINIDUMP_DIRECTORY.Read(self.minidump, offset)) directories.append(MINIDUMP_DIRECTORY.Read(self.minidump, offset))
offset += MINIDUMP_DIRECTORY.size offset += MINIDUMP_DIRECTORY.size
self.arch = None self.arch = None
...@@ -677,7 +683,7 @@ class MinidumpReader(object): ...@@ -677,7 +683,7 @@ class MinidumpReader(object):
assert ctypes.sizeof(self.module_list) == d.location.data_size assert ctypes.sizeof(self.module_list) == d.location.data_size
DebugPrint(self.module_list) DebugPrint(self.module_list)
elif d.stream_type == MD_MEMORY_LIST_STREAM: elif d.stream_type == MD_MEMORY_LIST_STREAM:
print >>sys.stderr, "Warning: This is not a full minidump!" print("Warning: This is not a full minidump!", file=sys.stderr)
assert self.memory_list is None assert self.memory_list is None
self.memory_list = MINIDUMP_MEMORY_LIST.Read( self.memory_list = MINIDUMP_MEMORY_LIST.Read(
self.minidump, d.location.rva) self.minidump, d.location.rva)
...@@ -699,8 +705,8 @@ class MinidumpReader(object): ...@@ -699,8 +705,8 @@ class MinidumpReader(object):
else: else:
objdump_bin = self._FindThirdPartyObjdump() objdump_bin = self._FindThirdPartyObjdump()
if not objdump_bin or not os.path.exists(objdump_bin): if not objdump_bin or not os.path.exists(objdump_bin):
print "# Cannot find '%s', falling back to default objdump '%s'" % ( print("# Cannot find '%s', falling back to default objdump '%s'" % (
objdump_bin, DEFAULT_OBJDUMP_BIN) objdump_bin, DEFAULT_OBJDUMP_BIN))
objdump_bin = DEFAULT_OBJDUMP_BIN objdump_bin = DEFAULT_OBJDUMP_BIN
global OBJDUMP_BIN global OBJDUMP_BIN
OBJDUMP_BIN = objdump_bin OBJDUMP_BIN = objdump_bin
...@@ -722,12 +728,12 @@ class MinidumpReader(object): ...@@ -722,12 +728,12 @@ class MinidumpReader(object):
else: else:
# use default otherwise # use default otherwise
return None return None
print ("# Looking for platform specific (%s) objdump in " print(("# Looking for platform specific (%s) objdump in "
"third_party directory.") % platform_filter "third_party directory.") % platform_filter)
objdumps = filter(lambda file: platform_filter in file >= 0, objdumps) objdumps = filter(lambda file: platform_filter in file >= 0, objdumps)
if len(objdumps) == 0: if len(objdumps) == 0:
print "# Could not find platform specific objdump in third_party." print("# Could not find platform specific objdump in third_party.")
print "# Make sure you installed the correct SDK." print("# Make sure you installed the correct SDK.")
return None return None
return objdumps[0] return objdumps[0]
...@@ -822,7 +828,7 @@ class MinidumpReader(object): ...@@ -822,7 +828,7 @@ class MinidumpReader(object):
def IsProbableASCIIRegion(self, location, length): def IsProbableASCIIRegion(self, location, length):
ascii_bytes = 0 ascii_bytes = 0
non_ascii_bytes = 0 non_ascii_bytes = 0
for i in xrange(length): for i in range(length):
loc = location + i loc = location + i
byte = ctypes.c_uint8.from_buffer(self.minidump, loc).value byte = ctypes.c_uint8.from_buffer(self.minidump, loc).value
if byte >= 0x7f: if byte >= 0x7f:
...@@ -844,7 +850,7 @@ class MinidumpReader(object): ...@@ -844,7 +850,7 @@ class MinidumpReader(object):
def IsProbableExecutableRegion(self, location, length): def IsProbableExecutableRegion(self, location, length):
opcode_bytes = 0 opcode_bytes = 0
sixty_four = self.Is64() sixty_four = self.Is64()
for i in xrange(length): for i in range(length):
loc = location + i loc = location + i
byte = ctypes.c_uint8.from_buffer(self.minidump, loc).value byte = ctypes.c_uint8.from_buffer(self.minidump, loc).value
if (byte == 0x8b or # mov if (byte == 0x8b or # mov
...@@ -893,19 +899,19 @@ class MinidumpReader(object): ...@@ -893,19 +899,19 @@ class MinidumpReader(object):
def FindWord(self, word, alignment=0): def FindWord(self, word, alignment=0):
def search_inside_region(reader, start, size, location): def search_inside_region(reader, start, size, location):
location = (location + alignment) & ~alignment location = (location + alignment) & ~alignment
for i in xrange(size - self.PointerSize()): for i in range(size - self.PointerSize()):
loc = location + i loc = location + i
if reader._ReadWord(loc) == word: if reader._ReadWord(loc) == word:
slot = start + (loc - location) slot = start + (loc - location)
print "%s: %s" % (reader.FormatIntPtr(slot), print("%s: %s" % (reader.FormatIntPtr(slot),
reader.FormatIntPtr(word)) reader.FormatIntPtr(word)))
self.ForEachMemoryRegion(search_inside_region) self.ForEachMemoryRegion(search_inside_region)
def FindWordList(self, word): def FindWordList(self, word):
aligned_res = [] aligned_res = []
unaligned_res = [] unaligned_res = []
def search_inside_region(reader, start, size, location): def search_inside_region(reader, start, size, location):
for i in xrange(size - self.PointerSize()): for i in range(size - self.PointerSize()):
loc = location + i loc = location + i
if reader._ReadWord(loc) == word: if reader._ReadWord(loc) == word:
slot = start + (loc - location) slot = start + (loc - location)
...@@ -1026,7 +1032,7 @@ class MinidumpReader(object): ...@@ -1026,7 +1032,7 @@ class MinidumpReader(object):
# http://code.google.com/p/google-breakpad/wiki/SymbolFiles # http://code.google.com/p/google-breakpad/wiki/SymbolFiles
# #
def _LoadSymbolsFrom(self, symfile, baseaddr): def _LoadSymbolsFrom(self, symfile, baseaddr):
print "Loading symbols from %s" % (symfile) print("Loading symbols from %s" % (symfile))
funcs = [] funcs = []
with open(symfile) as f: with open(symfile) as f:
for line in f: for line in f:
...@@ -1038,7 +1044,7 @@ class MinidumpReader(object): ...@@ -1038,7 +1044,7 @@ class MinidumpReader(object):
name = result.group(4).rstrip() name = result.group(4).rstrip()
bisect.insort_left(self.symbols, bisect.insort_left(self.symbols,
FuncSymbol(baseaddr + start, size, name)) FuncSymbol(baseaddr + start, size, name))
print " ... done" print(" ... done")
def TryLoadSymbolsFor(self, modulename, module): def TryLoadSymbolsFor(self, modulename, module):
try: try:
...@@ -1048,7 +1054,7 @@ class MinidumpReader(object): ...@@ -1048,7 +1054,7 @@ class MinidumpReader(object):
self._LoadSymbolsFrom(symfile, module.base_of_image) self._LoadSymbolsFrom(symfile, module.base_of_image)
self.modules_with_symbols.append(module) self.modules_with_symbols.append(module)
except Exception as e: except Exception as e:
print " ... failure (%s)" % (e) print(" ... failure (%s)" % (e))
# Returns true if address is covered by some module that has loaded symbols. # Returns true if address is covered by some module that has loaded symbols.
def _IsInModuleWithSymbols(self, addr): def _IsInModuleWithSymbols(self, addr):
...@@ -1090,11 +1096,11 @@ class Printer(object): ...@@ -1090,11 +1096,11 @@ class Printer(object):
self.indent -= 2 self.indent -= 2
def Print(self, string): def Print(self, string):
print "%s%s" % (self._IndentString(), string) print("%s%s" % (self._IndentString(), string))
def PrintLines(self, lines): def PrintLines(self, lines):
indent = self._IndentString() indent = self._IndentString()
print "\n".join("%s%s" % (indent, line) for line in lines) print("\n".join("%s%s" % (indent, line) for line in lines))
def _IndentString(self): def _IndentString(self):
return self.indent * " " return self.indent * " "
...@@ -1428,7 +1434,7 @@ class FixedArray(HeapObject): ...@@ -1428,7 +1434,7 @@ class FixedArray(HeapObject):
p.Indent() p.Indent()
p.Print("length: %d" % self.length) p.Print("length: %d" % self.length)
base_offset = self.ElementsOffset() base_offset = self.ElementsOffset()
for i in xrange(self.length): for i in range(self.length):
offset = base_offset + 4 * i offset = base_offset + 4 * i
try: try:
p.Print("[%08d] = %s" % (i, self.ObjectField(offset))) p.Print("[%08d] = %s" % (i, self.ObjectField(offset)))
...@@ -1498,7 +1504,7 @@ class DescriptorArray(object): ...@@ -1498,7 +1504,7 @@ class DescriptorArray(object):
p.Print("Descriptors(%08x, length=%d)" % (array.address, length)) p.Print("Descriptors(%08x, length=%d)" % (array.address, length))
p.Print("[et] %s" % (array.Get(1))) p.Print("[et] %s" % (array.Get(1)))
for di in xrange(length): for di in range(length):
i = 2 + di * 3 i = 2 + di * 3
p.Print("0x%x" % (array.address + array.MemberOffset(i))) p.Print("0x%x" % (array.address + array.MemberOffset(i)))
p.Print("[%i] name: %s" % (di, array.Get(i + 0))) p.Print("[%i] name: %s" % (di, array.Get(i + 0)))
...@@ -1543,7 +1549,7 @@ class TransitionArray(object): ...@@ -1543,7 +1549,7 @@ class TransitionArray(object):
if prototype is not None: if prototype is not None:
p.Print("[prototype ] %s" % (prototype)) p.Print("[prototype ] %s" % (prototype))
for di in xrange(length): for di in range(length):
i = 3 + di * 2 i = 3 + di * 2
p.Print("[%i] symbol: %s" % (di, array.Get(i + 0))) p.Print("[%i] symbol: %s" % (di, array.Get(i + 0)))
p.Print("[%i] target: %s" % (di, array.Get(i + 1))) p.Print("[%i] target: %s" % (di, array.Get(i + 1)))
...@@ -1941,10 +1947,10 @@ class InspectionInfo(object): ...@@ -1941,10 +1947,10 @@ class InspectionInfo(object):
exception_thread.stack.memory.data_size exception_thread.stack.memory.data_size
frame_pointer = self.reader.ExceptionFP() frame_pointer = self.reader.ExceptionFP()
self.styles[frame_pointer] = "frame" self.styles[frame_pointer] = "frame"
for slot in xrange(stack_top, stack_bottom, self.reader.PointerSize()): for slot in range(stack_top, stack_bottom, self.reader.PointerSize()):
# stack address # stack address
self.styles[slot] = "sa" self.styles[slot] = "sa"
for slot in xrange(stack_top, stack_bottom, self.reader.PointerSize()): for slot in range(stack_top, stack_bottom, self.reader.PointerSize()):
maybe_address = self.reader.ReadUIntPtr(slot) maybe_address = self.reader.ReadUIntPtr(slot)
# stack value # stack value
self.styles[maybe_address] = "sv" self.styles[maybe_address] = "sv"
...@@ -2087,15 +2093,15 @@ class InspectionPadawan(object): ...@@ -2087,15 +2093,15 @@ class InspectionPadawan(object):
raise NotImplementedError raise NotImplementedError
def PrintKnowledge(self): def PrintKnowledge(self):
print " known_first_map_page = %s\n"\ print(" known_first_map_page = %s\n"\
" known_first_old_page = %s" % ( " known_first_old_page = %s" % (
self.reader.FormatIntPtr(self.known_first_map_page), self.reader.FormatIntPtr(self.known_first_map_page),
self.reader.FormatIntPtr(self.known_first_old_page)) self.reader.FormatIntPtr(self.known_first_old_page)))
def FindFirstAsciiString(self, start, end=None, min_length=32): def FindFirstAsciiString(self, start, end=None, min_length=32):
""" Walk the memory until we find a large string """ """ Walk the memory until we find a large string """
if not end: end = start + 64 if not end: end = start + 64
for slot in xrange(start, end): for slot in range(start, end):
if not self.reader.IsValidAddress(slot): break if not self.reader.IsValidAddress(slot): break
message = self.reader.ReadAsciiString(slot) message = self.reader.ReadAsciiString(slot)
if len(message) > min_length: if len(message) > min_length:
...@@ -2113,7 +2119,7 @@ class InspectionPadawan(object): ...@@ -2113,7 +2119,7 @@ class InspectionPadawan(object):
if not self.reader.IsValidAddress(start): return start if not self.reader.IsValidAddress(start): return start
end = start + ptr_size * 1024 * 4 end = start + ptr_size * 1024 * 4
magic1 = None magic1 = None
for slot in xrange(start, end, ptr_size): for slot in range(start, end, ptr_size):
if not self.reader.IsValidAddress(slot + ptr_size): break if not self.reader.IsValidAddress(slot + ptr_size): break
magic1 = self.reader.ReadUIntPtr(slot) magic1 = self.reader.ReadUIntPtr(slot)
magic2 = self.reader.ReadUIntPtr(slot + ptr_size) magic2 = self.reader.ReadUIntPtr(slot + ptr_size)
...@@ -2138,23 +2144,23 @@ class InspectionPadawan(object): ...@@ -2138,23 +2144,23 @@ class InspectionPadawan(object):
end_search = start + (32 * 1024) + (header_size * ptr_size); end_search = start + (32 * 1024) + (header_size * ptr_size);
end_slot = self.FindPtr(end_marker, end_search, end_search + ptr_size * 512) end_slot = self.FindPtr(end_marker, end_search, end_search + ptr_size * 512)
if not end_slot: return start if not end_slot: return start
print "Stack Message (start=%s):" % self.heap.FormatIntPtr(slot) print("Stack Message (start=%s):" % self.heap.FormatIntPtr(slot))
slot += ptr_size slot += ptr_size
for name in ("isolate","ptr1", "ptr2", "ptr3", "ptr4", "codeObject1", for name in ("isolate","ptr1", "ptr2", "ptr3", "ptr4", "codeObject1",
"codeObject2", "codeObject3", "codeObject4"): "codeObject2", "codeObject3", "codeObject4"):
value = self.reader.ReadUIntPtr(slot) value = self.reader.ReadUIntPtr(slot)
print " %s: %s" % (name.rjust(14), self.heap.FormatIntPtr(value)) print(" %s: %s" % (name.rjust(14), self.heap.FormatIntPtr(value)))
slot += ptr_size slot += ptr_size
print " message start: %s" % self.heap.FormatIntPtr(slot) print(" message start: %s" % self.heap.FormatIntPtr(slot))
stack_start = end_slot + ptr_size stack_start = end_slot + ptr_size
print " stack_start: %s" % self.heap.FormatIntPtr(stack_start) print(" stack_start: %s" % self.heap.FormatIntPtr(stack_start))
(message_start, message) = self.FindFirstAsciiString(slot) (message_start, message) = self.FindFirstAsciiString(slot)
self.FormatStackTrace(message, print_message) self.FormatStackTrace(message, print_message)
return stack_start return stack_start
def FindPtr(self, expected_value, start, end): def FindPtr(self, expected_value, start, end):
ptr_size = self.reader.PointerSize() ptr_size = self.reader.PointerSize()
for slot in xrange(start, end, ptr_size): for slot in range(start, end, ptr_size):
if not self.reader.IsValidAddress(slot): return None if not self.reader.IsValidAddress(slot): return None
value = self.reader.ReadUIntPtr(slot) value = self.reader.ReadUIntPtr(slot)
if value == expected_value: return slot if value == expected_value: return slot
...@@ -2167,7 +2173,7 @@ class InspectionPadawan(object): ...@@ -2167,7 +2173,7 @@ class InspectionPadawan(object):
end_search = start + 1024 + (header_size * ptr_size); end_search = start + 1024 + (header_size * ptr_size);
end_slot = self.FindPtr(end_marker, end_search, end_search + ptr_size * 512) end_slot = self.FindPtr(end_marker, end_search, end_search + ptr_size * 512)
if not end_slot: return start if not end_slot: return start
print "Error Message (start=%s):" % self.heap.FormatIntPtr(slot) print("Error Message (start=%s):" % self.heap.FormatIntPtr(slot))
slot += ptr_size slot += ptr_size
(message_start, message) = self.FindFirstAsciiString(slot) (message_start, message) = self.FindFirstAsciiString(slot)
self.FormatStackTrace(message, print_message) self.FormatStackTrace(message, print_message)
...@@ -2193,27 +2199,27 @@ class InspectionPadawan(object): ...@@ -2193,27 +2199,27 @@ class InspectionPadawan(object):
# Make sure the address is word aligned # Make sure the address is word aligned
stack_start = stack_start - (stack_start % ptr_size) stack_start = stack_start - (stack_start % ptr_size)
if magic1 is None: if magic1 is None:
print "Stack Message:" print("Stack Message:")
print " message start: %s" % self.heap.FormatIntPtr(message_start) print(" message start: %s" % self.heap.FormatIntPtr(message_start))
print " stack_start: %s" % self.heap.FormatIntPtr(stack_start ) print(" stack_start: %s" % self.heap.FormatIntPtr(stack_start ))
else: else:
ptr1 = self.reader.ReadUIntPtr(slot + ptr_size * 2) ptr1 = self.reader.ReadUIntPtr(slot + ptr_size * 2)
ptr2 = self.reader.ReadUIntPtr(slot + ptr_size * 3) ptr2 = self.reader.ReadUIntPtr(slot + ptr_size * 3)
print "Stack Message:" print("Stack Message:")
print " magic1: %s" % self.heap.FormatIntPtr(magic1) print(" magic1: %s" % self.heap.FormatIntPtr(magic1))
print " magic2: %s" % self.heap.FormatIntPtr(magic2) print(" magic2: %s" % self.heap.FormatIntPtr(magic2))
print " ptr1: %s" % self.heap.FormatIntPtr(ptr1) print(" ptr1: %s" % self.heap.FormatIntPtr(ptr1))
print " ptr2: %s" % self.heap.FormatIntPtr(ptr2) print(" ptr2: %s" % self.heap.FormatIntPtr(ptr2))
print " message start: %s" % self.heap.FormatIntPtr(message_start) print(" message start: %s" % self.heap.FormatIntPtr(message_start))
print " stack_start: %s" % self.heap.FormatIntPtr(stack_start ) print(" stack_start: %s" % self.heap.FormatIntPtr(stack_start ))
print "" print("")
self.FormatStackTrace(message, print_message) self.FormatStackTrace(message, print_message)
return stack_start return stack_start
def FormatStackTrace(self, message, print_message): def FormatStackTrace(self, message, print_message):
if not print_message: if not print_message:
print " Use `dsa` to print the message with annotated addresses." print(" Use `dsa` to print the message with annotated addresses.")
print "" print("")
return return
ptr_size = self.reader.PointerSize() ptr_size = self.reader.PointerSize()
# Annotate all addresses in the dumped message # Annotate all addresses in the dumped message
...@@ -2224,11 +2230,11 @@ class InspectionPadawan(object): ...@@ -2224,11 +2230,11 @@ class InspectionPadawan(object):
address = self.heap.FormatIntPtr(int(address_org, 16)) address = self.heap.FormatIntPtr(int(address_org, 16))
if address_org != address: if address_org != address:
message = message.replace(address_org, address) message = message.replace(address_org, address)
print "Message:" print("Message:")
print "="*80 print("="*80)
print message print(message)
print "="*80 print("="*80)
print "" print("")
def TryInferFramePointer(self, slot, address): def TryInferFramePointer(self, slot, address):
...@@ -2279,9 +2285,9 @@ class InspectionPadawan(object): ...@@ -2279,9 +2285,9 @@ class InspectionPadawan(object):
free_space_end = 0 free_space_end = 0
ptr_size = self.reader.PointerSize() ptr_size = self.reader.PointerSize()
for slot in xrange(start, end, ptr_size): for slot in range(start, end, ptr_size):
if not self.reader.IsValidAddress(slot): if not self.reader.IsValidAddress(slot):
print "%s: Address is not contained within the minidump!" % slot print("%s: Address is not contained within the minidump!" % slot)
return return
maybe_address = self.reader.ReadUIntPtr(slot) maybe_address = self.reader.ReadUIntPtr(slot)
address_info = [] address_info = []
...@@ -2339,17 +2345,17 @@ class InspectionPadawan(object): ...@@ -2339,17 +2345,17 @@ class InspectionPadawan(object):
frame_pointer = maybe_address frame_pointer = maybe_address
address_type_marker = self.heap.AddressTypeMarker(maybe_address) address_type_marker = self.heap.AddressTypeMarker(maybe_address)
string_value = self.reader.ReadAsciiPtr(slot) string_value = self.reader.ReadAsciiPtr(slot)
print "%s: %s %s %s %s" % (self.reader.FormatIntPtr(slot), print("%s: %s %s %s %s" % (self.reader.FormatIntPtr(slot),
self.reader.FormatIntPtr(maybe_address), self.reader.FormatIntPtr(maybe_address),
address_type_marker, address_type_marker,
string_value, string_value,
' | '.join(address_info)) ' | '.join(address_info)))
if maybe_address_contents == 0xdecade01: if maybe_address_contents == 0xdecade01:
in_oom_dump_area = False in_oom_dump_area = False
heap_object = self.heap.FindObject(maybe_address) heap_object = self.heap.FindObject(maybe_address)
if heap_object: if heap_object:
heap_object.Print(Printer()) heap_object.Print(Printer())
print "" print("")
WEB_HEADER = """ WEB_HEADER = """
<!DOCTYPE html> <!DOCTYPE html>
...@@ -2701,7 +2707,7 @@ class InspectionWebFormatter(object): ...@@ -2701,7 +2707,7 @@ class InspectionWebFormatter(object):
stack_bottom = exception_thread.stack.start + \ stack_bottom = exception_thread.stack.start + \
exception_thread.stack.memory.data_size exception_thread.stack.memory.data_size
stack_map = {self.reader.ExceptionIP(): -1} stack_map = {self.reader.ExceptionIP(): -1}
for slot in xrange(stack_top, stack_bottom, self.reader.PointerSize()): for slot in range(stack_top, stack_bottom, self.reader.PointerSize()):
maybe_address = self.reader.ReadUIntPtr(slot) maybe_address = self.reader.ReadUIntPtr(slot)
if not maybe_address in stack_map: if not maybe_address in stack_map:
stack_map[maybe_address] = slot stack_map[maybe_address] = slot
...@@ -2719,7 +2725,7 @@ class InspectionWebFormatter(object): ...@@ -2719,7 +2725,7 @@ class InspectionWebFormatter(object):
address = int(straddress, 0) address = int(straddress, 0)
self.comments.set_comment(address, comment) self.comments.set_comment(address, comment)
except ValueError: except ValueError:
print "Invalid address" print("Invalid address")
def set_page_address(self, kind, straddress): def set_page_address(self, kind, straddress):
try: try:
...@@ -2730,7 +2736,7 @@ class InspectionWebFormatter(object): ...@@ -2730,7 +2736,7 @@ class InspectionWebFormatter(object):
self.padawan.known_first_map_page = address self.padawan.known_first_map_page = address
self.comments.save_page_address(kind, address) self.comments.save_page_address(kind, address)
except ValueError: except ValueError:
print "Invalid address" print("Invalid address")
def td_from_address(self, f, address): def td_from_address(self, f, address):
f.write("<td %s>" % self.comments.get_style_class_string(address)) f.write("<td %s>" % self.comments.get_style_class_string(address))
...@@ -2853,7 +2859,7 @@ class InspectionWebFormatter(object): ...@@ -2853,7 +2859,7 @@ class InspectionWebFormatter(object):
if details == InspectionWebFormatter.CONTEXT_FULL: if details == InspectionWebFormatter.CONTEXT_FULL:
if self.reader.exception.exception.parameter_count > 0: if self.reader.exception.exception.parameter_count > 0:
f.write("&nbsp;&nbsp; Exception parameters: ") f.write("&nbsp;&nbsp; Exception parameters: ")
for i in xrange(0, self.reader.exception.exception.parameter_count): for i in range(0, self.reader.exception.exception.parameter_count):
f.write("%08x" % self.reader.exception.exception.information[i]) f.write("%08x" % self.reader.exception.exception.information[i])
f.write("<br><br>") f.write("<br><br>")
...@@ -2929,19 +2935,19 @@ class InspectionWebFormatter(object): ...@@ -2929,19 +2935,19 @@ class InspectionWebFormatter(object):
f.write('<div class="code">') f.write('<div class="code">')
f.write("<table class=codedump>") f.write("<table class=codedump>")
for j in xrange(0, end_address - start_address, size): for j in range(0, end_address - start_address, size):
slot = start_address + j slot = start_address + j
heap_object = "" heap_object = ""
maybe_address = None maybe_address = None
end_region = region[0] + region[1] end_region = region[0] + region[1]
if slot < region[0] or slot + size > end_region: if slot < region[0] or slot + size > end_region:
straddress = "0x" straddress = "0x"
for i in xrange(end_region, slot + size): for i in range(end_region, slot + size):
straddress += "??" straddress += "??"
for i in reversed( for i in reversed(
xrange(max(slot, region[0]), min(slot + size, end_region))): range(max(slot, region[0]), min(slot + size, end_region))):
straddress += "%02x" % self.reader.ReadU8(i) straddress += "%02x" % self.reader.ReadU8(i)
for i in xrange(slot, region[0]): for i in range(slot, region[0]):
straddress += "??" straddress += "??"
else: else:
maybe_address = self.reader.ReadUIntPtr(slot) maybe_address = self.reader.ReadUIntPtr(slot)
...@@ -3003,7 +3009,7 @@ class InspectionWebFormatter(object): ...@@ -3003,7 +3009,7 @@ class InspectionWebFormatter(object):
start = self.align_down(start_address, line_width) start = self.align_down(start_address, line_width)
for i in xrange(end_address - start): for i in range(end_address - start):
address = start + i address = start + i
if address % 64 == 0: if address % 64 == 0:
if address != start: if address != start:
...@@ -3073,7 +3079,7 @@ class InspectionWebFormatter(object): ...@@ -3073,7 +3079,7 @@ class InspectionWebFormatter(object):
(start_address, end_address, highlight_address, expand)) (start_address, end_address, highlight_address, expand))
f.write('<div class="code">') f.write('<div class="code">')
f.write("<table class=\"codedump\">"); f.write("<table class=\"codedump\">");
for i in xrange(len(lines)): for i in range(len(lines)):
line = lines[i] line = lines[i]
next_address = count next_address = count
if i + 1 < len(lines): if i + 1 < len(lines):
...@@ -3449,8 +3455,8 @@ class InspectionShell(cmd.Cmd): ...@@ -3449,8 +3455,8 @@ class InspectionShell(cmd.Cmd):
def do_help(self, cmd=None): def do_help(self, cmd=None):
if len(cmd) == 0: if len(cmd) == 0:
print "Available commands" print("Available commands")
print "=" * 79 print("=" * 79)
prefix = "do_" prefix = "do_"
methods = inspect.getmembers(InspectionShell, predicate=inspect.ismethod) methods = inspect.getmembers(InspectionShell, predicate=inspect.ismethod)
for name,method in methods: for name,method in methods:
...@@ -3459,8 +3465,8 @@ class InspectionShell(cmd.Cmd): ...@@ -3459,8 +3465,8 @@ class InspectionShell(cmd.Cmd):
if not doc: continue if not doc: continue
name = prefix.join(name.split(prefix)[1:]) name = prefix.join(name.split(prefix)[1:])
description = doc.splitlines()[0] description = doc.splitlines()[0]
print (name + ": ").ljust(16) + description print((name + ": ").ljust(16) + description)
print "=" * 79 print("=" * 79)
else: else:
return super(InspectionShell, self).do_help(cmd) return super(InspectionShell, self).do_help(cmd)
...@@ -3488,9 +3494,9 @@ class InspectionShell(cmd.Cmd): ...@@ -3488,9 +3494,9 @@ class InspectionShell(cmd.Cmd):
address = self.ParseAddressExpr(address) address = self.ParseAddressExpr(address)
string = self.reader.ReadAsciiString(address) string = self.reader.ReadAsciiString(address)
if string == "": if string == "":
print "Not an ASCII string at %s" % self.reader.FormatIntPtr(address) print("Not an ASCII string at %s" % self.reader.FormatIntPtr(address))
else: else:
print "%s\n" % string print("%s\n" % string)
def do_dsa(self, address): def do_dsa(self, address):
""" see display_stack_ascii""" """ see display_stack_ascii"""
...@@ -3501,7 +3507,7 @@ class InspectionShell(cmd.Cmd): ...@@ -3501,7 +3507,7 @@ class InspectionShell(cmd.Cmd):
Print ASCII stack error message. Print ASCII stack error message.
""" """
if self.reader.exception is None: if self.reader.exception is None:
print "Minidump has no exception info" print("Minidump has no exception info")
return return
if len(address) == 0: if len(address) == 0:
address = None address = None
...@@ -3526,7 +3532,7 @@ class InspectionShell(cmd.Cmd): ...@@ -3526,7 +3532,7 @@ class InspectionShell(cmd.Cmd):
else: else:
self.dd_start += self.dd_num * self.reader.PointerSize() self.dd_start += self.dd_num * self.reader.PointerSize()
if not self.reader.IsAlignedAddress(self.dd_start): if not self.reader.IsAlignedAddress(self.dd_start):
print "Warning: Dumping un-aligned memory, is this what you had in mind?" print("Warning: Dumping un-aligned memory, is this what you had in mind?")
end = self.dd_start + self.reader.PointerSize() * self.dd_num end = self.dd_start + self.reader.PointerSize() * self.dd_num
self.padawan.InterpretMemory(self.dd_start, end) self.padawan.InterpretMemory(self.dd_start, end)
...@@ -3545,13 +3551,13 @@ class InspectionShell(cmd.Cmd): ...@@ -3545,13 +3551,13 @@ class InspectionShell(cmd.Cmd):
if self.reader.IsAlignedAddress(address): if self.reader.IsAlignedAddress(address):
address = address + 1 address = address + 1
elif not self.heap.IsTaggedObjectAddress(address): elif not self.heap.IsTaggedObjectAddress(address):
print "Address doesn't look like a valid pointer!" print("Address doesn't look like a valid pointer!")
return return
heap_object = self.padawan.SenseObject(address) heap_object = self.padawan.SenseObject(address)
if heap_object: if heap_object:
heap_object.Print(Printer()) heap_object.Print(Printer())
else: else:
print "Address cannot be interpreted as object!" print("Address cannot be interpreted as object!")
def do_dso(self, args): def do_dso(self, args):
""" see display_stack_objects """ """ see display_stack_objects """
...@@ -3618,10 +3624,10 @@ class InspectionShell(cmd.Cmd): ...@@ -3618,10 +3624,10 @@ class InspectionShell(cmd.Cmd):
address = self.ParseAddressExpr(address) address = self.ParseAddressExpr(address)
page_address = address & ~self.heap.PageAlignmentMask() page_address = address & ~self.heap.PageAlignmentMask()
if self.reader.IsValidAddress(page_address): if self.reader.IsValidAddress(page_address):
print "**** Not Implemented" print("**** Not Implemented")
return return
else: else:
print "Page header is not available!" print("Page header is not available!")
def do_k(self, arguments): def do_k(self, arguments):
""" """
...@@ -3666,10 +3672,10 @@ class InspectionShell(cmd.Cmd): ...@@ -3666,10 +3672,10 @@ class InspectionShell(cmd.Cmd):
List all available memory regions. List all available memory regions.
""" """
def print_region(reader, start, size, location): def print_region(reader, start, size, location):
print " %s - %s (%d bytes)" % (reader.FormatIntPtr(start), print(" %s - %s (%d bytes)" % (reader.FormatIntPtr(start),
reader.FormatIntPtr(start + size), reader.FormatIntPtr(start + size),
size) size))
print "Available memory regions:" print("Available memory regions:")
self.reader.ForEachMemoryRegion(print_region) self.reader.ForEachMemoryRegion(print_region)
def do_lm(self, arg): def do_lm(self, arg):
...@@ -3690,7 +3696,7 @@ class InspectionShell(cmd.Cmd): ...@@ -3690,7 +3696,7 @@ class InspectionShell(cmd.Cmd):
PrintModuleDetails(self.reader, module) PrintModuleDetails(self.reader, module)
else: else:
PrintModuleDetails(self.reader, module) PrintModuleDetails(self.reader, module)
print print()
def do_s(self, word): def do_s(self, word):
""" see search """ """ see search """
...@@ -3707,9 +3713,10 @@ class InspectionShell(cmd.Cmd): ...@@ -3707,9 +3713,10 @@ class InspectionShell(cmd.Cmd):
try: try:
word = self.ParseAddressExpr(word) word = self.ParseAddressExpr(word)
except ValueError: except ValueError:
print "Malformed word, prefix with '0x' to use hexadecimal format." print("Malformed word, prefix with '0x' to use hexadecimal format.")
return return
print "Searching for word %d/0x%s:" % (word, self.reader.FormatIntPtr(word)) print(
"Searching for word %d/0x%s:" % (word, self.reader.FormatIntPtr(word)))
self.reader.FindWord(word) self.reader.FindWord(word)
def do_sh(self, none): def do_sh(self, none):
...@@ -3719,7 +3726,7 @@ class InspectionShell(cmd.Cmd): ...@@ -3719,7 +3726,7 @@ class InspectionShell(cmd.Cmd):
You might get lucky and find this rare treasure full of invaluable You might get lucky and find this rare treasure full of invaluable
information. information.
""" """
print "**** Not Implemented" print("**** Not Implemented")
def do_u(self, args): def do_u(self, args):
""" see disassemble """ """ see disassemble """
...@@ -3742,24 +3749,24 @@ class InspectionShell(cmd.Cmd): ...@@ -3742,24 +3749,24 @@ class InspectionShell(cmd.Cmd):
skip = True skip = True
if not self.reader.IsValidAddress(self.u_start): if not self.reader.IsValidAddress(self.u_start):
print "Address %s is not contained within the minidump!" % ( print("Address %s is not contained within the minidump!" % (
self.reader.FormatIntPtr(self.u_start)) self.reader.FormatIntPtr(self.u_start)))
return return
lines = self.reader.GetDisasmLines(self.u_start, self.u_size) lines = self.reader.GetDisasmLines(self.u_start, self.u_size)
if len(lines) == 0: if len(lines) == 0:
print "Address %s could not be disassembled!" % ( print("Address %s could not be disassembled!" % (
self.reader.FormatIntPtr(self.u_start)) self.reader.FormatIntPtr(self.u_start)))
print " Could not disassemble using %s." % OBJDUMP_BIN print(" Could not disassemble using %s." % OBJDUMP_BIN)
print " Pass path to architecture specific objdump via --objdump?" print(" Pass path to architecture specific objdump via --objdump?")
return return
for line in lines: for line in lines:
if skip: if skip:
skip = False skip = False
continue continue
print FormatDisasmLine(self.u_start, self.heap, line) print(FormatDisasmLine(self.u_start, self.heap, line))
# Set the next start address = last line # Set the next start address = last line
self.u_start += lines[-1][0] self.u_start += lines[-1][0]
print print()
def do_EOF(self, none): def do_EOF(self, none):
raise KeyboardInterrupt raise KeyboardInterrupt
...@@ -3796,18 +3803,18 @@ def GetModuleName(reader, module): ...@@ -3796,18 +3803,18 @@ def GetModuleName(reader, module):
def PrintModuleDetails(reader, module): def PrintModuleDetails(reader, module):
print "%s" % GetModuleName(reader, module) print("%s" % GetModuleName(reader, module))
file_version = GetVersionString(module.version_info.dwFileVersionMS, file_version = GetVersionString(module.version_info.dwFileVersionMS,
module.version_info.dwFileVersionLS); module.version_info.dwFileVersionLS);
product_version = GetVersionString(module.version_info.dwProductVersionMS, product_version = GetVersionString(module.version_info.dwProductVersionMS,
module.version_info.dwProductVersionLS) module.version_info.dwProductVersionLS)
print " base: %s" % reader.FormatIntPtr(module.base_of_image) print(" base: %s" % reader.FormatIntPtr(module.base_of_image))
print " end: %s" % reader.FormatIntPtr(module.base_of_image + print(" end: %s" % reader.FormatIntPtr(module.base_of_image +
module.size_of_image) module.size_of_image))
print " file version: %s" % file_version print(" file version: %s" % file_version)
print " product version: %s" % product_version print(" product version: %s" % product_version)
time_date_stamp = datetime.datetime.fromtimestamp(module.time_date_stamp) time_date_stamp = datetime.datetime.fromtimestamp(module.time_date_stamp)
print " timestamp: %s" % time_date_stamp print(" timestamp: %s" % time_date_stamp)
def AnalyzeMinidump(options, minidump_name): def AnalyzeMinidump(options, minidump_name):
...@@ -3817,7 +3824,7 @@ def AnalyzeMinidump(options, minidump_name): ...@@ -3817,7 +3824,7 @@ def AnalyzeMinidump(options, minidump_name):
stack_top = reader.ExceptionSP() stack_top = reader.ExceptionSP()
stack_bottom = reader.StackBottom() stack_bottom = reader.StackBottom()
stack_map = {reader.ExceptionIP(): -1} stack_map = {reader.ExceptionIP(): -1}
for slot in xrange(stack_top, stack_bottom, reader.PointerSize()): for slot in range(stack_top, stack_bottom, reader.PointerSize()):
maybe_address = reader.ReadUIntPtr(slot) maybe_address = reader.ReadUIntPtr(slot)
if not maybe_address in stack_map: if not maybe_address in stack_map:
stack_map[maybe_address] = slot stack_map[maybe_address] = slot
...@@ -3827,51 +3834,51 @@ def AnalyzeMinidump(options, minidump_name): ...@@ -3827,51 +3834,51 @@ def AnalyzeMinidump(options, minidump_name):
DebugPrint("========================================") DebugPrint("========================================")
if reader.exception is None: if reader.exception is None:
print "Minidump has no exception info" print("Minidump has no exception info")
else: else:
print "Address markers:" print("Address markers:")
print " T = valid tagged pointer in the minidump" print(" T = valid tagged pointer in the minidump")
print " S = address on the exception stack" print(" S = address on the exception stack")
print " C = address in loaded C/C++ module" print(" C = address in loaded C/C++ module")
print " * = address in the minidump" print(" * = address in the minidump")
print "" print("")
print "Exception info:" print("Exception info:")
exception_thread = reader.ExceptionThread() exception_thread = reader.ExceptionThread()
print " thread id: %d" % exception_thread.id print(" thread id: %d" % exception_thread.id)
print " code: %08X" % reader.exception.exception.code print(" code: %08X" % reader.exception.exception.code)
print " context:" print(" context:")
context = CONTEXT_FOR_ARCH[reader.arch] context = CONTEXT_FOR_ARCH[reader.arch]
maxWidth = max(map(lambda s: len(s), context)) maxWidth = max(map(lambda s: len(s), context))
for r in context: for r in context:
register_value = reader.Register(r) register_value = reader.Register(r)
print " %s: %s" % (r.rjust(maxWidth), print(" %s: %s" % (r.rjust(maxWidth),
heap.FormatIntPtr(register_value)) heap.FormatIntPtr(register_value)))
# TODO(vitalyr): decode eflags. # TODO(vitalyr): decode eflags.
if reader.arch in [MD_CPU_ARCHITECTURE_ARM, MD_CPU_ARCHITECTURE_ARM64]: if reader.arch in [MD_CPU_ARCHITECTURE_ARM, MD_CPU_ARCHITECTURE_ARM64]:
print " cpsr: %s" % bin(reader.exception_context.cpsr)[2:] print(" cpsr: %s" % bin(reader.exception_context.cpsr)[2:])
else: else:
print " eflags: %s" % bin(reader.exception_context.eflags)[2:] print(" eflags: %s" % bin(reader.exception_context.eflags)[2:])
print print()
print " modules:" print(" modules:")
for module in reader.module_list.modules: for module in reader.module_list.modules:
name = GetModuleName(reader, module) name = GetModuleName(reader, module)
if name in KNOWN_MODULES: if name in KNOWN_MODULES:
print " %s at %08X" % (name, module.base_of_image) print(" %s at %08X" % (name, module.base_of_image))
reader.TryLoadSymbolsFor(name, module) reader.TryLoadSymbolsFor(name, module)
print print()
print " stack-top: %s" % heap.FormatIntPtr(reader.StackTop()) print(" stack-top: %s" % heap.FormatIntPtr(reader.StackTop()))
print " stack-bottom: %s" % heap.FormatIntPtr(reader.StackBottom()) print(" stack-bottom: %s" % heap.FormatIntPtr(reader.StackBottom()))
print "" print("")
if options.shell: if options.shell:
padawan.PrintStackTraceMessage(print_message=False) padawan.PrintStackTraceMessage(print_message=False)
print "Disassembly around exception.eip:" print("Disassembly around exception.eip:")
eip_symbol = reader.FindSymbol(reader.ExceptionIP()) eip_symbol = reader.FindSymbol(reader.ExceptionIP())
if eip_symbol is not None: if eip_symbol is not None:
print eip_symbol print(eip_symbol)
disasm_start = reader.ExceptionIP() - EIP_PROXIMITY disasm_start = reader.ExceptionIP() - EIP_PROXIMITY
disasm_bytes = 2 * EIP_PROXIMITY disasm_bytes = 2 * EIP_PROXIMITY
if (options.full): if (options.full):
...@@ -3883,12 +3890,12 @@ def AnalyzeMinidump(options, minidump_name): ...@@ -3883,12 +3890,12 @@ def AnalyzeMinidump(options, minidump_name):
lines = reader.GetDisasmLines(disasm_start, disasm_bytes) lines = reader.GetDisasmLines(disasm_start, disasm_bytes)
if not lines: if not lines:
print "Could not disassemble using %s." % OBJDUMP_BIN print("Could not disassemble using %s." % OBJDUMP_BIN)
print "Pass path to architecture specific objdump via --objdump?" print("Pass path to architecture specific objdump via --objdump?")
for line in lines: for line in lines:
print FormatDisasmLine(disasm_start, heap, line) print(FormatDisasmLine(disasm_start, heap, line))
print print()
if heap is None: if heap is None:
heap = V8Heap(reader, None) heap = V8Heap(reader, None)
...@@ -3903,10 +3910,10 @@ def AnalyzeMinidump(options, minidump_name): ...@@ -3903,10 +3910,10 @@ def AnalyzeMinidump(options, minidump_name):
try: try:
InspectionShell(reader, heap).cmdloop("type help to get help") InspectionShell(reader, heap).cmdloop("type help to get help")
except KeyboardInterrupt: except KeyboardInterrupt:
print "Kthxbye." print("Kthxbye.")
elif not options.command: elif not options.command:
if reader.exception is not None: if reader.exception is not None:
print "Annotated stack (from exception.esp to bottom):" print("Annotated stack (from exception.esp to bottom):")
stack_start = padawan.PrintStackTraceMessage() stack_start = padawan.PrintStackTraceMessage()
padawan.InterpretMemory(stack_start, stack_bottom) padawan.InterpretMemory(stack_start, stack_bottom)
reader.Dispose() reader.Dispose()
...@@ -3934,11 +3941,11 @@ if __name__ == "__main__": ...@@ -3934,11 +3941,11 @@ if __name__ == "__main__":
if options.web: if options.web:
try: try:
server = InspectionWebServer(PORT_NUMBER, options, args[0]) server = InspectionWebServer(PORT_NUMBER, options, args[0])
print 'Started httpserver on port ' , PORT_NUMBER print('Started httpserver on port ' , PORT_NUMBER)
webbrowser.open('http://localhost:%i/summary.html' % PORT_NUMBER) webbrowser.open('http://localhost:%i/summary.html' % PORT_NUMBER)
server.serve_forever() server.serve_forever()
except KeyboardInterrupt: except KeyboardInterrupt:
print '^C received, shutting down the web server' print('^C received, shutting down the web server')
server.socket.close() server.socket.close()
else: else:
AnalyzeMinidump(options, args[0]) AnalyzeMinidump(options, args[0])
...@@ -5,6 +5,9 @@ ...@@ -5,6 +5,9 @@
# found in the LICENSE file. # found in the LICENSE file.
# #
# for py2/py3 compatibility
from __future__ import print_function
import argparse import argparse
import heapq import heapq
import json import json
...@@ -54,8 +57,8 @@ def warn_if_counter_may_have_saturated(dispatches_table): ...@@ -54,8 +57,8 @@ def warn_if_counter_may_have_saturated(dispatches_table):
for source, counters_from_source in iteritems(dispatches_table): for source, counters_from_source in iteritems(dispatches_table):
for destination, counter in iteritems(counters_from_source): for destination, counter in iteritems(counters_from_source):
if counter == __COUNTER_MAX: if counter == __COUNTER_MAX:
print "WARNING: {} -> {} may have saturated.".format(source, print("WARNING: {} -> {} may have saturated.".format(source,
destination) destination))
def find_top_bytecode_dispatch_pairs(dispatches_table, top_count): def find_top_bytecode_dispatch_pairs(dispatches_table, top_count):
...@@ -71,9 +74,9 @@ def find_top_bytecode_dispatch_pairs(dispatches_table, top_count): ...@@ -71,9 +74,9 @@ def find_top_bytecode_dispatch_pairs(dispatches_table, top_count):
def print_top_bytecode_dispatch_pairs(dispatches_table, top_count): def print_top_bytecode_dispatch_pairs(dispatches_table, top_count):
top_bytecode_dispatch_pairs = ( top_bytecode_dispatch_pairs = (
find_top_bytecode_dispatch_pairs(dispatches_table, top_count)) find_top_bytecode_dispatch_pairs(dispatches_table, top_count))
print "Top {} bytecode dispatch pairs:".format(top_count) print("Top {} bytecode dispatch pairs:".format(top_count))
for source, destination, counter in top_bytecode_dispatch_pairs: for source, destination, counter in top_bytecode_dispatch_pairs:
print "{:>12d}\t{} -> {}".format(counter, source, destination) print("{:>12d}\t{} -> {}".format(counter, source, destination))
def find_top_bytecodes(dispatches_table): def find_top_bytecodes(dispatches_table):
...@@ -87,9 +90,9 @@ def find_top_bytecodes(dispatches_table): ...@@ -87,9 +90,9 @@ def find_top_bytecodes(dispatches_table):
def print_top_bytecodes(dispatches_table): def print_top_bytecodes(dispatches_table):
top_bytecodes = find_top_bytecodes(dispatches_table) top_bytecodes = find_top_bytecodes(dispatches_table)
print "Top bytecodes:" print("Top bytecodes:")
for bytecode, counter in top_bytecodes: for bytecode, counter in top_bytecodes:
print "{:>12d}\t{}".format(counter, bytecode) print("{:>12d}\t{}".format(counter, bytecode))
def find_top_dispatch_sources_and_destinations( def find_top_dispatch_sources_and_destinations(
...@@ -116,13 +119,13 @@ def print_top_dispatch_sources_and_destinations(dispatches_table, bytecode, ...@@ -116,13 +119,13 @@ def print_top_dispatch_sources_and_destinations(dispatches_table, bytecode,
top_count, sort_relative): top_count, sort_relative):
top_sources, top_destinations = find_top_dispatch_sources_and_destinations( top_sources, top_destinations = find_top_dispatch_sources_and_destinations(
dispatches_table, bytecode, top_count, sort_relative) dispatches_table, bytecode, top_count, sort_relative)
print "Top sources of dispatches to {}:".format(bytecode) print("Top sources of dispatches to {}:".format(bytecode))
for source_name, counter, ratio in top_sources: for source_name, counter, ratio in top_sources:
print "{:>12d}\t{:>5.1f}%\t{}".format(counter, ratio * 100, source_name) print("{:>12d}\t{:>5.1f}%\t{}".format(counter, ratio * 100, source_name))
print "\nTop destinations of dispatches from {}:".format(bytecode) print("\nTop destinations of dispatches from {}:".format(bytecode))
for destination_name, counter, ratio in top_destinations: for destination_name, counter, ratio in top_destinations:
print "{:>12d}\t{:>5.1f}%\t{}".format(counter, ratio * 100, destination_name) print("{:>12d}\t{:>5.1f}%\t{}".format(counter, ratio * 100, destination_name))
def build_counters_matrix(dispatches_table): def build_counters_matrix(dispatches_table):
......
#! /usr/bin/python2 #! /usr/bin/python
# #
# Copyright 2016 the V8 project authors. All rights reserved. # Copyright 2016 the V8 project authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be # Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file. # found in the LICENSE file.
# #
# for py2/py3 compatibility
from __future__ import print_function
import argparse import argparse
import collections import collections
import os import os
...@@ -94,18 +97,18 @@ def print_disassembly_annotation(offset_counts, bytecode_disassembly): ...@@ -94,18 +97,18 @@ def print_disassembly_annotation(offset_counts, bytecode_disassembly):
return offsets.pop() if offsets else -1 return offsets.pop() if offsets else -1
current_offset = next_offset() current_offset = next_offset()
print current_offset; print(current_offset);
for line in bytecode_disassembly: for line in bytecode_disassembly:
disassembly_offset = int(line.split()[1]) disassembly_offset = int(line.split()[1])
if disassembly_offset == current_offset: if disassembly_offset == current_offset:
count = offset_counts[current_offset] count = offset_counts[current_offset]
percentage = 100.0 * count / total percentage = 100.0 * count / total
print "{:>8d} ({:>5.1f}%) ".format(count, percentage), print("{:>8d} ({:>5.1f}%) ".format(count, percentage), end=' ')
current_offset = next_offset() current_offset = next_offset()
else: else:
print " ", print(" ", end=' ')
print line print(line)
if offsets: if offsets:
print ("WARNING: Offsets not empty. Output is most likely invalid due to " print ("WARNING: Offsets not empty. Output is most likely invalid due to "
......
...@@ -31,6 +31,9 @@ ...@@ -31,6 +31,9 @@
# char arrays. It is used for embedded JavaScript code in the V8 # char arrays. It is used for embedded JavaScript code in the V8
# library. # library.
# for py2/py3 compatibility
from functools import reduce
import os, re import os, re
import optparse import optparse
import textwrap import textwrap
...@@ -249,7 +252,7 @@ def BuildMetadata(sources, source_bytes, native_type): ...@@ -249,7 +252,7 @@ def BuildMetadata(sources, source_bytes, native_type):
get_script_name_cases = [] get_script_name_cases = []
get_script_source_cases = [] get_script_source_cases = []
offset = 0 offset = 0
for i in xrange(len(sources.modules)): for i in range(len(sources.modules)):
native_name = "native %s.js" % sources.names[i] native_name = "native %s.js" % sources.names[i]
d = { d = {
"i": i, "i": i,
...@@ -290,7 +293,7 @@ def PutInt(blob_file, value): ...@@ -290,7 +293,7 @@ def PutInt(blob_file, value):
value_with_length = (value << 2) | (size - 1) value_with_length = (value << 2) | (size - 1)
byte_sequence = bytearray() byte_sequence = bytearray()
for i in xrange(size): for i in range(size):
byte_sequence.append(value_with_length & 255) byte_sequence.append(value_with_length & 255)
value_with_length >>= 8; value_with_length >>= 8;
blob_file.write(byte_sequence) blob_file.write(byte_sequence)
...@@ -312,7 +315,7 @@ def WriteStartupBlob(sources, startup_blob): ...@@ -312,7 +315,7 @@ def WriteStartupBlob(sources, startup_blob):
output = open(startup_blob, "wb") output = open(startup_blob, "wb")
PutInt(output, len(sources.names)) PutInt(output, len(sources.names))
for i in xrange(len(sources.names)): for i in range(len(sources.names)):
PutStr(output, sources.names[i]); PutStr(output, sources.names[i]);
PutStr(output, sources.modules[i]); PutStr(output, sources.modules[i]);
......
...@@ -27,6 +27,10 @@ ...@@ -27,6 +27,10 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# for py2/py3 compatibility
from __future__ import print_function
import bisect import bisect
import collections import collections
import ctypes import ctypes
...@@ -157,7 +161,7 @@ class Code(object): ...@@ -157,7 +161,7 @@ class Code(object):
# Print annotated lines. # Print annotated lines.
address = lines[0][0] address = lines[0][0]
total_count = 0 total_count = 0
for i in xrange(len(lines)): for i in range(len(lines)):
start_offset = lines[i][0] - address start_offset = lines[i][0] - address
if i == len(lines) - 1: if i == len(lines) - 1:
end_offset = self.end_address - self.start_address end_offset = self.end_address - self.start_address
...@@ -183,10 +187,10 @@ class Code(object): ...@@ -183,10 +187,10 @@ class Code(object):
# 6 for the percentage number, incl. the '.' # 6 for the percentage number, incl. the '.'
# 1 for the '%' sign # 1 for the '%' sign
# => 15 # => 15
print "%5d | %6.2f%% %x(%d): %s" % (count, percent, offset, offset, lines[i][1]) print("%5d | %6.2f%% %x(%d): %s" % (count, percent, offset, offset, lines[i][1]))
else: else:
print "%s %x(%d): %s" % (" " * 15, offset, offset, lines[i][1]) print("%s %x(%d): %s" % (" " * 15, offset, offset, lines[i][1]))
print print()
assert total_count == self.self_ticks, \ assert total_count == self.self_ticks, \
"Lost ticks (%d != %d) in %s" % (total_count, self.self_ticks, self) "Lost ticks (%d != %d) in %s" % (total_count, self.self_ticks, self)
...@@ -267,9 +271,8 @@ class CodeMap(object): ...@@ -267,9 +271,8 @@ class CodeMap(object):
pages = 0 pages = 0
while page_id < limit_id: while page_id < limit_id:
if max_pages >= 0 and pages > max_pages: if max_pages >= 0 and pages > max_pages:
print >>sys.stderr, \ print("Warning: page limit (%d) reached for %s [%s]" % (
"Warning: page limit (%d) reached for %s [%s]" % ( max_pages, code.name, code.origin), file=sys.stderr)
max_pages, code.name, code.origin)
break break
if page_id in self.pages: if page_id in self.pages:
page = self.pages[page_id] page = self.pages[page_id]
...@@ -309,7 +312,7 @@ class CodeMap(object): ...@@ -309,7 +312,7 @@ class CodeMap(object):
def Print(self): def Print(self):
for code in self.AllCode(): for code in self.AllCode():
print code print(code)
def Find(self, pc): def Find(self, pc):
if pc < self.min_address or pc >= self.max_address: if pc < self.min_address or pc >= self.max_address:
...@@ -411,7 +414,7 @@ class LogReader(object): ...@@ -411,7 +414,7 @@ class LogReader(object):
continue continue
code = self.code_map.Find(old_start_address) code = self.code_map.Find(old_start_address)
if not code: if not code:
print >>sys.stderr, "Warning: Not found %x" % old_start_address print("Warning: Not found %x" % old_start_address, file=sys.stderr)
continue continue
assert code.start_address == old_start_address, \ assert code.start_address == old_start_address, \
"Inexact move address %x for %s" % (old_start_address, code) "Inexact move address %x for %s" % (old_start_address, code)
...@@ -591,7 +594,7 @@ class TraceReader(object): ...@@ -591,7 +594,7 @@ class TraceReader(object):
self.trace = mmap.mmap(self.trace_file.fileno(), 0, mmap.MAP_PRIVATE) self.trace = mmap.mmap(self.trace_file.fileno(), 0, mmap.MAP_PRIVATE)
self.trace_header = TRACE_HEADER_DESC.Read(self.trace, 0) self.trace_header = TRACE_HEADER_DESC.Read(self.trace, 0)
if self.trace_header.magic != TraceReader._TRACE_HEADER_MAGIC: if self.trace_header.magic != TraceReader._TRACE_HEADER_MAGIC:
print >>sys.stderr, "Warning: unsupported trace header magic" print("Warning: unsupported trace header magic", file=sys.stderr)
self.offset = self.trace_header.data_offset self.offset = self.trace_header.data_offset
self.limit = self.trace_header.data_offset + self.trace_header.data_size self.limit = self.trace_header.data_offset + self.trace_header.data_size
assert self.limit <= self.trace.size(), \ assert self.limit <= self.trace.size(), \
...@@ -642,7 +645,7 @@ class TraceReader(object): ...@@ -642,7 +645,7 @@ class TraceReader(object):
return sample return sample
sample.ips = [] sample.ips = []
offset += self.header_size + ctypes.sizeof(sample) offset += self.header_size + ctypes.sizeof(sample)
for _ in xrange(sample.nr): for _ in range(sample.nr):
sample.ips.append( sample.ips.append(
self.ip_struct.from_buffer(self.trace, offset).value) self.ip_struct.from_buffer(self.trace, offset).value)
offset += self.ip_size offset += self.ip_size
...@@ -786,7 +789,7 @@ class LibraryRepo(object): ...@@ -786,7 +789,7 @@ class LibraryRepo(object):
def _LoadKernelSymbols(self, code_map): def _LoadKernelSymbols(self, code_map):
if not os.path.exists(KERNEL_ALLSYMS_FILE): if not os.path.exists(KERNEL_ALLSYMS_FILE):
print >>sys.stderr, "Warning: %s not found" % KERNEL_ALLSYMS_FILE print("Warning: %s not found" % KERNEL_ALLSYMS_FILE, file=sys.stderr)
return False return False
kallsyms = open(KERNEL_ALLSYMS_FILE, "r") kallsyms = open(KERNEL_ALLSYMS_FILE, "r")
code = None code = None
...@@ -804,35 +807,35 @@ class LibraryRepo(object): ...@@ -804,35 +807,35 @@ class LibraryRepo(object):
def PrintReport(code_map, library_repo, arch, ticks, options): def PrintReport(code_map, library_repo, arch, ticks, options):
print "Ticks per symbol:" print("Ticks per symbol:")
used_code = [code for code in code_map.UsedCode()] used_code = [code for code in code_map.UsedCode()]
used_code.sort(key=lambda x: x.self_ticks, reverse=True) used_code.sort(key=lambda x: x.self_ticks, reverse=True)
for i, code in enumerate(used_code): for i, code in enumerate(used_code):
code_ticks = code.self_ticks code_ticks = code.self_ticks
print "%10d %5.1f%% %s [%s]" % (code_ticks, 100. * code_ticks / ticks, print("%10d %5.1f%% %s [%s]" % (code_ticks, 100. * code_ticks / ticks,
code.FullName(), code.origin) code.FullName(), code.origin))
if options.disasm_all or i < options.disasm_top: if options.disasm_all or i < options.disasm_top:
code.PrintAnnotated(arch, options) code.PrintAnnotated(arch, options)
print print()
print "Ticks per library:" print("Ticks per library:")
mmap_infos = [m for m in library_repo.infos if m.ticks > 0] mmap_infos = [m for m in library_repo.infos if m.ticks > 0]
mmap_infos.sort(key=lambda m: m.ticks, reverse=True) mmap_infos.sort(key=lambda m: m.ticks, reverse=True)
for mmap_info in mmap_infos: for mmap_info in mmap_infos:
mmap_ticks = mmap_info.ticks mmap_ticks = mmap_info.ticks
print "%10d %5.1f%% %s" % (mmap_ticks, 100. * mmap_ticks / ticks, print("%10d %5.1f%% %s" % (mmap_ticks, 100. * mmap_ticks / ticks,
mmap_info.unique_name) mmap_info.unique_name))
def PrintDot(code_map, options): def PrintDot(code_map, options):
print "digraph G {" print("digraph G {")
for code in code_map.UsedCode(): for code in code_map.UsedCode():
if code.self_ticks < 10: if code.self_ticks < 10:
continue continue
print "n%d [shape=box,label=\"%s\"];" % (code.id, code.name) print("n%d [shape=box,label=\"%s\"];" % (code.id, code.name))
if code.callee_ticks: if code.callee_ticks:
for callee, ticks in code.callee_ticks.iteritems(): for callee, ticks in code.callee_ticks.iteritems():
print "n%d -> n%d [label=\"%d\"];" % (code.id, callee.id, ticks) print("n%d -> n%d [label=\"%d\"];" % (code.id, callee.id, ticks))
print "}" print("}")
if __name__ == "__main__": if __name__ == "__main__":
...@@ -877,8 +880,8 @@ if __name__ == "__main__": ...@@ -877,8 +880,8 @@ if __name__ == "__main__":
options, args = parser.parse_args() options, args = parser.parse_args()
if not options.quiet: if not options.quiet:
print "V8 log: %s, %s.ll" % (options.log, options.log) print("V8 log: %s, %s.ll" % (options.log, options.log))
print "Perf trace file: %s" % options.trace print("Perf trace file: %s" % options.trace)
V8_GC_FAKE_MMAP = options.gc_fake_mmap V8_GC_FAKE_MMAP = options.gc_fake_mmap
HOST_ROOT = options.host_root HOST_ROOT = options.host_root
...@@ -886,7 +889,7 @@ if __name__ == "__main__": ...@@ -886,7 +889,7 @@ if __name__ == "__main__":
disasm.OBJDUMP_BIN = options.objdump disasm.OBJDUMP_BIN = options.objdump
OBJDUMP_BIN = options.objdump OBJDUMP_BIN = options.objdump
else: else:
print "Cannot find %s, falling back to default objdump" % options.objdump print("Cannot find %s, falling back to default objdump" % options.objdump)
# Stats. # Stats.
events = 0 events = 0
...@@ -904,8 +907,8 @@ if __name__ == "__main__": ...@@ -904,8 +907,8 @@ if __name__ == "__main__":
log_reader = LogReader(log_name=options.log + ".ll", log_reader = LogReader(log_name=options.log + ".ll",
code_map=code_map) code_map=code_map)
if not options.quiet: if not options.quiet:
print "Generated code architecture: %s" % log_reader.arch print("Generated code architecture: %s" % log_reader.arch)
print print()
sys.stdout.flush() sys.stdout.flush()
# Process the code and trace logs. # Process the code and trace logs.
...@@ -968,11 +971,11 @@ if __name__ == "__main__": ...@@ -968,11 +971,11 @@ if __name__ == "__main__":
def PrintTicks(number, total, description): def PrintTicks(number, total, description):
print("%10d %5.1f%% ticks in %s" % print("%10d %5.1f%% ticks in %s" %
(number, 100.0*number/total, description)) (number, 100.0*number/total, description))
print print()
print "Stats:" print("Stats:")
print "%10d total trace events" % events print("%10d total trace events" % events)
print "%10d total ticks" % ticks print("%10d total ticks" % ticks)
print "%10d ticks not in symbols" % missed_ticks print("%10d ticks not in symbols" % missed_ticks)
unaccounted = "unaccounted ticks" unaccounted = "unaccounted ticks"
if really_missed_ticks > 0: if really_missed_ticks > 0:
unaccounted += " (probably in the kernel, try --kernel)" unaccounted += " (probably in the kernel, try --kernel)"
...@@ -980,10 +983,10 @@ if __name__ == "__main__": ...@@ -980,10 +983,10 @@ if __name__ == "__main__":
PrintTicks(optimized_ticks, ticks, "ticks in optimized code") PrintTicks(optimized_ticks, ticks, "ticks in optimized code")
PrintTicks(generated_ticks, ticks, "ticks in other lazily compiled code") PrintTicks(generated_ticks, ticks, "ticks in other lazily compiled code")
PrintTicks(v8_internal_ticks, ticks, "ticks in v8::internal::*") PrintTicks(v8_internal_ticks, ticks, "ticks in v8::internal::*")
print "%10d total symbols" % len([c for c in code_map.AllCode()]) print("%10d total symbols" % len([c for c in code_map.AllCode()]))
print "%10d used symbols" % len([c for c in code_map.UsedCode()]) print("%10d used symbols" % len([c for c in code_map.UsedCode()]))
print "%9.2fs library processing time" % mmap_time print("%9.2fs library processing time" % mmap_time)
print "%9.2fs tick processing time" % sample_time print("%9.2fs tick processing time" % sample_time)
log_reader.Dispose() log_reader.Dispose()
trace_reader.Dispose() trace_reader.Dispose()
...@@ -5,6 +5,9 @@ ...@@ -5,6 +5,9 @@
# Load this file by adding this to your ~/.lldbinit: # Load this file by adding this to your ~/.lldbinit:
# command script import <this_dir>/lldb_commands.py # command script import <this_dir>/lldb_commands.py
# for py2/py3 compatibility
from __future__ import print_function
import lldb import lldb
import re import re
......
#!/usr/bin/env python3 #!/usr/bin/env python
# Copyright 2018 the V8 project authors. All rights reserved. # Copyright 2018 the V8 project authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be # Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file. # found in the LICENSE file.
...@@ -7,6 +8,9 @@ ...@@ -7,6 +8,9 @@
Consult --help for more information. Consult --help for more information.
""" """
# for py2/py3 compatibility
from __future__ import print_function
import argparse import argparse
import json import json
import os import os
......
...@@ -10,6 +10,7 @@ MB is a wrapper script for GN that can be used to generate build files ...@@ -10,6 +10,7 @@ MB is a wrapper script for GN that can be used to generate build files
for sets of canned configurations and analyze them. for sets of canned configurations and analyze them.
""" """
# for py2/py3 compatibility
from __future__ import print_function from __future__ import print_function
import argparse import argparse
...@@ -36,6 +37,12 @@ sys.path = [os.path.join(CHROMIUM_SRC_DIR, 'build')] + sys.path ...@@ -36,6 +37,12 @@ sys.path = [os.path.join(CHROMIUM_SRC_DIR, 'build')] + sys.path
import gn_helpers import gn_helpers
try:
cmp # Python 2
except NameError: # Python 3
def cmp(x, y): # pylint: disable=redefined-builtin
return (x > y) - (x < y)
def main(args): def main(args):
mbw = MetaBuildWrapper() mbw = MetaBuildWrapper()
...@@ -1155,7 +1162,7 @@ class MetaBuildWrapper(object): ...@@ -1155,7 +1162,7 @@ class MetaBuildWrapper(object):
def MaybeMakeDirectory(self, path): def MaybeMakeDirectory(self, path):
try: try:
os.makedirs(path) os.makedirs(path)
except OSError, e: except OSError as e:
if e.errno != errno.EEXIST: if e.errno != errno.EEXIST:
raise raise
......
...@@ -284,7 +284,7 @@ class UnitTest(unittest.TestCase): ...@@ -284,7 +284,7 @@ class UnitTest(unittest.TestCase):
self.assertEqual(['all', 'foo_unittests'], out['compile_targets']) self.assertEqual(['all', 'foo_unittests'], out['compile_targets'])
def test_analyze_handles_way_too_many_results(self): def test_analyze_handles_way_too_many_results(self):
too_many_files = ', '.join(['"//foo:foo%d"' % i for i in xrange(4 * 1024)]) too_many_files = ', '.join(['"//foo:foo%d"' % i for i in range(4 * 1024)])
files = {'/tmp/in.json': '''{\ files = {'/tmp/in.json': '''{\
"files": ["foo/foo_unittest.cc"], "files": ["foo/foo_unittest.cc"],
"test_targets": ["foo_unittests"], "test_targets": ["foo_unittests"],
......
...@@ -9,6 +9,9 @@ Use this script to fetch all dependencies for V8 to run build_gn.py. ...@@ -9,6 +9,9 @@ Use this script to fetch all dependencies for V8 to run build_gn.py.
Usage: fetch_deps.py <v8-path> Usage: fetch_deps.py <v8-path>
""" """
# for py2/py3 compatibility
from __future__ import print_function
import os import os
import subprocess import subprocess
import sys import sys
...@@ -52,9 +55,9 @@ def EnsureGit(v8_path): ...@@ -52,9 +55,9 @@ def EnsureGit(v8_path):
expected_git_dir = os.path.join(v8_path, ".git") expected_git_dir = os.path.join(v8_path, ".git")
actual_git_dir = git("rev-parse --absolute-git-dir") actual_git_dir = git("rev-parse --absolute-git-dir")
if expected_git_dir == actual_git_dir: if expected_git_dir == actual_git_dir:
print "V8 is tracked stand-alone by git." print("V8 is tracked stand-alone by git.")
return False return False
print "Initializing temporary git repository in v8." print("Initializing temporary git repository in v8.")
git("init") git("init")
git("config user.name \"Ada Lovelace\"") git("config user.name \"Ada Lovelace\"")
git("config user.email ada@lovela.ce") git("config user.email ada@lovela.ce")
...@@ -71,7 +74,7 @@ def FetchDeps(v8_path): ...@@ -71,7 +74,7 @@ def FetchDeps(v8_path):
temporary_git = EnsureGit(v8_path) temporary_git = EnsureGit(v8_path)
try: try:
print "Fetching dependencies." print("Fetching dependencies.")
env = os.environ.copy() env = os.environ.copy()
# gclient needs to have depot_tools in the PATH. # gclient needs to have depot_tools in the PATH.
env["PATH"] = depot_tools + os.pathsep + env["PATH"] env["PATH"] = depot_tools + os.pathsep + env["PATH"]
......
...@@ -3,6 +3,9 @@ ...@@ -3,6 +3,9 @@
# Use of this source code is governed by a BSD-style license that can be # Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file. # found in the LICENSE file.
# for py2/py3 compatibility
from __future__ import print_function
import os import os
import pipes import pipes
import shutil import shutil
...@@ -23,7 +26,7 @@ def EnsureDepotTools(v8_path, fetch_if_not_exist): ...@@ -23,7 +26,7 @@ def EnsureDepotTools(v8_path, fetch_if_not_exist):
except: except:
pass pass
if fetch_if_not_exist: if fetch_if_not_exist:
print "Checking out depot_tools." print("Checking out depot_tools.")
# shell=True needed on Windows to resolve git.bat. # shell=True needed on Windows to resolve git.bat.
subprocess.check_call("git clone {} {}".format( subprocess.check_call("git clone {} {}".format(
pipes.quote(DEPOT_TOOLS_URL), pipes.quote(DEPOT_TOOLS_URL),
...@@ -36,14 +39,14 @@ def EnsureDepotTools(v8_path, fetch_if_not_exist): ...@@ -36,14 +39,14 @@ def EnsureDepotTools(v8_path, fetch_if_not_exist):
return None return None
depot_tools = _Get(v8_path) depot_tools = _Get(v8_path)
assert depot_tools is not None assert depot_tools is not None
print "Using depot tools in %s" % depot_tools print("Using depot tools in %s" % depot_tools)
return depot_tools return depot_tools
def UninitGit(v8_path): def UninitGit(v8_path):
print "Uninitializing temporary git repository" print("Uninitializing temporary git repository")
target = os.path.join(v8_path, ".git") target = os.path.join(v8_path, ".git")
if os.path.isdir(target): if os.path.isdir(target):
print ">> Cleaning up %s" % target print(">> Cleaning up %s" % target)
def OnRmError(func, path, exec_info): def OnRmError(func, path, exec_info):
# This might happen on Windows # This might happen on Windows
os.chmod(path, stat.S_IWRITE) os.chmod(path, stat.S_IWRITE)
......
...@@ -23,6 +23,9 @@ Optional flags: ...@@ -23,6 +23,9 @@ Optional flags:
--with-patch Also include currently staged files in the V8 checkout. --with-patch Also include currently staged files in the V8 checkout.
""" """
# for py2/py3 compatibility
from __future__ import print_function
import argparse import argparse
import os import os
import shutil import shutil
...@@ -57,7 +60,7 @@ FILES_TO_KEEP = [ "gypfiles" ] ...@@ -57,7 +60,7 @@ FILES_TO_KEEP = [ "gypfiles" ]
def RunGclient(path): def RunGclient(path):
assert os.path.isdir(path) assert os.path.isdir(path)
print ">> Running gclient sync" print(">> Running gclient sync")
subprocess.check_call(["gclient", "sync", "--nohooks"], cwd=path) subprocess.check_call(["gclient", "sync", "--nohooks"], cwd=path)
def CommitPatch(options): def CommitPatch(options):
...@@ -67,7 +70,7 @@ def CommitPatch(options): ...@@ -67,7 +70,7 @@ def CommitPatch(options):
the fake git clone fetch it into node.js. We can leave the commit, as the fake git clone fetch it into node.js. We can leave the commit, as
bot_update will ensure a clean state on each run. bot_update will ensure a clean state on each run.
""" """
print ">> Committing patch" print(">> Committing patch")
subprocess.check_call( subprocess.check_call(
["git", "-c", "user.name=fake", "-c", "user.email=fake@chromium.org", ["git", "-c", "user.name=fake", "-c", "user.email=fake@chromium.org",
"commit", "--allow-empty", "-m", "placeholder-commit"], "commit", "--allow-empty", "-m", "placeholder-commit"],
...@@ -77,8 +80,8 @@ def CommitPatch(options): ...@@ -77,8 +80,8 @@ def CommitPatch(options):
def UpdateTarget(repository, options, files_to_keep): def UpdateTarget(repository, options, files_to_keep):
source = os.path.join(options.v8_path, *repository) source = os.path.join(options.v8_path, *repository)
target = os.path.join(options.node_path, TARGET_SUBDIR, *repository) target = os.path.join(options.node_path, TARGET_SUBDIR, *repository)
print ">> Updating target directory %s" % target print(">> Updating target directory %s" % target)
print ">> from active branch at %s" % source print(">> from active branch at %s" % source)
if not os.path.exists(target): if not os.path.exists(target):
os.makedirs(target) os.makedirs(target)
# Remove possible remnants of previous incomplete runs. # Remove possible remnants of previous incomplete runs.
...@@ -111,17 +114,17 @@ def UpdateTarget(repository, options, files_to_keep): ...@@ -111,17 +114,17 @@ def UpdateTarget(repository, options, files_to_keep):
def UpdateGitIgnore(options): def UpdateGitIgnore(options):
file_name = os.path.join(options.node_path, TARGET_SUBDIR, ".gitignore") file_name = os.path.join(options.node_path, TARGET_SUBDIR, ".gitignore")
assert os.path.isfile(file_name) assert os.path.isfile(file_name)
print ">> Updating .gitignore with lines" print(">> Updating .gitignore with lines")
with open(file_name) as gitignore: with open(file_name) as gitignore:
content = gitignore.readlines() content = gitignore.readlines()
content = [x.strip() for x in content] content = [x.strip() for x in content]
for x in DELETE_FROM_GITIGNORE: for x in DELETE_FROM_GITIGNORE:
if x in content: if x in content:
print "- %s" % x print("- %s" % x)
content.remove(x) content.remove(x)
for x in ADD_TO_GITIGNORE: for x in ADD_TO_GITIGNORE:
if x not in content: if x not in content:
print "+ %s" % x print("+ %s" % x)
content.append(x) content.append(x)
content.sort(key=lambda x: x[1:] if x.startswith("!") else x) content.sort(key=lambda x: x[1:] if x.startswith("!") else x)
with open(file_name, "w") as gitignore: with open(file_name, "w") as gitignore:
...@@ -129,7 +132,7 @@ def UpdateGitIgnore(options): ...@@ -129,7 +132,7 @@ def UpdateGitIgnore(options):
gitignore.write("%s\n" % x) gitignore.write("%s\n" % x)
def CreateCommit(options): def CreateCommit(options):
print ">> Creating commit." print(">> Creating commit.")
# Find git hash from source. # Find git hash from source.
githash = subprocess.check_output(["git", "rev-parse", "--short", "HEAD"], githash = subprocess.check_output(["git", "rev-parse", "--short", "HEAD"],
cwd=options.v8_path).strip() cwd=options.v8_path).strip()
......
...@@ -11,6 +11,9 @@ Examples: ...@@ -11,6 +11,9 @@ Examples:
%prog -t "x64 results" ../result.json master.json -o results.html %prog -t "x64 results" ../result.json master.json -o results.html
''' '''
# for py2/py3 compatibility
from __future__ import print_function
from collections import OrderedDict from collections import OrderedDict
import json import json
import math import math
...@@ -418,7 +421,7 @@ def Render(args): ...@@ -418,7 +421,7 @@ def Render(args):
run_names[run_name] = 0 run_names[run_name] = 0
for error in data["errors"]: for error in data["errors"]:
print "Error:", error print("Error:", error)
for trace in data["traces"]: for trace in data["traces"]:
suite_name = trace["graphs"][0] suite_name = trace["graphs"][0]
......
...@@ -14,11 +14,16 @@ The command is run up to three times and the printed allocation hash is ...@@ -14,11 +14,16 @@ The command is run up to three times and the printed allocation hash is
compared. Differences are reported as errors. compared. Differences are reported as errors.
""" """
# for py2/py3 compatibility
from __future__ import print_function
import sys import sys
from testrunner.local import command from testrunner.local import command
from testrunner.local import utils from testrunner.local import utils
MAX_TRIES = 3 MAX_TRIES = 3
TIMEOUT = 120 TIMEOUT = 120
...@@ -36,19 +41,19 @@ def main(args): ...@@ -36,19 +41,19 @@ def main(args):
previous_allocations = None previous_allocations = None
for run in range(1, MAX_TRIES + 1): for run in range(1, MAX_TRIES + 1):
print '### Predictable run #%d' % run print('### Predictable run #%d' % run)
output = cmd.execute() output = cmd.execute()
if output.stdout: if output.stdout:
print '### Stdout:' print('### Stdout:')
print output.stdout print(output.stdout)
if output.stderr: if output.stderr:
print '### Stderr:' print('### Stderr:')
print output.stderr print(output.stderr)
print '### Return code: %s' % output.exit_code print('### Return code: %s' % output.exit_code)
if output.HasTimedOut(): if output.HasTimedOut():
# If we get a timeout in any run, we are in an unpredictable state. Just # If we get a timeout in any run, we are in an unpredictable state. Just
# report it as a failure and don't rerun. # report it as a failure and don't rerun.
print '### Test timed out' print('### Test timed out')
return 1 return 1
allocations = allocation_str(output.stdout) allocations = allocation_str(output.stdout)
if not allocations: if not allocations:
...@@ -57,7 +62,7 @@ def main(args): ...@@ -57,7 +62,7 @@ def main(args):
'--verify-predictable is passed at the cmd line.') '--verify-predictable is passed at the cmd line.')
return 2 return 2
if previous_allocations and previous_allocations != allocations: if previous_allocations and previous_allocations != allocations:
print '### Allocations differ' print('### Allocations differ')
return 3 return 3
if run >= MAX_TRIES: if run >= MAX_TRIES:
# No difference on the last run -> report a success. # No difference on the last run -> report a success.
......
...@@ -26,6 +26,9 @@ ...@@ -26,6 +26,9 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# for py2/py3 compatibility
from __future__ import print_function
import argparse import argparse
import json import json
import os import os
...@@ -63,7 +66,7 @@ class LastReleaseBailout(Step): ...@@ -63,7 +66,7 @@ class LastReleaseBailout(Step):
format="%H", git_hash="%s..%s" % (last_release, self["candidate"])) format="%H", git_hash="%s..%s" % (last_release, self["candidate"]))
if not commits: if not commits:
print "Already pushed current candidate %s" % self["candidate"] print("Already pushed current candidate %s" % self["candidate"])
return True return True
...@@ -71,7 +74,7 @@ class CreateRelease(Step): ...@@ -71,7 +74,7 @@ class CreateRelease(Step):
MESSAGE = "Creating release if specified." MESSAGE = "Creating release if specified."
def RunStep(self): def RunStep(self):
print "Creating release for %s." % self["candidate"] print("Creating release for %s." % self["candidate"])
args = [ args = [
"--author", self._options.author, "--author", self._options.author,
...@@ -96,7 +99,7 @@ class AutoPush(ScriptsBase): ...@@ -96,7 +99,7 @@ class AutoPush(ScriptsBase):
def _ProcessOptions(self, options): def _ProcessOptions(self, options):
if not options.author or not options.reviewer: # pragma: no cover if not options.author or not options.reviewer: # pragma: no cover
print "You need to specify author and reviewer." print("You need to specify author and reviewer.")
return False return False
options.requires_editor = False options.requires_editor = False
return True return True
......
...@@ -3,6 +3,9 @@ ...@@ -3,6 +3,9 @@
# Use of this source code is governed by a BSD-style license that can be # Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file. # found in the LICENSE file.
# for py2/py3 compatibility
from __future__ import print_function
import argparse import argparse
import os import os
import sys import sys
...@@ -160,9 +163,9 @@ class UploadCL(Step): ...@@ -160,9 +163,9 @@ class UploadCL(Step):
cq=self._options.use_commit_queue, cq=self._options.use_commit_queue,
cq_dry_run=self._options.use_dry_run, cq_dry_run=self._options.use_dry_run,
cwd=cwd) cwd=cwd)
print "CL uploaded." print("CL uploaded.")
else: else:
print "Dry run - don't upload." print("Dry run - don't upload.")
self.GitCheckout("master", cwd=cwd) self.GitCheckout("master", cwd=cwd)
self.GitDeleteBranch("work-branch", cwd=cwd) self.GitDeleteBranch("work-branch", cwd=cwd)
...@@ -205,7 +208,7 @@ class AutoRoll(ScriptsBase): ...@@ -205,7 +208,7 @@ class AutoRoll(ScriptsBase):
def _ProcessOptions(self, options): # pragma: no cover def _ProcessOptions(self, options): # pragma: no cover
if not options.author or not options.reviewer: if not options.author or not options.reviewer:
print "A reviewer (-r) and an author (-a) are required." print("A reviewer (-r) and an author (-a) are required.")
return False return False
options.requires_editor = False options.requires_editor = False
......
...@@ -3,6 +3,9 @@ ...@@ -3,6 +3,9 @@
# Use of this source code is governed by a BSD-style license that can be # Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file. # found in the LICENSE file.
# for py2/py3 compatibility
from __future__ import print_function
import argparse import argparse
import sys import sys
...@@ -15,7 +18,7 @@ class Preparation(Step): ...@@ -15,7 +18,7 @@ class Preparation(Step):
def RunStep(self): def RunStep(self):
# TODO(machenbach): Remove after the git switch. # TODO(machenbach): Remove after the git switch.
if self.Config("PERSISTFILE_BASENAME") == "/tmp/v8-auto-tag-tempfile": if self.Config("PERSISTFILE_BASENAME") == "/tmp/v8-auto-tag-tempfile":
print "This script is disabled until after the v8 git migration." print("This script is disabled until after the v8 git migration.")
return True return True
self.CommonPrepare() self.CommonPrepare()
...@@ -80,7 +83,7 @@ class GetOldestUntaggedVersion(Step): ...@@ -80,7 +83,7 @@ class GetOldestUntaggedVersion(Step):
self["candidate_version"] = version self["candidate_version"] = version
if not self["candidate"] or not self["candidate_version"]: if not self["candidate"] or not self["candidate_version"]:
print "Nothing found to tag." print("Nothing found to tag.")
self.CommonCleanup() self.CommonCleanup()
return True return True
...@@ -120,18 +123,18 @@ class CalculateTagRevision(Step): ...@@ -120,18 +123,18 @@ class CalculateTagRevision(Step):
# Don't include the version change commit itself if there is no upper # Don't include the version change commit itself if there is no upper
# limit yet. # limit yet.
candidate_svn = str(int(candidate_svn) + 1) candidate_svn = str(int(candidate_svn) + 1)
next_svn = sys.maxint next_svn = sys.maxsize
lkgr_svn = self.LastLKGR(candidate_svn, next_svn) lkgr_svn = self.LastLKGR(candidate_svn, next_svn)
if not lkgr_svn: if not lkgr_svn:
print "There is no lkgr since the candidate version yet." print("There is no lkgr since the candidate version yet.")
self.CommonCleanup() self.CommonCleanup()
return True return True
# Let's check if the lkgr is at least three hours old. # Let's check if the lkgr is at least three hours old.
self["lkgr"] = self.vc.SvnGit(lkgr_svn) self["lkgr"] = self.vc.SvnGit(lkgr_svn)
if not self["lkgr"]: if not self["lkgr"]:
print "Couldn't find git hash for lkgr %s" % lkgr_svn print("Couldn't find git hash for lkgr %s" % lkgr_svn)
self.CommonCleanup() self.CommonCleanup()
return True return True
...@@ -139,11 +142,11 @@ class CalculateTagRevision(Step): ...@@ -139,11 +142,11 @@ class CalculateTagRevision(Step):
current_utc_time = self._side_effect_handler.GetUTCStamp() current_utc_time = self._side_effect_handler.GetUTCStamp()
if current_utc_time < lkgr_utc_time + 10800: if current_utc_time < lkgr_utc_time + 10800:
print "Candidate lkgr %s is too recent for tagging." % lkgr_svn print("Candidate lkgr %s is too recent for tagging." % lkgr_svn)
self.CommonCleanup() self.CommonCleanup()
return True return True
print "Tagging revision %s with %s" % (lkgr_svn, self["candidate_version"]) print("Tagging revision %s with %s" % (lkgr_svn, self["candidate_version"]))
class MakeTag(Step): class MakeTag(Step):
...@@ -172,7 +175,7 @@ class AutoTag(ScriptsBase): ...@@ -172,7 +175,7 @@ class AutoTag(ScriptsBase):
def _ProcessOptions(self, options): # pragma: no cover def _ProcessOptions(self, options): # pragma: no cover
if not options.dry_run and not options.author: if not options.dry_run and not options.author:
print "Specify your chromium.org email with -a" print("Specify your chromium.org email with -a")
return False return False
options.wait_for_lgtm = False options.wait_for_lgtm = False
options.force_readline_defaults = True options.force_readline_defaults = True
......
...@@ -13,6 +13,8 @@ written to public logs. Public automated callers of this script should ...@@ -13,6 +13,8 @@ written to public logs. Public automated callers of this script should
suppress stdout and stderr and only process contents of the results_file. suppress stdout and stderr and only process contents of the results_file.
""" """
# for py2/py3 compatibility
from __future__ import print_function
import argparse import argparse
import httplib import httplib
...@@ -222,7 +224,7 @@ def Main(): ...@@ -222,7 +224,7 @@ def Main():
with open(options.results_file, "w") as f: with open(options.results_file, "w") as f:
f.write(json.dumps(results)) f.write(json.dumps(results))
else: else:
print results print(results)
if __name__ == "__main__": if __name__ == "__main__":
......
...@@ -26,6 +26,9 @@ ...@@ -26,6 +26,9 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# for py2/py3 compatibility
from __future__ import print_function
import argparse import argparse
import datetime import datetime
import httplib import httplib
...@@ -199,8 +202,8 @@ def Command(cmd, args="", prefix="", pipe=True, cwd=None): ...@@ -199,8 +202,8 @@ def Command(cmd, args="", prefix="", pipe=True, cwd=None):
cwd = cwd or os.getcwd() cwd = cwd or os.getcwd()
# TODO(machenbach): Use timeout. # TODO(machenbach): Use timeout.
cmd_line = "%s %s %s" % (prefix, cmd, args) cmd_line = "%s %s %s" % (prefix, cmd, args)
print "Command: %s" % cmd_line print("Command: %s" % cmd_line)
print "in %s" % cwd print("in %s" % cwd)
sys.stdout.flush() sys.stdout.flush()
try: try:
if pipe: if pipe:
...@@ -272,8 +275,8 @@ class SideEffectHandler(object): # pragma: no cover ...@@ -272,8 +275,8 @@ class SideEffectHandler(object): # pragma: no cover
try: try:
return json.loads(data) return json.loads(data)
except: except:
print data print(data)
print "ERROR: Could not read response. Is your key valid?" print("ERROR: Could not read response. Is your key valid?")
raise raise
def Sleep(self, seconds): def Sleep(self, seconds):
...@@ -448,7 +451,7 @@ class Step(GitRecipesMixin): ...@@ -448,7 +451,7 @@ class Step(GitRecipesMixin):
if not self._state and os.path.exists(state_file): if not self._state and os.path.exists(state_file):
self._state.update(json.loads(FileToText(state_file))) self._state.update(json.loads(FileToText(state_file)))
print ">>> Step %d: %s" % (self._number, self._text) print(">>> Step %d: %s" % (self._number, self._text))
try: try:
return self.RunStep() return self.RunStep()
finally: finally:
...@@ -484,16 +487,16 @@ class Step(GitRecipesMixin): ...@@ -484,16 +487,16 @@ class Step(GitRecipesMixin):
raise Exception("Retried too often. Giving up. Reason: %s" % raise Exception("Retried too often. Giving up. Reason: %s" %
str(got_exception)) str(got_exception))
wait_time = wait_plan.pop() wait_time = wait_plan.pop()
print "Waiting for %f seconds." % wait_time print("Waiting for %f seconds." % wait_time)
self._side_effect_handler.Sleep(wait_time) self._side_effect_handler.Sleep(wait_time)
print "Retrying..." print("Retrying...")
else: else:
return result return result
def ReadLine(self, default=None): def ReadLine(self, default=None):
# Don't prompt in forced mode. # Don't prompt in forced mode.
if self._options.force_readline_defaults and default is not None: if self._options.force_readline_defaults and default is not None:
print "%s (forced)" % default print("%s (forced)" % default)
return default return default
else: else:
return self._side_effect_handler.ReadLine() return self._side_effect_handler.ReadLine()
...@@ -529,8 +532,8 @@ class Step(GitRecipesMixin): ...@@ -529,8 +532,8 @@ class Step(GitRecipesMixin):
def Die(self, msg=""): def Die(self, msg=""):
if msg != "": if msg != "":
print "Error: %s" % msg print("Error: %s" % msg)
print "Exiting" print("Exiting")
raise Exception(msg) raise Exception(msg)
def DieNoManualMode(self, msg=""): def DieNoManualMode(self, msg=""):
...@@ -539,7 +542,7 @@ class Step(GitRecipesMixin): ...@@ -539,7 +542,7 @@ class Step(GitRecipesMixin):
self.Die(msg) self.Die(msg)
def Confirm(self, msg): def Confirm(self, msg):
print "%s [Y/n] " % msg, print("%s [Y/n] " % msg, end=' ')
answer = self.ReadLine(default="Y") answer = self.ReadLine(default="Y")
return answer == "" or answer == "Y" or answer == "y" return answer == "" or answer == "Y" or answer == "y"
...@@ -549,7 +552,7 @@ class Step(GitRecipesMixin): ...@@ -549,7 +552,7 @@ class Step(GitRecipesMixin):
msg = "Branch %s exists, do you want to delete it?" % name msg = "Branch %s exists, do you want to delete it?" % name
if self.Confirm(msg): if self.Confirm(msg):
self.GitDeleteBranch(name, cwd=cwd) self.GitDeleteBranch(name, cwd=cwd)
print "Branch %s deleted." % name print("Branch %s deleted." % name)
else: else:
msg = "Can't continue. Please delete branch %s and try again." % name msg = "Can't continue. Please delete branch %s and try again." % name
self.Die(msg) self.Die(msg)
...@@ -612,10 +615,10 @@ class Step(GitRecipesMixin): ...@@ -612,10 +615,10 @@ class Step(GitRecipesMixin):
"change the headline of the uploaded CL.") "change the headline of the uploaded CL.")
answer = "" answer = ""
while answer != "LGTM": while answer != "LGTM":
print "> ", print("> ", end=' ')
answer = self.ReadLine(None if self._options.wait_for_lgtm else "LGTM") answer = self.ReadLine(None if self._options.wait_for_lgtm else "LGTM")
if answer != "LGTM": if answer != "LGTM":
print "That was not 'LGTM'." print("That was not 'LGTM'.")
def WaitForResolvingConflicts(self, patch_file): def WaitForResolvingConflicts(self, patch_file):
print("Applying the patch \"%s\" failed. Either type \"ABORT<Return>\", " print("Applying the patch \"%s\" failed. Either type \"ABORT<Return>\", "
...@@ -627,8 +630,8 @@ class Step(GitRecipesMixin): ...@@ -627,8 +630,8 @@ class Step(GitRecipesMixin):
if answer == "ABORT": if answer == "ABORT":
self.Die("Applying the patch failed.") self.Die("Applying the patch failed.")
if answer != "": if answer != "":
print "That was not 'RESOLVED' or 'ABORT'." print("That was not 'RESOLVED' or 'ABORT'.")
print "> ", print("> ", end=' ')
answer = self.ReadLine() answer = self.ReadLine()
# Takes a file containing the patch to apply as first argument. # Takes a file containing the patch to apply as first argument.
...@@ -769,16 +772,18 @@ class UploadStep(Step): ...@@ -769,16 +772,18 @@ class UploadStep(Step):
def RunStep(self): def RunStep(self):
reviewer = None reviewer = None
if self._options.reviewer: if self._options.reviewer:
print "Using account %s for review." % self._options.reviewer print("Using account %s for review." % self._options.reviewer)
reviewer = self._options.reviewer reviewer = self._options.reviewer
tbr_reviewer = None tbr_reviewer = None
if self._options.tbr_reviewer: if self._options.tbr_reviewer:
print "Using account %s for TBR review." % self._options.tbr_reviewer print("Using account %s for TBR review." % self._options.tbr_reviewer)
tbr_reviewer = self._options.tbr_reviewer tbr_reviewer = self._options.tbr_reviewer
if not reviewer and not tbr_reviewer: if not reviewer and not tbr_reviewer:
print "Please enter the email address of a V8 reviewer for your patch: ", print(
"Please enter the email address of a V8 reviewer for your patch: ",
end=' ')
self.DieNoManualMode("A reviewer must be specified in forced mode.") self.DieNoManualMode("A reviewer must be specified in forced mode.")
reviewer = self.ReadLine() reviewer = self.ReadLine()
...@@ -854,7 +859,7 @@ class ScriptsBase(object): ...@@ -854,7 +859,7 @@ class ScriptsBase(object):
# Process common options. # Process common options.
if options.step < 0: # pragma: no cover if options.step < 0: # pragma: no cover
print "Bad step number %d" % options.step print("Bad step number %d" % options.step)
parser.print_help() parser.print_help()
return None return None
......
...@@ -3,6 +3,9 @@ ...@@ -3,6 +3,9 @@
# Use of this source code is governed by a BSD-style license that can be # Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file. # found in the LICENSE file.
# for py2/py3 compatibility
from __future__ import print_function
import argparse import argparse
import os import os
import sys import sys
...@@ -27,7 +30,7 @@ class PrepareBranchRevision(Step): ...@@ -27,7 +30,7 @@ class PrepareBranchRevision(Step):
self["push_hash"] = (self._options.revision or self["push_hash"] = (self._options.revision or
self.GitLog(n=1, format="%H", branch="origin/master")) self.GitLog(n=1, format="%H", branch="origin/master"))
assert self["push_hash"] assert self["push_hash"]
print "Release revision %s" % self["push_hash"] print("Release revision %s" % self["push_hash"])
class IncrementVersion(Step): class IncrementVersion(Step):
...@@ -138,7 +141,7 @@ class PushBranchRef(Step): ...@@ -138,7 +141,7 @@ class PushBranchRef(Step):
def RunStep(self): def RunStep(self):
cmd = "push origin %s:refs/heads/%s" % (self["push_hash"], self["version"]) cmd = "push origin %s:refs/heads/%s" % (self["push_hash"], self["version"])
if self._options.dry_run: if self._options.dry_run:
print "Dry run. Command:\ngit %s" % cmd print("Dry run. Command:\ngit %s" % cmd)
else: else:
self.Git(cmd) self.Git(cmd)
...@@ -216,7 +219,7 @@ class LandBranch(Step): ...@@ -216,7 +219,7 @@ class LandBranch(Step):
def RunStep(self): def RunStep(self):
if self._options.dry_run: if self._options.dry_run:
print "Dry run - upload CL." print("Dry run - upload CL.")
else: else:
self.GitUpload(force=True, self.GitUpload(force=True,
bypass_hooks=True, bypass_hooks=True,
...@@ -224,7 +227,7 @@ class LandBranch(Step): ...@@ -224,7 +227,7 @@ class LandBranch(Step):
message_file=self.Config("COMMITMSG_FILE")) message_file=self.Config("COMMITMSG_FILE"))
cmd = "cl land --bypass-hooks -f" cmd = "cl land --bypass-hooks -f"
if self._options.dry_run: if self._options.dry_run:
print "Dry run. Command:\ngit %s" % cmd print("Dry run. Command:\ngit %s" % cmd)
else: else:
self.Git(cmd) self.Git(cmd)
...@@ -270,7 +273,7 @@ class CreateRelease(ScriptsBase): ...@@ -270,7 +273,7 @@ class CreateRelease(ScriptsBase):
def _ProcessOptions(self, options): # pragma: no cover def _ProcessOptions(self, options): # pragma: no cover
if not options.author or not options.reviewer: if not options.author or not options.reviewer:
print "Reviewer (-r) and author (-a) are required." print("Reviewer (-r) and author (-a) are required.")
return False return False
return True return True
......
...@@ -26,6 +26,9 @@ ...@@ -26,6 +26,9 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# for py2/py3 compatibility
from __future__ import print_function
import argparse import argparse
from collections import OrderedDict from collections import OrderedDict
import sys import sys
...@@ -186,10 +189,10 @@ class CleanUp(Step): ...@@ -186,10 +189,10 @@ class CleanUp(Step):
def RunStep(self): def RunStep(self):
self.CommonCleanup() self.CommonCleanup()
print "*** SUMMARY ***" print("*** SUMMARY ***")
print "branch: %s" % self["merge_to_branch"] print("branch: %s" % self["merge_to_branch"])
if self["revision_list"]: if self["revision_list"]:
print "patches: %s" % self["revision_list"] print("patches: %s" % self["revision_list"])
class MergeToBranch(ScriptsBase): class MergeToBranch(ScriptsBase):
...@@ -215,10 +218,10 @@ class MergeToBranch(ScriptsBase): ...@@ -215,10 +218,10 @@ class MergeToBranch(ScriptsBase):
def _ProcessOptions(self, options): def _ProcessOptions(self, options):
if len(options.revisions) < 1: if len(options.revisions) < 1:
if not options.patch: if not options.patch:
print "Either a patch file or revision numbers must be specified" print("Either a patch file or revision numbers must be specified")
return False return False
if not options.message: if not options.message:
print "You must specify a merge comment if no patches are specified" print("You must specify a merge comment if no patches are specified")
return False return False
options.bypass_upload_hooks = True options.bypass_upload_hooks = True
# CC ulan to make sure that fixes are merged to Google3. # CC ulan to make sure that fixes are merged to Google3.
...@@ -233,8 +236,8 @@ class MergeToBranch(ScriptsBase): ...@@ -233,8 +236,8 @@ class MergeToBranch(ScriptsBase):
for revision in options.revisions: for revision in options.revisions:
if (IsSvnNumber(revision) or if (IsSvnNumber(revision) or
(revision[0:1] == "r" and IsSvnNumber(revision[1:]))): (revision[0:1] == "r" and IsSvnNumber(revision[1:]))):
print "Please provide full git hashes of the patches to merge." print("Please provide full git hashes of the patches to merge.")
print "Got: %s" % revision print("Got: %s" % revision)
return False return False
return True return True
......
...@@ -3,6 +3,9 @@ ...@@ -3,6 +3,9 @@
# Use of this source code is governed by a BSD-style license that can be # Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file. # found in the LICENSE file.
# for py2/py3 compatibility
from __future__ import print_function
import argparse import argparse
import os import os
import sys import sys
...@@ -77,32 +80,32 @@ def get_first_v8_version(branches): ...@@ -77,32 +80,32 @@ def get_first_v8_version(branches):
return version return version
def print_analysis(git_working_dir, hash_to_search): def print_analysis(git_working_dir, hash_to_search):
print '1.) Searching for "' + hash_to_search + '"' print('1.) Searching for "' + hash_to_search + '"')
print '=====================ORIGINAL COMMIT START===================' print('=====================ORIGINAL COMMIT START===================')
print describe_commit(git_working_dir, hash_to_search) print(describe_commit(git_working_dir, hash_to_search))
print '=====================ORIGINAL COMMIT END=====================' print('=====================ORIGINAL COMMIT END=====================')
print '2.) General information:' print('2.) General information:')
branches = get_branches_for_commit(git_working_dir, hash_to_search) branches = get_branches_for_commit(git_working_dir, hash_to_search)
print 'Is LKGR: ' + str(is_lkgr(branches)) print('Is LKGR: ' + str(is_lkgr(branches)))
print 'Is on Canary: ' + str(get_first_canary(branches)) print('Is on Canary: ' + str(get_first_canary(branches)))
print 'First V8 branch: ' + str(get_first_v8_version(branches)) + \ print('First V8 branch: ' + str(get_first_v8_version(branches)) + \
' (Might not be the rolled version)' ' (Might not be the rolled version)')
print '3.) Found follow-up commits, reverts and ports:' print('3.) Found follow-up commits, reverts and ports:')
followups = get_followup_commits(git_working_dir, hash_to_search) followups = get_followup_commits(git_working_dir, hash_to_search)
for followup in followups: for followup in followups:
print describe_commit(git_working_dir, followup, True) print(describe_commit(git_working_dir, followup, True))
print '4.) Found merges:' print('4.) Found merges:')
merges = get_merge_commits(git_working_dir, hash_to_search) merges = get_merge_commits(git_working_dir, hash_to_search)
for currentMerge in merges: for currentMerge in merges:
print describe_commit(git_working_dir, currentMerge, True) print(describe_commit(git_working_dir, currentMerge, True))
print '---Merged to:' print('---Merged to:')
mergeOutput = git_execute(git_working_dir, ['branch', mergeOutput = git_execute(git_working_dir, ['branch',
'--contains', '--contains',
currentMerge, currentMerge,
'-r']).strip() '-r']).strip()
print mergeOutput print(mergeOutput)
print 'Finished successfully' print('Finished successfully')
if __name__ == '__main__': # pragma: no cover if __name__ == '__main__': # pragma: no cover
parser = argparse.ArgumentParser('Tool to check where a git commit was' parser = argparse.ArgumentParser('Tool to check where a git commit was'
......
...@@ -26,6 +26,9 @@ ...@@ -26,6 +26,9 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# for py2/py3 compatibility
from __future__ import print_function
import argparse import argparse
import os import os
import sys import sys
...@@ -46,7 +49,7 @@ class Preparation(Step): ...@@ -46,7 +49,7 @@ class Preparation(Step):
if(self["current_branch"] == self.Config("CANDIDATESBRANCH") if(self["current_branch"] == self.Config("CANDIDATESBRANCH")
or self["current_branch"] == self.Config("BRANCHNAME")): or self["current_branch"] == self.Config("BRANCHNAME")):
print "Warning: Script started on branch %s" % self["current_branch"] print("Warning: Script started on branch %s" % self["current_branch"])
self.PrepareBranch() self.PrepareBranch()
self.DeleteBranch(self.Config("CANDIDATESBRANCH")) self.DeleteBranch(self.Config("CANDIDATESBRANCH"))
...@@ -347,10 +350,10 @@ class PushToCandidates(ScriptsBase): ...@@ -347,10 +350,10 @@ class PushToCandidates(ScriptsBase):
def _ProcessOptions(self, options): # pragma: no cover def _ProcessOptions(self, options): # pragma: no cover
if not options.manual and not options.reviewer: if not options.manual and not options.reviewer:
print "A reviewer (-r) is required in (semi-)automatic mode." print("A reviewer (-r) is required in (semi-)automatic mode.")
return False return False
if not options.manual and not options.author: if not options.manual and not options.author:
print "Specify your chromium.org email with -a in (semi-)automatic mode." print("Specify your chromium.org email with -a in (semi-)automatic mode.")
return False return False
options.tbr_commit = not options.manual options.tbr_commit = not options.manual
......
...@@ -26,6 +26,9 @@ ...@@ -26,6 +26,9 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# for py2/py3 compatibility
from __future__ import print_function
import argparse import argparse
from collections import OrderedDict from collections import OrderedDict
import sys import sys
...@@ -202,7 +205,7 @@ class TagRevision(Step): ...@@ -202,7 +205,7 @@ class TagRevision(Step):
MESSAGE = "Create the tag." MESSAGE = "Create the tag."
def RunStep(self): def RunStep(self):
print "Creating tag %s" % self["version"] print("Creating tag %s" % self["version"])
self.vc.Tag(self["version"], self.vc.Tag(self["version"],
self.vc.RemoteBranch(self["merge_to_branch"]), self.vc.RemoteBranch(self["merge_to_branch"]),
self["commit_title"]) self["commit_title"])
...@@ -213,11 +216,11 @@ class CleanUp(Step): ...@@ -213,11 +216,11 @@ class CleanUp(Step):
def RunStep(self): def RunStep(self):
self.CommonCleanup() self.CommonCleanup()
print "*** SUMMARY ***" print("*** SUMMARY ***")
print "version: %s" % self["version"] print("version: %s" % self["version"])
print "branch: %s" % self["merge_to_branch"] print("branch: %s" % self["merge_to_branch"])
if self["revision_list"]: if self["revision_list"]:
print "patches: %s" % self["revision_list"] print("patches: %s" % self["revision_list"])
class RollMerge(ScriptsBase): class RollMerge(ScriptsBase):
...@@ -241,10 +244,10 @@ class RollMerge(ScriptsBase): ...@@ -241,10 +244,10 @@ class RollMerge(ScriptsBase):
def _ProcessOptions(self, options): def _ProcessOptions(self, options):
if len(options.revisions) < 1: if len(options.revisions) < 1:
if not options.patch: if not options.patch:
print "Either a patch file or revision numbers must be specified" print("Either a patch file or revision numbers must be specified")
return False return False
if not options.message: if not options.message:
print "You must specify a merge comment if no patches are specified" print("You must specify a merge comment if no patches are specified")
return False return False
options.bypass_upload_hooks = True options.bypass_upload_hooks = True
# CC ulan to make sure that fixes are merged to Google3. # CC ulan to make sure that fixes are merged to Google3.
...@@ -254,8 +257,8 @@ class RollMerge(ScriptsBase): ...@@ -254,8 +257,8 @@ class RollMerge(ScriptsBase):
for revision in options.revisions: for revision in options.revisions:
if (IsSvnNumber(revision) or if (IsSvnNumber(revision) or
(revision[0:1] == "r" and IsSvnNumber(revision[1:]))): (revision[0:1] == "r" and IsSvnNumber(revision[1:]))):
print "Please provide full git hashes of the patches to merge." print("Please provide full git hashes of the patches to merge.")
print "Got: %s" % revision print("Got: %s" % revision)
return False return False
return True return True
......
...@@ -29,6 +29,9 @@ ...@@ -29,6 +29,9 @@
# Wraps test execution with a coverage analysis. To get the best speed, the # Wraps test execution with a coverage analysis. To get the best speed, the
# native python coverage version >= 3.7.1 should be installed. # native python coverage version >= 3.7.1 should be installed.
# for py2/py3 compatibility
from __future__ import print_function
import coverage import coverage
import os import os
import unittest import unittest
...@@ -46,7 +49,7 @@ def Main(argv): ...@@ -46,7 +49,7 @@ def Main(argv):
]) ])
unittest.TextTestRunner(verbosity=2).run(unittest.TestSuite(alltests)) unittest.TextTestRunner(verbosity=2).run(unittest.TestSuite(alltests))
cov.stop() cov.stop()
print cov.report() print(cov.report())
if __name__ == '__main__': if __name__ == '__main__':
......
...@@ -3,6 +3,9 @@ ...@@ -3,6 +3,9 @@
# Use of this source code is governed by a BSD-style license that can be # Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file. # found in the LICENSE file.
# for py2/py3 compatibility
from __future__ import print_function
import argparse import argparse
import operator import operator
import os import os
...@@ -17,7 +20,7 @@ def search_all_related_commits( ...@@ -17,7 +20,7 @@ def search_all_related_commits(
all_commits_raw = _find_commits_inbetween( all_commits_raw = _find_commits_inbetween(
start_hash, until, git_working_dir, verbose) start_hash, until, git_working_dir, verbose)
if verbose: if verbose:
print "All commits between <of> and <until>: " + all_commits_raw print("All commits between <of> and <until>: " + all_commits_raw)
# Adding start hash too # Adding start hash too
all_commits = [start_hash] all_commits = [start_hash]
...@@ -61,7 +64,7 @@ def _search_related_commits( ...@@ -61,7 +64,7 @@ def _search_related_commits(
commit_position = matches.group(2) commit_position = matches.group(2)
if verbose: if verbose:
print "1.) Commit position to look for: " + commit_position print("1.) Commit position to look for: " + commit_position)
search_range = start_hash + ".." + until search_range = start_hash + ".." + until
...@@ -78,13 +81,13 @@ def _search_related_commits( ...@@ -78,13 +81,13 @@ def _search_related_commits(
git_working_dir, git_args(start_hash), verbose).strip() git_working_dir, git_args(start_hash), verbose).strip()
if verbose: if verbose:
print "2.) Found by hash: " + found_by_hash print("2.) Found by hash: " + found_by_hash)
found_by_commit_pos = git_execute( found_by_commit_pos = git_execute(
git_working_dir, git_args(commit_position), verbose).strip() git_working_dir, git_args(commit_position), verbose).strip()
if verbose: if verbose:
print "3.) Found by commit position: " + found_by_commit_pos print("3.) Found by commit position: " + found_by_commit_pos)
# Replace brackets or else they are wrongly interpreted by --grep # Replace brackets or else they are wrongly interpreted by --grep
title = title.replace("[", "\\[") title = title.replace("[", "\\[")
...@@ -94,7 +97,7 @@ def _search_related_commits( ...@@ -94,7 +97,7 @@ def _search_related_commits(
git_working_dir, git_args(title), verbose).strip() git_working_dir, git_args(title), verbose).strip()
if verbose: if verbose:
print "4.) Found by title: " + found_by_title print("4.) Found by title: " + found_by_title)
hits = ( hits = (
_convert_to_array(found_by_hash) + _convert_to_array(found_by_hash) +
...@@ -132,8 +135,8 @@ def _remove_duplicates(array): ...@@ -132,8 +135,8 @@ def _remove_duplicates(array):
def git_execute(working_dir, args, verbose=False): def git_execute(working_dir, args, verbose=False):
command = ["git", "-C", working_dir] + args command = ["git", "-C", working_dir] + args
if verbose: if verbose:
print "Git working dir: " + working_dir print("Git working dir: " + working_dir)
print "Executing git command:" + str(command) print("Executing git command:" + str(command))
p = Popen(args=command, stdin=PIPE, p = Popen(args=command, stdin=PIPE,
stdout=PIPE, stderr=PIPE) stdout=PIPE, stderr=PIPE)
output, err = p.communicate() output, err = p.communicate()
...@@ -141,7 +144,7 @@ def git_execute(working_dir, args, verbose=False): ...@@ -141,7 +144,7 @@ def git_execute(working_dir, args, verbose=False):
if rc != 0: if rc != 0:
raise Exception(err) raise Exception(err)
if verbose: if verbose:
print "Git return value: " + output print("Git return value: " + output)
return output return output
def _pretty_print_entry(hash, git_dir, pre_text, verbose): def _pretty_print_entry(hash, git_dir, pre_text, verbose):
...@@ -215,4 +218,4 @@ if __name__ == "__main__": # pragma: no cover ...@@ -215,4 +218,4 @@ if __name__ == "__main__": # pragma: no cover
args = sys.argv[1:] args = sys.argv[1:]
options = parser.parse_args(args) options = parser.parse_args(args)
for current_line in main(options): for current_line in main(options):
print current_line print(current_line)
...@@ -26,6 +26,9 @@ ...@@ -26,6 +26,9 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# for py2/py3 compatibility
from __future__ import print_function
import os import os
import shutil import shutil
import tempfile import tempfile
...@@ -383,11 +386,11 @@ class ScriptTest(unittest.TestCase): ...@@ -383,11 +386,11 @@ class ScriptTest(unittest.TestCase):
return script(TEST_CONFIG, self, self._state).RunSteps([step_class], args) return script(TEST_CONFIG, self, self._state).RunSteps([step_class], args)
def Call(self, fun, *args, **kwargs): def Call(self, fun, *args, **kwargs):
print "Calling %s with %s and %s" % (str(fun), str(args), str(kwargs)) print("Calling %s with %s and %s" % (str(fun), str(args), str(kwargs)))
def Command(self, cmd, args="", prefix="", pipe=True, cwd=None): def Command(self, cmd, args="", prefix="", pipe=True, cwd=None):
print "%s %s" % (cmd, args) print("%s %s" % (cmd, args))
print "in %s" % cwd print("in %s" % cwd)
return self._mock.Call("command", cmd + " " + args, cwd=cwd) return self._mock.Call("command", cmd + " " + args, cwd=cwd)
def ReadLine(self): def ReadLine(self):
......
...@@ -4,6 +4,9 @@ ...@@ -4,6 +4,9 @@
# Use of this source code is governed by a BSD-style license that can be # Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file. # found in the LICENSE file.
# for py2/py3 compatibility
from __future__ import print_function
import json import json
import multiprocessing import multiprocessing
import optparse import optparse
...@@ -376,29 +379,29 @@ def main(): ...@@ -376,29 +379,29 @@ def main():
options.build_folder = DetectBuildFolder() options.build_folder = DetectBuildFolder()
if not CheckClangTidy(): if not CheckClangTidy():
print 'Could not find clang-tidy' print('Could not find clang-tidy')
elif options.build_folder is None or not os.path.isdir(options.build_folder): elif options.build_folder is None or not os.path.isdir(options.build_folder):
print 'Please provide a build folder with -b' print('Please provide a build folder with -b')
elif options.gen_compdb: elif options.gen_compdb:
GenerateCompileCommands(options.build_folder) GenerateCompileCommands(options.build_folder)
elif not CheckCompDB(options.build_folder): elif not CheckCompDB(options.build_folder):
print 'Could not find compilation database, ' \ print('Could not find compilation database, ' \
'please generate it with --gen-compdb' 'please generate it with --gen-compdb')
else: else:
print 'Using build folder:', options.build_folder print('Using build folder:', options.build_folder)
if options.full: if options.full:
print 'Running clang-tidy - full' print('Running clang-tidy - full')
ClangTidyRunFull(options.build_folder, ClangTidyRunFull(options.build_folder,
options.no_output_filter, options.no_output_filter,
options.checks, options.checks,
options.auto_fix) options.auto_fix)
elif options.aggregate: elif options.aggregate:
print 'Running clang-tidy - aggregating warnings' print('Running clang-tidy - aggregating warnings')
if options.auto_fix: if options.auto_fix:
print 'Auto fix not working in aggregate mode, running without.' print('Auto fix not working in aggregate mode, running without.')
ClangTidyRunAggregate(options.build_folder, options.show_loc) ClangTidyRunAggregate(options.build_folder, options.show_loc)
elif options.single: elif options.single:
print 'Running clang-tidy - single on ' + options.file_name print('Running clang-tidy - single on ' + options.file_name)
if options.file_name is not None: if options.file_name is not None:
line_ranges = [] line_ranges = []
for match in re.findall(r'(\[.*?\])', options.line_ranges): for match in re.findall(r'(\[.*?\])', options.line_ranges):
...@@ -409,9 +412,9 @@ def main(): ...@@ -409,9 +412,9 @@ def main():
options.auto_fix, options.auto_fix,
line_ranges) line_ranges)
else: else:
print 'Filename provided, please specify a filename with --file' print('Filename provided, please specify a filename with --file')
else: else:
print 'Running clang-tidy' print('Running clang-tidy')
ClangTidyRunDiff(options.build_folder, ClangTidyRunDiff(options.build_folder,
options.diff_branch, options.diff_branch,
options.auto_fix) options.auto_fix)
......
...@@ -99,6 +99,10 @@ Path pieces are concatenated. D8 is always run with the suite's path as cwd. ...@@ -99,6 +99,10 @@ Path pieces are concatenated. D8 is always run with the suite's path as cwd.
The test flags are passed to the js test file after '--'. The test flags are passed to the js test file after '--'.
""" """
# for py2/py3 compatibility
from __future__ import print_function
from functools import reduce
from collections import OrderedDict from collections import OrderedDict
import json import json
import logging import logging
...@@ -114,6 +118,11 @@ from testrunner.local import android ...@@ -114,6 +118,11 @@ from testrunner.local import android
from testrunner.local import command from testrunner.local import command
from testrunner.local import utils from testrunner.local import utils
try:
basestring # Python 2
except NameError: # Python 3
basestring = str
ARCH_GUESS = utils.DefaultArch() ARCH_GUESS = utils.DefaultArch()
SUPPORTED_ARCHS = ["arm", SUPPORTED_ARCHS = ["arm",
"ia32", "ia32",
...@@ -1074,7 +1083,7 @@ def Main(args): ...@@ -1074,7 +1083,7 @@ def Main(args):
def Runner(): def Runner():
"""Output generator that reruns several times.""" """Output generator that reruns several times."""
total_runs = runnable.run_count * options.run_count_multiplier total_runs = runnable.run_count * options.run_count_multiplier
for i in xrange(0, max(1, total_runs)): for i in range(0, max(1, total_runs)):
# TODO(machenbach): Allow timeout per arch like with run_count per # TODO(machenbach): Allow timeout per arch like with run_count per
# arch. # arch.
try: try:
...@@ -1092,12 +1101,12 @@ def Main(args): ...@@ -1092,12 +1101,12 @@ def Main(args):
if options.json_test_results: if options.json_test_results:
results.WriteToFile(options.json_test_results) results.WriteToFile(options.json_test_results)
else: # pragma: no cover else: # pragma: no cover
print results print(results)
if options.json_test_results_secondary: if options.json_test_results_secondary:
results_secondary.WriteToFile(options.json_test_results_secondary) results_secondary.WriteToFile(options.json_test_results_secondary)
else: # pragma: no cover else: # pragma: no cover
print results_secondary print(results_secondary)
if results.errors or have_failed_tests[0]: if results.errors or have_failed_tests[0]:
return 1 return 1
......
...@@ -39,6 +39,10 @@ directory. It's not checked out by default and must be added as a custom deps: ...@@ -39,6 +39,10 @@ directory. It's not checked out by default and must be added as a custom deps:
'https://chromium.googlesource.com/external/llvm.org/compiler-rt.git' 'https://chromium.googlesource.com/external/llvm.org/compiler-rt.git'
""" """
# for py2/py3 compatibility
from __future__ import print_function
from functools import reduce
import argparse import argparse
import json import json
import logging import logging
...@@ -426,26 +430,26 @@ def main(args=None): ...@@ -426,26 +430,26 @@ def main(args=None):
options.build_dir = os.path.abspath(options.build_dir) options.build_dir = os.path.abspath(options.build_dir)
if options.action.lower() == 'all': if options.action.lower() == 'all':
if not options.json_output: if not options.json_output:
print '--json-output is required' print('--json-output is required')
return 1 return 1
write_instrumented(options) write_instrumented(options)
elif options.action.lower() == 'merge': elif options.action.lower() == 'merge':
if not options.coverage_dir: if not options.coverage_dir:
print '--coverage-dir is required' print('--coverage-dir is required')
return 1 return 1
if not options.json_input: if not options.json_input:
print '--json-input is required' print('--json-input is required')
return 1 return 1
if not options.json_output: if not options.json_output:
print '--json-output is required' print('--json-output is required')
return 1 return 1
merge(options) merge(options)
elif options.action.lower() == 'split': elif options.action.lower() == 'split':
if not options.json_input: if not options.json_input:
print '--json-input is required' print('--json-input is required')
return 1 return 1
if not options.output_dir: if not options.output_dir:
print '--output-dir is required' print('--output-dir is required')
return 1 return 1
split(options) split(options)
return 0 return 0
......
...@@ -106,7 +106,7 @@ def generate_inputs(keep, coverage_dir, file_map, cpus): ...@@ -106,7 +106,7 @@ def generate_inputs(keep, coverage_dir, file_map, cpus):
n = max(2, int(math.ceil(len(files) / float(cpus)))) n = max(2, int(math.ceil(len(files) / float(cpus))))
# Chop files into buckets. # Chop files into buckets.
buckets = [files[i:i+n] for i in xrange(0, len(files), n)] buckets = [files[i:i+n] for i in range(0, len(files), n)]
# Inputs for multiprocessing. List of tuples containing: # Inputs for multiprocessing. List of tuples containing:
# Keep-files option, base path, executable name, index of bucket, # Keep-files option, base path, executable name, index of bucket,
......
...@@ -5,7 +5,10 @@ ...@@ -5,7 +5,10 @@
"""Corrects objdump output. The logic is from sancov.py, see comments there.""" """Corrects objdump output. The logic is from sancov.py, see comments there."""
import sys; # for py2/py3 compatibility
from __future__ import print_function
import sys
for line in sys.stdin: for line in sys.stdin:
print '0x%x' % (int(line.strip(), 16) + 4) print('0x%x' % (int(line.strip(), 16) + 4))
...@@ -34,6 +34,9 @@ The stats viewer reads counters from a binary file and displays them ...@@ -34,6 +34,9 @@ The stats viewer reads counters from a binary file and displays them
in a window, re-reading and re-displaying with regular intervals. in a window, re-reading and re-displaying with regular intervals.
""" """
# for py2/py3 compatibility
from __future__ import print_function
import mmap import mmap
import optparse import optparse
import os import os
...@@ -100,7 +103,7 @@ class StatsViewer(object): ...@@ -100,7 +103,7 @@ class StatsViewer(object):
if not os.path.exists(self.data_name): if not os.path.exists(self.data_name):
maps_name = "/proc/%s/maps" % self.data_name maps_name = "/proc/%s/maps" % self.data_name
if not os.path.exists(maps_name): if not os.path.exists(maps_name):
print "\"%s\" is neither a counter file nor a PID." % self.data_name print("\"%s\" is neither a counter file nor a PID." % self.data_name)
sys.exit(1) sys.exit(1)
maps_file = open(maps_name, "r") maps_file = open(maps_name, "r")
try: try:
...@@ -110,7 +113,7 @@ class StatsViewer(object): ...@@ -110,7 +113,7 @@ class StatsViewer(object):
self.data_name = m.group(0) self.data_name = m.group(0)
break break
if self.data_name is None: if self.data_name is None:
print "Can't find counter file in maps for PID %s." % self.data_name print("Can't find counter file in maps for PID %s." % self.data_name)
sys.exit(1) sys.exit(1)
finally: finally:
maps_file.close() maps_file.close()
...@@ -123,7 +126,7 @@ class StatsViewer(object): ...@@ -123,7 +126,7 @@ class StatsViewer(object):
return CounterCollection(data_access) return CounterCollection(data_access)
elif data_access.IntAt(0) == CHROME_COUNTERS_FILE_MAGIC_NUMBER: elif data_access.IntAt(0) == CHROME_COUNTERS_FILE_MAGIC_NUMBER:
return ChromeCounterCollection(data_access) return ChromeCounterCollection(data_access)
print "File %s is not stats data." % self.data_name print("File %s is not stats data." % self.data_name)
sys.exit(1) sys.exit(1)
def CleanUp(self): def CleanUp(self):
...@@ -143,7 +146,7 @@ class StatsViewer(object): ...@@ -143,7 +146,7 @@ class StatsViewer(object):
self.RefreshCounters() self.RefreshCounters()
changed = True changed = True
else: else:
for i in xrange(self.data.CountersInUse()): for i in range(self.data.CountersInUse()):
counter = self.data.Counter(i) counter = self.data.Counter(i)
name = counter.Name() name = counter.Name()
if name in self.ui_counters: if name in self.ui_counters:
...@@ -188,7 +191,7 @@ class StatsViewer(object): ...@@ -188,7 +191,7 @@ class StatsViewer(object):
sorted by prefix. sorted by prefix.
""" """
names = {} names = {}
for i in xrange(self.data.CountersInUse()): for i in range(self.data.CountersInUse()):
counter = self.data.Counter(i) counter = self.data.Counter(i)
name = counter.Name() name = counter.Name()
names[name] = counter names[name] = counter
...@@ -233,7 +236,7 @@ class StatsViewer(object): ...@@ -233,7 +236,7 @@ class StatsViewer(object):
text=counter_name) text=counter_name)
name.grid(row=index, column=0, padx=1, pady=1) name.grid(row=index, column=0, padx=1, pady=1)
count = len(counter_objs) count = len(counter_objs)
for i in xrange(count): for i in range(count):
counter = counter_objs[i] counter = counter_objs[i]
name = counter.Name() name = counter.Name()
var = Tkinter.StringVar() var = Tkinter.StringVar()
...@@ -435,7 +438,7 @@ class ChromeCounterCollection(object): ...@@ -435,7 +438,7 @@ class ChromeCounterCollection(object):
def CountersInUse(self): def CountersInUse(self):
"""Return the number of counters in active use.""" """Return the number of counters in active use."""
for i in xrange(self.max_counters): for i in range(self.max_counters):
name_offset = self.counter_names_offset + i * self._COUNTER_NAME_SIZE name_offset = self.counter_names_offset + i * self._COUNTER_NAME_SIZE
if self.data.ByteAt(name_offset) == 0: if self.data.ByteAt(name_offset) == 0:
return i return i
......
...@@ -6,6 +6,9 @@ ...@@ -6,6 +6,9 @@
"""This program either generates the parser files for Torque, generating """This program either generates the parser files for Torque, generating
the source and header files directly in V8's src directory.""" the source and header files directly in V8's src directory."""
# for py2/py3 compatibility
from __future__ import print_function
import subprocess import subprocess
import sys import sys
import re import re
...@@ -96,13 +99,13 @@ def process(filename, lint, should_format): ...@@ -96,13 +99,13 @@ def process(filename, lint, should_format):
output, err = p.communicate(preprocess(content)) output, err = p.communicate(preprocess(content))
output = postprocess(output) output = postprocess(output)
rc = p.returncode rc = p.returncode
if (rc <> 0): if (rc != 0):
print "error code " + str(rc) + " running clang-format. Exiting..." print("error code " + str(rc) + " running clang-format. Exiting...")
sys.exit(rc); sys.exit(rc);
if lint: if lint:
if (output != original_input): if (output != original_input):
print >>sys.stderr, filename + ' requires formatting' print(filename + ' requires formatting', file=sys.stderr)
if should_format: if should_format:
output_file = open(filename, 'w') output_file = open(filename, 'w')
...@@ -110,14 +113,14 @@ def process(filename, lint, should_format): ...@@ -110,14 +113,14 @@ def process(filename, lint, should_format):
output_file.close() output_file.close()
def print_usage(): def print_usage():
print 'format-torque -i file1[, file2[, ...]]' print('format-torque -i file1[, file2[, ...]]')
print ' format and overwrite input files' print(' format and overwrite input files')
print 'format-torque -l file1[, file2[, ...]]' print('format-torque -l file1[, file2[, ...]]')
print ' merely indicate which files need formatting' print(' merely indicate which files need formatting')
def Main(): def Main():
if len(sys.argv) < 3: if len(sys.argv) < 3:
print "error: at least 2 arguments required" print("error: at least 2 arguments required")
print_usage(); print_usage();
sys.exit(-1) sys.exit(-1)
...@@ -137,7 +140,7 @@ def Main(): ...@@ -137,7 +140,7 @@ def Main():
lint = True lint = True
should_format = True should_format = True
else: else:
print "error: -i and/or -l flags must be specified" print("error: -i and/or -l flags must be specified")
print_usage(); print_usage();
sys.exit(-1); sys.exit(-1);
......
...@@ -23,7 +23,7 @@ result = subprocess.call(cargs) ...@@ -23,7 +23,7 @@ result = subprocess.call(cargs)
os.chdir(cwd) os.chdir(cwd)
def fix_file(filename): def fix_file(filename):
is_header = re.search(r'\.h', filename) <> None; is_header = re.search(r'\.h', filename) is not None;
header_macro = filename.upper(); header_macro = filename.upper();
header_macro = re.sub('\.', '_', header_macro); header_macro = re.sub('\.', '_', header_macro);
header_macro = "V8_TORQUE_" + header_macro + '_'; header_macro = "V8_TORQUE_" + header_macro + '_';
......
...@@ -3,6 +3,9 @@ ...@@ -3,6 +3,9 @@
# Use of this source code is governed by a BSD-style license that can be # Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file. # found in the LICENSE file.
# for py2/py3 compatibility
from __future__ import print_function
import sys import sys
...@@ -169,4 +172,4 @@ elif action == "count": ...@@ -169,4 +172,4 @@ elif action == "count":
reasons_list.append("%8d %s" % (reasons[r], r)) reasons_list.append("%8d %s" % (reasons[r], r))
reasons_list.sort(reverse=True) reasons_list.sort(reverse=True)
for r in reasons_list[:20]: for r in reasons_list[:20]:
print r print(r)
...@@ -3,6 +3,9 @@ ...@@ -3,6 +3,9 @@
# Use of this source code is governed by a BSD-style license that can be # Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file. # found in the LICENSE file.
# for py2/py3 compatibility
from __future__ import print_function
import argparse import argparse
import os import os
import subprocess import subprocess
...@@ -67,11 +70,11 @@ def main(): ...@@ -67,11 +70,11 @@ def main():
help='Add %s trybot.' % BOTS[option]) help='Add %s trybot.' % BOTS[option])
options = parser.parse_args() options = parser.parse_args()
if not options.bots: if not options.bots:
print 'No trybots specified. Using default %s.' % ','.join(DEFAULT_BOTS) print('No trybots specified. Using default %s.' % ','.join(DEFAULT_BOTS))
options.bots = DEFAULT_BOTS options.bots = DEFAULT_BOTS
if not options.benchmarks: if not options.benchmarks:
print 'Please specify the benchmarks to run as arguments.' print('Please specify the benchmarks to run as arguments.')
return 1 return 1
for benchmark in options.benchmarks: for benchmark in options.benchmarks:
...@@ -79,7 +82,7 @@ def main(): ...@@ -79,7 +82,7 @@ def main():
print ('%s not found in our benchmark list. The respective trybot might ' print ('%s not found in our benchmark list. The respective trybot might '
'fail, unless you run something this script isn\'t aware of. ' 'fail, unless you run something this script isn\'t aware of. '
'Available public benchmarks: %s' % (benchmark, PUBLIC_BENCHMARKS)) 'Available public benchmarks: %s' % (benchmark, PUBLIC_BENCHMARKS))
print 'Proceed anyways? [Y/n] ', print('Proceed anyways? [Y/n] ', end=' ')
answer = sys.stdin.readline().strip() answer = sys.stdin.readline().strip()
if answer != "" and answer != "Y" and answer != "y": if answer != "" and answer != "Y" and answer != "y":
return 1 return 1
...@@ -100,7 +103,7 @@ def main(): ...@@ -100,7 +103,7 @@ def main():
cmd += ['-p \'extra_flags="%s"\'' % options.extra_flags] cmd += ['-p \'extra_flags="%s"\'' % options.extra_flags]
if options.verbose: if options.verbose:
cmd.append('-vv') cmd.append('-vv')
print 'Running %s' % ' '.join(cmd) print('Running %s' % ' '.join(cmd))
subprocess.check_call(' '.join(cmd), shell=True, cwd=V8_BASE) subprocess.check_call(' '.join(cmd), shell=True, cwd=V8_BASE)
if __name__ == '__main__': # pragma: no cover if __name__ == '__main__': # pragma: no cover
......
...@@ -2,6 +2,9 @@ ...@@ -2,6 +2,9 @@
# Use of this source code is governed by a BSD-style license that can be # Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file. # found in the LICENSE file.
# for py2/py3 compatibility
from __future__ import print_function
import os import os
import sys import sys
import json import json
...@@ -25,7 +28,7 @@ def trace_begin(): ...@@ -25,7 +28,7 @@ def trace_begin():
known_addrs.add(result.group(0)) known_addrs.add(result.group(0))
def trace_end(): def trace_end():
print json.dumps(json_obj) print(json.dumps(json_obj))
def process_event(param_dict): def process_event(param_dict):
addr = "0x%x" % int(param_dict['sample']['ip']) addr = "0x%x" % int(param_dict['sample']['ip'])
......
...@@ -3,6 +3,9 @@ ...@@ -3,6 +3,9 @@
# Use of this source code is governed by a BSD-style license that can be # Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file. # found in the LICENSE file.
# for py2/py3 compatibility
from __future__ import print_function
from collections import namedtuple from collections import namedtuple
import coverage import coverage
import json import json
...@@ -103,8 +106,8 @@ class PerfTest(unittest.TestCase): ...@@ -103,8 +106,8 @@ class PerfTest(unittest.TestCase):
@classmethod @classmethod
def tearDownClass(cls): def tearDownClass(cls):
cls._cov.stop() cls._cov.stop()
print "" print("")
print cls._cov.report() print(cls._cov.report())
def setUp(self): def setUp(self):
self.maxDiff = None self.maxDiff = None
......
...@@ -17,6 +17,9 @@ with different test suite extensions and build configurations. ...@@ -17,6 +17,9 @@ with different test suite extensions and build configurations.
# TODO(machenbach): Coverage data from multiprocessing doesn't work. # TODO(machenbach): Coverage data from multiprocessing doesn't work.
# TODO(majeski): Add some tests for the fuzzers. # TODO(majeski): Add some tests for the fuzzers.
# for py2/py3 compatibility
from __future__ import print_function
import collections import collections
import contextlib import contextlib
import json import json
...@@ -126,7 +129,7 @@ class SystemTest(unittest.TestCase): ...@@ -126,7 +129,7 @@ class SystemTest(unittest.TestCase):
import coverage import coverage
if int(coverage.__version__.split('.')[0]) < 4: if int(coverage.__version__.split('.')[0]) < 4:
cls._cov = None cls._cov = None
print 'Python coverage version >= 4 required.' print('Python coverage version >= 4 required.')
raise ImportError() raise ImportError()
cls._cov = coverage.Coverage( cls._cov = coverage.Coverage(
source=([os.path.join(TOOLS_ROOT, 'testrunner')]), source=([os.path.join(TOOLS_ROOT, 'testrunner')]),
...@@ -142,7 +145,7 @@ class SystemTest(unittest.TestCase): ...@@ -142,7 +145,7 @@ class SystemTest(unittest.TestCase):
cls._cov.exclude('assert False') cls._cov.exclude('assert False')
cls._cov.start() cls._cov.start()
except ImportError: except ImportError:
print 'Running without python coverage.' print('Running without python coverage.')
sys.path.append(TOOLS_ROOT) sys.path.append(TOOLS_ROOT)
global standard_runner global standard_runner
from testrunner import standard_runner from testrunner import standard_runner
...@@ -157,8 +160,8 @@ class SystemTest(unittest.TestCase): ...@@ -157,8 +160,8 @@ class SystemTest(unittest.TestCase):
def tearDownClass(cls): def tearDownClass(cls):
if cls._cov: if cls._cov:
cls._cov.stop() cls._cov.stop()
print '' print('')
print cls._cov.report(show_missing=True) print(cls._cov.report(show_missing=True))
def testPass(self): def testPass(self):
"""Test running only passing tests in two variants. """Test running only passing tests in two variants.
......
...@@ -3,5 +3,8 @@ ...@@ -3,5 +3,8 @@
# Use of this source code is governed by a BSD-style license that can be # Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file. # found in the LICENSE file.
print 'Richards: 1.2' # for py2/py3 compatibility
print 'DeltaBlue: 2.1' from __future__ import print_function
print('Richards: 1.2')
print('DeltaBlue: 2.1')
...@@ -3,8 +3,11 @@ ...@@ -3,8 +3,11 @@
# Use of this source code is governed by a BSD-style license that can be # Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file. # found in the LICENSE file.
print 'Richards1: 1' # for py2/py3 compatibility
print 'DeltaBlue1: 1' from __future__ import print_function
print 'Richards2: 0.2'
print 'DeltaBlue2: 1.0' print('Richards1: 1')
print 'DeltaBlue3: 0.1' print('DeltaBlue1: 1')
print('Richards2: 0.2')
print('DeltaBlue2: 1.0')
print('DeltaBlue3: 0.1')
...@@ -3,22 +3,25 @@ ...@@ -3,22 +3,25 @@
# Use of this source code is governed by a BSD-style license that can be # Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file. # found in the LICENSE file.
# for py2/py3 compatibility
from __future__ import print_function
import sys import sys
assert len(sys.argv) == 3 assert len(sys.argv) == 3
if sys.argv[1] == 'equal': if sys.argv[1] == 'equal':
# 1. Scenario: print equal allocation hashes. # 1. Scenario: print equal allocation hashes.
print '### Allocations = 9497, hash = 0xc322c6b0' print('### Allocations = 9497, hash = 0xc322c6b0')
elif sys.argv[1] == 'differ': elif sys.argv[1] == 'differ':
# 2. Scenario: print different allocation hashes. This prints a different # 2. Scenario: print different allocation hashes. This prints a different
# hash on the second run, based on the content of a semaphore file. This # hash on the second run, based on the content of a semaphore file. This
# file is expected to be empty in the beginning. # file is expected to be empty in the beginning.
with open(sys.argv[2]) as f: with open(sys.argv[2]) as f:
if f.read(): if f.read():
print '### Allocations = 9497, hash = 0xc322c6b0' print('### Allocations = 9497, hash = 0xc322c6b0')
else: else:
print '### Allocations = 9497, hash = 0xc322c6b1' print('### Allocations = 9497, hash = 0xc322c6b1')
with open(sys.argv[2], 'w') as f: with open(sys.argv[2], 'w') as f:
f.write('something') f.write('something')
else: else:
......
...@@ -7,6 +7,9 @@ ...@@ -7,6 +7,9 @@
Fake results processor for testing that just sums some things up. Fake results processor for testing that just sums some things up.
""" """
# for py2/py3 compatibility
from __future__ import print_function
import fileinput import fileinput
import re import re
...@@ -21,5 +24,5 @@ for line in fileinput.input(): ...@@ -21,5 +24,5 @@ for line in fileinput.input():
if match: if match:
deltablue += float(match.group(1)) deltablue += float(match.group(1))
print 'Richards: %f' % richards print('Richards: %f' % richards)
print 'DeltaBlue: %f' % deltablue print('DeltaBlue: %f' % deltablue)
...@@ -6,10 +6,13 @@ ...@@ -6,10 +6,13 @@
Dummy d8 replacement. Just passes all test, except if 'berries' is in args. Dummy d8 replacement. Just passes all test, except if 'berries' is in args.
""" """
# for py2/py3 compatibility
from __future__ import print_function
import sys import sys
args = ' '.join(sys.argv[1:]) args = ' '.join(sys.argv[1:])
print args print(args)
# Let all berries fail. # Let all berries fail.
if 'berries' in args: if 'berries' in args:
sys.exit(1) sys.exit(1)
......
...@@ -6,12 +6,15 @@ ...@@ -6,12 +6,15 @@
Dummy d8 replacement for flaky tests. Dummy d8 replacement for flaky tests.
""" """
# for py2/py3 compatibility
from __future__ import print_function
import os import os
import sys import sys
PATH = os.path.dirname(os.path.abspath(__file__)) PATH = os.path.dirname(os.path.abspath(__file__))
print ' '.join(sys.argv[1:]) print(' '.join(sys.argv[1:]))
# Test files ending in 'flakes' should first fail then pass. We store state in # Test files ending in 'flakes' should first fail then pass. We store state in
# a file side by side with the executable. No clean-up required as all tests # a file side by side with the executable. No clean-up required as all tests
......
#!/usr/bin/env python3 #!/usr/bin/env python3
# Copyright 2018 the V8 project authors. All rights reserved. # Copyright 2018 the V8 project authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be # Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file. # found in the LICENSE file.
......
...@@ -27,10 +27,14 @@ ...@@ -27,10 +27,14 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# for py2/py3 compatibility
from __future__ import print_function
try: try:
import hashlib import hashlib
md5er = hashlib.md5 md5er = hashlib.md5
except ImportError, e: except ImportError as e:
import md5 import md5
md5er = md5.new md5er = md5.new
...@@ -84,7 +88,7 @@ def CppLintWorker(command): ...@@ -84,7 +88,7 @@ def CppLintWorker(command):
out_line = process.stderr.readline() out_line = process.stderr.readline()
if out_line == '' and process.poll() != None: if out_line == '' and process.poll() != None:
if error_count == -1: if error_count == -1:
print "Failed to process %s" % command.pop() print("Failed to process %s" % command.pop())
return 1 return 1
break break
m = LINT_OUTPUT_PATTERN.match(out_line) m = LINT_OUTPUT_PATTERN.match(out_line)
...@@ -268,7 +272,7 @@ class CacheableSourceFileProcessor(SourceFileProcessor): ...@@ -268,7 +272,7 @@ class CacheableSourceFileProcessor(SourceFileProcessor):
files = cache.FilterUnchangedFiles(files) files = cache.FilterUnchangedFiles(files)
if len(files) == 0: if len(files) == 0:
print 'No changes in %s files detected. Skipping check' % self.file_type print('No changes in %s files detected. Skipping check' % self.file_type)
return True return True
files_requiring_changes = self.DetectFilesToChange(files) files_requiring_changes = self.DetectFilesToChange(files)
...@@ -293,7 +297,7 @@ class CacheableSourceFileProcessor(SourceFileProcessor): ...@@ -293,7 +297,7 @@ class CacheableSourceFileProcessor(SourceFileProcessor):
try: try:
results = pool.map_async(worker, commands).get(timeout=240) results = pool.map_async(worker, commands).get(timeout=240)
except KeyboardInterrupt: except KeyboardInterrupt:
print "\nCaught KeyboardInterrupt, terminating workers." print("\nCaught KeyboardInterrupt, terminating workers.")
pool.terminate() pool.terminate()
pool.join() pool.join()
sys.exit(1) sys.exit(1)
...@@ -487,12 +491,12 @@ class SourceProcessor(SourceFileProcessor): ...@@ -487,12 +491,12 @@ class SourceProcessor(SourceFileProcessor):
base = basename(name) base = basename(name)
if not base in SourceProcessor.IGNORE_TABS: if not base in SourceProcessor.IGNORE_TABS:
if '\t' in contents: if '\t' in contents:
print "%s contains tabs" % name print("%s contains tabs" % name)
result = False result = False
if not base in SourceProcessor.IGNORE_COPYRIGHTS and \ if not base in SourceProcessor.IGNORE_COPYRIGHTS and \
not SourceProcessor.IGNORE_COPYRIGHTS_DIRECTORY in name: not SourceProcessor.IGNORE_COPYRIGHTS_DIRECTORY in name:
if not COPYRIGHT_HEADER_PATTERN.search(contents): if not COPYRIGHT_HEADER_PATTERN.search(contents):
print "%s is missing a correct copyright header." % name print("%s is missing a correct copyright header." % name)
result = False result = False
if ' \n' in contents or contents.endswith(' '): if ' \n' in contents or contents.endswith(' '):
line = 0 line = 0
...@@ -505,34 +509,34 @@ class SourceProcessor(SourceFileProcessor): ...@@ -505,34 +509,34 @@ class SourceProcessor(SourceFileProcessor):
lines.append(str(line)) lines.append(str(line))
linenumbers = ', '.join(lines) linenumbers = ', '.join(lines)
if len(lines) > 1: if len(lines) > 1:
print "%s has trailing whitespaces in lines %s." % (name, linenumbers) print("%s has trailing whitespaces in lines %s." % (name, linenumbers))
else: else:
print "%s has trailing whitespaces in line %s." % (name, linenumbers) print("%s has trailing whitespaces in line %s." % (name, linenumbers))
result = False result = False
if not contents.endswith('\n') or contents.endswith('\n\n'): if not contents.endswith('\n') or contents.endswith('\n\n'):
print "%s does not end with a single new line." % name print("%s does not end with a single new line." % name)
result = False result = False
# Sanitize flags for fuzzer. # Sanitize flags for fuzzer.
if ".js" in name and ("mjsunit" in name or "debugger" in name): if ".js" in name and ("mjsunit" in name or "debugger" in name):
match = FLAGS_LINE.search(contents) match = FLAGS_LINE.search(contents)
if match: if match:
print "%s Flags should use '-' (not '_')" % name print("%s Flags should use '-' (not '_')" % name)
result = False result = False
if not "mjsunit/mjsunit.js" in name: if not "mjsunit/mjsunit.js" in name:
if ASSERT_OPTIMIZED_PATTERN.search(contents) and \ if ASSERT_OPTIMIZED_PATTERN.search(contents) and \
not FLAGS_ENABLE_OPT.search(contents): not FLAGS_ENABLE_OPT.search(contents):
print "%s Flag --opt should be set if " \ print("%s Flag --opt should be set if " \
"assertOptimized() is used" % name "assertOptimized() is used" % name)
result = False result = False
if ASSERT_UNOPTIMIZED_PATTERN.search(contents) and \ if ASSERT_UNOPTIMIZED_PATTERN.search(contents) and \
not FLAGS_NO_ALWAYS_OPT.search(contents): not FLAGS_NO_ALWAYS_OPT.search(contents):
print "%s Flag --no-always-opt should be set if " \ print("%s Flag --no-always-opt should be set if " \
"assertUnoptimized() is used" % name "assertUnoptimized() is used" % name)
result = False result = False
match = self.runtime_function_call_pattern.search(contents) match = self.runtime_function_call_pattern.search(contents)
if match: if match:
print "%s has unexpected spaces in a runtime call '%s'" % (name, match.group(1)) print("%s has unexpected spaces in a runtime call '%s'" % (name, match.group(1)))
result = False result = False
return result return result
...@@ -548,7 +552,7 @@ class SourceProcessor(SourceFileProcessor): ...@@ -548,7 +552,7 @@ class SourceProcessor(SourceFileProcessor):
violations += 1 violations += 1
finally: finally:
handle.close() handle.close()
print "Total violating files: %s" % violations print("Total violating files: %s" % violations)
return success return success
def _CheckStatusFileForDuplicateKeys(filepath): def _CheckStatusFileForDuplicateKeys(filepath):
...@@ -655,7 +659,7 @@ def PyTests(workspace): ...@@ -655,7 +659,7 @@ def PyTests(workspace):
join(workspace, 'tools', 'unittests', 'run_tests_test.py'), join(workspace, 'tools', 'unittests', 'run_tests_test.py'),
join(workspace, 'tools', 'testrunner', 'testproc', 'variant_unittest.py'), join(workspace, 'tools', 'testrunner', 'testproc', 'variant_unittest.py'),
]: ]:
print 'Running ' + script print('Running ' + script)
result &= subprocess.call( result &= subprocess.call(
[sys.executable, script], stdout=subprocess.PIPE) == 0 [sys.executable, script], stdout=subprocess.PIPE) == 0
...@@ -677,22 +681,22 @@ def Main(): ...@@ -677,22 +681,22 @@ def Main():
parser = GetOptions() parser = GetOptions()
(options, args) = parser.parse_args() (options, args) = parser.parse_args()
success = True success = True
print "Running checkdeps..." print("Running checkdeps...")
success &= CheckDeps(workspace) success &= CheckDeps(workspace)
use_linter_cache = not options.no_linter_cache use_linter_cache = not options.no_linter_cache
if not options.no_lint: if not options.no_lint:
print "Running C++ lint check..." print("Running C++ lint check...")
success &= CppLintProcessor(use_cache=use_linter_cache).RunOnPath(workspace) success &= CppLintProcessor(use_cache=use_linter_cache).RunOnPath(workspace)
print "Running Torque formatting check..." print("Running Torque formatting check...")
success &= TorqueLintProcessor(use_cache=use_linter_cache).RunOnPath( success &= TorqueLintProcessor(use_cache=use_linter_cache).RunOnPath(
workspace) workspace)
print "Running copyright header, trailing whitespaces and " \ print("Running copyright header, trailing whitespaces and " \
"two empty lines between declarations check..." "two empty lines between declarations check...")
success &= SourceProcessor().RunOnPath(workspace) success &= SourceProcessor().RunOnPath(workspace)
print "Running status-files check..." print("Running status-files check...")
success &= StatusFilesProcessor().RunOnPath(workspace) success &= StatusFilesProcessor().RunOnPath(workspace)
print "Running python tests..." print("Running python tests...")
success &= PyTests(workspace) success &= PyTests(workspace)
if success: if success:
return 0 return 0
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment