mirror of https://github.com/google/oss-fuzz.git
* [infra] Fix helper.py as per feedback from @evverx + fix issues from #1519. * Remove stuff from local testing * Suppress unnecessary output from GSUtil.
This commit is contained in:
parent
82108f6083
commit
883cdcf3b0
|
@ -20,8 +20,10 @@ python infra/helper.py build_fuzzers --sanitizer=profile $project_name
|
|||
To get a good understanding of quality of the fuzz testing established for your
|
||||
project, code coverage should be generated by running fuzz targets against the
|
||||
corpus aggregated by OSS-Fuzz. The helper script will download the corpus
|
||||
automatically using `gsutil` tool. To check whether you have access to the
|
||||
corpus for your project, run:
|
||||
automatically using `gsutil` tool. To make it work, you need:
|
||||
|
||||
* Install [gsutil tool]
|
||||
* Check whether you have access to the corpus for your project:
|
||||
|
||||
```bash
|
||||
gsutil ls gs://${project_name}-corpus.clusterfuzz-external.appspot.com/
|
||||
|
@ -45,8 +47,8 @@ python infra/helper.py profile $project_name
|
|||
```
|
||||
|
||||
If you want to generate code coverage report using the corpus you have locally,
|
||||
copy the corpus into `build/$project_name/$fuzz_target/` directories for each
|
||||
fuzz target, then run:
|
||||
copy the corpus into `build/corpus/$project_name/$fuzz_target/` directories for
|
||||
each fuzz target, then run:
|
||||
|
||||
```bash
|
||||
python infra/helper.py profile --no-corpus-download $project_name
|
||||
|
@ -54,3 +56,4 @@ python infra/helper.py profile --no-corpus-download $project_name
|
|||
|
||||
|
||||
[Clang Source-based Code Coverage]: https://clang.llvm.org/docs/SourceBasedCodeCoverage.html
|
||||
[gsutil tool]: https://cloud.google.com/storage/docs/gsutil_install
|
||||
|
|
|
@ -68,6 +68,6 @@ llvm-cov show -format=html -output-dir=report -path-equivalence="/,$OUT" \
|
|||
-instr-profile merged.profdata $objects
|
||||
|
||||
# Serve the report locally.
|
||||
echo "Serving the report on http://127.0.0.1:8008/"
|
||||
echo "Serving the report on http://127.0.0.1:$HTTP_PORT/"
|
||||
cd report
|
||||
python3 -m http.server 8008
|
||||
python3 -m http.server $HTTP_PORT
|
||||
|
|
|
@ -126,6 +126,8 @@ def main():
|
|||
profile_parser.add_argument('--no-corpus-download', action='store_true',
|
||||
help='do not download corpus backup from OSS-Fuzz; '
|
||||
'use corpus located in build/corpus/<project>/<fuzz_target>/')
|
||||
profile_parser.add_argument('--port', default='8008', help='specify port for '
|
||||
'a local HTTP server rendering coverage report')
|
||||
|
||||
reproduce_parser = subparsers.add_parser(
|
||||
'reproduce', help='Reproduce a crash.')
|
||||
|
@ -464,11 +466,13 @@ def check_build(args):
|
|||
|
||||
def _get_fuzz_targets(project_name):
|
||||
"""Return names of fuzz targest build in the project's /out directory."""
|
||||
return [
|
||||
p
|
||||
for p in os.listdir(_get_output_dir(project_name))
|
||||
if os.access(p, os.X_OK)
|
||||
]
|
||||
fuzz_targets = []
|
||||
for name in os.listdir(_get_output_dir(project_name)):
|
||||
path = os.path.join(_get_output_dir(project_name), name)
|
||||
if os.path.isfile(path) and os.access(path, os.X_OK):
|
||||
fuzz_targets.append(name)
|
||||
|
||||
return fuzz_targets
|
||||
|
||||
|
||||
def _get_latest_corpus(project_name, fuzz_target, base_corpus_dir):
|
||||
|
@ -490,11 +494,13 @@ def _get_latest_corpus(project_name, fuzz_target, base_corpus_dir):
|
|||
archive_path = corpus_dir + '.zip'
|
||||
command = [
|
||||
'gsutil',
|
||||
'-q',
|
||||
'cp',
|
||||
latest_backup_url,
|
||||
archive_path
|
||||
]
|
||||
subprocess.check_call(command)
|
||||
|
||||
command = [
|
||||
'unzip',
|
||||
'-q',
|
||||
|
@ -523,17 +529,31 @@ def _get_latest_corpus(project_name, fuzz_target, base_corpus_dir):
|
|||
|
||||
def download_corpus(project_name):
|
||||
"""Download most recent corpus from GCS for the given project."""
|
||||
try:
|
||||
with open(os.devnull, 'w') as stdout:
|
||||
subprocess.check_call(['gsutil', '--version'], stdout=stdout)
|
||||
except OSError:
|
||||
print('ERROR: gsutil not found. Please install it from '
|
||||
'https://cloud.google.com/storage/docs/gsutil_install',
|
||||
file=sys.stderr)
|
||||
return False
|
||||
|
||||
fuzz_targets = _get_fuzz_targets(project_name)
|
||||
corpus_dir = _get_corpus_dir(project_name)
|
||||
if not os.path.exists(corpus_dir):
|
||||
os.makedirs(corpus_dir)
|
||||
|
||||
def _download_for_single_target(fuzz_target):
|
||||
_get_latest_corpus(project_name, fuzz_target, corpus_dir)
|
||||
try:
|
||||
_get_latest_corpus(project_name, fuzz_target, corpus_dir)
|
||||
except Exception as e:
|
||||
print('ERROR: corpus download for %s failed: %s' % (fuzz_target, str(e)),
|
||||
file=sys.stderr)
|
||||
|
||||
print('Downloading corpus for %s' % project_name)
|
||||
print('Downloading corpus for %s project' % project_name)
|
||||
thread_pool = ThreadPool(multiprocessing.cpu_count())
|
||||
thread_pool.map(_download_for_single_target, fuzz_targets)
|
||||
return True
|
||||
|
||||
|
||||
def profile(args):
|
||||
|
@ -541,18 +561,20 @@ def profile(args):
|
|||
if not _check_project_exists(args.project_name):
|
||||
return 1
|
||||
if not args.no_corpus_download:
|
||||
download_corpus(args.project_name)
|
||||
if not download_corpus(args.project_name):
|
||||
return 1
|
||||
|
||||
env = [
|
||||
'FUZZING_ENGINE=libfuzzer',
|
||||
'PROJECT=%s' % args.project_name,
|
||||
'SANITIZER=profile'
|
||||
'SANITIZER=profile',
|
||||
'HTTP_PORT=%s' % args.port,
|
||||
]
|
||||
|
||||
run_args = _env_to_docker_args(env) + [
|
||||
'-v', '%s:/out' % _get_output_dir(args.project_name),
|
||||
'-v', '%s:/corpus' % _get_corpus_dir(args.project_name),
|
||||
'-p', '8008:8008',
|
||||
'-p', '%s:%s' % (args.port, args.port),
|
||||
'-t', 'gcr.io/oss-fuzz-base/base-runner',
|
||||
]
|
||||
|
||||
|
|
Loading…
Reference in New Issue