Path: blob/master/src/hotspot/share/services/diagnosticCommand.cpp
41144 views
/*1* Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324#include "precompiled.hpp"25#include "jvm.h"26#include "classfile/classLoaderHierarchyDCmd.hpp"27#include "classfile/classLoaderStats.hpp"28#include "classfile/javaClasses.hpp"29#include "classfile/systemDictionary.hpp"30#include "classfile/vmClasses.hpp"31#include "code/codeCache.hpp"32#include "compiler/compileBroker.hpp"33#include "compiler/directivesParser.hpp"34#include "gc/shared/gcVMOperations.hpp"35#include "memory/metaspace/metaspaceDCmd.hpp"36#include "memory/resourceArea.hpp"37#include "memory/universe.hpp"38#include "oops/objArrayOop.inline.hpp"39#include "oops/oop.inline.hpp"40#include "oops/typeArrayOop.inline.hpp"41#include "runtime/fieldDescriptor.inline.hpp"42#include "runtime/flags/jvmFlag.hpp"43#include "runtime/handles.inline.hpp"44#include "runtime/interfaceSupport.inline.hpp"45#include "runtime/javaCalls.hpp"46#include "runtime/jniHandles.hpp"47#include "runtime/os.hpp"48#include "runtime/vmOperations.hpp"49#include "runtime/vm_version.hpp"50#include "services/diagnosticArgument.hpp"51#include "services/diagnosticCommand.hpp"52#include "services/diagnosticFramework.hpp"53#include "services/heapDumper.hpp"54#include "services/management.hpp"55#include "services/writeableFlags.hpp"56#include "utilities/debug.hpp"57#include "utilities/events.hpp"58#include "utilities/formatBuffer.hpp"59#include "utilities/macros.hpp"606162static void loadAgentModule(TRAPS) {63ResourceMark rm(THREAD);64HandleMark hm(THREAD);6566JavaValue result(T_OBJECT);67Handle h_module_name = java_lang_String::create_from_str("jdk.management.agent", CHECK);68JavaCalls::call_static(&result,69vmClasses::module_Modules_klass(),70vmSymbols::loadModule_name(),71vmSymbols::loadModule_signature(),72h_module_name,73THREAD);74}7576void DCmdRegistrant::register_dcmds(){77// Registration of the diagnostic commands78// First argument specifies which interfaces will export the command79// Second argument specifies if the command is enabled80// Third argument specifies if the command is hidden81uint32_t full_export = DCmd_Source_Internal | DCmd_Source_AttachAPI82| DCmd_Source_MBean;83DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<HelpDCmd>(full_export, true, false));84DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<VersionDCmd>(full_export, true, false));85DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<CommandLineDCmd>(full_export, true, false));86DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<PrintSystemPropertiesDCmd>(full_export, true, false));87DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<PrintVMFlagsDCmd>(full_export, true, false));88DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<SetVMFlagDCmd>(full_export, true, false));89DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<VMDynamicLibrariesDCmd>(full_export, true, false));90DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<VMUptimeDCmd>(full_export, true, false));91DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<VMInfoDCmd>(full_export, true, false));92DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<SystemGCDCmd>(full_export, true, false));93DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<RunFinalizationDCmd>(full_export, true, false));94DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<HeapInfoDCmd>(full_export, true, false));95DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<FinalizerInfoDCmd>(full_export, true, false));96#if INCLUDE_SERVICES97DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<HeapDumpDCmd>(DCmd_Source_Internal | DCmd_Source_AttachAPI, true, false));98DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ClassHistogramDCmd>(full_export, true, false));99DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<SystemDictionaryDCmd>(full_export, true, false));100DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ClassHierarchyDCmd>(full_export, true, false));101DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<SymboltableDCmd>(full_export, true, false));102DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<StringtableDCmd>(full_export, true, false));103DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<metaspace::MetaspaceDCmd>(full_export, true, false));104DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<EventLogDCmd>(full_export, true, false));105#if INCLUDE_JVMTI // Both JVMTI and SERVICES have to be enabled to have this dcmd106DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JVMTIAgentLoadDCmd>(full_export, true, false));107#endif // INCLUDE_JVMTI108#endif // INCLUDE_SERVICES109#if INCLUDE_JVMTI110DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JVMTIDataDumpDCmd>(full_export, true, false));111#endif // INCLUDE_JVMTI112DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ThreadDumpDCmd>(full_export, true, false));113DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ClassLoaderStatsDCmd>(full_export, true, false));114DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ClassLoaderHierarchyDCmd>(full_export, true, false));115DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<CompileQueueDCmd>(full_export, true, false));116DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<CodeListDCmd>(full_export, true, false));117DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<CodeCacheDCmd>(full_export, true, false));118#ifdef LINUX119DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<PerfMapDCmd>(full_export, true, false));120#endif // LINUX121DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<TouchedMethodsDCmd>(full_export, true, false));122DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<CodeHeapAnalyticsDCmd>(full_export, true, false));123124DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<CompilerDirectivesPrintDCmd>(full_export, true, false));125DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<CompilerDirectivesAddDCmd>(full_export, true, false));126DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<CompilerDirectivesRemoveDCmd>(full_export, true, false));127DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<CompilerDirectivesClearDCmd>(full_export, true, false));128129// Enhanced JMX Agent Support130// These commands won't be exported via the DiagnosticCommandMBean until an131// appropriate permission is created for them132uint32_t jmx_agent_export_flags = DCmd_Source_Internal | DCmd_Source_AttachAPI;133DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JMXStartRemoteDCmd>(jmx_agent_export_flags, true,false));134DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JMXStartLocalDCmd>(jmx_agent_export_flags, true,false));135DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JMXStopRemoteDCmd>(jmx_agent_export_flags, true,false));136DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JMXStatusDCmd>(jmx_agent_export_flags, true,false));137138// Debug on cmd (only makes sense with JVMTI since the agentlib needs it).139#if INCLUDE_JVMTI140DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<DebugOnCmdStartDCmd>(full_export, true, true));141#endif // INCLUDE_JVMTI142143#if INCLUDE_CDS144DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<DumpSharedArchiveDCmd>(full_export, true, false));145#endif // INCLUDE_CDS146}147148#ifndef HAVE_EXTRA_DCMD149void DCmdRegistrant::register_dcmds_ext(){150// Do nothing here151}152#endif153154155HelpDCmd::HelpDCmd(outputStream* output, bool heap) : DCmdWithParser(output, heap),156_all("-all", "Show help for all commands", "BOOLEAN", false, "false"),157_cmd("command name", "The name of the command for which we want help",158"STRING", false) {159_dcmdparser.add_dcmd_option(&_all);160_dcmdparser.add_dcmd_argument(&_cmd);161};162163164static int compare_strings(const char** s1, const char** s2) {165return ::strcmp(*s1, *s2);166}167168void HelpDCmd::execute(DCmdSource source, TRAPS) {169if (_all.value()) {170GrowableArray<const char*>* cmd_list = DCmdFactory::DCmd_list(source);171cmd_list->sort(compare_strings);172for (int i = 0; i < cmd_list->length(); i++) {173DCmdFactory* factory = DCmdFactory::factory(source, cmd_list->at(i),174strlen(cmd_list->at(i)));175output()->print_cr("%s%s", factory->name(),176factory->is_enabled() ? "" : " [disabled]");177output()->print_cr("\t%s", factory->description());178output()->cr();179factory = factory->next();180}181} else if (_cmd.has_value()) {182DCmd* cmd = NULL;183DCmdFactory* factory = DCmdFactory::factory(source, _cmd.value(),184strlen(_cmd.value()));185if (factory != NULL) {186output()->print_cr("%s%s", factory->name(),187factory->is_enabled() ? "" : " [disabled]");188output()->print_cr("%s", factory->description());189output()->print_cr("\nImpact: %s", factory->impact());190JavaPermission p = factory->permission();191if(p._class != NULL) {192if(p._action != NULL) {193output()->print_cr("\nPermission: %s(%s, %s)",194p._class, p._name == NULL ? "null" : p._name, p._action);195} else {196output()->print_cr("\nPermission: %s(%s)",197p._class, p._name == NULL ? "null" : p._name);198}199}200output()->cr();201cmd = factory->create_resource_instance(output());202if (cmd != NULL) {203DCmdMark mark(cmd);204cmd->print_help(factory->name());205}206} else {207output()->print_cr("Help unavailable : '%s' : No such command", _cmd.value());208}209} else {210output()->print_cr("The following commands are available:");211GrowableArray<const char *>* cmd_list = DCmdFactory::DCmd_list(source);212cmd_list->sort(compare_strings);213for (int i = 0; i < cmd_list->length(); i++) {214DCmdFactory* factory = DCmdFactory::factory(source, cmd_list->at(i),215strlen(cmd_list->at(i)));216output()->print_cr("%s%s", factory->name(),217factory->is_enabled() ? "" : " [disabled]");218factory = factory->_next;219}220output()->print_cr("\nFor more information about a specific command use 'help <command>'.");221}222}223224void VersionDCmd::execute(DCmdSource source, TRAPS) {225output()->print_cr("%s version %s", VM_Version::vm_name(),226VM_Version::vm_release());227JDK_Version jdk_version = JDK_Version::current();228if (jdk_version.patch_version() > 0) {229output()->print_cr("JDK %d.%d.%d.%d", jdk_version.major_version(),230jdk_version.minor_version(), jdk_version.security_version(),231jdk_version.patch_version());232} else {233output()->print_cr("JDK %d.%d.%d", jdk_version.major_version(),234jdk_version.minor_version(), jdk_version.security_version());235}236}237238PrintVMFlagsDCmd::PrintVMFlagsDCmd(outputStream* output, bool heap) :239DCmdWithParser(output, heap),240_all("-all", "Print all flags supported by the VM", "BOOLEAN", false, "false") {241_dcmdparser.add_dcmd_option(&_all);242}243244void PrintVMFlagsDCmd::execute(DCmdSource source, TRAPS) {245if (_all.value()) {246JVMFlag::printFlags(output(), true);247} else {248JVMFlag::printSetFlags(output());249}250}251252SetVMFlagDCmd::SetVMFlagDCmd(outputStream* output, bool heap) :253DCmdWithParser(output, heap),254_flag("flag name", "The name of the flag we want to set",255"STRING", true),256_value("string value", "The value we want to set", "STRING", false) {257_dcmdparser.add_dcmd_argument(&_flag);258_dcmdparser.add_dcmd_argument(&_value);259}260261void SetVMFlagDCmd::execute(DCmdSource source, TRAPS) {262const char* val = NULL;263if (_value.value() != NULL) {264val = _value.value();265}266267FormatBuffer<80> err_msg("%s", "");268int ret = WriteableFlags::set_flag(_flag.value(), val, JVMFlagOrigin::MANAGEMENT, err_msg);269270if (ret != JVMFlag::SUCCESS) {271output()->print_cr("%s", err_msg.buffer());272}273}274275void JVMTIDataDumpDCmd::execute(DCmdSource source, TRAPS) {276if (JvmtiExport::should_post_data_dump()) {277JvmtiExport::post_data_dump();278}279}280281#if INCLUDE_SERVICES282#if INCLUDE_JVMTI283JVMTIAgentLoadDCmd::JVMTIAgentLoadDCmd(outputStream* output, bool heap) :284DCmdWithParser(output, heap),285_libpath("library path", "Absolute path of the JVMTI agent to load.",286"STRING", true),287_option("agent option", "Option string to pass the agent.", "STRING", false) {288_dcmdparser.add_dcmd_argument(&_libpath);289_dcmdparser.add_dcmd_argument(&_option);290}291292void JVMTIAgentLoadDCmd::execute(DCmdSource source, TRAPS) {293294if (_libpath.value() == NULL) {295output()->print_cr("JVMTI.agent_load dcmd needs library path.");296return;297}298299char *suffix = strrchr(_libpath.value(), '.');300bool is_java_agent = (suffix != NULL) && (strncmp(".jar", suffix, 4) == 0);301302if (is_java_agent) {303if (_option.value() == NULL) {304JvmtiExport::load_agent_library("instrument", "false",305_libpath.value(), output());306} else {307size_t opt_len = strlen(_libpath.value()) + strlen(_option.value()) + 2;308if (opt_len > 4096) {309output()->print_cr("JVMTI agent attach failed: Options is too long.");310return;311}312313char *opt = (char *)os::malloc(opt_len, mtInternal);314if (opt == NULL) {315output()->print_cr("JVMTI agent attach failed: "316"Could not allocate " SIZE_FORMAT " bytes for argument.",317opt_len);318return;319}320321jio_snprintf(opt, opt_len, "%s=%s", _libpath.value(), _option.value());322JvmtiExport::load_agent_library("instrument", "false", opt, output());323324os::free(opt);325}326} else {327JvmtiExport::load_agent_library(_libpath.value(), "true",328_option.value(), output());329}330}331332#endif // INCLUDE_JVMTI333#endif // INCLUDE_SERVICES334335void PrintSystemPropertiesDCmd::execute(DCmdSource source, TRAPS) {336// load VMSupport337Symbol* klass = vmSymbols::jdk_internal_vm_VMSupport();338Klass* k = SystemDictionary::resolve_or_fail(klass, true, CHECK);339InstanceKlass* ik = InstanceKlass::cast(k);340if (ik->should_be_initialized()) {341ik->initialize(THREAD);342}343if (HAS_PENDING_EXCEPTION) {344java_lang_Throwable::print(PENDING_EXCEPTION, output());345output()->cr();346CLEAR_PENDING_EXCEPTION;347return;348}349350// invoke the serializePropertiesToByteArray method351JavaValue result(T_OBJECT);352JavaCallArguments args;353354Symbol* signature = vmSymbols::serializePropertiesToByteArray_signature();355JavaCalls::call_static(&result,356ik,357vmSymbols::serializePropertiesToByteArray_name(),358signature,359&args,360THREAD);361if (HAS_PENDING_EXCEPTION) {362java_lang_Throwable::print(PENDING_EXCEPTION, output());363output()->cr();364CLEAR_PENDING_EXCEPTION;365return;366}367368// The result should be a [B369oop res = result.get_oop();370assert(res->is_typeArray(), "just checking");371assert(TypeArrayKlass::cast(res->klass())->element_type() == T_BYTE, "just checking");372373// copy the bytes to the output stream374typeArrayOop ba = typeArrayOop(res);375jbyte* addr = typeArrayOop(res)->byte_at_addr(0);376output()->print_raw((const char*)addr, ba->length());377}378379VMUptimeDCmd::VMUptimeDCmd(outputStream* output, bool heap) :380DCmdWithParser(output, heap),381_date("-date", "Add a prefix with current date", "BOOLEAN", false, "false") {382_dcmdparser.add_dcmd_option(&_date);383}384385void VMUptimeDCmd::execute(DCmdSource source, TRAPS) {386if (_date.value()) {387output()->date_stamp(true, "", ": ");388}389output()->time_stamp().update_to(tty->time_stamp().ticks());390output()->stamp();391output()->print_cr(" s");392}393394void VMInfoDCmd::execute(DCmdSource source, TRAPS) {395VMError::print_vm_info(_output);396}397398void SystemGCDCmd::execute(DCmdSource source, TRAPS) {399Universe::heap()->collect(GCCause::_dcmd_gc_run);400}401402void RunFinalizationDCmd::execute(DCmdSource source, TRAPS) {403Klass* k = vmClasses::System_klass();404JavaValue result(T_VOID);405JavaCalls::call_static(&result, k,406vmSymbols::run_finalization_name(),407vmSymbols::void_method_signature(), CHECK);408}409410void HeapInfoDCmd::execute(DCmdSource source, TRAPS) {411MutexLocker hl(THREAD, Heap_lock);412Universe::heap()->print_on(output());413}414415void FinalizerInfoDCmd::execute(DCmdSource source, TRAPS) {416ResourceMark rm(THREAD);417418Klass* k = SystemDictionary::resolve_or_fail(419vmSymbols::finalizer_histogram_klass(), true, CHECK);420421JavaValue result(T_ARRAY);422423// We are calling lang.ref.FinalizerHistogram.getFinalizerHistogram() method424// and expect it to return array of FinalizerHistogramEntry as Object[]425426JavaCalls::call_static(&result, k,427vmSymbols::get_finalizer_histogram_name(),428vmSymbols::void_finalizer_histogram_entry_array_signature(), CHECK);429430objArrayOop result_oop = (objArrayOop) result.get_oop();431if (result_oop->length() == 0) {432output()->print_cr("No instances waiting for finalization found");433return;434}435436oop foop = result_oop->obj_at(0);437InstanceKlass* ik = InstanceKlass::cast(foop->klass());438439fieldDescriptor count_fd, name_fd;440441Klass* count_res = ik->find_field(442vmSymbols::finalizer_histogram_entry_count_field(), vmSymbols::int_signature(), &count_fd);443444Klass* name_res = ik->find_field(445vmSymbols::finalizer_histogram_entry_name_field(), vmSymbols::string_signature(), &name_fd);446447assert(count_res != NULL && name_res != NULL, "Unexpected layout of FinalizerHistogramEntry");448449output()->print_cr("Unreachable instances waiting for finalization");450output()->print_cr("#instances class name");451output()->print_cr("-----------------------");452453for (int i = 0; i < result_oop->length(); ++i) {454oop element_oop = result_oop->obj_at(i);455oop str_oop = element_oop->obj_field(name_fd.offset());456char *name = java_lang_String::as_utf8_string(str_oop);457int count = element_oop->int_field(count_fd.offset());458output()->print_cr("%10d %s", count, name);459}460}461462#if INCLUDE_SERVICES // Heap dumping/inspection supported463HeapDumpDCmd::HeapDumpDCmd(outputStream* output, bool heap) :464DCmdWithParser(output, heap),465_filename("filename","Name of the dump file", "STRING",true),466_all("-all", "Dump all objects, including unreachable objects",467"BOOLEAN", false, "false"),468_gzip("-gz", "If specified, the heap dump is written in gzipped format "469"using the given compression level. 1 (recommended) is the fastest, "470"9 the strongest compression.", "INT", false, "1") {471_dcmdparser.add_dcmd_option(&_all);472_dcmdparser.add_dcmd_argument(&_filename);473_dcmdparser.add_dcmd_option(&_gzip);474}475476void HeapDumpDCmd::execute(DCmdSource source, TRAPS) {477jlong level = -1; // -1 means no compression.478479if (_gzip.is_set()) {480level = _gzip.value();481482if (level < 1 || level > 9) {483output()->print_cr("Compression level out of range (1-9): " JLONG_FORMAT, level);484return;485}486}487488// Request a full GC before heap dump if _all is false489// This helps reduces the amount of unreachable objects in the dump490// and makes it easier to browse.491HeapDumper dumper(!_all.value() /* request GC if _all is false*/);492dumper.dump(_filename.value(), output(), (int) level);493}494495ClassHistogramDCmd::ClassHistogramDCmd(outputStream* output, bool heap) :496DCmdWithParser(output, heap),497_all("-all", "Inspect all objects, including unreachable objects",498"BOOLEAN", false, "false"),499_parallel_thread_num("-parallel",500"Number of parallel threads to use for heap inspection. "501"0 (the default) means let the VM determine the number of threads to use. "502"1 means use one thread (disable parallelism). "503"For any other value the VM will try to use the specified number of "504"threads, but might use fewer.",505"INT", false, "0") {506_dcmdparser.add_dcmd_option(&_all);507_dcmdparser.add_dcmd_option(&_parallel_thread_num);508}509510void ClassHistogramDCmd::execute(DCmdSource source, TRAPS) {511jlong num = _parallel_thread_num.value();512if (num < 0) {513output()->print_cr("Parallel thread number out of range (>=0): " JLONG_FORMAT, num);514return;515}516uint parallel_thread_num = num == 0517? MAX2<uint>(1, (uint)os::initial_active_processor_count() * 3 / 8)518: num;519VM_GC_HeapInspection heapop(output(),520!_all.value(), /* request full gc if false */521parallel_thread_num);522VMThread::execute(&heapop);523}524525#endif // INCLUDE_SERVICES526527ThreadDumpDCmd::ThreadDumpDCmd(outputStream* output, bool heap) :528DCmdWithParser(output, heap),529_locks("-l", "print java.util.concurrent locks", "BOOLEAN", false, "false"),530_extended("-e", "print extended thread information", "BOOLEAN", false, "false") {531_dcmdparser.add_dcmd_option(&_locks);532_dcmdparser.add_dcmd_option(&_extended);533}534535void ThreadDumpDCmd::execute(DCmdSource source, TRAPS) {536// thread stacks537VM_PrintThreads op1(output(), _locks.value(), _extended.value());538VMThread::execute(&op1);539540// JNI global handles541VM_PrintJNI op2(output());542VMThread::execute(&op2);543544// Deadlock detection545VM_FindDeadlocks op3(output());546VMThread::execute(&op3);547}548549// Enhanced JMX Agent support550551JMXStartRemoteDCmd::JMXStartRemoteDCmd(outputStream *output, bool heap_allocated) :552553DCmdWithParser(output, heap_allocated),554555_config_file556("config.file",557"set com.sun.management.config.file", "STRING", false),558559_jmxremote_host560("jmxremote.host",561"set com.sun.management.jmxremote.host", "STRING", false),562563_jmxremote_port564("jmxremote.port",565"set com.sun.management.jmxremote.port", "STRING", false),566567_jmxremote_rmi_port568("jmxremote.rmi.port",569"set com.sun.management.jmxremote.rmi.port", "STRING", false),570571_jmxremote_ssl572("jmxremote.ssl",573"set com.sun.management.jmxremote.ssl", "STRING", false),574575_jmxremote_registry_ssl576("jmxremote.registry.ssl",577"set com.sun.management.jmxremote.registry.ssl", "STRING", false),578579_jmxremote_authenticate580("jmxremote.authenticate",581"set com.sun.management.jmxremote.authenticate", "STRING", false),582583_jmxremote_password_file584("jmxremote.password.file",585"set com.sun.management.jmxremote.password.file", "STRING", false),586587_jmxremote_access_file588("jmxremote.access.file",589"set com.sun.management.jmxremote.access.file", "STRING", false),590591_jmxremote_login_config592("jmxremote.login.config",593"set com.sun.management.jmxremote.login.config", "STRING", false),594595_jmxremote_ssl_enabled_cipher_suites596("jmxremote.ssl.enabled.cipher.suites",597"set com.sun.management.jmxremote.ssl.enabled.cipher.suite", "STRING", false),598599_jmxremote_ssl_enabled_protocols600("jmxremote.ssl.enabled.protocols",601"set com.sun.management.jmxremote.ssl.enabled.protocols", "STRING", false),602603_jmxremote_ssl_need_client_auth604("jmxremote.ssl.need.client.auth",605"set com.sun.management.jmxremote.need.client.auth", "STRING", false),606607_jmxremote_ssl_config_file608("jmxremote.ssl.config.file",609"set com.sun.management.jmxremote.ssl.config.file", "STRING", false),610611// JDP Protocol support612_jmxremote_autodiscovery613("jmxremote.autodiscovery",614"set com.sun.management.jmxremote.autodiscovery", "STRING", false),615616_jdp_port617("jdp.port",618"set com.sun.management.jdp.port", "INT", false),619620_jdp_address621("jdp.address",622"set com.sun.management.jdp.address", "STRING", false),623624_jdp_source_addr625("jdp.source_addr",626"set com.sun.management.jdp.source_addr", "STRING", false),627628_jdp_ttl629("jdp.ttl",630"set com.sun.management.jdp.ttl", "INT", false),631632_jdp_pause633("jdp.pause",634"set com.sun.management.jdp.pause", "INT", false),635636_jdp_name637("jdp.name",638"set com.sun.management.jdp.name", "STRING", false)639640{641_dcmdparser.add_dcmd_option(&_config_file);642_dcmdparser.add_dcmd_option(&_jmxremote_host);643_dcmdparser.add_dcmd_option(&_jmxremote_port);644_dcmdparser.add_dcmd_option(&_jmxremote_rmi_port);645_dcmdparser.add_dcmd_option(&_jmxremote_ssl);646_dcmdparser.add_dcmd_option(&_jmxremote_registry_ssl);647_dcmdparser.add_dcmd_option(&_jmxremote_authenticate);648_dcmdparser.add_dcmd_option(&_jmxremote_password_file);649_dcmdparser.add_dcmd_option(&_jmxremote_access_file);650_dcmdparser.add_dcmd_option(&_jmxremote_login_config);651_dcmdparser.add_dcmd_option(&_jmxremote_ssl_enabled_cipher_suites);652_dcmdparser.add_dcmd_option(&_jmxremote_ssl_enabled_protocols);653_dcmdparser.add_dcmd_option(&_jmxremote_ssl_need_client_auth);654_dcmdparser.add_dcmd_option(&_jmxremote_ssl_config_file);655_dcmdparser.add_dcmd_option(&_jmxremote_autodiscovery);656_dcmdparser.add_dcmd_option(&_jdp_port);657_dcmdparser.add_dcmd_option(&_jdp_address);658_dcmdparser.add_dcmd_option(&_jdp_source_addr);659_dcmdparser.add_dcmd_option(&_jdp_ttl);660_dcmdparser.add_dcmd_option(&_jdp_pause);661_dcmdparser.add_dcmd_option(&_jdp_name);662}663664void JMXStartRemoteDCmd::execute(DCmdSource source, TRAPS) {665ResourceMark rm(THREAD);666HandleMark hm(THREAD);667668// Load and initialize the jdk.internal.agent.Agent class669// invoke startRemoteManagementAgent(string) method to start670// the remote management server.671// throw java.lang.NoSuchMethodError if the method doesn't exist672673loadAgentModule(CHECK);674Handle loader = Handle(THREAD, SystemDictionary::java_system_loader());675Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::jdk_internal_agent_Agent(), loader, Handle(), true, CHECK);676677JavaValue result(T_VOID);678679// Pass all command line arguments to java as key=value,...680// All checks are done on java side681682int len = 0;683stringStream options;684char comma[2] = {0,0};685686// Leave default values on Agent.class side and pass only687// agruments explicitly set by user. All arguments passed688// to jcmd override properties with the same name set by689// command line with -D or by managmenent.properties690// file.691#define PUT_OPTION(a) \692do { \693if ( (a).is_set() ){ \694if ( *((a).type()) == 'I' ) { \695options.print("%scom.sun.management.%s=" JLONG_FORMAT, comma, (a).name(), (jlong)((a).value())); \696} else { \697options.print("%scom.sun.management.%s=%s", comma, (a).name(), (char*)((a).value())); \698} \699comma[0] = ','; \700}\701} while(0);702703704PUT_OPTION(_config_file);705PUT_OPTION(_jmxremote_host);706PUT_OPTION(_jmxremote_port);707PUT_OPTION(_jmxremote_rmi_port);708PUT_OPTION(_jmxremote_ssl);709PUT_OPTION(_jmxremote_registry_ssl);710PUT_OPTION(_jmxremote_authenticate);711PUT_OPTION(_jmxremote_password_file);712PUT_OPTION(_jmxremote_access_file);713PUT_OPTION(_jmxremote_login_config);714PUT_OPTION(_jmxremote_ssl_enabled_cipher_suites);715PUT_OPTION(_jmxremote_ssl_enabled_protocols);716PUT_OPTION(_jmxremote_ssl_need_client_auth);717PUT_OPTION(_jmxremote_ssl_config_file);718PUT_OPTION(_jmxremote_autodiscovery);719PUT_OPTION(_jdp_port);720PUT_OPTION(_jdp_address);721PUT_OPTION(_jdp_source_addr);722PUT_OPTION(_jdp_ttl);723PUT_OPTION(_jdp_pause);724PUT_OPTION(_jdp_name);725726#undef PUT_OPTION727728Handle str = java_lang_String::create_from_str(options.as_string(), CHECK);729JavaCalls::call_static(&result, k, vmSymbols::startRemoteAgent_name(), vmSymbols::string_void_signature(), str, CHECK);730}731732JMXStartLocalDCmd::JMXStartLocalDCmd(outputStream *output, bool heap_allocated) :733DCmd(output, heap_allocated) {734// do nothing735}736737void JMXStartLocalDCmd::execute(DCmdSource source, TRAPS) {738ResourceMark rm(THREAD);739HandleMark hm(THREAD);740741// Load and initialize the jdk.internal.agent.Agent class742// invoke startLocalManagementAgent(void) method to start743// the local management server744// throw java.lang.NoSuchMethodError if method doesn't exist745746loadAgentModule(CHECK);747Handle loader = Handle(THREAD, SystemDictionary::java_system_loader());748Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::jdk_internal_agent_Agent(), loader, Handle(), true, CHECK);749750JavaValue result(T_VOID);751JavaCalls::call_static(&result, k, vmSymbols::startLocalAgent_name(), vmSymbols::void_method_signature(), CHECK);752}753754void JMXStopRemoteDCmd::execute(DCmdSource source, TRAPS) {755ResourceMark rm(THREAD);756HandleMark hm(THREAD);757758// Load and initialize the jdk.internal.agent.Agent class759// invoke stopRemoteManagementAgent method to stop the760// management server761// throw java.lang.NoSuchMethodError if method doesn't exist762763loadAgentModule(CHECK);764Handle loader = Handle(THREAD, SystemDictionary::java_system_loader());765Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::jdk_internal_agent_Agent(), loader, Handle(), true, CHECK);766767JavaValue result(T_VOID);768JavaCalls::call_static(&result, k, vmSymbols::stopRemoteAgent_name(), vmSymbols::void_method_signature(), CHECK);769}770771JMXStatusDCmd::JMXStatusDCmd(outputStream *output, bool heap_allocated) :772DCmd(output, heap_allocated) {773// do nothing774}775776void JMXStatusDCmd::execute(DCmdSource source, TRAPS) {777ResourceMark rm(THREAD);778HandleMark hm(THREAD);779780// Load and initialize the jdk.internal.agent.Agent class781// invoke getManagementAgentStatus() method to generate the status info782// throw java.lang.NoSuchMethodError if method doesn't exist783784loadAgentModule(CHECK);785Handle loader = Handle(THREAD, SystemDictionary::java_system_loader());786Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::jdk_internal_agent_Agent(), loader, Handle(), true, CHECK);787788JavaValue result(T_OBJECT);789JavaCalls::call_static(&result, k, vmSymbols::getAgentStatus_name(), vmSymbols::void_string_signature(), CHECK);790791jvalue* jv = (jvalue*) result.get_value_addr();792oop str = cast_to_oop(jv->l);793if (str != NULL) {794char* out = java_lang_String::as_utf8_string(str);795if (out) {796output()->print_cr("%s", out);797return;798}799}800output()->print_cr("Error obtaining management agent status");801}802803VMDynamicLibrariesDCmd::VMDynamicLibrariesDCmd(outputStream *output, bool heap_allocated) :804DCmd(output, heap_allocated) {805// do nothing806}807808void VMDynamicLibrariesDCmd::execute(DCmdSource source, TRAPS) {809os::print_dll_info(output());810output()->cr();811}812813void CompileQueueDCmd::execute(DCmdSource source, TRAPS) {814VM_PrintCompileQueue printCompileQueueOp(output());815VMThread::execute(&printCompileQueueOp);816}817818void CodeListDCmd::execute(DCmdSource source, TRAPS) {819CodeCache::print_codelist(output());820}821822void CodeCacheDCmd::execute(DCmdSource source, TRAPS) {823CodeCache::print_layout(output());824}825826#ifdef LINUX827void PerfMapDCmd::execute(DCmdSource source, TRAPS) {828CodeCache::write_perf_map();829}830#endif // LINUX831832//---< BEGIN >--- CodeHeap State Analytics.833CodeHeapAnalyticsDCmd::CodeHeapAnalyticsDCmd(outputStream* output, bool heap) :834DCmdWithParser(output, heap),835_function("function", "Function to be performed (aggregate, UsedSpace, FreeSpace, MethodCount, MethodSpace, MethodAge, MethodNames, discard", "STRING", false, "all"),836_granularity("granularity", "Detail level - smaller value -> more detail", "INT", false, "4096") {837_dcmdparser.add_dcmd_argument(&_function);838_dcmdparser.add_dcmd_argument(&_granularity);839}840841void CodeHeapAnalyticsDCmd::execute(DCmdSource source, TRAPS) {842jlong granularity = _granularity.value();843if (granularity < 1) {844Exceptions::fthrow(THREAD_AND_LOCATION, vmSymbols::java_lang_IllegalArgumentException(),845"Invalid granularity value " JLONG_FORMAT ". Should be positive.\n", granularity);846return;847}848849CompileBroker::print_heapinfo(output(), _function.value(), granularity);850}851//---< END >--- CodeHeap State Analytics.852853EventLogDCmd::EventLogDCmd(outputStream* output, bool heap) :854DCmdWithParser(output, heap),855_log("log", "Name of log to be printed. If omitted, all logs are printed.", "STRING", false, NULL),856_max("max", "Maximum number of events to be printed (newest first). If omitted, all events are printed.", "STRING", false, NULL)857{858_dcmdparser.add_dcmd_option(&_log);859_dcmdparser.add_dcmd_option(&_max);860}861862void EventLogDCmd::execute(DCmdSource source, TRAPS) {863const char* max_value = _max.value();864long max = -1;865if (max_value != NULL) {866char* endptr = NULL;867max = ::strtol(max_value, &endptr, 10);868if (max == 0 && max_value == endptr) {869output()->print_cr("Invalid max option: \"%s\".", max_value);870return;871}872}873const char* log_name = _log.value();874if (log_name != NULL) {875Events::print_one(output(), log_name, max);876} else {877Events::print_all(output(), max);878}879}880881void CompilerDirectivesPrintDCmd::execute(DCmdSource source, TRAPS) {882DirectivesStack::print(output());883}884885CompilerDirectivesAddDCmd::CompilerDirectivesAddDCmd(outputStream* output, bool heap) :886DCmdWithParser(output, heap),887_filename("filename","Name of the directives file", "STRING",true) {888_dcmdparser.add_dcmd_argument(&_filename);889}890891void CompilerDirectivesAddDCmd::execute(DCmdSource source, TRAPS) {892DirectivesParser::parse_from_file(_filename.value(), output());893}894895void CompilerDirectivesRemoveDCmd::execute(DCmdSource source, TRAPS) {896DirectivesStack::pop(1);897}898899void CompilerDirectivesClearDCmd::execute(DCmdSource source, TRAPS) {900DirectivesStack::clear();901}902#if INCLUDE_SERVICES903ClassHierarchyDCmd::ClassHierarchyDCmd(outputStream* output, bool heap) :904DCmdWithParser(output, heap),905_print_interfaces("-i", "Inherited interfaces should be printed.", "BOOLEAN", false, "false"),906_print_subclasses("-s", "If a classname is specified, print its subclasses. "907"Otherwise only its superclasses are printed.", "BOOLEAN", false, "false"),908_classname("classname", "Name of class whose hierarchy should be printed. "909"If not specified, all class hierarchies are printed.",910"STRING", false) {911_dcmdparser.add_dcmd_option(&_print_interfaces);912_dcmdparser.add_dcmd_option(&_print_subclasses);913_dcmdparser.add_dcmd_argument(&_classname);914}915916void ClassHierarchyDCmd::execute(DCmdSource source, TRAPS) {917VM_PrintClassHierarchy printClassHierarchyOp(output(), _print_interfaces.value(),918_print_subclasses.value(), _classname.value());919VMThread::execute(&printClassHierarchyOp);920}921#endif922923class VM_DumpTouchedMethods : public VM_Operation {924private:925outputStream* _out;926public:927VM_DumpTouchedMethods(outputStream* out) {928_out = out;929}930931virtual VMOp_Type type() const { return VMOp_DumpTouchedMethods; }932933virtual void doit() {934Method::print_touched_methods(_out);935}936};937938void TouchedMethodsDCmd::execute(DCmdSource source, TRAPS) {939if (!LogTouchedMethods) {940output()->print_cr("VM.print_touched_methods command requires -XX:+LogTouchedMethods");941return;942}943VM_DumpTouchedMethods dumper(output());944VMThread::execute(&dumper);945}946947#if INCLUDE_CDS948DumpSharedArchiveDCmd::DumpSharedArchiveDCmd(outputStream* output, bool heap) :949DCmdWithParser(output, heap),950_suboption("subcmd", "static_dump | dynamic_dump", "STRING", true),951_filename("filename", "Name of shared archive to be dumped", "STRING", false)952{953_dcmdparser.add_dcmd_argument(&_suboption);954_dcmdparser.add_dcmd_argument(&_filename);955}956957void DumpSharedArchiveDCmd::execute(DCmdSource source, TRAPS) {958jboolean is_static;959const char* scmd = _suboption.value();960const char* file = _filename.value();961962if (strcmp(scmd, "static_dump") == 0) {963is_static = JNI_TRUE;964output()->print_cr("Static dump:");965} else if (strcmp(scmd, "dynamic_dump") == 0) {966is_static = JNI_FALSE;967output()->print_cr("Dynamic dump:");968if (!UseSharedSpaces) {969output()->print_cr("Dynamic dump is unsupported when base CDS archive is not loaded");970return;971}972if (!RecordDynamicDumpInfo) {973output()->print_cr("Dump dynamic should run with -XX:+RecordDynamicDumpInfo");974return;975}976} else {977output()->print_cr("Invalid command for VM.cds, valid input is static_dump or dynamic_dump");978return;979}980981// call CDS.dumpSharedArchive982Handle fileh;983if (file != NULL) {984fileh = java_lang_String::create_from_str(_filename.value(), CHECK);985}986Symbol* cds_name = vmSymbols::jdk_internal_misc_CDS();987Klass* cds_klass = SystemDictionary::resolve_or_fail(cds_name, true /*throw error*/, CHECK);988JavaValue result(T_VOID);989JavaCallArguments args;990args.push_int(is_static);991args.push_oop(fileh);992JavaCalls::call_static(&result,993cds_klass,994vmSymbols::dumpSharedArchive(),995vmSymbols::dumpSharedArchive_signature(),996&args, CHECK);997}998#endif // INCLUDE_CDS9991000#if INCLUDE_JVMTI1001extern "C" typedef char const* (JNICALL *debugInit_startDebuggingViaCommandPtr)(JNIEnv* env, jthread thread, char const** transport_name,1002char const** address, jboolean* first_start);1003static debugInit_startDebuggingViaCommandPtr dvc_start_ptr = NULL;10041005void DebugOnCmdStartDCmd::execute(DCmdSource source, TRAPS) {1006char const* transport = NULL;1007char const* addr = NULL;1008jboolean is_first_start = JNI_FALSE;1009JavaThread* thread = THREAD;1010jthread jt = JNIHandles::make_local(thread->threadObj());1011ThreadToNativeFromVM ttn(thread);1012const char *error = "Could not find jdwp agent.";10131014if (!dvc_start_ptr) {1015for (AgentLibrary* agent = Arguments::agents(); agent != NULL; agent = agent->next()) {1016if ((strcmp("jdwp", agent->name()) == 0) && (dvc_start_ptr == NULL)) {1017char const* func = "debugInit_startDebuggingViaCommand";1018dvc_start_ptr = (debugInit_startDebuggingViaCommandPtr) os::find_agent_function(agent, false, &func, 1);1019}1020}1021}10221023if (dvc_start_ptr) {1024error = dvc_start_ptr(thread->jni_environment(), jt, &transport, &addr, &is_first_start);1025}10261027if (error != NULL) {1028output()->print_cr("Debugging has not been started: %s", error);1029} else {1030output()->print_cr(is_first_start ? "Debugging has been started." : "Debugging is already active.");1031output()->print_cr("Transport : %s", transport ? transport : "#unknown");1032output()->print_cr("Address : %s", addr ? addr : "#unknown");1033}1034}1035#endif // INCLUDE_JVMTI103610371038