8031304: Add dcmd to print all loaded dynamic libraries.
Summary: Adding VM.dynlibs as a dcmd to dump all loaded dynamic libraries.
Reviewed-by: sla, fparain, mgronlun, dsamersoff
--- a/hotspot/src/share/vm/services/diagnosticCommand.cpp Mon Jan 13 18:30:57 2014 -0500
+++ b/hotspot/src/share/vm/services/diagnosticCommand.cpp Tue Jan 14 15:27:01 2014 +0100
@@ -25,6 +25,7 @@
#include "precompiled.hpp"
#include "gc_implementation/shared/vmGCOperations.hpp"
#include "runtime/javaCalls.hpp"
+#include "runtime/os.hpp"
#include "services/diagnosticArgument.hpp"
#include "services/diagnosticCommand.hpp"
#include "services/diagnosticFramework.hpp"
@@ -44,6 +45,7 @@
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<CommandLineDCmd>(full_export, true, false));
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<PrintSystemPropertiesDCmd>(full_export, true, false));
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<PrintVMFlagsDCmd>(full_export, true, false));
+ DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<VMDynamicLibrariesDCmd>(full_export, true, false));
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<VMUptimeDCmd>(full_export, true, false));
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<SystemGCDCmd>(full_export, true, false));
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<RunFinalizationDCmd>(full_export, true, false));
@@ -610,8 +612,7 @@
}
JMXStartLocalDCmd::JMXStartLocalDCmd(outputStream *output, bool heap_allocated) :
- DCmd(output, heap_allocated)
-{
+ DCmd(output, heap_allocated) {
// do nothing
}
@@ -632,7 +633,6 @@
JavaCalls::call_static(&result, ik, vmSymbols::startLocalAgent_name(), vmSymbols::void_method_signature(), CHECK);
}
-
void JMXStopRemoteDCmd::execute(DCmdSource source, TRAPS) {
ResourceMark rm(THREAD);
HandleMark hm(THREAD);
@@ -650,3 +650,12 @@
JavaCalls::call_static(&result, ik, vmSymbols::stopRemoteAgent_name(), vmSymbols::void_method_signature(), CHECK);
}
+VMDynamicLibrariesDCmd::VMDynamicLibrariesDCmd(outputStream *output, bool heap_allocated) :
+ DCmd(output, heap_allocated) {
+ // do nothing
+}
+
+void VMDynamicLibrariesDCmd::execute(DCmdSource source, TRAPS) {
+ os::print_dll_info(output());
+ output()->cr();
+}
--- a/hotspot/src/share/vm/services/diagnosticCommand.hpp Mon Jan 13 18:30:57 2014 -0500
+++ b/hotspot/src/share/vm/services/diagnosticCommand.hpp Tue Jan 14 15:27:01 2014 +0100
@@ -132,6 +132,29 @@
virtual void execute(DCmdSource source, TRAPS);
};
+class VMDynamicLibrariesDCmd : public DCmd {
+public:
+ VMDynamicLibrariesDCmd(outputStream* output, bool heap);
+ static const char* name() {
+ return "VM.dynlibs";
+ }
+ static const char* description() {
+ return "Print loaded dynamic libraries.";
+ }
+ static const char* impact() {
+ return "Low";
+ }
+ static const JavaPermission permission() {
+ JavaPermission p = {"java.lang.management.ManagementPermission",
+ "monitor", NULL};
+ return p;
+ }
+ static int num_arguments() {
+ return 0;
+ };
+ virtual void execute(DCmdSource source, TRAPS);
+};
+
class VMUptimeDCmd : public DCmdWithParser {
protected:
DCmdArgument<bool> _date;
--- a/hotspot/test/TEST.groups Mon Jan 13 18:30:57 2014 -0500
+++ b/hotspot/test/TEST.groups Tue Jan 14 15:27:01 2014 +0100
@@ -86,7 +86,8 @@
runtime/RedefineObject/TestRedefineObject.java \
runtime/XCheckJniJsig/XCheckJSig.java \
serviceability/attach/AttachWithStalePidFile.java \
- serviceability/sa/jmap-hprof/JMapHProfLargeHeapTest.java
+ serviceability/sa/jmap-hprof/JMapHProfLargeHeapTest.java \
+ serviceability/dcmd/DynLibDcmdTest.java
# JRE adds further tests to compact3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/dcmd/DcmdUtil.java Tue Jan 14 15:27:01 2014 +0100
@@ -0,0 +1,73 @@
+/*
+ * 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.
+ */
+
+import sun.management.ManagementFactoryHelper;
+
+import com.sun.management.DiagnosticCommandMBean;
+
+public class DcmdUtil
+{
+ public static String executeDcmd(String cmd, String ... args) {
+ DiagnosticCommandMBean dcmd = ManagementFactoryHelper.getDiagnosticCommandMBean();
+ Object[] dcmdArgs = {args};
+ String[] signature = {String[].class.getName()};
+
+ try {
+ System.out.print("> " + cmd + " ");
+ for (String s : args) {
+ System.out.print(s + " ");
+ }
+ System.out.println(":");
+ String result = (String) dcmd.invoke(transform(cmd), dcmdArgs, signature);
+ System.out.println(result);
+ return result;
+ } catch(Exception ex) {
+ ex.printStackTrace();
+ }
+ return null;
+ }
+
+ private static String transform(String name) {
+ StringBuilder sb = new StringBuilder();
+ boolean toLower = true;
+ boolean toUpper = false;
+ for (int i = 0; i < name.length(); i++) {
+ char c = name.charAt(i);
+ if (c == '.' || c == '_') {
+ toLower = false;
+ toUpper = true;
+ } else {
+ if (toUpper) {
+ toUpper = false;
+ sb.append(Character.toUpperCase(c));
+ } else if(toLower) {
+ sb.append(Character.toLowerCase(c));
+ } else {
+ sb.append(c);
+ }
+ }
+ }
+ return sb.toString();
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/dcmd/DynLibDcmdTest.java Tue Jan 14 15:27:01 2014 +0100
@@ -0,0 +1,67 @@
+import java.util.HashSet;
+import java.util.Set;
+import com.oracle.java.testlibrary.Platform;
+
+/*
+ * 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
+ * @summary Test of VM.dynlib diagnostic command via MBean
+ * @library /testlibrary
+ * @compile DcmdUtil.java
+ * @run main DynLibDcmdTest
+ */
+
+public class DynLibDcmdTest {
+
+ public static void main(String[] args) throws Exception {
+ String result = DcmdUtil.executeDcmd("VM.dynlibs");
+
+ String osDependentBaseString = null;
+ if (Platform.isSolaris()) {
+ osDependentBaseString = "lib%s.so";
+ } else if (Platform.isWindows()) {
+ osDependentBaseString = "%s.dll";
+ } else if (Platform.isOSX()) {
+ osDependentBaseString = "lib%s.dylib";
+ } else if (Platform.isLinux()) {
+ osDependentBaseString = "lib%s.so";
+ }
+
+ if (osDependentBaseString == null) {
+ throw new Exception("Unsupported OS");
+ }
+
+ Set<String> expectedContent = new HashSet<>();
+ expectedContent.add(String.format(osDependentBaseString, "jvm"));
+ expectedContent.add(String.format(osDependentBaseString, "java"));
+ expectedContent.add(String.format(osDependentBaseString, "management"));
+
+ for(String expected : expectedContent) {
+ if (!result.contains(expected)) {
+ throw new Exception("Dynamic library list output did not contain the expected string: '" + expected + "'");
+ }
+ }
+ }
+}