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  * @requires vm.cds
  31  * @library /test/lib
  32  * @compile CanGenerateAllClassHook.java
  33  * @run main/othervm/native CanGenerateAllClassHook
  34  */
  35 
  36 import jdk.test.lib.cds.CDSTestUtils;
  37 import jdk.test.lib.process.OutputAnalyzer;
  38 import jdk.test.lib.process.ProcessTools;
  39 import java.io.File;
  40 import java.io.IOException;
  41 
  42 /*
  43  * The simplest way to test is to use system classes.jsa,
  44  * but we cannot rely on tested JRE/JDK has it.
  45  * So the test runs 2 java processes -
  46  * 1st to generate custom shared archive file:
  47  *     java -XX:+UnlockDiagnosticVMOptions -XX:SharedArchiveFile=<jsa_file> -Xshare:dump
  48  * and 2nd to perform the actual testing using generated shared archive:
  49  *     java -XX:+UnlockDiagnosticVMOptions -XX:SharedArchiveFile=<jsa_file> -Xshare:on
  50   *         -agentlib:<agent> CanGenerateAllClassHook
  51  */
  52 public class CanGenerateAllClassHook {
  53 
  54     private static final String agentLib = "CanGenerateAllClassHook";
  55 
  56     private static native int getClassHookAvail();
  57     private static native int getOnLoadClassHookAvail();
  58 
  59     public static void main(String[] args) throws Exception {
  60         if (args.length == 0) {
  61             // this is master run
  62 
  63             final File jsaFile = File.createTempFile(agentLib, ".jsa");
  64             jsaFile.deleteOnExit();
  65             final String jsaPath = jsaFile.getAbsolutePath();
  66 
  67             log("generating CDS archive...");
  68             execJava(
  69                         "-XX:+UnlockDiagnosticVMOptions",
  70                         "-XX:SharedArchiveFile=" + jsaPath,
  71                         "-Xshare:dump")
  72                     .shouldHaveExitValue(0);
  73             log("CDS generation completed.");
  74 
  75             OutputAnalyzer output = execJava(
  76                     "-XX:+UnlockDiagnosticVMOptions",
  77                     "-XX:SharedArchiveFile=" + jsaPath,
  78                     "-Xshare:on",
  79                     "-agentlib:" + agentLib,
  80                     // copy java.library.path
  81                     "-Djava.library.path=" + System.getProperty("java.library.path"),
  82                     // specify "-showversion" to ensure the test runs in shared mode
  83                     "-showversion",
  84                     // class to run
  85                     CanGenerateAllClassHook.class.getCanonicalName(),
  86                     // and arg
  87                     "test");
  88             // Xshare:on can cause intermittent failure
  89             // checkExec handles this.
  90             CDSTestUtils.checkExec(output);
  91 
  92             log("Test PASSED.");
  93         } else {
  94             // this is test run
  95             try {
  96                 System.loadLibrary(agentLib);
  97             } catch (UnsatisfiedLinkError ex) {
  98                 System.err.println("Failed to load " + agentLib + " lib");
  99                 System.err.println("java.library.path: " + System.getProperty("java.library.path"));
 100                 throw ex;
 101             }
 102 
 103             final int onLoadValue = getOnLoadClassHookAvail();
 104             final int liveValue = getClassHookAvail();
 105             // Possible values returned:
 106             // 1 - the capability is supported;
 107             // 0 - the capability is not supported;
 108             // -1 - error occured.
 109 
 110             log("can_generate_all_class_hook_events value capability:");
 111             log("ONLOAD phase: " + (onLoadValue < 0 ? "Failed to read" : onLoadValue));
 112             log("LIVE phase: " + (liveValue < 0 ? "Failed to read" : liveValue));
 113             if (onLoadValue != 1 || liveValue != 1) {
 114                 throw new RuntimeException("The can_generate_all_class_hook_events capability "
 115                         + " is expected to be available in both ONLOAD and LIVE phases");
 116             }
 117         }
 118     }
 119 
 120     private static void log(String msg) {
 121         System.out.println(msg);
 122         System.out.flush();
 123     }
 124 
 125     private static OutputAnalyzer execJava(String... args) throws IOException {
 126         ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(args);
 127 
 128         OutputAnalyzer output = new OutputAnalyzer(pb.start());
 129 
 130         log("[STDERR]\n" + output.getStderr());
 131         log("[STDOUT]\n" + output.getStdout());
 132 
 133         return output;
 134     }
 135 
 136 }