Skip to content

Commit

Permalink
Allowlist ReferenceCountUpdater.retryRelease0 in Netty blockhound int… (
Browse files Browse the repository at this point in the history
#13677)

…egration

Motivation:

Running the Netty blockhound integration results in false positive
BlockingOperatorErrors on fireChannelUnregistered when using reference
counted SSL engine. I've attached a stack trace below indicating that
the `thread.yeild()` is called and marked as a blocking operator within
the `ReferenceCountUpdater` `retryRelease0` method. My guess is that
this is intentional and generally assumed to be ok, meaning we dont'
want to throw and cause a pipeline error.

Modifications:

Add `allowBlockingCallsInside` for the
`ReferenceCountUpdater.retryRelease0` in the blockhound integration

Result:

`BlockingOperationError` will no longer be thrown when
`fireChannelUnregistered` is called with a reference counted ssl engine.

Example Stack Trace:

```
[2023-10-27 15:03:36,117] [WARN] An exceptionCaught() event was fired, and it reached at the tail of the pipeline. It usually means the last handler in the pipeline did not handle the exception.
(thread: thrift-eventloop-27)
(logger: io.netty.channel.DefaultChannelPipeline)
(err: reactor.blockhound.BlockingOperationError)
(errmsg: Blocking call! java.lang.Thread.yield)
(origin: java.base/java.lang.Thread.yield(Thread.java))
(fullstack:
io.netty.channel.ChannelPipelineException: io.netty.handler.ssl.SslHandler.handlerRemoved() has thrown an exception.
	at io.netty.channel.DefaultChannelPipeline.callHandlerRemoved0(DefaultChannelPipeline.java:640)
	at io.netty.channel.DefaultChannelPipeline.destroyDown(DefaultChannelPipeline.java:876)
	at io.netty.channel.DefaultChannelPipeline.destroyUp(DefaultChannelPipeline.java:844)
	at io.netty.channel.DefaultChannelPipeline.destroy(DefaultChannelPipeline.java:836)
	at io.netty.channel.DefaultChannelPipeline.access$700(DefaultChannelPipeline.java:46)
	at io.netty.channel.DefaultChannelPipeline$HeadContext.channelUnregistered(DefaultChannelPipeline.java:1392)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelUnregistered(AbstractChannelHandlerContext.java:215)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelUnregistered(AbstractChannelHandlerContext.java:195)
	at io.netty.channel.DefaultChannelPipeline.fireChannelUnregistered(DefaultChannelPipeline.java:821)
	at io.netty.channel.AbstractChannel$AbstractUnsafe$7.run(AbstractChannel.java:821)
	at io.netty.util.concurrent.AbstractEventExecutor.runTask(AbstractEventExecutor.java:173)
	at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:166)
	at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:470)
	at io.netty.channel.epoll.EpollEventLoop.run(Unknown Source)
	at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997)
	at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
	at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
	at java.base/java.lang.Thread.run(Unknown Source)
Caused by: reactor.blockhound.BlockingOperationError: Blocking call! java.lang.Thread.yield
	at java.base/java.lang.Thread.yield(Thread.java)
	at io.netty.util.internal.ReferenceCountUpdater.retryRelease0(ReferenceCountUpdater.java:186)
	at io.netty.util.internal.ReferenceCountUpdater.nonFinalRelease0(ReferenceCountUpdater.java:168)
	at io.netty.util.internal.ReferenceCountUpdater.release(ReferenceCountUpdater.java:148)
	at io.netty.util.AbstractReferenceCounted.release(AbstractReferenceCounted.java:76)
	at io.netty.handler.ssl.ReferenceCountedOpenSslContext.release(ReferenceCountedOpenSslContext.java:766)
	at io.netty.handler.ssl.ReferenceCountedOpenSslEngine$1.deallocate(ReferenceCountedOpenSslEngine.java:182)
	at io.netty.util.AbstractReferenceCounted.handleRelease(AbstractReferenceCounted.java:86)
	at io.netty.util.AbstractReferenceCounted.release(AbstractReferenceCounted.java:76)
	at io.netty.handler.ssl.ReferenceCountedOpenSslEngine.release(ReferenceCountedOpenSslEngine.java:517)
	at io.netty.util.ReferenceCountUtil.release(ReferenceCountUtil.java:90)
	at io.netty.handler.ssl.SslHandler.handlerRemoved0(SslHandler.java:724)
	at io.netty.handler.codec.ByteToMessageDecoder.handlerRemoved(ByteToMessageDecoder.java:272)
	at io.netty.channel.AbstractChannelHandlerContext.callHandlerRemoved(AbstractChannelHandlerContext.java:1122)
	at io.netty.channel.DefaultChannelPipeline.callHandlerRemoved0(DefaultChannelPipeline.java:637)
	... 17 more

```
  • Loading branch information
j-bahr authored Nov 3, 2023
1 parent d2a7264 commit 2e3f540
Showing 1 changed file with 3 additions and 0 deletions.
3 changes: 3 additions & 0 deletions common/src/main/java/io/netty/util/internal/Hidden.java
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,9 @@ public void applyTo(BlockHound.Builder builder) {
"io.netty.util.NetUtil$SoMaxConnAction",
"run");

builder.allowBlockingCallsInside("io.netty.util.internal.ReferenceCountUpdater",
"retryRelease0");

builder.allowBlockingCallsInside("io.netty.util.internal.PlatformDependent", "createTempFile");
builder.nonBlockingThreadPredicate(new Function<Predicate<Thread>, Predicate<Thread>>() {
@Override
Expand Down

0 comments on commit 2e3f540

Please sign in to comment.