From 621b19d4548f81d4dc4ac4b650d01212a48f5a20 Mon Sep 17 00:00:00 2001 From: dbuck Date: Thu, 21 Dec 2017 19:11:17 -0500 Subject: [PATCH] 8031304: Add dcmd to print all loaded dynamic libraries. Summary: Adding VM.dynlibs as a dcmd to dump all loaded dynamic libraries. Reviewed-by: fparain, mgronlun --- src/share/vm/services/diagnosticCommand.cpp | 16 ++++- src/share/vm/services/diagnosticCommand.hpp | 23 ++++++ test/TEST.groups | 1 + test/serviceability/dcmd/DcmdUtil.java | 73 ++++++++++++++++++++ test/serviceability/dcmd/DynLibDcmdTest.java | 67 ++++++++++++++++++ 5 files changed, 177 insertions(+), 3 deletions(-) create mode 100644 test/serviceability/dcmd/DcmdUtil.java create mode 100644 test/serviceability/dcmd/DynLibDcmdTest.java diff --git a/src/share/vm/services/diagnosticCommand.cpp b/src/share/vm/services/diagnosticCommand.cpp index 32c950d72..187453beb 100644 --- a/src/share/vm/services/diagnosticCommand.cpp +++ b/src/share/vm/services/diagnosticCommand.cpp @@ -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" @@ -47,6 +48,7 @@ void DCmdRegistrant::register_dcmds(){ DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); @@ -676,8 +678,7 @@ void JMXStartRemoteDCmd::execute(DCmdSource source, TRAPS) { } JMXStartLocalDCmd::JMXStartLocalDCmd(outputStream *output, bool heap_allocated) : - DCmd(output, heap_allocated) -{ + DCmd(output, heap_allocated) { // do nothing } @@ -698,7 +699,6 @@ void JMXStartLocalDCmd::execute(DCmdSource source, TRAPS) { 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); @@ -716,6 +716,16 @@ void JMXStopRemoteDCmd::execute(DCmdSource source, TRAPS) { 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(); +} + void RotateGCLogDCmd::execute(DCmdSource source, TRAPS) { if (UseGCLogFileRotation) { VM_RotateGCLog rotateop(output()); diff --git a/src/share/vm/services/diagnosticCommand.hpp b/src/share/vm/services/diagnosticCommand.hpp index b3bcad35a..b1fb57e53 100644 --- a/src/share/vm/services/diagnosticCommand.hpp +++ b/src/share/vm/services/diagnosticCommand.hpp @@ -132,6 +132,29 @@ public: 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 _date; diff --git a/test/TEST.groups b/test/TEST.groups index f2209c83e..40750364b 100644 --- a/test/TEST.groups +++ b/test/TEST.groups @@ -96,6 +96,7 @@ needs_jdk = \ runtime/XCheckJniJsig/XCheckJSig.java \ serviceability/attach/AttachWithStalePidFile.java \ serviceability/sa/jmap-hprof/JMapHProfLargeHeapTest.java \ + serviceability/dcmd/DynLibDcmdTest.java \ testlibrary_tests/ diff --git a/test/serviceability/dcmd/DcmdUtil.java b/test/serviceability/dcmd/DcmdUtil.java new file mode 100644 index 000000000..2542e6754 --- /dev/null +++ b/test/serviceability/dcmd/DcmdUtil.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2013, 2017, 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(); + } + +} diff --git a/test/serviceability/dcmd/DynLibDcmdTest.java b/test/serviceability/dcmd/DynLibDcmdTest.java new file mode 100644 index 000000000..c1a4a92c3 --- /dev/null +++ b/test/serviceability/dcmd/DynLibDcmdTest.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2013, 2017, 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 java.util.HashSet; +import java.util.Set; +import com.oracle.java.testlibrary.Platform; + +/* + * @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 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 + "'"); + } + } + } +} -- GitLab