aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--infra/bisector.py26
-rw-r--r--infra/build_specified_commit.py25
-rw-r--r--infra/build_specified_commit_test.py10
-rwxr-xr-xinfra/helper.py14
-rw-r--r--infra/repo_manager.py10
5 files changed, 60 insertions, 25 deletions
diff --git a/infra/bisector.py b/infra/bisector.py
index 5eb1e776..fdb078b3 100644
--- a/infra/bisector.py
+++ b/infra/bisector.py
@@ -32,6 +32,7 @@ This is done with the following steps:
import argparse
import logging
+import os
import tempfile
import build_specified_commit
@@ -42,6 +43,7 @@ import utils
def main():
"""Finds the commit SHA where an error was initally introduced."""
+ logging.getLogger().setLevel(logging.INFO)
utils.chdir_to_root()
parser = argparse.ArgumentParser(
description='git bisection for finding introduction of bugs')
@@ -90,7 +92,7 @@ def main():
return 0
-def bisect(old_commit, new_commit, test_case_path, fuzz_target, build_data):
+def bisect(old_commit, new_commit, test_case_path, fuzz_target, build_data): # pylint: disable=too-many-locals
"""From a commit range, this function caluclates which introduced a
specific error from a fuzz test_case_path.
@@ -108,27 +110,33 @@ def bisect(old_commit, new_commit, test_case_path, fuzz_target, build_data):
ValueError: when a repo url can't be determine from the project.
"""
with tempfile.TemporaryDirectory() as tmp_dir:
- repo_url, repo_name = build_specified_commit.detect_main_repo(
+ repo_url, repo_path = build_specified_commit.detect_main_repo(
build_data.project_name, commit=old_commit)
- if not repo_url or not repo_name:
+ if not repo_url or not repo_path:
raise ValueError('Main git repo can not be determined.')
- bisect_repo_manager = repo_manager.RepoManager(repo_url,
- tmp_dir,
- repo_name=repo_name)
+
+ host_src_dir = build_specified_commit.copy_src_from_docker(
+ build_data.project_name, tmp_dir)
+
+ bisect_repo_manager = repo_manager.RepoManager(
+ repo_url, host_src_dir, repo_name=os.path.basename(repo_path))
commit_list = bisect_repo_manager.get_commit_list(old_commit, new_commit)
old_idx = len(commit_list) - 1
new_idx = 0
+ logging.info('Testing against new_commit (%s)', commit_list[new_idx])
build_specified_commit.build_fuzzers_from_commit(commit_list[new_idx],
bisect_repo_manager,
- build_data)
+ host_src_dir, build_data)
expected_error_code = helper.reproduce_impl(build_data.project_name,
fuzz_target, False, [], [],
test_case_path)
# Check if the error is persistent through the commit range
+ logging.info('Testing against old_commit (%s)', commit_list[old_idx])
build_specified_commit.build_fuzzers_from_commit(
commit_list[old_idx],
bisect_repo_manager,
+ host_src_dir,
build_data,
)
@@ -139,9 +147,11 @@ def bisect(old_commit, new_commit, test_case_path, fuzz_target, build_data):
while old_idx - new_idx > 1:
curr_idx = (old_idx + new_idx) // 2
+ logging.info('Testing against %s (idx=%d)', commit_list[curr_idx],
+ curr_idx)
build_specified_commit.build_fuzzers_from_commit(commit_list[curr_idx],
bisect_repo_manager,
- build_data)
+ host_src_dir, build_data)
error_code = helper.reproduce_impl(build_data.project_name, fuzz_target,
False, [], [], test_case_path)
if expected_error_code == error_code:
diff --git a/infra/build_specified_commit.py b/infra/build_specified_commit.py
index 515dae24..f4134ab8 100644
--- a/infra/build_specified_commit.py
+++ b/infra/build_specified_commit.py
@@ -29,7 +29,25 @@ BuildData = collections.namedtuple(
'BuildData', ['project_name', 'engine', 'sanitizer', 'architecture'])
-def build_fuzzers_from_commit(commit, build_repo_manager, build_data):
+def copy_src_from_docker(project_name, host_dir):
+ """Copy /src from docker to the host."""
+ # Copy /src to host.
+ image_name = 'gcr.io/oss-fuzz/' + project_name
+ docker_args = [
+ '-v',
+ host_dir + ':/out',
+ image_name,
+ 'cp',
+ '-r',
+ '/src',
+ '/out',
+ ]
+ helper.docker_run(docker_args)
+ return os.path.join(host_dir, 'src')
+
+
+def build_fuzzers_from_commit(commit, build_repo_manager, host_src_path,
+ build_data):
"""Builds a OSS-Fuzz fuzzer at a specific commit SHA.
Args:
@@ -46,9 +64,8 @@ def build_fuzzers_from_commit(commit, build_repo_manager, build_data):
sanitizer=build_data.sanitizer,
architecture=build_data.architecture,
env_to_add=None,
- source_path=build_repo_manager.repo_dir,
- mount_location=os.path.join(
- '/src', build_repo_manager.repo_name))
+ source_path=host_src_path,
+ mount_location=os.path.join('/src'))
def detect_main_repo(project_name, repo_name=None, commit=None):
diff --git a/infra/build_specified_commit_test.py b/infra/build_specified_commit_test.py
index 9fdaae47..6f666856 100644
--- a/infra/build_specified_commit_test.py
+++ b/infra/build_specified_commit_test.py
@@ -44,8 +44,12 @@ class BuildImageIntegrationTests(unittest.TestCase):
with tempfile.TemporaryDirectory() as tmp_dir:
test_case = test_repos.TEST_REPOS[0]
+ self.assertTrue(helper.build_image_impl(test_case.project_name))
+ host_src_dir = build_specified_commit.copy_src_from_docker(
+ test_case.project_name, tmp_dir)
+
test_repo_manager = repo_manager.RepoManager(
- test_case.git_url, tmp_dir, repo_name=test_case.oss_repo_name)
+ test_case.git_url, host_src_dir, repo_name=test_case.oss_repo_name)
build_data = build_specified_commit.BuildData(
sanitizer='address',
architecture='x86_64',
@@ -54,13 +58,13 @@ class BuildImageIntegrationTests(unittest.TestCase):
build_specified_commit.build_fuzzers_from_commit(test_case.old_commit,
test_repo_manager,
- build_data)
+ host_src_dir, build_data)
old_error_code = helper.reproduce_impl(test_case.project_name,
test_case.fuzz_target, False, [],
[], test_case.test_case_path)
build_specified_commit.build_fuzzers_from_commit(test_case.new_commit,
test_repo_manager,
- build_data)
+ host_src_dir, build_data)
new_error_code = helper.reproduce_impl(test_case.project_name,
test_case.fuzz_target, False, [],
[], test_case.test_case_path)
diff --git a/infra/helper.py b/infra/helper.py
index 1d512e13..844b7baa 100755
--- a/infra/helper.py
+++ b/infra/helper.py
@@ -498,18 +498,20 @@ def build_fuzzers_impl( # pylint: disable=too-many-arguments
command = ['--cap-add', 'SYS_PTRACE'] + _env_to_docker_args(env)
if source_path:
workdir = _workdir_from_dockerfile(project_name)
- if workdir == '/src':
- print('Cannot use local checkout with "WORKDIR: /src".', file=sys.stderr)
- return 1
- if not mount_location:
+ if mount_location:
command += [
'-v',
- '%s:%s' % (_get_absolute_path(source_path), workdir),
+ '%s:%s' % (_get_absolute_path(source_path), mount_location),
]
else:
+ if workdir == '/src':
+ print('Cannot use local checkout with "WORKDIR: /src".',
+ file=sys.stderr)
+ return 1
+
command += [
'-v',
- '%s:%s' % (_get_absolute_path(source_path), mount_location),
+ '%s:%s' % (_get_absolute_path(source_path), workdir),
]
command += [
diff --git a/infra/repo_manager.py b/infra/repo_manager.py
index a6789fb0..d240ae1f 100644
--- a/infra/repo_manager.py
+++ b/infra/repo_manager.py
@@ -53,7 +53,9 @@ class RepoManager:
else:
self.repo_name = os.path.basename(self.repo_url).replace('.git', '')
self.repo_dir = os.path.join(self.base_dir, self.repo_name)
- self._clone()
+
+ if not os.path.exists(self.repo_dir):
+ self._clone()
def _clone(self):
"""Creates a clone of the repo in the specified directory.
@@ -136,7 +138,7 @@ class RepoManager:
ValueError: When either the old or new commit does not exist.
RuntimeError: When there is an error getting the commit list.
"""
-
+ self.fetch_unshallow()
if not self.commit_exists(old_commit):
raise ValueError('The old commit %s does not exist' % old_commit)
if not self.commit_exists(new_commit):
@@ -157,8 +159,8 @@ class RepoManager:
def fetch_unshallow(self):
"""Gets the current git repository history."""
- git_path = os.path.join(self.repo_dir, '.git', 'shallow')
- if os.path.exists(git_path):
+ shallow_file = os.path.join(self.repo_dir, '.git', 'shallow')
+ if os.path.exists(shallow_file):
utils.execute(['git', 'fetch', '--unshallow'],
self.repo_dir,
check_result=True)