diff --git a/jdk/src/share/classes/com/sun/management/VMOption.java b/jdk/src/share/classes/com/sun/management/VMOption.java index d79bc5b4d67..fb6d8a6f469 100644 --- a/jdk/src/share/classes/com/sun/management/VMOption.java +++ b/jdk/src/share/classes/com/sun/management/VMOption.java @@ -96,6 +96,11 @@ public class VMOption { * The VM option was set via the VM ergonomic support. */ ERGONOMIC, + /** + * The VM option was set using the attach framework. + * @since 1.9 + */ + ATTACH_ON_DEMAND, /** * The VM option was set via some other mechanism. */ diff --git a/jdk/src/share/javavm/export/jmm.h b/jdk/src/share/javavm/export/jmm.h index 3f938e25055..f55610d1c0a 100644 --- a/jdk/src/share/javavm/export/jmm.h +++ b/jdk/src/share/javavm/export/jmm.h @@ -153,6 +153,7 @@ typedef enum { JMM_VMGLOBAL_ORIGIN_ENVIRON_VAR = 4, /* Set via environment variables */ JMM_VMGLOBAL_ORIGIN_CONFIG_FILE = 5, /* Set via config file (such as .hotspotrc) */ JMM_VMGLOBAL_ORIGIN_ERGONOMIC = 6, /* Set via ergonomic */ + JMM_VMGLOBAL_ORIGIN_ATTACH_ON_DEMAND = 7, /* Set via attach */ JMM_VMGLOBAL_ORIGIN_OTHER = 99 /* Set via some other mechanism */ } jmmVMGlobalOrigin; diff --git a/jdk/src/share/native/sun/management/Flag.c b/jdk/src/share/native/sun/management/Flag.c index cda64d51f8f..82aaaa77578 100644 --- a/jdk/src/share/native/sun/management/Flag.c +++ b/jdk/src/share/native/sun/management/Flag.c @@ -36,6 +36,7 @@ static jobject mgmt_origin = NULL; static jobject envvar_origin = NULL; static jobject config_file_origin = NULL; static jobject ergo_origin = NULL; +static jobject attach_origin = NULL; static jobject other_origin = NULL; JNIEXPORT jint JNICALL @@ -74,6 +75,7 @@ Java_sun_management_Flag_initialize envvar_origin = find_origin_constant(env, "ENVIRON_VAR"); config_file_origin = find_origin_constant(env, "CONFIG_FILE"); ergo_origin = find_origin_constant(env, "ERGONOMIC"); + attach_origin = find_origin_constant(env, "ATTACH_ON_DEMAND"); other_origin = find_origin_constant(env, "OTHER"); } @@ -154,6 +156,9 @@ Java_sun_management_Flag_getFlags case JMM_VMGLOBAL_ORIGIN_ERGONOMIC: origin = ergo_origin; break; + case JMM_VMGLOBAL_ORIGIN_ATTACH_ON_DEMAND: + origin = attach_origin; + break; case JMM_VMGLOBAL_ORIGIN_OTHER: origin = other_origin; break; diff --git a/jdk/test/com/sun/management/HotSpotDiagnosticMXBean/CheckOrigin.java b/jdk/test/com/sun/management/HotSpotDiagnosticMXBean/CheckOrigin.java new file mode 100644 index 00000000000..8c28db26cf9 --- /dev/null +++ b/jdk/test/com/sun/management/HotSpotDiagnosticMXBean/CheckOrigin.java @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8028994 + * @author Staffan Larsen + * @library /lib/testlibrary + * @run main CheckOrigin + */ + +import com.sun.management.HotSpotDiagnosticMXBean; +import com.sun.management.VMOption; +import com.sun.management.VMOption.Origin; +import com.sun.tools.attach.VirtualMachine; +import java.io.File; +import java.io.FileWriter; +import java.io.InputStream; +import java.io.PrintWriter; +import java.lang.management.ManagementFactory; +import java.util.Map; +import jdk.testlibrary.ProcessTools; +import sun.tools.attach.HotSpotVirtualMachine; + +public class CheckOrigin { + + private static HotSpotDiagnosticMXBean mbean; + + public static void main(String... args) throws Exception { + if (args.length == 0) { + // start a process that has options set in a number of different ways + + File flagsFile = File.createTempFile("CheckOriginFlags", null); + try (PrintWriter pw = + new PrintWriter(new FileWriter(flagsFile))) { + pw.println("+PrintSafepointStatistics"); + } + + ProcessBuilder pb = ProcessTools. + createJavaProcessBuilder( + "-XX:+PrintGCDetails", + "-XX:Flags=" + flagsFile.getAbsolutePath(), + "-cp", System.getProperty("test.class.path") + File.pathSeparator + getToolsJarPath(), + "CheckOrigin", + "-runtests"); + + Map env = pb.environment(); + env.put("_JAVA_OPTIONS", "-XX:+PrintOopAddress"); + + pb.redirectOutput(ProcessBuilder.Redirect.INHERIT); + pb.redirectError(ProcessBuilder.Redirect.INHERIT); + Process p = pb.start(); + int exit = p.waitFor(); + System.out.println("sub process exit == " + exit); + if (exit != 0) { + throw new Exception("Unexpected exit code from subprocess == " + exit); + } + } else { + mbean = + ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class); + + // set a few more options + mbean.setVMOption("HeapDumpOnOutOfMemoryError", "true"); + setOptionUsingAttach("HeapDumpPath", "/a/sample/path"); + + // check the origin field for all the options we set + checkOrigin("ManagementServer", Origin.DEFAULT); + checkOrigin("PrintGCDetails", Origin.VM_CREATION); + checkOrigin("PrintOopAddress", Origin.ENVIRON_VAR); + checkOrigin("PrintSafepointStatistics", Origin.CONFIG_FILE); + checkOrigin("HeapDumpOnOutOfMemoryError", Origin.MANAGEMENT); + checkOrigin("NewSize", Origin.ERGONOMIC); + checkOrigin("HeapDumpPath", Origin.ATTACH_ON_DEMAND); + } + } + + private static void checkOrigin(String option, Origin origin) throws Exception + { + Origin o = mbean.getVMOption(option).getOrigin(); + if (!o.equals(origin)) { + throw new Exception("Option '" + option + "' should have origin '" + origin + "' but had '" + o + "'"); + } + System.out.println("Option '" + option + "' verified origin = '" + origin + "'"); + } + + // use attach to set a manageable vm option + private static void setOptionUsingAttach(String option, String value) throws Exception { + HotSpotVirtualMachine vm = (HotSpotVirtualMachine) VirtualMachine.attach(ProcessTools.getProcessId()+""); + InputStream in = vm.setFlag(option, value); + System.out.println("Result from setting '" + option + "' to '" + value + "' using attach:"); + drain(vm, in); + System.out.println("-- end -- "); + } + + // Read the stream from the target VM until EOF, print to output, then detach + private static void drain(VirtualMachine vm, InputStream in) throws Exception { + byte b[] = new byte[256]; + int n; + do { + n = in.read(b); + if (n > 0) { + String s = new String(b, 0, n, "UTF-8"); + System.out.print(s); + } + } while (n > 0); + in.close(); + vm.detach(); + } + + private static String getToolsJarPath() { + return System.getProperty("java.home") + + "/../lib/tools.jar".replace("/", File.separator); + } +}