Skip to content

Commit 2557d48

Browse files
committed
feat: add exploreState(byte) overload with auto-generated call-site id
Add a convenience overload of Jazzer.exploreState that doesn't require manually providing an id parameter. During instrumentation, calls to this method are replaced with calls to exploreState(byte, int) using automatically generated unique identifiers for each call site. This simplifies the API for users who don't need to manually control the id parameter, while still ensuring each call site is tracked separately. Changes: - Add exploreState(byte) method to Jazzer API - Add JazzerApiHooks with REPLACE hook for the new method - Register JazzerApiHooks in Agent.kt - Update MazeFuzzer example to use the new overload
1 parent 305244c commit 2557d48

5 files changed

Lines changed: 62 additions & 2 deletions

File tree

examples/src/main/java/com/example/MazeFuzzer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ public static void fuzzerTestOneInput(byte[] commands) {
6767
// every new combination of x and y as a new feature. Without it, the fuzzer would be
6868
// completely lost in the maze as guessing an escaping path by chance is close to
6969
// impossible.
70-
Jazzer.exploreState((byte) Objects.hash(x, y), 0);
70+
Jazzer.exploreState((byte) Objects.hash(x, y));
7171
if (REACHED_FIELDS[y][x] == ' ') {
7272
// Fuzzer reached a new field in the maze, print its progress.
7373
REACHED_FIELDS[y][x] = '.';

src/main/java/com/code_intelligence/jazzer/agent/Agent.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ fun installInternal(
111111
InstrumentationType.NATIVE -> "com.code_intelligence.jazzer.runtime.NativeLibHooks"
112112
else -> null
113113
}
114-
}
114+
} + listOf("com.code_intelligence.jazzer.runtime.JazzerApiHooks")
115115
val coverageIdSynchronizer =
116116
if (idSyncFilePath != null) {
117117
FileSyncCoverageIdStrategy(idSyncFilePath)

src/main/java/com/code_intelligence/jazzer/api/Jazzer.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,19 @@ public static void exploreState(byte state, int id) {
217217
}
218218
}
219219

220+
/**
221+
* Convenience overload of {@link #exploreState(byte, int)} that allows using automatically
222+
* generated call-site identifiers. During instrumentation, calls to this method are replaced with
223+
* calls to {@link #exploreState(byte, int)} using a unique id for each call site.
224+
*
225+
* @param state a numeric encoding of a state that should be varied by the fuzzer
226+
* @see #exploreState(byte, int)
227+
*/
228+
public static void exploreState(byte state) {
229+
// Instrumentation replaces calls to this method with calls to exploreState(byte, int) using
230+
// an automatically generated call-site id. Without instrumentation, this is a no-op.
231+
}
232+
220233
/**
221234
* Make Jazzer report the provided {@link Throwable} as a finding.
222235
*

src/main/java/com/code_intelligence/jazzer/runtime/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ java_library(
149149
name = "runtime",
150150
srcs = [
151151
"HardToCatchError.java",
152+
"JazzerApiHooks.java",
152153
"JazzerInternal.java",
153154
"NativeLibHooks.java",
154155
"TraceCmpHooks.java",
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
* Copyright 2026 Code Intelligence GmbH
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.code_intelligence.jazzer.runtime;
18+
19+
import com.code_intelligence.jazzer.api.HookType;
20+
import com.code_intelligence.jazzer.api.Jazzer;
21+
import com.code_intelligence.jazzer.api.MethodHook;
22+
import java.lang.invoke.MethodHandle;
23+
24+
/**
25+
* Hooks for the Jazzer API that add call-site specific identifiers to methods that don't require an
26+
* explicit id parameter.
27+
*/
28+
@SuppressWarnings("unused")
29+
public final class JazzerApiHooks {
30+
/**
31+
* Replaces calls to {@link Jazzer#exploreState(byte)} with calls to {@link
32+
* Jazzer#exploreState(byte, int)} using the hook id as the id parameter.
33+
*
34+
* <p>This allows each call site to be tracked separately without requiring the user to manually
35+
* provide a unique id.
36+
*/
37+
@MethodHook(
38+
type = HookType.REPLACE,
39+
targetClassName = "com.code_intelligence.jazzer.api.Jazzer",
40+
targetMethod = "exploreState",
41+
targetMethodDescriptor = "(B)V")
42+
public static void exploreStateWithId(
43+
MethodHandle method, Object thisObject, Object[] arguments, int hookId) {
44+
Jazzer.exploreState((byte) arguments[0], hookId);
45+
}
46+
}

0 commit comments

Comments
 (0)