ed6a7173a1
As with other crashes, also SIGABRT cuts of execution earlier. While the reason might be interesting in normal fuzzing, in correctness fuzzing, it leads to spurious reports due to the output differences. No-Try: true Bug: chromium:1242193 Change-Id: I6ee9a8e2a0254255d02b0106575931b523fbf666 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3124808 Auto-Submit: Michael Achenbach <machenbach@chromium.org> Commit-Queue: Jakob Kummerow <jkummerow@chromium.org> Reviewed-by: Jakob Kummerow <jkummerow@chromium.org> Cr-Commit-Position: refs/heads/main@{#76569}
155 lines
4.0 KiB
Python
155 lines
4.0 KiB
Python
# Copyright 2016 the V8 project authors. All rights reserved.
|
|
# Use of this source code is governed by a BSD-style license that can be
|
|
# found in the LICENSE file.
|
|
|
|
# Fork from commands.py and output.py in v8 test driver.
|
|
|
|
import os
|
|
import signal
|
|
import subprocess
|
|
import sys
|
|
from threading import Event, Timer
|
|
|
|
import v8_fuzz_config
|
|
|
|
PYTHON3 = sys.version_info >= (3, 0)
|
|
|
|
# List of default flags passed to each d8 run.
|
|
DEFAULT_FLAGS = [
|
|
'--correctness-fuzzer-suppressions',
|
|
'--expose-gc',
|
|
'--fuzzing',
|
|
'--allow-natives-for-differential-fuzzing',
|
|
'--invoke-weak-callbacks',
|
|
'--omit-quit',
|
|
'--es-staging',
|
|
'--wasm-staging',
|
|
'--no-wasm-async-compilation',
|
|
'--suppress-asm-messages',
|
|
]
|
|
|
|
BASE_PATH = os.path.dirname(os.path.abspath(__file__))
|
|
|
|
# List of files passed to each d8 run before the testcase.
|
|
DEFAULT_MOCK = os.path.join(BASE_PATH, 'v8_mock.js')
|
|
|
|
# Suppressions on JavaScript level for known issues.
|
|
JS_SUPPRESSIONS = os.path.join(BASE_PATH, 'v8_suppressions.js')
|
|
|
|
# Config-specific mock files.
|
|
ARCH_MOCKS = os.path.join(BASE_PATH, 'v8_mock_archs.js')
|
|
WEBASSEMBLY_MOCKS = os.path.join(BASE_PATH, 'v8_mock_webassembly.js')
|
|
|
|
|
|
def _startup_files(options):
|
|
"""Default files and optional config-specific mock files."""
|
|
files = [DEFAULT_MOCK]
|
|
if not options.skip_suppressions:
|
|
files.append(JS_SUPPRESSIONS)
|
|
if options.first.arch != options.second.arch:
|
|
files.append(ARCH_MOCKS)
|
|
# Mock out WebAssembly when comparing with jitless mode.
|
|
if '--jitless' in options.first.flags + options.second.flags:
|
|
files.append(WEBASSEMBLY_MOCKS)
|
|
return files
|
|
|
|
|
|
class BaseException(Exception):
|
|
"""Used to abort the comparison workflow and print the given message."""
|
|
def __init__(self, message):
|
|
self.message = message
|
|
|
|
|
|
class PassException(BaseException):
|
|
"""Represents an early abort making the overall run pass."""
|
|
pass
|
|
|
|
|
|
class FailException(BaseException):
|
|
"""Represents an early abort making the overall run fail."""
|
|
pass
|
|
|
|
|
|
class Command(object):
|
|
"""Represents a configuration for running V8 multiple times with certain
|
|
flags and files.
|
|
"""
|
|
def __init__(self, options, label, executable, config_flags):
|
|
self.label = label
|
|
self.executable = executable
|
|
self.config_flags = config_flags
|
|
self.common_flags = DEFAULT_FLAGS[:]
|
|
self.common_flags.extend(['--random-seed', str(options.random_seed)])
|
|
|
|
self.files = _startup_files(options)
|
|
|
|
def run(self, testcase, timeout, verbose=False):
|
|
"""Run the executable with a specific testcase."""
|
|
args = [self.executable] + self.flags + self.files + [testcase]
|
|
if verbose:
|
|
print('# Command line for %s comparison:' % self.label)
|
|
print(' '.join(args))
|
|
if self.executable.endswith('.py'):
|
|
# Wrap with python in tests.
|
|
args = [sys.executable] + args
|
|
return Execute(
|
|
args,
|
|
cwd=os.path.dirname(os.path.abspath(testcase)),
|
|
timeout=timeout,
|
|
)
|
|
|
|
@property
|
|
def flags(self):
|
|
return self.common_flags + self.config_flags
|
|
|
|
|
|
class Output(object):
|
|
def __init__(self, exit_code, stdout, pid):
|
|
self.exit_code = exit_code
|
|
self.stdout = stdout
|
|
self.pid = pid
|
|
|
|
def HasCrashed(self):
|
|
return self.exit_code < 0
|
|
|
|
|
|
def Execute(args, cwd, timeout=None):
|
|
popen_args = [c for c in args if c != ""]
|
|
kwargs = {}
|
|
if PYTHON3:
|
|
kwargs['encoding'] = 'utf-8'
|
|
try:
|
|
process = subprocess.Popen(
|
|
args=popen_args,
|
|
stdout=subprocess.PIPE,
|
|
stderr=subprocess.PIPE,
|
|
cwd=cwd,
|
|
**kwargs
|
|
)
|
|
except Exception as e:
|
|
sys.stderr.write("Error executing: %s\n" % popen_args)
|
|
raise e
|
|
|
|
timeout_event = Event()
|
|
|
|
def kill_process():
|
|
timeout_event.set()
|
|
try:
|
|
process.kill()
|
|
except OSError:
|
|
sys.stderr.write('Error: Process %s already ended.\n' % process.pid)
|
|
|
|
timer = Timer(timeout, kill_process)
|
|
timer.start()
|
|
stdout, _ = process.communicate()
|
|
timer.cancel()
|
|
|
|
if timeout_event.is_set():
|
|
raise PassException('# V8 correctness - T-I-M-E-O-U-T')
|
|
|
|
return Output(
|
|
process.returncode,
|
|
stdout,
|
|
process.pid,
|
|
)
|