google / ksp

Kotlin Symbol Processing API
https://github.com/google/ksp
Apache License 2.0
2.84k stars 266 forks source link

StackOverflowError in KSValidateVisitor #1114

Open jbarr21 opened 2 years ago

jbarr21 commented 2 years ago

Types with generics that reference each either cause a StackOverflowError in the KSValidateVisitor when processing Java source files.

KSP version: 1.7.10-1.0.6 Kotlin version: 1.7.10 Room Compiler-Processing version: 2.5.0-alpha03 Build system: Buck

Example Java source files (non-Foo classes are Kotlin classes from uber/RIBs or Android View):

public abstract class FooInteractor<
        P extends FooPresenter, R extends FooRouter<?, ?, ?>>
    extends Interactor<P, R> { ... }

public abstract class FooPresenter<V extends View> extends Presenter { ... }

public abstract class FooRouter<
        V extends View, I extends FooInteractor, C extends InteractorComponent>
    extends Router<I> { ... }

Non-Foo classes from uber/RIBs:

interface InteractorComponent<P : Presenter, T : Interactor<P, *>> : InteractorBaseComponent<T> { ... }

abstract class Interactor<P : Any, R : Router<*>> : LifecycleScopeProvider<InteractorEvent>, InteractorType { ... }

abstract class Router<I : InteractorType> protected constructor(...) { ... }

interface InteractorType : LifecycleScopeProvider<InteractorEvent> { ... }

Output from console logging the typeReference.toString() on breakpoint on KSValidateVisitor.visitTypeReference():

FooInteractor<(FooPresenter<*>..FooPresenter<*>?), (FooRouter<*, *, *>..FooRouter<*, *, *>?)>
FooPresenter<*>
View
FooRouter<*, *, *>
View
FooInteractor<(FooPresenter<*>..FooPresenter<*>?), (FooRouter<*, *, *>..FooRouter<*, *, *>?)>
FooPresenter<*>
View
FooRouter<*, *, *>
View
.
.
.
FooInteractor<(FooPresenter<*>..FooPresenter<*>?), (FooRouter<*, *, *>..FooRouter<*, *, *>?)>
FooPresenter<*>
View
FooRouter<*, *, *>
View

Stacktrace:

com.google.devtools.ksp.symbol.impl.binary.KSTypeReferenceDescriptorImpl.accept(KSTypeReferenceDescriptorImpl.kt:72)
com.google.devtools.ksp.visitor.KSValidateVisitor.validateType(KSValidateVisitor.kt:9)
com.google.devtools.ksp.visitor.KSValidateVisitor.visitTypeReference(KSValidateVisitor.kt:57)
com.google.devtools.ksp.visitor.KSValidateVisitor.visitTypeReference(KSValidateVisitor.kt:5)
.
.
.
com.google.devtools.ksp.symbol.impl.binary.KSTypeReferenceDescriptorImpl.accept(KSTypeReferenceDescriptorImpl.kt:72)
com.google.devtools.ksp.visitor.KSValidateVisitor.validateType(KSValidateVisitor.kt:9)
com.google.devtools.ksp.visitor.KSValidateVisitor.visitTypeReference(KSValidateVisitor.kt:57)
com.google.devtools.ksp.visitor.KSValidateVisitor.visitTypeReference(KSValidateVisitor.kt:5)
com.google.devtools.ksp.symbol.impl.binary.KSTypeReferenceDescriptorImpl.accept(KSTypeReferenceDescriptorImpl.kt:72)
com.google.devtools.ksp.visitor.KSValidateVisitor.validateType(KSValidateVisitor.kt:9)
com.google.devtools.ksp.visitor.KSValidateVisitor.visitTypeReference(KSValidateVisitor.kt:57)
com.google.devtools.ksp.visitor.KSValidateVisitor.visitTypeReference(KSValidateVisitor.kt:5)
com.google.devtools.ksp.symbol.impl.binary.KSTypeReferenceDescriptorImpl.accept(KSTypeReferenceDescriptorImpl.kt:72)
com.google.devtools.ksp.visitor.KSValidateVisitor.validateType(KSValidateVisitor.kt:9)
com.google.devtools.ksp.visitor.KSValidateVisitor.visitTypeReference(KSValidateVisitor.kt:57)
com.google.devtools.ksp.visitor.KSValidateVisitor.visitTypeReference(KSValidateVisitor.kt:5)
com.google.devtools.ksp.symbol.impl.kotlin.KSTypeReferenceImpl.accept(KSTypeReferenceImpl.kt:132)
com.google.devtools.ksp.visitor.KSValidateVisitor.visitFunctionDeclaration(KSValidateVisitor.kt:78)
com.google.devtools.ksp.visitor.KSValidateVisitor.visitFunctionDeclaration(KSValidateVisitor.kt:5)
com.google.devtools.ksp.symbol.impl.kotlin.KSFunctionDeclarationImpl.accept(KSFunctionDeclarationImpl.kt:118)
com.google.devtools.ksp.visitor.KSValidateVisitor.visitDeclarationContainer(KSValidateVisitor.kt:28)
com.google.devtools.ksp.visitor.KSValidateVisitor.visitClassDeclaration(KSValidateVisitor.kt:70)
com.google.devtools.ksp.visitor.KSValidateVisitor.visitClassDeclaration(KSValidateVisitor.kt:5)
com.google.devtools.ksp.symbol.impl.kotlin.KSClassDeclarationImpl.accept(KSClassDeclarationImpl.kt:136)
com.google.devtools.ksp.UtilsKt.validate(utils.kt:125)
com.google.devtools.ksp.UtilsKt.validate$default(utils.kt:124)
androidx.room.compiler.processing.ksp.KspElement.validate(KspElement.kt:65)
androidx.room.compiler.processing.CommonProcessorDelegate.processRound(XBasicAnnotationProcessor.kt:104)
androidx.room.compiler.processing.ksp.KspBasicAnnotationProcessor.process(KspBasicAnnotationProcessor.kt:63)
com.google.devtools.ksp.AbstractKotlinSymbolProcessingExtension$doAnalysis$4$1.invoke(KotlinSymbolProcessingExtension.kt:237)
com.google.devtools.ksp.AbstractKotlinSymbolProcessingExtension$doAnalysis$4$1.invoke(KotlinSymbolProcessingExtension.kt:235)
com.google.devtools.ksp.AbstractKotlinSymbolProcessingExtension.handleException(KotlinSymbolProcessingExtension.kt:330)
com.google.devtools.ksp.AbstractKotlinSymbolProcessingExtension.doAnalysis(KotlinSymbolProcessingExtension.kt:235)
org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(TopDownAnalyzerFacadeForJVM.kt:123)
org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration$default(TopDownAnalyzerFacadeForJVM.kt:99)
org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler$analyze$1.invoke(KotlinToJVMBytecodeCompiler.kt:264)
org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler$analyze$1.invoke(KotlinToJVMBytecodeCompiler.kt:55)
org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport.analyzeAndReport(AnalyzerWithCompilerReport.kt:115)
org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.analyze(KotlinToJVMBytecodeCompiler.kt:255)
org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.compileModules$cli(KotlinToJVMBytecodeCompiler.kt:101)
org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.compileModules$cli$default(KotlinToJVMBytecodeCompiler.kt:60)
org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecute(K2JVMCompiler.kt:157)
org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecute(K2JVMCompiler.kt:52)
org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:94)
org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:43)
org.jetbrains.kotlin.cli.common.CLITool.exec(CLITool.kt:101)
org.jetbrains.kotlin.cli.common.CLITool.exec(CLITool.kt:79)
org.jetbrains.kotlin.cli.common.CLITool.exec(CLITool.kt:40)
java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.base/java.lang.reflect.Method.invoke(Method.java:566)
com.facebook.buck.jvm.kotlin.JarBackedReflectedKotlinc.buildWithClasspath(JarBackedReflectedKotlinc.java:244)
com.facebook.buck.jvm.kotlin.KotlincStep.execute(KotlincStep.java:101)
com.facebook.buck.step.StepRunner.runStep(StepRunner.java:62)
com.facebook.buck.core.build.engine.impl.CachingBuildRuleBuilder$BuildRuleSteps.executeCommands(CachingBuildRuleBuilder.java:1424)
com.facebook.buck.core.build.engine.impl.CachingBuildRuleBuilder$BuildRuleSteps.runWithDefaultExecutor(CachingBuildRuleBuilder.java:1400)
com.facebook.buck.util.concurrent.WeightedListeningExecutorService.lambda$submit$2(WeightedListeningExecutorService.java:117)
com.facebook.buck.util.concurrent.WeightedListeningExecutorService.lambda$submitWithSemaphore$0(WeightedListeningExecutorService.java:91)
com.google.common.util.concurrent.AbstractTransformFuture$AsyncTransformFuture.doTransform(AbstractTransformFuture.java:206)
com.google.common.util.concurrent.AbstractTransformFuture$AsyncTransformFuture.doTransform(AbstractTransformFuture.java:195)
com.google.common.util.concurrent.AbstractTransformFuture.run(AbstractTransformFuture.java:115)
com.google.common.util.concurrent.MoreExecutors$5$1.run(MoreExecutors.java:999)
java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
java.base/java.lang.Thread.run(Thread.java:829)
sushma-92 commented 9 months ago

hi @jbarr21 @neetopia any solution helped to solve this issue, facing the same . with KSP version: 1.9.21-1.0.15 Kotlin version: 1.9.20 oom Compiler-Processing - 2.6.1

e: java.lang.StackOverflowError at com.google.devtools.ksp.symbol.impl.kotlin.KSTypeImpl$Companion.getCached(KSTypeImpl.kt) at com.google.devtools.ksp.symbol.impl.kotlin.KSTypeImplKt.getKSTypeCached(KSTypeImpl.kt:145) at com.google.devtools.ksp.symbol.impl.kotlin.KSTypeImplKt.getKSTypeCached$default(KSTypeImpl.kt:135) at com.google.devtools.ksp.symbol.impl.binary.KSTypeReferenceDescriptorImpl.resolve(KSTypeReferenceDescriptorImpl.kt:72) at com.google.devtools.ksp.visitor.KSValidateVisitor.visitTypeReference(KSValidateVisitor.kt:57) at com.google.devtools.ksp.visitor.KSValidateVisitor.visitTypeReference(KSValidateVisitor.kt:5) at com.google.devtools.ksp.symbol.impl.binary.KSTypeReferenceDescriptorImpl.accept(KSTypeReferenceDescriptorImpl.kt:76) at com.google.devtools.ksp.visitor.KSValidateVisitor.validateType(KSValidateVisitor.kt:9) at com.google.devtools.ksp.visitor.KSValidateVisitor.visitTypeReference(KSValidateVisitor.kt:57) at com.google.devtools.ksp.visitor.KSValidateVisitor.visitTypeReference(KSValidateVisitor.kt:5) at com.google.devtools.ksp.symbol.impl.binary.KSTypeReferenceDescriptorImpl.accept(KSTypeReferenceDescriptorImpl.kt:76) at com.google.devtools.ksp.visitor.KSValidateVisitor.validateType(KSValidateVisitor.kt:9) at com.google.devtools.ksp.visitor.KSValidateVisitor.visitTypeReference(KSValidateVisitor.kt:57) at com.google.devtools.ksp.visitor.KSValidateVisitor.visitTypeReference(KSValidateVisitor.kt:5) at com.google.devtools.ksp.symbol.impl.binary.KSTypeReferenceDescriptorImpl.accept(KSTypeReferenceDescriptorImpl.kt:76) at com.google.devtools.ksp.visitor.KSValidateVisitor.validateType(KSValidateVisitor.kt:9) at com.google.devtools.ksp.visitor.KSValidateVisitor.visitTypeReference(KSValidateVisitor.kt:57) at com.google.devtools.ksp.visitor.KSValidateVisitor.visitTypeReference(KSValidateVisitor.kt:5) at com.google.devtools.ksp.symbol.impl.binary.KSTypeReferenceDescriptorImpl.accept(KSTypeReferenceDescriptorImpl.kt:76) at com.google.devtools.ksp.visitor.KSValidateVisitor.validateType(KSValidateVisitor.kt:9) at com.google.devtools.ksp.visitor.KSValidateVisitor.visitTypeReference(KSValidateVisitor.kt:57) at com.google.devtools.ksp.visitor.KSValidateVisitor.visitTypeReference(KSValidateVisitor.kt:5) at com.google.devtools.ksp.symbol.impl.binary.KSTypeReferenceDescriptorImpl.accept(KSTypeReferenceDescriptorImpl.kt:76) at com.google.devtools.ksp.visitor.KSValidateVisitor.validateType(KSValidateVisitor.kt:9) at com.google.devtools.ksp.visitor.KSValidateVisitor.visitTypeReference(KSValidateVisitor.kt:57) at com.google.devtools.ksp.visitor.KSValidateVisitor.visitTypeReference(KSValidateVisitor.kt:5)

AlexanderGH commented 5 months ago

I just debugged this and the cause was a usage of Enum<>. I'm guessing ksp tries to verify the matches the underlying recursive generic which is Enum<> and gets stuck as expected. Arguably in my case, since isn't guaranteed to be an T = , and isn't guaranteed to be an Enum, it fails, but i doubt hitting a stack overflow exception was intended. It should detect this case and fail fast.

As for everyone else, I'd suggest verifying whether you're properly using any classes which have recursive generics.

ScryptX commented 3 months ago

I just debugged this and the cause was a usage of Enum<_>. I'm guessing ksp tries to verify the matches the underlying recursive generic which is Enum<_> and gets stuck as expected. Arguably in my case, since isn't guaranteed to be an T = , and isn't guaranteed to be an Enum, it fails, but i doubt hitting a stack overflow exception was intended. It should detect this case and fail fast.

As for everyone else, I'd suggest verifying whether you're properly using any classes which have recursive generics.

Thank you for this comment, you saved me quite a bit of time. In my case, it was also the Enum<*> that broke ksp.