summaryrefslogtreecommitdiff
path: root/chromium/v8/tools/clusterfuzz/v8_foozzie.py
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2020-10-12 14:27:29 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2020-10-13 09:35:20 +0000
commitc30a6232df03e1efbd9f3b226777b07e087a1122 (patch)
treee992f45784689f373bcc38d1b79a239ebe17ee23 /chromium/v8/tools/clusterfuzz/v8_foozzie.py
parent7b5b123ac58f58ffde0f4f6e488bcd09aa4decd3 (diff)
downloadqtwebengine-chromium-85-based.tar.gz
BASELINE: Update Chromium to 85.0.4183.14085-based
Change-Id: Iaa42f4680837c57725b1344f108c0196741f6057 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/v8/tools/clusterfuzz/v8_foozzie.py')
-rwxr-xr-xchromium/v8/tools/clusterfuzz/v8_foozzie.py80
1 files changed, 69 insertions, 11 deletions
diff --git a/chromium/v8/tools/clusterfuzz/v8_foozzie.py b/chromium/v8/tools/clusterfuzz/v8_foozzie.py
index b6638cc3774..b3cb8cf94fa 100755
--- a/chromium/v8/tools/clusterfuzz/v8_foozzie.py
+++ b/chromium/v8/tools/clusterfuzz/v8_foozzie.py
@@ -94,6 +94,10 @@ RETURN_FAIL = 2
BASE_PATH = os.path.dirname(os.path.abspath(__file__))
SANITY_CHECKS = os.path.join(BASE_PATH, 'v8_sanity_checks.js')
+# Timeout for one d8 run.
+SANITY_CHECK_TIMEOUT_SEC = 1
+TEST_TIMEOUT_SEC = 3
+
SUPPORTED_ARCHS = ['ia32', 'x64', 'arm', 'arm64']
# Output for suppressed failure case.
@@ -143,6 +147,25 @@ ORIGINAL_SOURCE_HASH_LENGTH = 3
# Placeholder string if no original source file could be determined.
ORIGINAL_SOURCE_DEFAULT = 'none'
+# Placeholder string for failures from crash tests. If a failure is found with
+# this signature, the matching sources should be moved to the mapping below.
+ORIGINAL_SOURCE_CRASHTESTS = 'placeholder for CrashTests'
+
+# Mapping from relative original source path (e.g. CrashTests/path/to/file.js)
+# to a string key. Map to the same key for duplicate issues. The key should
+# have more than 3 characters to not collide with other existing hashes.
+# If a symptom from a particular original source file is known to map to a
+# known failure, it can be added to this mapping. This should be done for all
+# failures from CrashTests, as those by default map to the placeholder above.
+KNOWN_FAILURES = {
+ # Foo.caller with asm.js: https://crbug.com/1042556
+ 'CrashTests/5712410200899584/04483.js': '.caller',
+ 'CrashTests/5703451898085376/02176.js': '.caller',
+ 'CrashTests/4846282433495040/04342.js': '.caller',
+ # Flaky issue that almost never repros.
+ 'CrashTests/5694376231632896/1033966.js': 'flaky',
+}
+
def infer_arch(d8):
"""Infer the V8 architecture from the build configuration next to the
@@ -229,7 +252,7 @@ def parse_args():
options.first = first_config_arguments.make_options(options)
options.second = second_config_arguments.make_options(options)
- # Ensure we make a sane comparison.
+ # Ensure we make a valid comparison.
if (options.first.d8 == options.second.d8 and
options.first.config == options.second.config):
parser.error('Need either executable or config difference.')
@@ -292,6 +315,7 @@ def print_difference(
else:
first_stdout = first_config_output.stdout.decode('utf-8', 'replace')
second_stdout = second_config_output.stdout.decode('utf-8', 'replace')
+ difference = difference.decode('utf-8', 'replace')
text = (FAILURE_TEMPLATE % dict(
configs='%s:%s' % (first_config_label, second_config_label),
@@ -313,6 +337,31 @@ def print_difference(
print(text.encode('utf-8', 'replace'))
+def cluster_failures(source, known_failures=None):
+ """Returns a string key for clustering duplicate failures.
+
+ Args:
+ source: The original source path where the failure happened.
+ known_failures: Mapping from original source path to failure key.
+ """
+ known_failures = known_failures or KNOWN_FAILURES
+ # No source known. Typical for manually uploaded issues. This
+ # requires also manual issue creation.
+ if not source:
+ return ORIGINAL_SOURCE_DEFAULT
+ # Source is known to produce a particular failure.
+ if source in known_failures:
+ return known_failures[source]
+ # Subsume all other sources from CrashTests under one key. Otherwise
+ # failures lead to new crash tests which in turn lead to new failures.
+ if source.startswith('CrashTests'):
+ return ORIGINAL_SOURCE_CRASHTESTS
+
+ # We map all remaining failures to a short hash of the original source.
+ long_key = hashlib.sha1(source.encode('utf-8')).hexdigest()
+ return long_key[:ORIGINAL_SOURCE_HASH_LENGTH]
+
+
def main():
options = parse_args()
@@ -342,8 +391,20 @@ def main():
# Sanity checks. Run both configurations with the sanity-checks file only and
# bail out early if different.
if not options.skip_sanity_checks:
- first_config_output = first_cmd.run(SANITY_CHECKS)
- second_config_output = second_cmd.run(SANITY_CHECKS)
+ first_config_output = first_cmd.run(
+ SANITY_CHECKS, timeout=SANITY_CHECK_TIMEOUT_SEC)
+
+ # Early bailout if first run was a timeout.
+ if timeout_bailout(first_config_output, 1):
+ return RETURN_PASS
+
+ second_config_output = second_cmd.run(
+ SANITY_CHECKS, timeout=SANITY_CHECK_TIMEOUT_SEC)
+
+ # Bailout if second run was a timeout.
+ if timeout_bailout(second_config_output, 2):
+ return RETURN_PASS
+
difference, _ = suppress.diff(first_config_output, second_config_output)
if difference:
# Special source key for sanity checks so that clusterfuzz dedupes all
@@ -354,13 +415,15 @@ def main():
first_config_output, second_config_output, difference)
return RETURN_FAIL
- first_config_output = first_cmd.run(options.testcase, verbose=True)
+ first_config_output = first_cmd.run(
+ options.testcase, timeout=TEST_TIMEOUT_SEC, verbose=True)
# Early bailout if first run was a timeout.
if timeout_bailout(first_config_output, 1):
return RETURN_PASS
- second_config_output = second_cmd.run(options.testcase, verbose=True)
+ second_config_output = second_cmd.run(
+ options.testcase, timeout=TEST_TIMEOUT_SEC, verbose=True)
# Bailout if second run was a timeout.
if timeout_bailout(second_config_output, 2):
@@ -368,12 +431,6 @@ def main():
difference, source = suppress.diff(first_config_output, second_config_output)
- if source:
- long_key = hashlib.sha1(source.encode('utf-8')).hexdigest()
- source_key = long_key[:ORIGINAL_SOURCE_HASH_LENGTH]
- else:
- source_key = ORIGINAL_SOURCE_DEFAULT
-
if difference:
# Only bail out due to suppressed output if there was a difference. If a
# suppression doesn't show up anymore in the statistics, we might want to
@@ -383,6 +440,7 @@ def main():
if fail_bailout(second_config_output, suppress.ignore_by_output2):
return RETURN_FAIL
+ source_key = cluster_failures(source)
print_difference(
options, source_key, first_cmd, second_cmd,
first_config_output, second_config_output, difference, source)