Skip to content

Commit bb193e4

Browse files
authored
Don't compare crash state for stack-overflow bugs. (#2620)
* Don't compare crash state for stack-overflow bugs. Fixes #2619. * fix reproduce_tool tests.
1 parent b64fb4d commit bb193e4

File tree

4 files changed

+53
-6
lines changed

4 files changed

+53
-6
lines changed

.pylintrc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ disable=
3939
raise-missing-from,
4040
super-with-arguments,
4141
use-a-generator,
42-
consider-using-generator
42+
consider-using-generator,
43+
consider-using-f-string # Too much legacy usages.
4344

4445
[BASIC]
4546

src/clusterfuzz/_internal/bot/testcase_manager.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,11 @@
7777
'logging service has stopped',
7878
]
7979

80+
# Flaky crash types for which crash comparison does not make sense.
81+
IGNORE_STATE_CRASH_TYPES = [
82+
'Stack-overflow',
83+
]
84+
8085

8186
class TestcaseManagerError(Exception):
8287
"""Base exception."""
@@ -198,7 +203,7 @@ def read_resource_list(resource_file_path):
198203

199204
resources = []
200205
base_directory = os.path.dirname(resource_file_path)
201-
with open(resource_file_path) as file_handle:
206+
with open(resource_file_path, encoding='utf-8') as file_handle:
202207
resource_file_contents = file_handle.read()
203208
for line in resource_file_contents.splitlines():
204209
resource = os.path.join(base_directory, line.strip())
@@ -773,7 +778,7 @@ def test_for_crash_with_retries(testcase,
773778
if crash_retries is None:
774779
crash_retries = environment.get_value('CRASH_RETRIES')
775780

776-
if compare_crash:
781+
if compare_crash and testcase.crash_type not in IGNORE_STATE_CRASH_TYPES:
777782
expected_state = testcase.crash_state
778783
expected_security_flag = testcase.security_flag
779784
else:

src/clusterfuzz/_internal/tests/core/bot/testcase_manager_test.py

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,8 @@ def test_create(self):
6464
'cc.txt',
6565
'aa/dd.txt',
6666
])
67-
actual_files_list = set(open(testcase_list_file_path).read().splitlines())
67+
actual_files_list = set(
68+
open(testcase_list_file_path, encoding='utf-8').read().splitlines())
6869
self.assertEqual(expected_files_list, actual_files_list)
6970

7071

@@ -601,6 +602,44 @@ def test_test_for_crash_with_retries_blackbox_succeed_no_comparison(self):
601602
mock.call('Crash stacktrace comparison skipped.')
602603
])
603604

605+
def test_test_for_crash_with_retries_blackbox_stack_overflow(self):
606+
"""Test test_for_crash_with_retries reproducing a Stack-overflow crash."""
607+
self.mock.run_process.side_effect = [
608+
(0, 0, 'output'),
609+
(1, 1, 'crash'),
610+
]
611+
612+
self.blackbox_testcase.crash_type = 'Stack-overflow'
613+
self.blackbox_testcase.put()
614+
615+
# compare_crash should be overridden to False.
616+
crash_result = testcase_manager.test_for_crash_with_retries(
617+
self.blackbox_testcase, '/fuzz-testcase', 10, compare_crash=True)
618+
self.assertEqual(1, crash_result.return_code)
619+
self.assertEqual(1, crash_result.crash_time)
620+
self.assertEqual('crash', crash_result.output)
621+
self.assertEqual(2, self.mock.run_process.call_count)
622+
623+
self.mock.run_process.assert_has_calls([
624+
mock.call(
625+
'/build_dir/app_name -arg1 -arg2',
626+
current_working_directory='/build_dir',
627+
gestures=[],
628+
timeout=120),
629+
mock.call(
630+
'/build_dir/app_name -arg1 -arg2',
631+
current_working_directory='/build_dir',
632+
gestures=[],
633+
timeout=10),
634+
])
635+
self.mock.log.assert_has_calls([
636+
mock.call('No crash occurred (round 1).', output='output'),
637+
mock.call(
638+
'Crash occurred in 1 seconds (round 2). State:\nstate',
639+
output='crash'),
640+
mock.call('Crash stacktrace comparison skipped.')
641+
])
642+
604643
def test_test_for_crash_with_retries_greybox_succeed(self):
605644
"""Test test_for_crash_with_retries reproducing a crash (greybox)."""
606645
mock_engine = mock.Mock()
@@ -672,7 +711,7 @@ def test_test_for_crash_with_retries_greybox_legacy(self):
672711
]
673712
self.mock.get.return_value = mock_engine
674713

675-
with open('/flags-testcase', 'w') as f:
714+
with open('/flags-testcase', 'w', encoding='utf-8') as f:
676715
f.write('%TESTCASE% target -arg1 -arg2')
677716

678717
testcase_manager.test_for_crash_with_retries(self.greybox_testcase,

src/clusterfuzz/_internal/tests/core/local/butler/reproduce_test.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
def _fake_get_echo_testcase(*_):
3434
"""Fake test case output intended to run "echo -n"."""
3535
testcase_map = {
36+
'crash_type': 'type',
3637
'crash_state': 'state',
3738
'security_flag': False,
3839
'gestures': [],
@@ -58,6 +59,7 @@ def _fake_get_echo_testcase(*_):
5859
def _fake_get_libfuzzer_testcase(*_):
5960
"""Fake test case output intended to run "echo -n"."""
6061
testcase_map = {
62+
'crash_type': 'type',
6163
'crash_state': 'state',
6264
'security_flag': False,
6365
'gestures': [],
@@ -122,7 +124,7 @@ def test_reproduce_with_echo(self):
122124
self.mock._get_testcase.side_effect = _fake_get_echo_testcase
123125

124126
binary_path = os.path.join(self.build_directory, 'echo')
125-
with open(binary_path, 'w') as f:
127+
with open(binary_path, 'w', encoding='utf-8') as f:
126128
f.write('test')
127129

128130
crash_retries = 3

0 commit comments

Comments
 (0)