Skip to content

Handling of an error through a long chain of completions leads to StackOverflowError #5949

@guss77

Description

@guss77

Version

5.0.7

Context

I often get these errors in my server logs:

ip-172-24-16-229 API.Core [6377]: [vert.x-eventloop-thread-2] ERROR io.vertx.core.impl.ContextImpl - Unhandled exception
ip-172-24-16-229 API.Core [6377]: java.lang.StackOverflowError
ip-172-24-16-229 API.Core [6377]: #011at java.base/java.io.BufferedOutputStream.growIfNeeded(BufferedOutputStream.java:138)
ip-172-24-16-229 API.Core [6377]: #011at java.base/java.io.BufferedOutputStream.implWrite(BufferedOutputStream.java:220)
ip-172-24-16-229 API.Core [6377]: #011at java.base/java.io.BufferedOutputStream.write(BufferedOutputStream.java:200)
ip-172-24-16-229 API.Core [6377]: #011at java.base/java.io.PrintStream.implWrite(PrintStream.java:643)
ip-172-24-16-229 API.Core [6377]: #011at java.base/java.io.PrintStream.write(PrintStream.java:623)
ip-172-24-16-229 API.Core [6377]: #011at java.base/sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:309)
ip-172-24-16-229 API.Core [6377]: #011at java.base/sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:405)
ip-172-24-16-229 API.Core [6377]: #011at java.base/sun.nio.cs.StreamEncoder.lockedFlushBuffer(StreamEncoder.java:123)
ip-172-24-16-229 API.Core [6377]: #011at java.base/sun.nio.cs.StreamEncoder.flushBuffer(StreamEncoder.java:110)
ip-172-24-16-229 API.Core [6377]: #011at java.base/java.io.OutputStreamWriter.flushBuffer(OutputStreamWriter.java:192)
ip-172-24-16-229 API.Core [6377]: #011at java.base/java.io.PrintStream.implWriteln(PrintStream.java:849)
ip-172-24-16-229 API.Core [6377]: #011at java.base/java.io.PrintStream.writeln(PrintStream.java:826)
ip-172-24-16-229 API.Core [6377]: #011at java.base/java.io.PrintStream.println(PrintStream.java:1191)
ip-172-24-16-229 API.Core [6377]: #011at java.base/java.lang.Throwable$WrappedPrintStream.println(Throwable.java:785)
ip-172-24-16-229 API.Core [6377]: #011at java.base/java.lang.Throwable.lockedPrintStackTrace(Throwable.java:684)
ip-172-24-16-229 API.Core [6377]: #011at java.base/java.lang.Throwable.printStackTrace(Throwable.java:668)
ip-172-24-16-229 API.Core [6377]: #011at java.base/java.lang.Throwable.printStackTrace(Throwable.java:660)
ip-172-24-16-229 API.Core [6377]: #011at org.slf4j.simple.SimpleLogger.writeThrowable(SimpleLogger.java:270)
ip-172-24-16-229 API.Core [6377]: #011at org.slf4j.simple.SimpleLogger.write(SimpleLogger.java:262)
ip-172-24-16-229 API.Core [6377]: #011at org.slf4j.simple.SimpleLogger.innerHandleNormalizedLoggingCall(SimpleLogger.java:439)
ip-172-24-16-229 API.Core [6377]: #011at org.slf4j.simple.SimpleLogger.handleNormalizedLoggingCall(SimpleLogger.java:377)
ip-172-24-16-229 API.Core [6377]: #011at org.slf4j.helpers.AbstractLogger.handle_0ArgsCall(AbstractLogger.java:382)
ip-172-24-16-229 API.Core [6377]: #011at org.slf4j.helpers.AbstractLogger.error(AbstractLogger.java:347)
ip-172-24-16-229 API.Core [6377]: #011at io.vertx.core.logging.SLF4JLogDelegate.error(SLF4JLogDelegate.java:69)
ip-172-24-16-229 API.Core [6377]: #011at io.vertx.core.internal.logging.LoggerAdapter.error(LoggerAdapter.java:100)
ip-172-24-16-229 API.Core [6377]: #011at io.vertx.core.impl.ContextImpl.reportException(ContextImpl.java:181)
ip-172-24-16-229 API.Core [6377]: #011at io.vertx.core.impl.future.FutureBase.emitResult(FutureBase.java:71)
ip-172-24-16-229 API.Core [6377]: #011at io.vertx.core.impl.future.FutureImpl.completeInternal(FutureImpl.java:163)
ip-172-24-16-229 API.Core [6377]: #011at io.vertx.core.impl.future.FutureBase.emitResult(FutureBase.java:68)
ip-172-24-16-229 API.Core [6377]: #011at io.vertx.core.impl.future.FutureImpl.completeInternal(FutureImpl.java:163)
ip-172-24-16-229 API.Core [6377]: #011at io.vertx.core.impl.future.FutureBase.emitResult(FutureBase.java:68)
ip-172-24-16-229 API.Core [6377]: #011at io.vertx.core.impl.future.FutureImpl.completeInternal(FutureImpl.java:163)
...
[last two lines repeat ~1000 times]

I cannot isolate the actual cause because the stack trace implicates none of my LOCs - probably because the beginning of the trace is cut off.

This only appears to happen related to a ContextImpl.reportException() call, so this is likely caused by my code returning a FailedFuture somewhere from a deep completion chain. Still - if there was a way to avoid a chain of future compositions triggering a stack overflow - that would be best.

BTW - looking at emitResult(FutureBase.java:68) - it calls listener.compelete(), an implementation of which isn't listed in the stack trace. This probably means that the listener being completed is created by a function reference in either Transformation.java:44 or Composition.java:48 (my money is on the latter).

If there's a workaround that I can employ in my code - for example, this completion chain is probably generated by iterating many times through an internal HTTP processing mapper, which I can modify - maybe by somehow delegating the completion to a new stack (new thread / new event loop invocation), please let me know.

Steps to reproduce

Sorry, no reproducer ATM.

Do you have a reproducer?

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions