From fedcd556ffcb32294c6a4fe6e2aa1837a59ec8f6 Mon Sep 17 00:00:00 2001 From: Fabian Meumertzheim Date: Wed, 10 Nov 2021 16:11:40 +0100 Subject: Port JavaNoThrowMethods to Java --- .../jazzer/agent/RuntimeInstrumentor.kt | 2 +- .../code_intelligence/jazzer/generated/BUILD.bazel | 16 ++---- .../jazzer/generated/JavaNoThrowMethods.java | 59 ++++++++++++++++++++++ .../jazzer/generated/JavaNoThrowMethods.kt | 39 -------------- .../instrumentor/EdgeCoverageInstrumentor.kt | 4 +- 5 files changed, 66 insertions(+), 54 deletions(-) create mode 100644 agent/src/main/java/com/code_intelligence/jazzer/generated/JavaNoThrowMethods.java delete mode 100644 agent/src/main/java/com/code_intelligence/jazzer/generated/JavaNoThrowMethods.kt (limited to 'agent/src/main/java/com') diff --git a/agent/src/main/java/com/code_intelligence/jazzer/agent/RuntimeInstrumentor.kt b/agent/src/main/java/com/code_intelligence/jazzer/agent/RuntimeInstrumentor.kt index 35c590c7..e2283aa2 100644 --- a/agent/src/main/java/com/code_intelligence/jazzer/agent/RuntimeInstrumentor.kt +++ b/agent/src/main/java/com/code_intelligence/jazzer/agent/RuntimeInstrumentor.kt @@ -137,7 +137,7 @@ internal class RuntimeInstrumentor( try { instrument(internalClassName, classfileBuffer, fullInstrumentation) } catch (e: CoverageIdException) { - println("ERROR: Coverage IDs are out of sync") + System.err.println("ERROR: Coverage IDs are out of sync") e.printStackTrace() exitProcess(1) } catch (e: Exception) { diff --git a/agent/src/main/java/com/code_intelligence/jazzer/generated/BUILD.bazel b/agent/src/main/java/com/code_intelligence/jazzer/generated/BUILD.bazel index 339ab577..df4f6382 100644 --- a/agent/src/main/java/com/code_intelligence/jazzer/generated/BUILD.bazel +++ b/agent/src/main/java/com/code_intelligence/jazzer/generated/BUILD.bazel @@ -1,5 +1,3 @@ -load("@io_bazel_rules_kotlin//kotlin:jvm.bzl", "kt_jvm_library") - java_binary( name = "NoThrowDoclet", srcs = ["NoThrowDoclet.java"], @@ -33,21 +31,15 @@ genrule( ], ) -# Workaround for https://github.com/bazelbuild/rules_kotlin/issues/281 -java_library( - name = "JavaNoThrowMethodsResource", - resources = [":java_no_throw_methods_list.dat"], -) - # To regenerate the list of methods, ensure that your local JDK is as recent as possible and contains `lib/src.zip`. # This will be the case if you are using the release binaries of the OpenJDK or if the `openjdk--source` # package is installed. -# Then, exceute +# Then, execute # agent/src/main/java/com/code_intelligence/jazzer/generated/update_java_no_throw_methods_list.sh # from the Bazel root. -kt_jvm_library( +java_library( name = "JavaNoThrowMethods", - srcs = [":JavaNoThrowMethods.kt"], + srcs = ["JavaNoThrowMethods.java"], + resources = ["java_no_throw_methods_list.dat"], visibility = ["//agent/src/main/java/com/code_intelligence/jazzer/instrumentor:__pkg__"], - deps = ["JavaNoThrowMethodsResource"], ) diff --git a/agent/src/main/java/com/code_intelligence/jazzer/generated/JavaNoThrowMethods.java b/agent/src/main/java/com/code_intelligence/jazzer/generated/JavaNoThrowMethods.java new file mode 100644 index 00000000..8bb43ef3 --- /dev/null +++ b/agent/src/main/java/com/code_intelligence/jazzer/generated/JavaNoThrowMethods.java @@ -0,0 +1,59 @@ +// Copyright 2021 Code Intelligence GmbH +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.code_intelligence.jazzer.generated; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.HashSet; +import java.util.Set; +import java.util.stream.Collectors; + +public class JavaNoThrowMethods { + private static final String DATA_FILE_NAME = "java_no_throw_methods_list.dat"; + private static final String DATA_FILE_RESOURCE_PATH = String.format( + "%s/%s", JavaNoThrowMethods.class.getPackage().getName().replace('.', '/'), DATA_FILE_NAME); + + public static final Set LIST = readJavaNoThrowMethods(); + + private static Set readJavaNoThrowMethods() { + // If we successfully appended the agent JAR to the bootstrap class loader path in Agent, the + // classLoader property of JavaNoThrowMethods returns null and we have to use the system class + // loader instead. + ClassLoader classLoader = JavaNoThrowMethods.class.getClassLoader(); + if (classLoader == null) { + classLoader = ClassLoader.getSystemClassLoader(); + } + Set list; + try (InputStream resourceStream = classLoader.getResourceAsStream(DATA_FILE_RESOURCE_PATH)) { + if (resourceStream == null) { + System.out.printf("ERROR: No-throw method signatures not found at resource path: %s%n", + DATA_FILE_RESOURCE_PATH); + return new HashSet<>(); + } + try (BufferedReader resourceReader = + new BufferedReader(new InputStreamReader(resourceStream))) { + list = resourceReader.lines().collect(Collectors.toSet()); + } + } catch (IOException e) { + System.out.println("ERROR: Failed to load no-throw method signatures"); + e.printStackTrace(); + return new HashSet<>(); + } + System.out.printf("INFO: Loaded %d no-throw method signatures%n", list.size()); + return list; + } +} diff --git a/agent/src/main/java/com/code_intelligence/jazzer/generated/JavaNoThrowMethods.kt b/agent/src/main/java/com/code_intelligence/jazzer/generated/JavaNoThrowMethods.kt deleted file mode 100644 index b727ae39..00000000 --- a/agent/src/main/java/com/code_intelligence/jazzer/generated/JavaNoThrowMethods.kt +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2021 Code Intelligence GmbH -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package com.code_intelligence.jazzer.generated - -private object JavaNoThrowMethods { - val dataFilePath: String = JavaNoThrowMethods.javaClass.`package`.name.replace('.', '/') - const val dataFileName = "java_no_throw_methods_list.dat" - - fun readJavaNoThrowMethods(): Set { - // If we successfully appended the agent JAR to the bootstrap class loader path in Agent, the classLoader - // property of JavaNoThrowMethods returns null and we have to use the system class loader instead. - val ownClassLoader = JavaNoThrowMethods::class.java.classLoader ?: ClassLoader.getSystemClassLoader() - val resource = ownClassLoader.getResource("$dataFilePath/$dataFileName")!! - return resource.openStream().bufferedReader().useLines { line -> line.toSet() }.also { - println("INFO: Loaded ${it.size} no-throw method signatures") - } - } -} - -/** - * A list of Java standard library methods that are known not to throw any exceptions (including - * [java.lang.RuntimeException], but ignoring [java.lang.VirtualMachineError]). - * - * Note: Since methods only declare their thrown exceptions that are not subclasses of [java.lang.RuntimeException], - * this list cannot be generated purely based on information available via reflection. - */ -val JAVA_NO_THROW_METHODS = JavaNoThrowMethods.readJavaNoThrowMethods() diff --git a/agent/src/main/java/com/code_intelligence/jazzer/instrumentor/EdgeCoverageInstrumentor.kt b/agent/src/main/java/com/code_intelligence/jazzer/instrumentor/EdgeCoverageInstrumentor.kt index 2e2a0b11..0e492c40 100644 --- a/agent/src/main/java/com/code_intelligence/jazzer/instrumentor/EdgeCoverageInstrumentor.kt +++ b/agent/src/main/java/com/code_intelligence/jazzer/instrumentor/EdgeCoverageInstrumentor.kt @@ -14,7 +14,7 @@ package com.code_intelligence.jazzer.instrumentor -import com.code_intelligence.jazzer.generated.JAVA_NO_THROW_METHODS +import com.code_intelligence.jazzer.generated.JavaNoThrowMethods import com.code_intelligence.jazzer.runtime.CoverageMap import com.code_intelligence.jazzer.third_party.jacoco.core.analysis.Analyzer import com.code_intelligence.jazzer.third_party.jacoco.core.analysis.ICoverageVisitor @@ -178,7 +178,7 @@ class EdgeCoverageInstrumentor( if (!internalClassName.startsWith("java/")) return false val key = "$internalClassName#$methodName#$descriptor" - return key in JAVA_NO_THROW_METHODS + return key in JavaNoThrowMethods.LIST } // The remainder of this file interfaces with classes in org.jacoco.core.internal. Changes to this part should not be -- cgit v1.2.3