Skip to content

tsan: okhttpserver socket close data race #10228

Closed
@YifeiZhuang

Description

@YifeiZhuang

Problem

TSAN(go/tsan) reports error:

WARNING: ThreadSanitizer: data race (pid=2317)
  Read of size 1 at 0x0000cfabb9bc by thread T56 (mutexes: write M0, write M1, write M2):
    #0 java.net.Socket.close()V Socket.java:1512 
    #1 io.grpc.okhttp.OkHttpServerTransportTest$PipeSocket.close()V OkHttpServerTransportTest.java:1384 
    #2 io.grpc.internal.GrpcUtil.closeQuietly(Ljava/io/Closeable;)V GrpcUtil.java:812 
    #3 io.grpc.okhttp.OkHttpServerTransport.shutdown(Ljava/lang/Long;)V OkHttpServerTransport.java:271 
    #4 io.grpc.okhttp.OkHttpServerTransport.shutdown()V OkHttpServerTransport.java:259 
    #5 io.grpc.okhttp.OkHttpServerTransportTest.shutdownDuringHandshake()V OkHttpServerTransportTest.java:262 
    #6 (Generated Stub) <null> 
    #7 jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object; NativeMethodAccessorImpl.java:62 
    #8 jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object; DelegatingMethodAccessorImpl.java:43 
    #9 java.lang.reflect.Method.invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object; Method.java:566 
    #10 org.junit.runners.model.FrameworkMethod$1.runReflectiveCall()Ljava/lang/Object; FrameworkMethod.java:59 
    #11 org.junit.internal.runners.model.ReflectiveCallable.run()Ljava/lang/Object; ReflectiveCallable.java:12 
    #12 org.junit.runners.model.FrameworkMethod.invokeExplosively(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object; FrameworkMethod.java:61 
    #13 org.junit.internal.runners.statements.InvokeMethod.evaluate()V InvokeMethod.java:17 
    #14 org.junit.internal.runners.statements.RunBefores.evaluate()V RunBefores.java:26 
    #15 org.junit.internal.runners.statements.RunAfters.evaluate()V RunAfters.java:27 
    #16 org.junit.internal.runners.statements.FailOnTimeout$CallableStatement.call()Ljava/lang/Throwable; FailOnTimeout.java:299 
    #17 org.junit.internal.runners.statements.FailOnTimeout$CallableStatement.call()Ljava/lang/Object; FailOnTimeout.java:293 
    #18 java.util.concurrent.FutureTask.run()V FutureTask.java:264 
    #19 java.lang.Thread.run()V Thread.java:830 
    #20 (Generated Stub) <null> 

  Previous write of size 1 at 0x0000cfabb9bc by thread T57:
    #0 java.net.Socket.createImpl(Z)V Socket.java:478 
    #1 java.net.Socket.getImpl()Ljava/net/SocketImpl; Socket.java:540 
    #2 java.net.Socket.setTcpNoDelay(Z)V Socket.java:998 
    #3 io.grpc.okhttp.OkHttpServerTransport.startIo(Lio/grpc/internal/SerializingExecutor;)V OkHttpServerTransport.java:164 
    #4 io.grpc.okhttp.OkHttpServerTransport.lambda$start$0(Lio/grpc/internal/SerializingExecutor;)V OkHttpServerTransport.java:159 
    #5 io.grpc.okhttp.OkHttpServerTransport$$Lambda$56.run()V ?? 
    #6 io.grpc.internal.SerializingExecutor.run()V SerializingExecutor.java:133 
    #7 java.util.concurrent.ThreadPoolExecutor.runWorker(Ljava/util/concurrent/ThreadPoolExecutor$Worker;)V ThreadPoolExecutor.java:1130 
    #8 java.util.concurrent.ThreadPoolExecutor$Worker.run()V ThreadPoolExecutor.java:630 
    #9 java.lang.Thread.run()V Thread.java:830 
    #10 (Generated Stub) <null> 

Fushion link

The tls wrapper socket is synchronizing on bareSocket, however, okhttpserver is using bareSocket APIs directly that is not threadsafe.

Solution

To fix, we will want to use the wrapper socket consistently cross the implementation and tests.

Acceptance Criteria

Reproduction and verification run in google3 passed (blaze flag --config=tsan)

cc. @ejona86

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions