src/share/vm/services/diagnosticCommand.cpp

Print this page


   1 /*
   2  * Copyright (c) 2011, 2012, 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  *


  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"
  33 
  34 void DCmdRegistrant::register_dcmds(){
  35   // Registration of the diagnostic commands
  36   // First boolean argument specifies if the command is enabled
  37   // Second boolean argument specifies if the command is hidden
  38   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<HelpDCmd>(true, false));
  39   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<VersionDCmd>(true, false));
  40   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<CommandLineDCmd>(true, false));
  41   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<PrintSystemPropertiesDCmd>(true, false));
  42   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<PrintVMFlagsDCmd>(true, false));
  43   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<VMUptimeDCmd>(true, false));
  44   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<SystemGCDCmd>(true, false));
  45   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<RunFinalizationDCmd>(true, false));
  46 #if INCLUDE_SERVICES // Heap dumping supported
  47   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<HeapDumpDCmd>(true, false));
  48 #endif // INCLUDE_SERVICES
  49   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ClassHistogramDCmd>(true, false));




  50   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ThreadDumpDCmd>(true, false));
  51 
  52   //Enhanced JMX Agent Support
  53   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JMXStartRemoteDCmd>(true,false));
  54   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JMXStartLocalDCmd>(true,false));
  55   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JMXStopRemoteDCmd>(true,false));
  56 
  57 }
  58 
  59 #ifndef HAVE_EXTRA_DCMD
  60 void DCmdRegistrant::register_dcmds_ext(){
  61    // Do nothing here
  62 }
  63 #endif
  64 
  65 
  66 HelpDCmd::HelpDCmd(outputStream* output, bool heap) : DCmdWithParser(output, heap),
  67   _all("-all", "Show help for all commands", "BOOLEAN", false, "false"),
  68   _cmd("command name", "The name of the command for which we want help",
  69         "STRING", false) {
  70   _dcmdparser.add_dcmd_option(&_all);
  71   _dcmdparser.add_dcmd_argument(&_cmd);


 235     return dcmd->_dcmdparser.num_arguments();
 236   } else {
 237     return 0;
 238   }
 239 }
 240 
 241 void SystemGCDCmd::execute(TRAPS) {
 242   Universe::heap()->collect(GCCause::_java_lang_system_gc);
 243 }
 244 
 245 void RunFinalizationDCmd::execute(TRAPS) {
 246   Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_System(),
 247                                                  true, CHECK);
 248   instanceKlassHandle klass(THREAD, k);
 249   JavaValue result(T_VOID);
 250   JavaCalls::call_static(&result, klass,
 251                          vmSymbols::run_finalization_name(),
 252                          vmSymbols::void_method_signature(), CHECK);
 253 }
 254 
 255 #if INCLUDE_SERVICES // Heap dumping supported
 256 HeapDumpDCmd::HeapDumpDCmd(outputStream* output, bool heap) :
 257                            DCmdWithParser(output, heap),
 258   _filename("filename","Name of the dump file", "STRING",true),
 259   _all("-all", "Dump all objects, including unreachable objects",
 260        "BOOLEAN", false, "false") {
 261   _dcmdparser.add_dcmd_option(&_all);
 262   _dcmdparser.add_dcmd_argument(&_filename);
 263 }
 264 
 265 void HeapDumpDCmd::execute(TRAPS) {
 266   // Request a full GC before heap dump if _all is false
 267   // This helps reduces the amount of unreachable objects in the dump
 268   // and makes it easier to browse.
 269   HeapDumper dumper(!_all.value() /* request GC if _all is false*/);
 270   int res = dumper.dump(_filename.value());
 271   if (res == 0) {
 272     output()->print_cr("Heap dump file created");
 273   } else {
 274     // heap dump failed
 275     ResourceMark rm;
 276     char* error = dumper.error_as_C_string();
 277     if (error == NULL) {
 278       output()->print_cr("Dump failed - reason unknown");
 279     } else {
 280       output()->print_cr("%s", error);
 281     }
 282   }
 283 }
 284 
 285 int HeapDumpDCmd::num_arguments() {
 286   ResourceMark rm;
 287   HeapDumpDCmd* dcmd = new HeapDumpDCmd(NULL, false);
 288   if (dcmd != NULL) {
 289     DCmdMark mark(dcmd);
 290     return dcmd->_dcmdparser.num_arguments();
 291   } else {
 292     return 0;
 293   }
 294 }
 295 #endif // INCLUDE_SERVICES
 296 
 297 ClassHistogramDCmd::ClassHistogramDCmd(outputStream* output, bool heap) :
 298                                        DCmdWithParser(output, heap),
 299   _all("-all", "Inspect all objects, including unreachable objects",
 300        "BOOLEAN", false, "false") {
 301   _dcmdparser.add_dcmd_option(&_all);
 302 }
 303 
 304 void ClassHistogramDCmd::execute(TRAPS) {
 305   VM_GC_HeapInspection heapop(output(),
 306                               !_all.value() /* request full gc if false */,
 307                               true /* need_prologue */);
 308   VMThread::execute(&heapop);
 309 }
 310 
 311 int ClassHistogramDCmd::num_arguments() {
 312   ResourceMark rm;
 313   ClassHistogramDCmd* dcmd = new ClassHistogramDCmd(NULL, false);
 314   if (dcmd != NULL) {
 315     DCmdMark mark(dcmd);
 316     return dcmd->_dcmdparser.num_arguments();
 317   } else {
 318     return 0;
 319   }
 320 }






















































 321 
 322 ThreadDumpDCmd::ThreadDumpDCmd(outputStream* output, bool heap) :
 323                                DCmdWithParser(output, heap),
 324   _locks("-l", "print java.util.concurrent locks", "BOOLEAN", false, "false") {
 325   _dcmdparser.add_dcmd_option(&_locks);
 326 }
 327 
 328 void ThreadDumpDCmd::execute(TRAPS) {
 329   // thread stacks
 330   VM_PrintThreads op1(output(), _locks.value());
 331   VMThread::execute(&op1);
 332 
 333   // JNI global handles
 334   VM_PrintJNI op2(output());
 335   VMThread::execute(&op2);
 336 
 337   // Deadlock detection
 338   VM_FindDeadlocks op3(output());
 339   VMThread::execute(&op3);
 340 }


   1 /*
   2  * Copyright (c) 2011, 2013, 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  *


  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"
  33 
  34 void DCmdRegistrant::register_dcmds(){
  35   // Registration of the diagnostic commands
  36   // First boolean argument specifies if the command is enabled
  37   // Second boolean argument specifies if the command is hidden
  38   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<HelpDCmd>(true, false));
  39   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<VersionDCmd>(true, false));
  40   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<CommandLineDCmd>(true, false));
  41   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<PrintSystemPropertiesDCmd>(true, false));
  42   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<PrintVMFlagsDCmd>(true, false));
  43   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<VMUptimeDCmd>(true, false));
  44   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<SystemGCDCmd>(true, false));
  45   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<RunFinalizationDCmd>(true, false));
  46 #if INCLUDE_SERVICES // Heap dumping/inspection supported
  47   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<HeapDumpDCmd>(true, false));

  48   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ClassHistogramDCmd>(true, false));
  49   if (UnlockDiagnosticVMOptions) {
  50     DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ClassStatsDCmd>(true, false));
  51   }
  52 #endif // INCLUDE_SERVICES
  53   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ThreadDumpDCmd>(true, false));

  54   //Enhanced JMX Agent Support
  55   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JMXStartRemoteDCmd>(true,false));
  56   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JMXStartLocalDCmd>(true,false));
  57   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JMXStopRemoteDCmd>(true,false));
  58 
  59 }
  60 
  61 #ifndef HAVE_EXTRA_DCMD
  62 void DCmdRegistrant::register_dcmds_ext(){
  63    // Do nothing here
  64 }
  65 #endif
  66 
  67 
  68 HelpDCmd::HelpDCmd(outputStream* output, bool heap) : DCmdWithParser(output, heap),
  69   _all("-all", "Show help for all commands", "BOOLEAN", false, "false"),
  70   _cmd("command name", "The name of the command for which we want help",
  71         "STRING", false) {
  72   _dcmdparser.add_dcmd_option(&_all);
  73   _dcmdparser.add_dcmd_argument(&_cmd);


 237     return dcmd->_dcmdparser.num_arguments();
 238   } else {
 239     return 0;
 240   }
 241 }
 242 
 243 void SystemGCDCmd::execute(TRAPS) {
 244   Universe::heap()->collect(GCCause::_java_lang_system_gc);
 245 }
 246 
 247 void RunFinalizationDCmd::execute(TRAPS) {
 248   Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_System(),
 249                                                  true, CHECK);
 250   instanceKlassHandle klass(THREAD, k);
 251   JavaValue result(T_VOID);
 252   JavaCalls::call_static(&result, klass,
 253                          vmSymbols::run_finalization_name(),
 254                          vmSymbols::void_method_signature(), CHECK);
 255 }
 256 
 257 #if INCLUDE_SERVICES // Heap dumping/inspection supported
 258 HeapDumpDCmd::HeapDumpDCmd(outputStream* output, bool heap) :
 259                            DCmdWithParser(output, heap),
 260   _filename("filename","Name of the dump file", "STRING",true),
 261   _all("-all", "Dump all objects, including unreachable objects",
 262        "BOOLEAN", false, "false") {
 263   _dcmdparser.add_dcmd_option(&_all);
 264   _dcmdparser.add_dcmd_argument(&_filename);
 265 }
 266 
 267 void HeapDumpDCmd::execute(TRAPS) {
 268   // Request a full GC before heap dump if _all is false
 269   // This helps reduces the amount of unreachable objects in the dump
 270   // and makes it easier to browse.
 271   HeapDumper dumper(!_all.value() /* request GC if _all is false*/);
 272   int res = dumper.dump(_filename.value());
 273   if (res == 0) {
 274     output()->print_cr("Heap dump file created");
 275   } else {
 276     // heap dump failed
 277     ResourceMark rm;
 278     char* error = dumper.error_as_C_string();
 279     if (error == NULL) {
 280       output()->print_cr("Dump failed - reason unknown");
 281     } else {
 282       output()->print_cr("%s", error);
 283     }
 284   }
 285 }
 286 
 287 int HeapDumpDCmd::num_arguments() {
 288   ResourceMark rm;
 289   HeapDumpDCmd* dcmd = new HeapDumpDCmd(NULL, false);
 290   if (dcmd != NULL) {
 291     DCmdMark mark(dcmd);
 292     return dcmd->_dcmdparser.num_arguments();
 293   } else {
 294     return 0;
 295   }
 296 }

 297 
 298 ClassHistogramDCmd::ClassHistogramDCmd(outputStream* output, bool heap) :
 299                                        DCmdWithParser(output, heap),
 300   _all("-all", "Inspect all objects, including unreachable objects",
 301        "BOOLEAN", false, "false") {
 302   _dcmdparser.add_dcmd_option(&_all);
 303 }
 304 
 305 void ClassHistogramDCmd::execute(TRAPS) {
 306   VM_GC_HeapInspection heapop(output(),
 307                               !_all.value() /* request full gc if false */,
 308                               true /* need_prologue */);
 309   VMThread::execute(&heapop);
 310 }
 311 
 312 int ClassHistogramDCmd::num_arguments() {
 313   ResourceMark rm;
 314   ClassHistogramDCmd* dcmd = new ClassHistogramDCmd(NULL, false);
 315   if (dcmd != NULL) {
 316     DCmdMark mark(dcmd);
 317     return dcmd->_dcmdparser.num_arguments();
 318   } else {
 319     return 0;
 320   }
 321 }
 322 
 323 #define DEFAULT_COLUMNS "InstBytes,KlassBytes,CpAll,annotations,MethodCount,Bytecodes,MethodAll,ROAll,RWAll,Total"
 324 ClassStatsDCmd::ClassStatsDCmd(outputStream* output, bool heap) :
 325                                        DCmdWithParser(output, heap),
 326   _csv("-csv", "Print in CSV (comma-separated values) format for spreadsheets",
 327        "BOOLEAN", false, "false"),
 328   _all("-all", "Show all columns",
 329        "BOOLEAN", false, "false"),
 330   _help("-help", "Show meaning of all the columns",
 331        "BOOLEAN", false, "false"),
 332   _columns("columns", "Comma-separated list of all the columns to show. "
 333            "If not specified, the following columns are shown: " DEFAULT_COLUMNS,
 334            "STRING", false) {
 335   _dcmdparser.add_dcmd_option(&_all);
 336   _dcmdparser.add_dcmd_option(&_csv);
 337   _dcmdparser.add_dcmd_option(&_help);
 338   _dcmdparser.add_dcmd_argument(&_columns);
 339 }
 340 
 341 void ClassStatsDCmd::execute(TRAPS) {
 342   VM_GC_HeapInspection heapop(output(),
 343                               true, /* request_full_gc */
 344                               true /* need_prologue */);
 345   heapop.set_csv_format(_csv.value());
 346   heapop.set_print_help(_help.value());
 347   heapop.set_print_class_stats(true);
 348   if (_all.value()) {
 349     if (_columns.has_value()) {
 350       output()->print_cr("Cannot specify -all and individual columns at the same time");
 351       return;
 352     } else {
 353       heapop.set_columns(NULL);
 354     }
 355   } else {
 356     if (_columns.has_value()) {
 357       heapop.set_columns(_columns.value());
 358     } else {
 359       heapop.set_columns(DEFAULT_COLUMNS);
 360     }
 361   }
 362   VMThread::execute(&heapop);
 363 }
 364 
 365 int ClassStatsDCmd::num_arguments() {
 366   ResourceMark rm;
 367   ClassStatsDCmd* dcmd = new ClassStatsDCmd(NULL, false);
 368   if (dcmd != NULL) {
 369     DCmdMark mark(dcmd);
 370     return dcmd->_dcmdparser.num_arguments();
 371   } else {
 372     return 0;
 373   }
 374 }
 375 #endif // INCLUDE_SERVICES
 376 
 377 ThreadDumpDCmd::ThreadDumpDCmd(outputStream* output, bool heap) :
 378                                DCmdWithParser(output, heap),
 379   _locks("-l", "print java.util.concurrent locks", "BOOLEAN", false, "false") {
 380   _dcmdparser.add_dcmd_option(&_locks);
 381 }
 382 
 383 void ThreadDumpDCmd::execute(TRAPS) {
 384   // thread stacks
 385   VM_PrintThreads op1(output(), _locks.value());
 386   VMThread::execute(&op1);
 387 
 388   // JNI global handles
 389   VM_PrintJNI op2(output());
 390   VMThread::execute(&op2);
 391 
 392   // Deadlock detection
 393   VM_FindDeadlocks op3(output());
 394   VMThread::execute(&op3);
 395 }