Skip to content

Commit

Permalink
Fix missing fuzz_target in build_manager (#4281)
Browse files Browse the repository at this point in the history
Co-authored-by: jonathanmetzman <[email protected]>
  • Loading branch information
paulsemel and jonathanmetzman authored Sep 30, 2024
1 parent e2c3d67 commit b284e12
Show file tree
Hide file tree
Showing 9 changed files with 30 additions and 16 deletions.
17 changes: 10 additions & 7 deletions src/clusterfuzz/_internal/bot/tasks/utasks/analyze_task.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,8 @@ def handle_analyze_no_revisions_list_error(output):
handle_build_setup_error(output)


def setup_build(testcase: data_types.Testcase,
bad_revisions) -> Optional[uworker_msg_pb2.Output]: # pylint: disable=no-member
def setup_build(testcase: data_types.Testcase, bad_revisions,
fuzz_target) -> Optional[uworker_msg_pb2.Output]: # pylint: disable=no-member
"""Set up a custom or regular build based on revision. For regular builds,
if a provided revision is not found, set up a build with the
closest revision <= provided revision."""
Expand All @@ -100,6 +100,7 @@ def setup_build(testcase: data_types.Testcase,
error_type=uworker_msg_pb2.ErrorType.ANALYZE_NO_REVISION_INDEX) # pylint: disable=no-member
revision = revision_list[revision_index]

fuzz_target = fuzz_target.binary if fuzz_target else None
build_manager.setup_build(revision)
return None

Expand Down Expand Up @@ -131,8 +132,8 @@ def prepare_env_for_main(testcase_upload_metadata):


def setup_testcase_and_build(
testcase, job_type, setup_input,
bad_revisions) -> (Optional[str], Optional[uworker_msg_pb2.Output]): # pylint: disable=no-member
testcase, job_type, setup_input, bad_revisions,
fuzz_target) -> (Optional[str], Optional[uworker_msg_pb2.Output]): # pylint: disable=no-member
"""Sets up the |testcase| and builds. Returns the path to the testcase on
success, None on error."""
# Set up testcase and get absolute testcase path.
Expand All @@ -142,7 +143,7 @@ def setup_testcase_and_build(
return None, error

# Set up build.
error = setup_build(testcase, bad_revisions)
error = setup_build(testcase, bad_revisions, fuzz_target)
if error:
return None, error

Expand Down Expand Up @@ -356,9 +357,12 @@ def utask_main(uworker_input):
# Creates empty local blacklist so all leaks will be visible to uploader.
leak_blacklist.create_empty_local_blacklist()

# TODO(metzman): Move this function outside of testcase_manager.
# Also, make it get the binary.
fuzz_target = testcase_manager.get_fuzz_target_from_input(uworker_input)
testcase_file_path, output = setup_testcase_and_build(
testcase, uworker_input.job_type, uworker_input.setup_input,
uworker_input.analyze_task_input.bad_revisions)
uworker_input.analyze_task_input.bad_revisions, fuzz_target)
testcase.crash_revision = environment.get_value('APP_REVISION')

if not testcase_file_path:
Expand All @@ -368,7 +372,6 @@ def utask_main(uworker_input):

# Initialize some variables.
test_timeout = environment.get_value('TEST_TIMEOUT')
fuzz_target = testcase_manager.get_fuzz_target_from_input(uworker_input)
result, http_flag = test_for_crash_with_retries(
fuzz_target, testcase, testcase_file_path, test_timeout)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -605,7 +605,8 @@ def do_corpus_pruning(uworker_input, context, revision):
from clusterfuzz._internal.bot.untrusted_runner import tasks_host
return tasks_host.do_corpus_pruning(uworker_input, context, revision)

if not build_manager.setup_build(revision=revision):
if not build_manager.setup_build(
revision=revision, fuzz_target=context.fuzz_target.binary):
raise CorpusPruningError('Failed to setup build.')

build_directory = environment.get_value('BUILD_DIR')
Expand Down
4 changes: 3 additions & 1 deletion src/clusterfuzz/_internal/bot/tasks/utasks/minimize_task.py
Original file line number Diff line number Diff line change
Expand Up @@ -422,7 +422,9 @@ def utask_main(uworker_input: uworker_msg_pb2.Input): # pylint: disable=no-memb
'last_tested_crash_revision')

crash_revision = last_tested_crash_revision or testcase.crash_revision
build_manager.setup_build(crash_revision)
fuzz_target = testcase_manager.get_fuzz_target_from_input(uworker_input)
fuzz_target = fuzz_target.binary if fuzz_target else None
build_manager.setup_build(crash_revision, fuzz_target)

# Check if we have an application path. If not, our build failed
# to setup correctly.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import time
from typing import Dict
from typing import List
from typing import Optional

from clusterfuzz._internal.base import bisection
from clusterfuzz._internal.base import errors
Expand Down Expand Up @@ -313,13 +314,14 @@ def _update_issue_metadata(testcase: data_types.Testcase, metadata: Dict):

def _testcase_reproduces_in_revision(
testcase: data_types.Testcase, testcase_file_path: str, job_type: str,
revision: int, fuzz_target: data_types.FuzzTarget,
revision: int, fuzz_target: Optional[data_types.FuzzTarget],
progression_task_output: uworker_msg_pb2.ProgressionTaskOutput): # pylint: disable=no-member
"""Tests to see if a test case reproduces in the specified revision.
Returns a tuple containing the (result, error) depending on whether
there was an error."""
try:
build_manager.setup_build(revision)
fuzz_target_binary = fuzz_target.binary if fuzz_target else None
build_manager.setup_build(revision, fuzz_target=fuzz_target_binary)
except errors.BuildNotFoundError as e:
# Build no longer exists, so we need to mark this testcase as invalid.
error_message = f'Build not found at r{e.revision}'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,8 @@ def _testcase_reproduces_in_revision(
log_message += ' (current range %d:%d)' % (min_revision, max_revision)
logs.info(log_message)

build_manager.setup_build(revision)
fuzz_target_binary = fuzz_target.binary if fuzz_target else None
build_manager.setup_build(revision, fuzz_target=fuzz_target_binary)
if not build_manager.check_app_path():
error_message = f'Build setup failed r{revision}'
return None, uworker_msg_pb2.Output(
Expand Down
4 changes: 3 additions & 1 deletion src/clusterfuzz/_internal/bot/tasks/utasks/symbolize_task.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,10 @@ def utask_main(uworker_input):
else:
build_revision = testcase.crash_revision

fuzz_target = testcase_manager.get_fuzz_target_from_input(uworker_input)
fuzz_target = fuzz_target.binary if fuzz_target else None
# Set up a custom or regular build based on revision.
build = build_manager.setup_build(build_revision)
build = build_manager.setup_build(build_revision, fuzz_target)

# Get crash revision used in setting up build.
crash_revision = environment.get_value('APP_REVISION')
Expand Down
4 changes: 3 additions & 1 deletion src/clusterfuzz/_internal/bot/tasks/utasks/variant_task.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,9 @@ def utask_main(uworker_input):
# Set up a custom or regular build. We explicitly omit the crash revision
# since we want to test against the latest build here.
try:
build_manager.setup_build()
fuzz_target = testcase_manager.get_fuzz_target_from_input(uworker_input)
fuzz_target = fuzz_target.binary if fuzz_target else None
build_manager.setup_build(fuzz_target=fuzz_target)
except errors.BuildNotFoundError:
logs.warning('Matching build not found.')
return uworker_msg_pb2.Output( # pylint: disable=no-member
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,8 @@ def test_field_setting(self):
os.environ['GN_ARGS_PATH'] = gn_args_path.name
gn_args_path.write(bytes(self.gn_args, 'utf-8'))
gn_args_path.seek(0)
result = analyze_task.setup_testcase_and_build(testcase, 'job', None, [])
result = analyze_task.setup_testcase_and_build(testcase, 'job', None, [],
None)
metadata = json.loads(testcase.additional_metadata)
self.assertEqual(metadata['gn_args'], self.gn_args)
self.assertEqual(result, (self.testcase_path, None))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ def tearDown(self):
shutil.rmtree(self.corpus_bucket, ignore_errors=True)
shutil.rmtree(self.local_gcs_buckets_path, ignore_errors=True)

def _mock_setup_build(self, revision=None):
def _mock_setup_build(self, revision=None, fuzz_target=None):
os.environ['BUILD_DIR'] = self.build_dir
return True

Expand Down

0 comments on commit b284e12

Please sign in to comment.