1 /*
   2  * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /**
  25  * @test
  26  * @bug 8161605
  27  * @summary Tests that jvmtiEnv::GetPotentialCapabilities reports
  28  *          can_generate_all_class_hook_events capability with CDS (-Xshare:on)
  29  *          at ONLOAD and LIVE phases
  30  * @library /test/lib
  31  * @compile CanGenerateAllClassHook.java
  32  * @run main/othervm/native CanGenerateAllClassHook
  33  */
  34 
  35 import jdk.test.lib.cds.CDSTestUtils;
  36 import jdk.test.lib.process.OutputAnalyzer;
  37 import jdk.test.lib.process.ProcessTools;
  38 import java.io.File;
  39 import java.io.IOException;
  40 
  41 /*
  42  * The simplest way to test is to use system classes.jsa,
  43  * but we cannot rely on tested JRE/JDK has it.
  44  * So the test runs 2 java processes -
  45  * 1st to generate custom shared archive file:
  46  *     java -XX:+UnlockDiagnosticVMOptions -XX:SharedArchiveFile=<jsa_file> -Xshare:dump
  47  * and 2nd to perform the actual testing using generated shared archive:
  48  *     java -XX:+UnlockDiagnosticVMOptions -XX:SharedArchiveFile=<jsa_file> -Xshare:on
  49   *         -agentlib:<agent> CanGenerateAllClassHook
  50  */
  51 public class CanGenerateAllClassHook {
  52 
  53     private static final String agentLib = "CanGenerateAllClassHook";
  54 
  55     private static native int getClassHookAvail();
  56     private static native int getOnLoadClassHookAvail();
  57 
  58     public static void main(String[] args) throws Exception {
  59         if (args.length == 0) {
  60             // this is master run
  61 
  62             final File jsaFile = File.createTempFile(agentLib, ".jsa");
  63             jsaFile.deleteOnExit();
  64             final String jsaPath = jsaFile.getAbsolutePath();
  65 
  66             log("generating CDS archive...");
  67             execJava(
  68                         "-XX:+UnlockDiagnosticVMOptions",
  69                         "-XX:SharedArchiveFile=" + jsaPath,
  70                         "-Xshare:dump")
  71                     .shouldHaveExitValue(0);
  72             log("CDS generation completed.");
  73 
  74             OutputAnalyzer output = execJava(
  75                     "-XX:+UnlockDiagnosticVMOptions",
  76                     "-XX:SharedArchiveFile=" + jsaPath,
  77                     "-Xshare:on",
  78                     "-agentlib:" + agentLib,
  79                     // copy java.library.path
  80                     "-Djava.library.path=" + System.getProperty("java.library.path"),
  81                     // specify "-showversion" to ensure the test runs in shared mode
  82                     "-showversion",
  83                     // class to run
  84                     CanGenerateAllClassHook.class.getCanonicalName(),
  85                     // and arg
  86                     "test");
  87             // Xshare:on can cause intermittent failure
  88             // checkExec handles this.
  89             CDSTestUtils.checkExec(output);
  90 
  91             log("Test PASSED.");
  92         } else {
  93             // this is test run
  94             try {
  95                 System.loadLibrary(agentLib);
  96             } catch (UnsatisfiedLinkError ex) {
  97                 System.err.println("Failed to load " + agentLib + " lib");
  98                 System.err.println("java.library.path: " + System.getProperty("java.library.path"));
  99                 throw ex;
 100             }
 101 
 102             final int onLoadValue = getOnLoadClassHookAvail();
 103             final int liveValue = getClassHookAvail();
 104             // Possible values returned:
 105             // 1 - the capability is supported;
 106             // 0 - the capability is not supported;
 107             // -1 - error occured.
 108 
 109             log("can_generate_all_class_hook_events value capability:");
 110             log("ONLOAD phase: " + (onLoadValue < 0 ? "Failed to read" : onLoadValue));
 111             log("LIVE phase: " + (liveValue < 0 ? "Failed to read" : liveValue));
 112             if (onLoadValue != 1 || liveValue != 1) {
 113                 throw new RuntimeException("The can_generate_all_class_hook_events capability "
 114                         + " is expected to be available in both ONLOAD and LIVE phases");
 115             }
 116         }
 117     }
 118 
 119     private static void log(String msg) {
 120         System.out.println(msg);
 121         System.out.flush();
 122     }
 123 
 124     private static OutputAnalyzer execJava(String... args) throws IOException {
 125         ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(args);
 126 
 127         OutputAnalyzer output = new OutputAnalyzer(pb.start());
 128 
 129         log("[STDERR]\n" + output.getStderr());
 130         log("[STDOUT]\n" + output.getStdout());
 131 
 132         return output;
 133     }
 134 
 135 }