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

test/jdk/tools/jlink/JLinkReproducibleTest.java fails randomly when cds is disabled

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Closed
    • Priority: P4
    • Resolution: Cannot Reproduce
    • Affects Version/s: 11
    • Fix Version/s: None
    • Component/s: tools
    • Labels:
    • Subcomponent:
    • Introduced In Build:
      b01
    • Introduced In Version:

      Description

      $ bash configure --disable-cds-archive

      $ jtreg -va test/jdk/tools/jlink/JLinkReproducibleTest.java(1/100)
      STDERR:
      java.lang.RuntimeException: assertEquals: expected -1 to equal 53610
              at jdk.test.lib.Asserts.fail(Asserts.java:594)
              at jdk.test.lib.Asserts.assertEquals(Asserts.java:205)
              at jdk.test.lib.Asserts.assertEquals(Asserts.java:189)
              at JLinkReproducibleTest.main(JLinkReproducibleTest.java:115)
              at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
              at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:78)
              at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
              at java.base/java.lang.reflect.Method.invoke(Method.java:567)
              at com.sun.javatest.regtest.agent.MainWrapper$MainThread.run(MainWrapper.java:127)
              at java.base/java.lang.Thread.run(Thread.java:831)

      JavaTest Message: Test threw exception: java.lang.RuntimeException: assertEquals: expected -1 to equal 53610

      $ cd JTwork/scratch/
      $ jimage extract --dir module-a image-first/lib/modules && jimage extract --dir module-b image-second/lib/modules
      $ javap -verbose -constants -s -l -private module-a/java.base/jdk/internal/module/SystemModules\$all.class > SystemModules$all.class.a && javap -verbose -constants -s -l -private module-b/java.base/jdk/internal/module/SystemModules\$all.class > SystemModules$all.class.b

      $ diff -U0 SystemModules$all.class.a SystemModules$all.class.b
      --- SystemModules.class.a 2020-12-25 11:12:49.552000000 +0800
      +++ SystemModules.class.b 2020-12-25 11:12:39.440000000 +0800
      @@ -1 +1 @@
      -Classfile /home/hedongbo/myprojects/github/jdk.bak/test_result-JLinkReproducibleTest/jtwork-52/scratch/module-a/java.base/jdk/internal/module/SystemModules$all.class
      +Classfile /home/hedongbo/myprojects/github/jdk.bak/test_result-JLinkReproducibleTest/jtwork-52/scratch/module-b/java.base/jdk/internal/module/SystemModules$all.class
      @@ -3 +3 @@
      - SHA-256 checksum b3e38cdf0f162d1d1e35ef2f43d28a961cd4b97c611a43e8e97064f8bcff41fb
      + SHA-256 checksum b2c4b6048130ad249f26d97b005e861b042c894bcd3e69c40a9a193c8674258d
      @@ -628 +628 @@
      - #617 = Integer 1300050017
      + #617 = Integer 2026721104
      @@ -2744 +2744 @@
      - 3592: ldc_w #617 // int 1300050017
      + 3592: ldc_w #617 // int 2026721104

      We first discovered this problem in jdk11 (after backport JDK-8214230), and then I found that this problem will also occur when removing JDK-8202951 in jdk/jdk





      The random value is md.hashCode() in the SystemModulesPlugin.SystemModulesPlugin.SystemModulesPlugin:putmoduledescriptor()
      ```
      void putModuleDescriptor() {
          mv.visitVarInsn(ALOAD, MD_VAR);
          pushInt(mv, index);
          mv.visitVarInsn(ALOAD, BUILDER_VAR);
          mv.visitLdcInsn(md.hashCode()); // md.hashCode() is a random value
          mv.visitMethodInsn(INVOKEVIRTUAL, MODULE_DESCRIPTOR_BUILDER,
              "build", "(I)Ljava/lang/module/ModuleDescriptor;",
              false);
          mv.visitInsn(AASTORE);
      }
      ```
      When calculating md.hashCode(), it will use the hashcode of modifiers, requirements, exports and opens. However, these values have the Modifier field directly or indirectly (Modifier is an enum). Because the object hashcode of enum may be different in different JVMs, random values will be generated here.
      ```
      public int hashCode() {
          int hc = hash;
          if (hc == 0) {
              hc = name.hashCode();
              hc = hc * 43 + Objects.hashCode(modifiers); // Set<Modifier> modifiers;
              hc = hc * 43 + requires.hashCode(); // Set<Requires> requires
              hc = hc * 43 + Objects.hashCode(packages);
              hc = hc * 43 + exports.hashCode(); // Set<Exports> exports
              hc = hc * 43 + opens.hashCode(); // Set<Opens> opens
              hc = hc * 43 + uses.hashCode();
              hc = hc * 43 + provides.hashCode();
              hc = hc * 43 + Objects.hashCode(version);
              hc = hc * 43 + Objects.hashCode(rawVersionString);
              hc = hc * 43 + Objects.hashCode(mainClass);
              if (hc == 0)
                  hc = -1;
              hash = hc;
          }
          return hc;
      }
      ```
      In the case of this issue, the Modifier field in modifiers, exports and opens is null. Only requires has a Modifier field.
      So, when I fixed the hashCode of requires in the code, the case in issue passed in 1,000 runs



        Attachments

          Issue Links

            Activity

              People

              Assignee:
              sundar Sundararajan Athijegannathan
              Reporter:
              dongbohe Dongbo He
              Votes:
              0 Vote for this issue
              Watchers:
              6 Start watching this issue

                Dates

                Created:
                Updated:
                Resolved: