Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8210373

Deadlock in libj2gss.so when loading "j2gss" and "net" libraries in parallel.

XMLWordPrintable

    • b11
    • x86_64
    • linux

        ADDITIONAL SYSTEM INFORMATION :
        $ uname -a
        Linux ip-172-31-5-194.ec2.internal 4.14.62-70.117.amzn2.x86_64 #1 SMP Fri Aug 10 20:14:53 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux

        $ rpm -q glibc
        glibc-2.26-28.amzn2.0.1.x86_64

        $ getconf GNU_LIBPTHREAD_VERSION
        NPTL 2.26

        $ cat /etc/os-release
        NAME="Amazon Linux"
        VERSION="2"
        ID="amzn"
        ID_LIKE="centos rhel fedora"
        VERSION_ID="2"
        PRETTY_NAME="Amazon Linux 2"
        ANSI_COLOR="0;33"
        CPE_NAME="cpe:2.3:o:amazon:amazon_linux:2"
        HOME_URL="https://amazonlinux.com/"

        A DESCRIPTION OF THE PROBLEM :
        I ran into this deadlock when running GSSManager.getInstance() and InetAddress.getLocalHost() in parallel. From a thread dump I found that GSSManager.getInstance() is loading SunNativeProvider and it gets stuck during class loading trying to load "j2gss". See here: http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/share/classes/sun/security/jgss/wrapper/SunNativeProvider.java#l75 . InetAddress loads "net" at class load: http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/share/classes/java/net/InetAddress.java#l273

        Loading these two libraries in parallel seems to cause the deadlock.

        STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
        Run attached code.
        $ javac -d bin -sourcepath src src/com/test/BugTest.java
        $ java -cp bin com.test.BugTest

        EXPECTED VERSUS ACTUAL BEHAVIOR :
        EXPECTED -
        The process completes.
        ACTUAL -
        The process hangs.

        ---------- BEGIN SOURCE ----------
        package com.test;

        import java.net.InetAddress;

        public class BugTest {
            public static void main(String[] args) throws InterruptedException {
                Thread load_j2gss = new Thread(() -> System.loadLibrary("j2gss"));
                Thread load_net = new Thread(() -> getHostname());

                load_j2gss.start();
                load_net.start();

                Thread.sleep(30000);

                if (load_j2gss.isAlive() || load_net.isAlive()) {
                    System.out.println("Hung!!!!");
                }

                System.out.println("Done");
            }

            private static void getHostname() {
                try {
                    InetAddress.getLocalHost();
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
        }
        ---------- END SOURCE ----------

        CUSTOMER SUBMITTED WORKAROUND :
        Load libraries sequentially.

        FREQUENCY : often


              weijun Weijun Wang
              webbuggrp Webbug Group
              Votes:
              0 Vote for this issue
              Watchers:
              10 Start watching this issue

                Created:
                Updated:
                Resolved: