src/share/vm/services/diagnosticCommand.cpp

Mon, 09 Jan 2012 10:27:24 +0100

author
fparain
date
Mon, 09 Jan 2012 10:27:24 +0100
changeset 3402
4f25538b54c9
parent 3329
3b688d6ff3d0
child 3478
a42c07c38c47
permissions
-rw-r--r--

7120511: Add diagnostic commands
Reviewed-by: acorn, phh, dcubed, sspitsyn

     1 /*
     2  * Copyright (c) 2011, 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  */
    25 #include "precompiled.hpp"
    26 #include "gc_implementation/shared/vmGCOperations.hpp"
    27 #include "runtime/javaCalls.hpp"
    28 #include "services/diagnosticArgument.hpp"
    29 #include "services/diagnosticCommand.hpp"
    30 #include "services/diagnosticFramework.hpp"
    31 #include "services/heapDumper.hpp"
    32 #include "services/management.hpp"
    34 HelpDCmd::HelpDCmd(outputStream* output, bool heap) : DCmdWithParser(output, heap),
    35   _all("-all", "Show help for all commands", "BOOLEAN", false, "false"),
    36   _cmd("command name", "The name of the command for which we want help",
    37         "STRING", false) {
    38   _dcmdparser.add_dcmd_option(&_all);
    39   _dcmdparser.add_dcmd_argument(&_cmd);
    40 };
    42 void HelpDCmd::execute(TRAPS) {
    43   if (_all.value()) {
    44     GrowableArray<const char*>* cmd_list = DCmdFactory::DCmd_list();
    45     for (int i = 0; i < cmd_list->length(); i++) {
    46       DCmdFactory* factory = DCmdFactory::factory(cmd_list->at(i),
    47                                                   strlen(cmd_list->at(i)));
    48       if (!factory->is_hidden()) {
    49         output()->print_cr("%s%s", factory->name(),
    50                            factory->is_enabled() ? "" : " [disabled]");
    51         output()->print_cr("\t%s", factory->description());
    52         output()->cr();
    53       }
    54       factory = factory->next();
    55     }
    56   } else if (_cmd.has_value()) {
    57     DCmd* cmd = NULL;
    58     DCmdFactory* factory = DCmdFactory::factory(_cmd.value(),
    59                                                 strlen(_cmd.value()));
    60     if (factory != NULL) {
    61       output()->print_cr("%s%s", factory->name(),
    62                          factory->is_enabled() ? "" : " [disabled]");
    63       output()->print_cr(factory->description());
    64       output()->print_cr("\nImpact: %s", factory->impact());
    65       output()->cr();
    66       cmd = factory->create_resource_instance(output());
    67       if (cmd != NULL) {
    68         DCmdMark mark(cmd);
    69         cmd->print_help(factory->name());
    70       }
    71     } else {
    72       output()->print_cr("Help unavailable : '%s' : No such command", _cmd.value());
    73     }
    74   } else {
    75     output()->print_cr("The following commands are available:");
    76     GrowableArray<const char *>* cmd_list = DCmdFactory::DCmd_list();
    77     for (int i = 0; i < cmd_list->length(); i++) {
    78       DCmdFactory* factory = DCmdFactory::factory(cmd_list->at(i),
    79                                                   strlen(cmd_list->at(i)));
    80       if (!factory->is_hidden()) {
    81         output()->print_cr("%s%s", factory->name(),
    82                            factory->is_enabled() ? "" : " [disabled]");
    83       }
    84       factory = factory->_next;
    85     }
    86     output()->print_cr("\nFor more information about a specific command use 'help <command>'.");
    87   }
    88 }
    90 int HelpDCmd::num_arguments() {
    91   ResourceMark rm;
    92   HelpDCmd* dcmd = new HelpDCmd(NULL, false);
    93   if (dcmd != NULL) {
    94     DCmdMark mark(dcmd);
    95     return dcmd->_dcmdparser.num_arguments();
    96   } else {
    97     return 0;
    98   }
    99 }
   101 void VersionDCmd::execute(TRAPS) {
   102   output()->print_cr("%s version %s", Abstract_VM_Version::vm_name(),
   103           Abstract_VM_Version::vm_release());
   104   JDK_Version jdk_version = JDK_Version::current();
   105   if (jdk_version.update_version() > 0) {
   106     output()->print_cr("JDK %d.%d_%02d", jdk_version.major_version(),
   107             jdk_version.minor_version(), jdk_version.update_version());
   108   } else {
   109     output()->print_cr("JDK %d.%d", jdk_version.major_version(),
   110             jdk_version.minor_version());
   111   }
   112 }
   114 PrintVMFlagsDCmd::PrintVMFlagsDCmd(outputStream* output, bool heap) :
   115                                    DCmdWithParser(output, heap),
   116   _all("-all", "Print all flags supported by the VM", "BOOLEAN", false, "false") {
   117   _dcmdparser.add_dcmd_option(&_all);
   118 }
   120 void PrintVMFlagsDCmd::execute(TRAPS) {
   121   if (_all.value()) {
   122     CommandLineFlags::printFlags(output(), true);
   123   } else {
   124     CommandLineFlags::printSetFlags(output());
   125   }
   126 }
   128 int PrintVMFlagsDCmd::num_arguments() {
   129     ResourceMark rm;
   130     PrintVMFlagsDCmd* dcmd = new PrintVMFlagsDCmd(NULL, false);
   131     if (dcmd != NULL) {
   132       DCmdMark mark(dcmd);
   133       return dcmd->_dcmdparser.num_arguments();
   134     } else {
   135       return 0;
   136     }
   137 }
   139 void PrintSystemPropertiesDCmd::execute(TRAPS) {
   140   // load sun.misc.VMSupport
   141   Symbol* klass = vmSymbols::sun_misc_VMSupport();
   142   klassOop k = SystemDictionary::resolve_or_fail(klass, true, CHECK);
   143   instanceKlassHandle ik (THREAD, k);
   144   if (ik->should_be_initialized()) {
   145     ik->initialize(THREAD);
   146   }
   147   if (HAS_PENDING_EXCEPTION) {
   148     java_lang_Throwable::print(PENDING_EXCEPTION, output());
   149     output()->cr();
   150     CLEAR_PENDING_EXCEPTION;
   151     return;
   152   }
   154   // invoke the serializePropertiesToByteArray method
   155   JavaValue result(T_OBJECT);
   156   JavaCallArguments args;
   158   Symbol* signature = vmSymbols::serializePropertiesToByteArray_signature();
   159   JavaCalls::call_static(&result,
   160                          ik,
   161                          vmSymbols::serializePropertiesToByteArray_name(),
   162                          signature,
   163                          &args,
   164                          THREAD);
   165   if (HAS_PENDING_EXCEPTION) {
   166     java_lang_Throwable::print(PENDING_EXCEPTION, output());
   167     output()->cr();
   168     CLEAR_PENDING_EXCEPTION;
   169     return;
   170   }
   172   // The result should be a [B
   173   oop res = (oop)result.get_jobject();
   174   assert(res->is_typeArray(), "just checking");
   175   assert(typeArrayKlass::cast(res->klass())->element_type() == T_BYTE, "just checking");
   177   // copy the bytes to the output stream
   178   typeArrayOop ba = typeArrayOop(res);
   179   jbyte* addr = typeArrayOop(res)->byte_at_addr(0);
   180   output()->print_raw((const char*)addr, ba->length());
   181 }
   183 VMUptimeDCmd::VMUptimeDCmd(outputStream* output, bool heap) :
   184                            DCmdWithParser(output, heap),
   185   _date("-date", "Add a prefix with current date", "BOOLEAN", false, "false") {
   186   _dcmdparser.add_dcmd_option(&_date);
   187 }
   189 void VMUptimeDCmd::execute(TRAPS) {
   190   if (_date.value()) {
   191     output()->date_stamp(true, "", ": ");
   192   }
   193   output()->time_stamp().update_to(tty->time_stamp().ticks());
   194   output()->stamp();
   195   output()->print_cr(" s");
   196 }
   198 int VMUptimeDCmd::num_arguments() {
   199   ResourceMark rm;
   200   VMUptimeDCmd* dcmd = new VMUptimeDCmd(NULL, false);
   201   if (dcmd != NULL) {
   202     DCmdMark mark(dcmd);
   203     return dcmd->_dcmdparser.num_arguments();
   204   } else {
   205     return 0;
   206   }
   207 }
   209 void SystemGCDCmd::execute(TRAPS) {
   210   Universe::heap()->collect(GCCause::_java_lang_system_gc);
   211 }
   213 void RunFinalizationDCmd::execute(TRAPS) {
   214   klassOop k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_System(),
   215                                                  true, CHECK);
   216   instanceKlassHandle klass(THREAD, k);
   217   JavaValue result(T_VOID);
   218   JavaCalls::call_static(&result, klass,
   219                          vmSymbols::run_finalization_name(),
   220                          vmSymbols::void_method_signature(), CHECK);
   221 }
   223 #ifndef SERVICES_KERNEL   // Heap dumping not supported
   224 HeapDumpDCmd::HeapDumpDCmd(outputStream* output, bool heap) :
   225                            DCmdWithParser(output, heap),
   226   _filename("filename","Name of the dump file", "STRING",true),
   227   _all("-all", "Dump all objects, including unreachable objects",
   228        "BOOLEAN", false, "false") {
   229   _dcmdparser.add_dcmd_option(&_all);
   230   _dcmdparser.add_dcmd_argument(&_filename);
   231 }
   233 void HeapDumpDCmd::execute(TRAPS) {
   234   // Request a full GC before heap dump if _all is false
   235   // This helps reduces the amount of unreachable objects in the dump
   236   // and makes it easier to browse.
   237   HeapDumper dumper(!_all.value() /* request GC if _all is false*/);
   238   int res = dumper.dump(_filename.value());
   239   if (res == 0) {
   240     output()->print_cr("Heap dump file created");
   241   } else {
   242     // heap dump failed
   243     ResourceMark rm;
   244     char* error = dumper.error_as_C_string();
   245     if (error == NULL) {
   246       output()->print_cr("Dump failed - reason unknown");
   247     } else {
   248       output()->print_cr("%s", error);
   249     }
   250   }
   251 }
   253 int HeapDumpDCmd::num_arguments() {
   254   ResourceMark rm;
   255   HeapDumpDCmd* dcmd = new HeapDumpDCmd(NULL, false);
   256   if (dcmd != NULL) {
   257     DCmdMark mark(dcmd);
   258     return dcmd->_dcmdparser.num_arguments();
   259   } else {
   260     return 0;
   261   }
   262 }
   263 #endif // SERVICES_KERNEL
   265 ClassHistogramDCmd::ClassHistogramDCmd(outputStream* output, bool heap) :
   266                                        DCmdWithParser(output, heap),
   267   _all("-all", "Inspect all objects, including unreachable objects",
   268        "BOOLEAN", false, "false") {
   269   _dcmdparser.add_dcmd_option(&_all);
   270 }
   272 void ClassHistogramDCmd::execute(TRAPS) {
   273   VM_GC_HeapInspection heapop(output(),
   274                               !_all.value() /* request full gc if false */,
   275                               true /* need_prologue */);
   276   VMThread::execute(&heapop);
   277 }
   279 int ClassHistogramDCmd::num_arguments() {
   280   ResourceMark rm;
   281   ClassHistogramDCmd* dcmd = new ClassHistogramDCmd(NULL, false);
   282   if (dcmd != NULL) {
   283     DCmdMark mark(dcmd);
   284     return dcmd->_dcmdparser.num_arguments();
   285   } else {
   286     return 0;
   287   }
   288 }
   290 ThreadDumpDCmd::ThreadDumpDCmd(outputStream* output, bool heap) :
   291                                DCmdWithParser(output, heap),
   292   _locks("-l", "print java.util.concurrent locks", "BOOLEAN", false, "false") {
   293   _dcmdparser.add_dcmd_option(&_locks);
   294 }
   296 void ThreadDumpDCmd::execute(TRAPS) {
   297   // thread stacks
   298   VM_PrintThreads op1(output(), _locks.value());
   299   VMThread::execute(&op1);
   301   // JNI global handles
   302   VM_PrintJNI op2(output());
   303   VMThread::execute(&op2);
   305   // Deadlock detection
   306   VM_FindDeadlocks op3(output());
   307   VMThread::execute(&op3);
   308 }
   310 int ThreadDumpDCmd::num_arguments() {
   311   ResourceMark rm;
   312   ThreadDumpDCmd* dcmd = new ThreadDumpDCmd(NULL, false);
   313   if (dcmd != NULL) {
   314     DCmdMark mark(dcmd);
   315     return dcmd->_dcmdparser.num_arguments();
   316   } else {
   317     return 0;
   318   }
   319 }

mercurial