Skip to content

Commit

Permalink
Tracking fuzzing time on engine fuzzers (#4356)
Browse files Browse the repository at this point in the history
### Motivation

Clusterfuzz only tracks fuzzing time for blackbox fuzzers at the moment,
this PR extends the tracking to engine fuzzers as well by emmiting the
JOB_TOTAL_FUZZ_TIME and FUZZER_TOTAL_FUZZ_TIME metrics.

Since all engine fuzzing is single process/single threaded, it suffices
to track start and end time for each test case run. The only difference
in behavior is that only libfuzzer indicates a timeout, and thus all
other engines are expected to concentrate their metrics on
timeout=False.

### Testing strategy

Ran a fuzz task locally and verified the code path for _TrackFuzzTime is
reached and produces sane output.
Command used:
```
fuzz libFuzzer libfuzzer_asan_log4j2
```

![image](https://github.com/user-attachments/assets/908895e2-16a5-4cf5-843c-d1e57412ff19)

Part of #4271
  • Loading branch information
vitorguidi authored Oct 29, 2024
1 parent 24f9760 commit 42ac6d9
Showing 1 changed file with 9 additions and 6 deletions.
15 changes: 9 additions & 6 deletions src/clusterfuzz/_internal/bot/tasks/utasks/fuzz_task.py
Original file line number Diff line number Diff line change
Expand Up @@ -1495,9 +1495,13 @@ def do_engine_fuzzing(self, engine_impl):
for fuzzing_round in range(environment.get_value('MAX_TESTCASES', 1)):
logs.info(f'Fuzzing round {fuzzing_round}.')
try:
result, current_fuzzer_metadata, fuzzing_strategies = run_engine_fuzzer(
engine_impl, self.fuzz_target.binary, sync_corpus_directory,
self.testcase_directory)
with _TrackFuzzTime(self.fully_qualified_fuzzer_name,
self.job_type) as tracker:
result, cur_fuzzer_metadata, fuzzing_strategies = run_engine_fuzzer(
engine_impl, self.fuzz_target.binary, sync_corpus_directory,
self.testcase_directory)
# Timeouts are only accounted for in libfuzzer, this can be None
tracker.timeout = bool(result.timed_out)
except FuzzTargetNotFoundError:
# Ocassionally fuzz targets are deleted. This is pretty rare. Since
# ClusterFuzz did nothing wrong, don't bubble up an exception, consider
Expand All @@ -1507,7 +1511,7 @@ def do_engine_fuzzing(self, engine_impl):
logs.error(f'{self.fuzz_target.binary} is not in the build.')
return [], {}

fuzzer_metadata.update(current_fuzzer_metadata)
fuzzer_metadata.update(cur_fuzzer_metadata)

# Prepare stats.
testcase_run = engine_common.get_testcase_run(result.stats,
Expand Down Expand Up @@ -2045,8 +2049,7 @@ def _to_engine_output(output: str, return_code: int,
def _upload_engine_output_log(engine_output):
timestamp = uworker_io.proto_timestamp_to_timestamp(engine_output.timestamp)
testcase_manager.upload_log(engine_output.output.decode(),
engine_output.return_code,
timestamp)
engine_output.return_code, timestamp)


def utask_postprocess(output):
Expand Down

0 comments on commit 42ac6d9

Please sign in to comment.