Skip to content

Comments

Maximize API#1036

Merged
kyakdan merged 4 commits intomainfrom
CIF-1902-maximize
Feb 20, 2026
Merged

Maximize API#1036
kyakdan merged 4 commits intomainfrom
CIF-1902-maximize

Conversation

@kyakdan
Copy link
Member

@kyakdan kyakdan commented Feb 3, 2026

Summary

Add a hill-climbing maximize() API to Jazzer that guides the fuzzer toward maximizing a value over time. This enables fuzzing scenarios where standard code coverage provides insufficient guidance, such as finding inputs that maximize some computed metric.

Changes

Jazzer.maximize() API

// Guide fuzzer to maximize 'value' within [0, 1023]
Jazzer.maximize(value, id);

// Convenience overload with auto-generated call-site ID (requires instrumentation)
Jazzer.maximize(value);

How it works: For each observed value v, sets coverage counters [0, 1023 - v] to 1. This creates incremental progress feedback - higher values trigger more "coverage," guiding the fuzzer toward the maximum. Corpus minimization naturally retains only the input producing the highest value.

Example

Added ReactorFuzzTest demonstrating the API on a chaotic feedback system where standard coverage is constant but the fuzzer needs to maximize a computed temperature value.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a maximize() API to Jazzer that enables hill-climbing fuzzing scenarios where standard code coverage is insufficient. The API guides the fuzzer to maximize a value by setting coverage counters for all values from the minimum up to the observed value, creating incremental progress feedback.

Changes:

  • Added CountersTracker infrastructure (Java and C++) to manage extra coverage counters separate from regular code coverage
  • Added Jazzer.maximize() API with automatic call-site ID generation via instrumentation hooks
  • Added comprehensive test coverage for the new APIs
  • Added ReactorFuzzTest example demonstrating the maximize API on a chaotic feedback system

Reviewed changes

Copilot reviewed 14 out of 14 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
src/main/native/com/code_intelligence/jazzer/driver/counters_tracker.h Refactored header from CoverageTracker to CountersTracker, adding support for separate extra counters region
src/main/native/com/code_intelligence/jazzer/driver/counters_tracker.cpp New implementation managing both coverage and extra counters with libFuzzer registration
src/main/native/com/code_intelligence/jazzer/driver/BUILD.bazel Updated build dependencies to reference counters_tracker instead of coverage_tracker
src/main/java/com/code_intelligence/jazzer/runtime/CountersTracker.java New Java class providing thread-safe counter allocation and management API
src/main/java/com/code_intelligence/jazzer/runtime/BUILD.bazel Added CountersTracker build target and dependencies
src/main/java/com/code_intelligence/jazzer/runtime/JazzerApiHooks.java Added instrumentation hook to auto-generate call-site IDs for maximize() calls
src/main/java/com/code_intelligence/jazzer/api/Jazzer.java Added maximize() API methods with documentation
src/test/java/com/code_intelligence/jazzer/runtime/CountersTrackerTest.java Comprehensive unit tests for CountersTracker including concurrency tests
src/test/java/com/code_intelligence/jazzer/api/MaximizeTest.java Unit tests for the maximize() API covering edge cases
examples/junit/src/test/java/com/example/ReactorFuzzTest.java Example demonstrating maximize() on a temperature maximization problem

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 14 out of 14 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 14 out of 14 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 14 out of 14 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Contributor

@oetr oetr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice addition, thanks!

@kyakdan kyakdan force-pushed the CIF-1902-maximize branch 4 times, most recently from 429b534 to d692165 Compare February 12, 2026 13:23
Copy link
Contributor

@oetr oetr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM already! Consider auto-mapping to our range--it will make this way easier to use.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 20 out of 20 changed files in this pull request and generated 5 comments.

Comments suppressed due to low confidence (1)

src/main/java/com/code_intelligence/jazzer/runtime/CoverageMap.java:92

  • Potential inconsistency between registered counters and currentNumCounters. Line 84 registers Math.min(INITIAL_NUM_COUNTERS, MAX_NUM_COUNTERS) counters with libFuzzer, but line 92 initializes currentNumCounters to INITIAL_NUM_COUNTERS unconditionally. If MAX_NUM_COUNTERS < INITIAL_NUM_COUNTERS (e.g., via environment variable), currentNumCounters will be larger than the actually registered count, which could cause issues. Consider changing line 92 to: private static int currentNumCounters = Math.min(INITIAL_NUM_COUNTERS, MAX_NUM_COUNTERS);
    registerNewCounters(0, Math.min(INITIAL_NUM_COUNTERS, MAX_NUM_COUNTERS));
  }

  /**
   * The number of coverage counters that are currently registered with libFuzzer. This number grows
   * dynamically as classes are instrumented and should be kept as low as possible as libFuzzer has
   * to iterate over the whole map for every execution.
   */
  private static int currentNumCounters = INITIAL_NUM_COUNTERS;

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@kyakdan kyakdan force-pushed the CIF-1902-maximize branch 3 times, most recently from ee007df to 532601d Compare February 20, 2026 09:30
Copy link
Contributor

@oetr oetr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good!
I left a few minor suggestions for exception messages.

Properly parse JAZZER_MAX_NUM_COUNTERS with trimming, reject negative
values with a clear error message, and cap INITIAL_NUM_COUNTERS at
MAX_NUM_COUNTERS to prevent out-of-bounds registration.
@kyakdan kyakdan enabled auto-merge (rebase) February 20, 2026 11:52
Add ExtraCountersTracker, a Java/C++ component that manages dynamically
allocated coverage counters separate from the main coverage map. This
enables user-facing APIs (like maximize) to register synthetic coverage
counters that are tracked by libFuzzer.

Features:
- Thread-safe counter allocation with per-id tracking
- JNI bridge to register counters with libFuzzer's 8-bit counter API
- Configurable max counter limit via JAZZER_EXTRA_COUNTERS_MAX env var
- Convenience overloads for setCounter and setCounterRange
Introduce JazzerApiException to distinguish API misuse errors (invalid
arguments, incompatible runtime) from findings in the code under test.
The fuzzing engine treats this exception as a fatal error rather than
a reportable bug.
Add Jazzer.maximize(value, minValue, maxValue) for guiding the fuzzer to
maximize a value over time. The user's value range is linearly mapped
onto a fixed number of coverage counters (default 1024), avoiding the
risk of exhausting counter space with large ranges. The effective counter
count is capped at the actual range size when the range is smaller than
the requested number.

Three overloads are provided:
- maximize(value, minValue, maxValue) — convenience, auto-generated id
- maximize(value, minValue, maxValue, numCounters) — custom counter count
- maximize(value, minValue, maxValue, numCounters, id) — full control

Also wraps all Jazzer API methods with JazzerApiException error handling
and adds a ReactorFuzzTest example demonstrating the maximize API.
@kyakdan kyakdan merged commit 1c0deb4 into main Feb 20, 2026
9 checks passed
@kyakdan kyakdan deleted the CIF-1902-maximize branch February 20, 2026 13:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants