Skip to content

Commit 7d7dd66

Browse files
authored
Improve fuzzing of Two (#8006)
1. We must be careful to not use randomness differently when the second file is provided (or else reductions can fail weirdly). 2. Automatically fuzz the second wasm when `BINARYEN_FIRST_WASM` is provided (which means the first is to be kept fixed). 4. Add some docs.
1 parent 6cb5010 commit 7d7dd66

1 file changed

Lines changed: 50 additions & 19 deletions

File tree

scripts/fuzz_opt.py

Lines changed: 50 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1786,32 +1786,54 @@ def ensure(self):
17861786
# Tests linking two wasm files at runtime, and that optimizations do not break
17871787
# anything. This is similar to Split(), but rather than split a wasm file into
17881788
# two and link them at runtime, this starts with two separate wasm files.
1789+
#
1790+
# Fuzzing failures here is a little trickier, as there are two wasm files.
1791+
# You can reduce the primary file by finding the secondary one in the log
1792+
# (usually out/test/second.wasm), copy that to the side, and add
1793+
#
1794+
# BINARYEN_SECOND_WASM=${saved_second}
1795+
#
1796+
# in the env. That will keep the secondary wasm fixed as you reduce the primary
1797+
# one.
1798+
#
1799+
# Note it may be better to reduce the second one first, so it imports less from
1800+
# the first (otherwise, when the second one imports many things, the first will
1801+
# fail to remove exports that are used). To reduce the second one, set
1802+
#
1803+
# BINARYEN_FIRST_WASM=${saved_first}
1804+
#
1805+
# The reduce.sh script will then do the right thing, using that as the first
1806+
# wasm, and reducing on the second one, if you replace "original.wasm" in the
1807+
# reduction command (the command that this fuzzer script recommended that you
1808+
# run) with "second.wasm" as needed.
1809+
#
1810+
# In both cases, make sure to copy the files to a saved location first (do not
1811+
# use a path to the scratch files that get constantly overwritten).
17891812
class Two(TestCaseHandler):
17901813
# Run at relatively high priority, as this is the main place we check cross-
17911814
# module interactions.
17921815
frequency = 1
17931816

17941817
def handle(self, wasm):
1795-
# Generate a second wasm file, unless we were given one (useful during
1796-
# reduction).
1818+
# Generate a second wasm file. (For fuzzing, we may be given one, but we
1819+
# still do the work to prepare to generate it, as that consumes random
1820+
# values, and we don't want that to affect anything later.)
17971821
second_wasm = abspath('second.wasm')
1822+
second_input = abspath('second_input.dat')
1823+
second_size = random_size()
1824+
make_random_input(second_size, second_input)
1825+
args = [second_input, '-ttf']
1826+
# Most of the time, use the first wasm as an import to the second.
1827+
if random.random() < 0.8:
1828+
args += ['--fuzz-import=' + wasm]
1829+
17981830
given = os.environ.get('BINARYEN_SECOND_WASM')
1799-
if given:
1800-
# TODO: should we de-nan this etc. as with the primary?
1801-
shutil.copyfile(given, second_wasm)
1831+
if not given:
1832+
print('Generate second wasm')
1833+
run([in_bin('wasm-opt'), '-o', second_wasm] + args + GEN_ARGS + FEATURE_OPTS)
18021834
else:
1803-
# generate a second wasm file to merge. pick a smaller size when
1804-
# the main wasm file is smaller, so reduction shrinks this too.
1805-
wasm_size = os.stat(wasm).st_size
1806-
second_size = min(wasm_size, random_size())
1807-
1808-
second_input = abspath('second_input.dat')
1809-
make_random_input(second_size, second_input)
1810-
args = [second_input, '-ttf', '-o', second_wasm]
1811-
# Most of the time, use the first wasm as an import to the second.
1812-
if random.random() < 0.8:
1813-
args += ['--fuzz-import=' + wasm]
1814-
run([in_bin('wasm-opt')] + args + GEN_ARGS + FEATURE_OPTS)
1835+
print(f'Use given second wasm {given}')
1836+
shutil.copyfile(given, second_wasm)
18151837

18161838
# Run the wasm.
18171839
#
@@ -2591,9 +2613,18 @@ def get_random_opts():
25912613
%(wasm_opt)s %(features)s %(temp_wasm)s
25922614
echo " " $?
25932615
2594-
# run the command
25952616
echo "The following value should be 1:"
2596-
./scripts/fuzz_opt.py %(auto_init)s --binaryen-bin %(bin)s %(seed)d %(temp_wasm)s > o 2> e
2617+
2618+
if [ -z "$BINARYEN_FIRST_WASM" ]; then
2619+
# run the command normally
2620+
./scripts/fuzz_opt.py %(auto_init)s --binaryen-bin %(bin)s %(seed)d %(temp_wasm)s > o 2> e
2621+
else
2622+
# BINARYEN_FIRST_WASM was provided so we should actually reduce the *second*
2623+
# file. pass the first one in as the main file, and use the env var for the
2624+
# second.
2625+
BINARYEN_SECOND_WASM=%(temp_wasm)s ./scripts/fuzz_opt.py %(auto_init)s --binaryen-bin %(bin)s %(seed)d $BINARYEN_FIRST_WASM > o 2> e
2626+
fi
2627+
25972628
echo " " $?
25982629
25992630
#

0 commit comments

Comments
 (0)