aboutsummaryrefslogtreecommitdiff
path: root/agent
diff options
context:
space:
mode:
authorFabian Meumertzheim <meumertzheim@code-intelligence.com>2021-06-11 10:08:03 +0200
committerFabian Meumertzheim <fabian@meumertzhe.im>2021-06-21 14:17:04 +0200
commit47ad28e5b6d4609b0f476d36ea0cb4a47ce439ee (patch)
tree6a4c49a0947c2149953f8444d81652141d3dd1a6 /agent
parent316da57a8688470fcfd5521673239b5fa66512ba (diff)
downloadjazzer-api-47ad28e5b6d4609b0f476d36ea0cb4a47ce439ee.tar.gz
Allow dumping instrumented classes
With --dump_classes_dir=<dir>, all classes that are instrumented by the agent at runtime will be dumped into a subdirectory of <dir> according to their internal class name.
Diffstat (limited to 'agent')
-rw-r--r--agent/src/main/java/com/code_intelligence/jazzer/agent/Agent.kt17
-rw-r--r--agent/src/main/java/com/code_intelligence/jazzer/agent/RuntimeInstrumentor.kt10
2 files changed, 26 insertions, 1 deletions
diff --git a/agent/src/main/java/com/code_intelligence/jazzer/agent/Agent.kt b/agent/src/main/java/com/code_intelligence/jazzer/agent/Agent.kt
index bb277633..71c20e78 100644
--- a/agent/src/main/java/com/code_intelligence/jazzer/agent/Agent.kt
+++ b/agent/src/main/java/com/code_intelligence/jazzer/agent/Agent.kt
@@ -23,6 +23,9 @@ import java.io.File
import java.lang.instrument.Instrumentation
import java.nio.file.Paths
import java.util.jar.JarFile
+import kotlin.io.path.ExperimentalPathApi
+import kotlin.io.path.exists
+import kotlin.io.path.isDirectory
val KNOWN_ARGUMENTS = listOf(
"instrumentation_includes",
@@ -32,6 +35,7 @@ val KNOWN_ARGUMENTS = listOf(
"trace",
"custom_hooks",
"id_sync_file",
+ "dump_classes_dir",
)
private object AgentJarFinder {
@@ -39,6 +43,7 @@ private object AgentJarFinder {
val agentJarFile = agentJarPath?.let { JarFile(File(it)) }
}
+@OptIn(ExperimentalPathApi::class)
fun premain(agentArgs: String?, instrumentation: Instrumentation) {
// Add the agent jar (i.e., the jar out of which we are currently executing) to the search path of the bootstrap
// class loader to ensure that instrumented classes can find the CoverageMap class regardless of which ClassLoader
@@ -97,12 +102,22 @@ fun premain(agentArgs: String?, instrumentation: Instrumentation) {
println("INFO: Synchronizing coverage IDs in ${path.toAbsolutePath()}")
}
}
+ val dumpClassesDir = argumentMap["dump_classes_dir"]?.let {
+ Paths.get(it.single()).toAbsolutePath().also { path ->
+ if (path.exists() && path.isDirectory()) {
+ println("INFO: Dumping instrumented classes into $path")
+ } else {
+ println("ERROR: Cannot dump instrumented classes into $path; does not exist or not a directory")
+ }
+ }
+ }
val runtimeInstrumentor = RuntimeInstrumentor(
instrumentation,
classNameGlobber,
dependencyClassNameGlobber,
instrumentationTypes,
- idSyncFile
+ idSyncFile,
+ dumpClassesDir,
)
instrumentation.apply {
addTransformer(runtimeInstrumentor)
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 b6bed2a6..64a5ca56 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
@@ -122,6 +122,7 @@ internal class RuntimeInstrumentor(
private val dependencyClassesToInstrument: ClassNameGlobber,
private val instrumentationTypes: Set<InstrumentationType>,
idSyncFile: Path?,
+ private val dumpClassesDir: Path?,
) : ClassFileTransformer {
private val coverageIdSynchronizer = if (idSyncFile != null)
@@ -166,6 +167,15 @@ internal class RuntimeInstrumentor(
// https://docs.oracle.com/javase/9/docs/api/java/lang/instrument/ClassFileTransformer.html
t.printStackTrace()
throw t
+ }.also { instrumentedByteCode ->
+ // Only dump classes that were instrumented.
+ if (instrumentedByteCode != null && dumpClassesDir != null) {
+ val relativePath = "$internalClassName.class"
+ val absolutePath = dumpClassesDir.resolve(relativePath)
+ val dumpFile = absolutePath.toFile()
+ dumpFile.parentFile.mkdirs()
+ dumpFile.writeBytes(instrumentedByteCode)
+ }
}
}