data race in java.lang.ClassLoader.loadClass

Jérémy Coulon jeremy.coulon.jrmc at gmail.com
Fri Sep 18 13:39:10 UTC 2020


Hello

I would love to use TSan in my project that uses both Java and C++ code
(via JNI).
openjdk-tsan looks the perfect solution but I wonder if it is advanced
enough to give me useful results.

I built openjdk-tsan with gcc9. Currently I have a lot of reports from the
JVM itself.

For example, TSan says I have a data race
in java.lang.ClassLoader.loadClass():

>  ==================
>  WARNING: ThreadSanitizer: data race (pid=358045)
>    Read of size 4 at 0x0005cf6fe900 by thread T24 (mutexes: write
> M1068479037050653848, write M699465342575271728, write M210543308024232960,
> write M226868856673487656, write M289074826522627400, write
> M469218811642843152, write M236439005409773704, write M331748, write
> M848084129784262448):
>      #0 java.nio.Buffer.position()I Buffer.java:291
>      #1 java.util.zip.Inflater.inflate([BII)I Inflater.java:386
>      #2 java.util.zip.InflaterInputStream.read([BII)I
> InflaterInputStream.java:152
>      #3 jdk.internal.loader.Resource.getBytes()[B Resource.java:126
>      #4
> jdk.internal.loader.BuiltinClassLoader.defineClass(Ljava/lang/String;Ljdk/internal/loader/Resource;)Ljava/lang/Class;
> BuiltinClassLoader.java:822
>      #5
> jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(Ljava/lang/String;)Ljava/lang/Class;
> BuiltinClassLoader.java:723
>      #6
> jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(Ljava/lang/String;Z)Ljava/lang/Class;
> BuiltinClassLoader.java:646
>      #7
> jdk.internal.loader.BuiltinClassLoader.loadClass(Ljava/lang/String;Z)Ljava/lang/Class;
> BuiltinClassLoader.java:604
>      #8
> jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(Ljava/lang/String;Z)Ljava/lang/Class;
> ClassLoaders.java:178
>      #9
> java.lang.ClassLoader.loadClass(Ljava/lang/String;)Ljava/lang/Class;
> ClassLoader.java:523
>      #10 (Generated Stub) <null>
>


   Previous write of size 4 at 0x0005cf6fe900 by thread T25 (mutexes: write
> M1144758755745824288, write M1145040230722535312, write
> M1144758755722805080, write M1145040230699515824, write
> M1144758755745928632, write M1145040230722639376, write M24769823420602496,
> write M19025):
>      #0 java.nio.Buffer.position(I)Ljava/nio/Buffer; Buffer.java:310
>      #1 java.nio.ByteBuffer.position(I)Ljava/nio/ByteBuffer;
> ByteBuffer.java:1309
>      #2 java.util.zip.Inflater.inflate([BII)I Inflater.java:427
>      #3 java.util.zip.InflaterInputStream.read([BII)I
> InflaterInputStream.java:152
>      #4 jdk.internal.loader.Resource.getBytes()[B Resource.java:126
>      #5
> jdk.internal.loader.BuiltinClassLoader.defineClass(Ljava/lang/String;Ljdk/internal/loader/Resource;)Ljava/lang/Class;
> BuiltinClassLoader.java:822
>      #6
> jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(Ljava/lang/String;)Ljava/lang/Class;
> BuiltinClassLoader.java:723
>      #7
> jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(Ljava/lang/String;Z)Ljava/lang/Class;
> BuiltinClassLoader.java:646
>      #8
> jdk.internal.loader.BuiltinClassLoader.loadClass(Ljava/lang/String;Z)Ljava/lang/Class;
> BuiltinClassLoader.java:604
>      #9
> jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(Ljava/lang/String;Z)Ljava/lang/Class;
> ClassLoaders.java:178
>      #10
> java.lang.ClassLoader.loadClass(Ljava/lang/String;)Ljava/lang/Class;
> ClassLoader.java:523
>      #11 (Generated Stub) <null>
>


   Mutex M1068479037050653848 is already destroyed.
>    Mutex M699465342575271728 is already destroyed.
>    Mutex M210543308024232960 is already destroyed.
>    Mutex M226868856673487656 is already destroyed.
>    Mutex M289074826522627400 is already destroyed.
>    Mutex M469218811642843152 is already destroyed.
>    Mutex M236439005409773704 is already destroyed.
>


    Mutex M331748 (0x0005df799308) created at:

     #0 __tsan_java_mutex_lock <null> (libtsan.so.0+0x851b7)

     #1 SharedRuntime::tsan_oop_lock(Thread*, oop)
> /data/Jenkins-Slave/workspace/3rd-party_openjdk_develop/.conan/data/openjdk/15.0.0-internal+5b22e18/user/testing/build/5fb562640607222bbb71a57209d2cb3e8de8666a/openjdk/src/hotspot/share/runtime/sharedRuntime.cpp:1068
> (libjvm.so+0x154fbe3)

     #2
> jdk.internal.loader.BuiltinClassLoader.loadClass(Ljava/lang/String;Z)Ljava/lang/Class;
> BuiltinClassLoader.java:604

     #3
> jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(Ljava/lang/String;Z)Ljava/lang/Class;
> ClassLoaders.java:178

     #4
> java.lang.ClassLoader.loadClass(Ljava/lang/String;)Ljava/lang/Class;
> ClassLoader.java:523

     #5 (Generated Stub) <null>



   Mutex M848084129784262448 is already destroyed.
>    Mutex M1144758755745824288 is already destroyed.
>    Mutex M1145040230722535312 is already destroyed.
>    Mutex M1144758755722805080 is already destroyed.
>    Mutex M1145040230699515824 is already destroyed.
>    Mutex M1144758755745928632 is already destroyed.
>    Mutex M1145040230722639376 is already destroyed.
>    Mutex M24769823420602496 is already destroyed.
>
>    Mutex M19025 (0x0005cf705290) created at:
>      #0 __tsan_java_mutex_lock <null> (libtsan.so.0+0x851b7)
>      #1 SharedRuntime::tsan_oop_lock(Thread*, oop)
> /data/Jenkins-Slave/workspace/3rd-party_openjdk_develop/.conan/data/openjdk/15.0.0-internal+5b22e18/exalead/testing/build/5fb562640607222bbb71a57209d2cb3e8de8666a/openjdk/src/hotspot/share/runtime/sharedRuntime.cpp:1068
> (libjvm.so+0x154fbe3)
>      #2 java.util.zip.InflaterInputStream.read([BII)I
> InflaterInputStream.java:152
>      #3 jdk.internal.loader.Resource.getBytes()[B Resource.java:126
>      #4
> jdk.internal.loader.BuiltinClassLoader.defineClass(Ljava/lang/String;Ljdk/internal/loader/Resource;)Ljava/lang/Class;
> BuiltinClassLoader.java:822
>      #5
> jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(Ljava/lang/String;)Ljava/lang/Class;
> BuiltinClassLoader.java:723
>      #6
> jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(Ljava/lang/String;Z)Ljava/lang/Class;
> BuiltinClassLoader.java:646
>      #7
> jdk.internal.loader.BuiltinClassLoader.loadClass(Ljava/lang/String;Z)Ljava/lang/Class;
> BuiltinClassLoader.java:604
>      #8
> jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(Ljava/lang/String;Z)Ljava/lang/Class;
> ClassLoaders.java:178
>      #9
> java.lang.ClassLoader.loadClass(Ljava/lang/String;)Ljava/lang/Class;
> ClassLoader.java:523
>      #10 (Generated Stub) <null>
>


 SUMMARY: ThreadSanitizer: data race Buffer.java:291 in
> java.nio.Buffer.position()I


I suspect that some libraries packaged in the JDK are not instrumented (eg.
libzip.so).

I also have reports from stuff in java.util.concurrent. For example
AbstractOwnableSynchronizer or AbstractQueuedSynchronizer.

Any help on whether this is expected behavior would be nice.

Jérémy


More information about the tsan-dev mailing list