From 2b7fc646ae82a2173ad4ab85c36d36a82dd779d2 Mon Sep 17 00:00:00 2001 From: DaniilStepanov Date: Thu, 23 Nov 2023 14:51:53 +0300 Subject: [PATCH] Fix of bug with classloader --- .../instrumentation/agent/ClassTransformer.kt | 4 +++- .../classloader/UtilClassLoader.kt | 3 +++ .../org/usvm/instrumentation/util/Classloader.kt | 2 +- .../org/usvm/instrumentation/util/Jacodb.kt | 16 ++++++++++------ 4 files changed, 17 insertions(+), 8 deletions(-) create mode 100644 usvm-jvm-instrumentation/src/main/kotlin/org/usvm/instrumentation/classloader/UtilClassLoader.kt diff --git a/usvm-jvm-instrumentation/src/main/kotlin/org/usvm/instrumentation/agent/ClassTransformer.kt b/usvm-jvm-instrumentation/src/main/kotlin/org/usvm/instrumentation/agent/ClassTransformer.kt index 711905ef2d..0c5da78fef 100644 --- a/usvm-jvm-instrumentation/src/main/kotlin/org/usvm/instrumentation/agent/ClassTransformer.kt +++ b/usvm-jvm-instrumentation/src/main/kotlin/org/usvm/instrumentation/agent/ClassTransformer.kt @@ -1,5 +1,6 @@ package org.usvm.instrumentation.agent +import org.usvm.instrumentation.classloader.UtilClassLoader import org.usvm.instrumentation.classloader.WorkerClassLoader import org.usvm.instrumentation.instrumentation.JcInstrumenterFactory import org.usvm.instrumentation.util.toByteArray @@ -17,6 +18,7 @@ class ClassTransformer( private val instrumenterFactoryInstance = Class.forName(instrumenterClassName).constructors.first().newInstance() as JcInstrumenterFactory<*> private val instrumenterCache = HashMap() + private val utilClassLoader = UtilClassLoader() override fun transform( @@ -34,7 +36,7 @@ class ClassTransformer( return instrumenterCache.getOrPut(className) { val instrumenter = instrumenterFactoryInstance.create(loader.jcClasspath) val instrumentedClassNode = instrumenter.instrumentClass(classfileBuffer.toClassNode()) - instrumentedClassNode.toByteArray(loader, checkClass = true) + instrumentedClassNode.toByteArray(utilClassLoader, checkClass = true) } } diff --git a/usvm-jvm-instrumentation/src/main/kotlin/org/usvm/instrumentation/classloader/UtilClassLoader.kt b/usvm-jvm-instrumentation/src/main/kotlin/org/usvm/instrumentation/classloader/UtilClassLoader.kt new file mode 100644 index 0000000000..e86a884ac9 --- /dev/null +++ b/usvm-jvm-instrumentation/src/main/kotlin/org/usvm/instrumentation/classloader/UtilClassLoader.kt @@ -0,0 +1,3 @@ +package org.usvm.instrumentation.classloader + +class UtilClassLoader: ClassLoader() \ No newline at end of file diff --git a/usvm-jvm-instrumentation/src/main/kotlin/org/usvm/instrumentation/util/Classloader.kt b/usvm-jvm-instrumentation/src/main/kotlin/org/usvm/instrumentation/util/Classloader.kt index 33895c4f18..ca45dc7c5c 100644 --- a/usvm-jvm-instrumentation/src/main/kotlin/org/usvm/instrumentation/util/Classloader.kt +++ b/usvm-jvm-instrumentation/src/main/kotlin/org/usvm/instrumentation/util/Classloader.kt @@ -16,7 +16,7 @@ class URLClassPathLoader(private val classPath: List) { fun getCodeSigners(): Array? } - private val urlClassLoader = URLClassLoader(classPath.map { it.toURI().toURL() }.toTypedArray()) + private val urlClassLoader = URLClassLoader(classPath.map { it.toURI().toURL() }.toTypedArray(), null) fun getResource(name: String): Resource { val resourceUrl = urlClassLoader.getResource(name) ?: error("Resource $name not found on classpath $classPath") diff --git a/usvm-jvm-instrumentation/src/main/kotlin/org/usvm/instrumentation/util/Jacodb.kt b/usvm-jvm-instrumentation/src/main/kotlin/org/usvm/instrumentation/util/Jacodb.kt index db635fa8af..575444fca7 100644 --- a/usvm-jvm-instrumentation/src/main/kotlin/org/usvm/instrumentation/util/Jacodb.kt +++ b/usvm-jvm-instrumentation/src/main/kotlin/org/usvm/instrumentation/util/Jacodb.kt @@ -50,9 +50,9 @@ val JcInst.enclosingMethod fun JcType.toJavaClass(classLoader: ClassLoader): Class<*> = when (this) { is JcPrimitiveType -> toJavaClass() - is JcArrayType -> findClassInLoader(toJvmType(), classLoader) ?: throw TestExecutorException("Can't find class in classpath") + is JcArrayType -> findClassInLoader(toJvmType(), classLoader) is JcClassType -> this.jcClass.toJavaClass(classLoader) - else -> findClassInLoader(typeName, classLoader) ?: throw TestExecutorException("Can't find class in classpath") + else -> findClassInLoader(typeName, classLoader) } private fun JcPrimitiveType.toJavaClass(): Class<*> { @@ -104,12 +104,16 @@ fun JcType.toJcClass(): JcClassOrInterface? = else -> error("Unexpected type") } -fun JcClassOrInterface.toJavaClass(classLoader: ClassLoader): Class<*> = - findClassInLoader(name, classLoader) ?: throw TestExecutorException("Can't find class in classpath") +fun JcClassOrInterface.toJavaClass(classLoader: ClassLoader, initialize: Boolean = false): Class<*> = + findClassInLoader(name, classLoader, initialize) -fun findClassInLoader(name: String, classLoader: ClassLoader): Class<*>? = - Class.forName(name, true, classLoader) +fun findClassInLoader(name: String, classLoader: ClassLoader, initialize: Boolean = false): Class<*> = + try { + Class.forName(name, initialize, classLoader) + } catch (e: Throwable) { + throw TestExecutorException("Can't find class in classpath") + } fun JcField.toJavaField(classLoader: ClassLoader): Field? = enclosingClass.toType().toJavaClass(classLoader).getFieldByName(name)