JDK-8231584 : Deadlock with ClassLoader.findLibrary and System.loadLibrary call
Type:Bug
Component:core-libs
Sub-Component:java.lang
Affected Version:14
Priority:P3
Status:Closed
Resolution:Fixed
Submitted:2019-09-27
Updated:2022-06-27
Resolved:2019-10-11
The Version table provides details related to the release that this issue/RFE will be addressed.
Unresolved : Release in which this issue/RFE will be addressed. Resolved: Release in which this issue/RFE has been resolved. Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.
JDK-8194653 seems to be applicable to jdk/jdk master.
Discussion thread: https://mail.openjdk.java.net/pipermail/core-libs-dev/2019-September/062621.html
Comments
As a result of discussion, skip this change for jdk13u for now... and take it in May. Applies cleanly.
29-05-2020
Please discuss 8u issue here https://mail.openjdk.java.net/pipermail/jdk8u-dev/2020-February/011256.html
25-02-2020
> I believe we need to restore this hunk (and make a simple regression test)
We cannot revert the hunk without reverting whole patch. The hunk was in critical section that was created by calling code. Without additional synchronization, the hunk will introduce race condition.
21-02-2020
I believe we need to restore this hunk (and make a simple regression test):
https://hg.openjdk.java.net/jdk8u/jdk8u/jdk/rev/1d666f78532a#l1.32
AFAICS, it would return the deadlock possibility when users hack "null"-s into it, but non-hacky code would still be unaffected.
21-02-2020
It seems to have caused regressions at least in 8u for some people. The new patch initializes sys_path once when initLibraryPaths is called during the bootstrap. Which works, until user code hacks into this with Reflection and sets sys_path back to null. AFAICS, previous code version would reinitialize sys_path when that was detected. See the example with jetbrains.buildServer.NativeLibraryPathHacker here: https://mail.openjdk.java.net/pipermail/jdk8u-dev/2020-January/011057.html
17-02-2020
Hi, Aleksey. Thanks for bookkeeping!
I would like to emphasis that openjdk14 and later, being new versions, do not need to maintain any expectations about private fields handling.
The fix may be considered as bringing regression for update projects only. For now, the patch was backported only to jdk8u and jdk11u. Let's discuss possible actions on appropriate maillist, if you'd like.
Hi Anton,
I'll run this through our test system and if no regressions spotted, I'll approve and push it for you. Ok?
03-12-2019
Thank you!
03-12-2019
OK, approved.
03-12-2019
Hi Christoph,
I have found a sponsor already, thank you. I'm just waiting for approve.
03-12-2019
Fix request (13u, 11u, 8u)
The fix have been in 14 repo for a while and no issues have been reported. So I would propose a backport of the fix (again:-)).
13u, 11u: applies cleanly
8u: https://mail.openjdk.java.net/pipermail/jdk8u-dev/2019-October/010475.html
25-11-2019
> If no issue is reported in the next 3-4 weeks (let's say), then it's good to proceed the backport.
OK, thanks!
> W.r.t. 8u backport: This fix might be applicable to 8u but this would require study of the 8u code base to confirm that.
I followed 8u implementation all the time to make sure it will fix the other bug. I found 8u/14 are equivalent from this fix perspective.
18-10-2019
[~akozlov] The new test you added is a good test case. As this fix changes the synchronization logic, giving it several weeks for the community to try out this fix that will be helpful as to shake out any issues in real-world applications. If no issue is reported in the next 3-4 weeks (let's say), then it's good to proceed the backport.
W.r.t. 8u backport: My suggestion to remove "synchronized" from Runtime::loadLibrary0 and Runtime::load0 was replying the current VM initialization that was significantly changed and improved in JDK 9 and the current implementation of ClassLoader.NativeLibrary loading. This fix might be applicable to 8u but this would require study of the 8u code base to confirm that.
17-10-2019
Oh. Does it mean the fix need to be evaluated by tests and/or users before we sure it's good?
I removed backport request labels for a while.
When would we be sure in the fix? Is this after some time passed and no one complains? Or after some tests passed?
I see "Resolved in Build" just got b19. So I believe the fix recently got in a build that is under tests now.
If so, is there any way to get know something broke after this? (or not)
I'm a bit rushing backport to 8u as it should resolve JDK-8194653 in OpenJDK. But I certainly do want to backport a good patch.
17-10-2019
[~akozlov] I would suggest to give time for this fix to bake before backporting to 11u and 13u.
16-10-2019
Fix request (13u, 11u)
The issue is reproducible on older versions of OpenJDK. Will request 8u after backport review approved
The deadlock is reproducible. Runtime::loadLibrary holds a lock on the Runtime object monitor should be re-visited.
"Thread-0" #12 prio=5 os_prio=31 cpu=16.15ms elapsed=65.19s tid=0x00007f8d33007000 nid=0x6003 waiting for monitor entry [0x000070000d065000]
java.lang.Thread.State: BLOCKED (on object monitor)
at java.lang.Runtime.loadLibrary0(java.base@14-internal/Runtime.java:798)
- waiting to lock <0x000000061fe021b0> (a java.lang.Runtime)
at java.lang.System.loadLibrary(java.base@14-internal/System.java:1909)
at jdk.net.MacOSXSocketOptions.<clinit>(jdk.net@14-internal/MacOSXSocketOptions.java:81)
at java.lang.Class.forName0(java.base@14-internal/Native Method)
at java.lang.Class.forName(java.base@14-internal/Class.java:333)
at jdk.net.ExtendedSocketOptions$PlatformSocketOptions.newInstance(jdk.net@14-internal/ExtendedSocketOptions.java:328)
at jdk.net.ExtendedSocketOptions$PlatformSocketOptions.create(jdk.net@14-internal/ExtendedSocketOptions.java:347)
at jdk.net.ExtendedSocketOptions$PlatformSocketOptions.<clinit>(jdk.net@14-internal/ExtendedSocketOptions.java:353)
at jdk.net.ExtendedSocketOptions.<clinit>(jdk.net@14-internal/ExtendedSocketOptions.java:165)
at Test8231584.someLibLoad(Test8231584.java:99)
at Test8231584$1.run(Test8231584.java:153)
"Thread-1" #13 prio=5 os_prio=31 cpu=2.82ms elapsed=65.19s tid=0x00007f8d3300c800 nid=0x9c03 in Object.wait() [0x000070000d169000]
java.lang.Thread.State: RUNNABLE
at Test8231584.someLibLoad(Test8231584.java:99)
- waiting on the Class initialization monitor for jdk.net.ExtendedSocketOptions
at Test8231584$TestClassLoader.findLibrary(Test8231584.java:119)
at java.lang.ClassLoader.loadLibrary(java.base@14-internal/ClassLoader.java:2633)
at java.lang.Runtime.loadLibrary0(java.base@14-internal/Runtime.java:806)
- locked <0x000000061fe021b0> (a java.lang.Runtime)
at java.lang.System.loadLibrary(java.base@14-internal/System.java:1909)
at Target.<clinit>(Test.java:9)
at java.lang.Class.forName0(java.base@14-internal/Native Method)
at java.lang.Class.forName(java.base@14-internal/Class.java:420)
at Test8231584$2.run(Test8231584.java:161)