1 /*
   2  * Copyright (c) 2011, 2015, 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  */
  24 
  25 #ifndef SHARE_VM_SERVICES_DIAGNOSTICCOMMAND_HPP
  26 #define SHARE_VM_SERVICES_DIAGNOSTICCOMMAND_HPP
  27 
  28 #include "classfile/vmSymbols.hpp"
  29 #include "runtime/arguments.hpp"
  30 #include "runtime/os.hpp"
  31 #include "runtime/vmThread.hpp"
  32 #include "services/diagnosticArgument.hpp"
  33 #include "services/diagnosticCommand.hpp"
  34 #include "services/diagnosticCommand_ext.hpp"
  35 #include "services/diagnosticFramework.hpp"
  36 #include "utilities/macros.hpp"
  37 #include "utilities/ostream.hpp"
  38 #include "oops/method.hpp"
  39 
  40 class HelpDCmd : public DCmdWithParser {
  41 protected:
  42   DCmdArgument<bool> _all;
  43   DCmdArgument<char*> _cmd;
  44 public:
  45   HelpDCmd(outputStream* output, bool heap);
  46   static const char* name() { return "help"; }
  47   static const char* description() {
  48     return "For more information about a specific command use 'help <command>'. "
  49            "With no argument this will show a list of available commands. "
  50            "'help all' will show help for all commands.";
  51   }
  52   static const char* impact() { return "Low"; }
  53   static int num_arguments();
  54   virtual void execute(DCmdSource source, TRAPS);
  55 };
  56 
  57 class VersionDCmd : public DCmd {
  58 public:
  59   VersionDCmd(outputStream* output, bool heap) : DCmd(output,heap) { }
  60   static const char* name() { return "VM.version"; }
  61   static const char* description() {
  62     return "Print JVM version information.";
  63   }
  64   static const char* impact() { return "Low"; }
  65   static const JavaPermission permission() {
  66     JavaPermission p = {"java.util.PropertyPermission",
  67                         "java.vm.version", "read"};
  68     return p;
  69   }
  70   static int num_arguments() { return 0; }
  71   virtual void execute(DCmdSource source, TRAPS);
  72 };
  73 
  74 class CommandLineDCmd : public DCmd {
  75 public:
  76   CommandLineDCmd(outputStream* output, bool heap) : DCmd(output, heap) { }
  77   static const char* name() { return "VM.command_line"; }
  78   static const char* description() {
  79     return "Print the command line used to start this VM instance.";
  80   }
  81   static const char* impact() { return "Low"; }
  82   static const JavaPermission permission() {
  83     JavaPermission p = {"java.lang.management.ManagementPermission",
  84                         "monitor", NULL};
  85     return p;
  86   }
  87   static int num_arguments() { return 0; }
  88   virtual void execute(DCmdSource source, TRAPS) {
  89     Arguments::print_on(_output);
  90   }
  91 };
  92 
  93 // See also: get_system_properties in attachListener.cpp
  94 class PrintSystemPropertiesDCmd : public DCmd {
  95 public:
  96   PrintSystemPropertiesDCmd(outputStream* output, bool heap) : DCmd(output, heap) { }
  97     static const char* name() { return "VM.system_properties"; }
  98     static const char* description() {
  99       return "Print system properties.";
 100     }
 101     static const char* impact() {
 102       return "Low";
 103     }
 104     static const JavaPermission permission() {
 105       JavaPermission p = {"java.util.PropertyPermission",
 106                           "*", "read"};
 107       return p;
 108     }
 109     static int num_arguments() { return 0; }
 110     virtual void execute(DCmdSource source, TRAPS);
 111 };
 112 
 113 // See also: print_flag in attachListener.cpp
 114 class PrintVMFlagsDCmd : public DCmdWithParser {
 115 protected:
 116   DCmdArgument<bool> _all;
 117 public:
 118   PrintVMFlagsDCmd(outputStream* output, bool heap);
 119   static const char* name() { return "VM.flags"; }
 120   static const char* description() {
 121     return "Print VM flag options and their current values.";
 122   }
 123   static const char* impact() {
 124     return "Low";
 125   }
 126   static const JavaPermission permission() {
 127     JavaPermission p = {"java.lang.management.ManagementPermission",
 128                         "monitor", NULL};
 129     return p;
 130   }
 131   static int num_arguments();
 132   virtual void execute(DCmdSource source, TRAPS);
 133 };
 134 
 135 class SetVMFlagDCmd : public DCmdWithParser {
 136 protected:
 137   DCmdArgument<char*> _flag;
 138   DCmdArgument<char*> _value;
 139 
 140 public:
 141   SetVMFlagDCmd(outputStream* output, bool heap);
 142   static const char* name() { return "VM.set_flag"; }
 143   static const char* description() {
 144     return "Sets VM flag option using the provided value.";
 145   }
 146   static const char* impact() {
 147     return "Low";
 148   }
 149   static const JavaPermission permission() {
 150     JavaPermission p = {"java.lang.management.ManagementPermission",
 151                         "control", NULL};
 152     return p;
 153   }
 154   static int num_arguments();
 155   virtual void execute(DCmdSource source, TRAPS);
 156 };
 157 
 158 class JVMTIDataDumpDCmd : public DCmd {
 159 public:
 160   JVMTIDataDumpDCmd(outputStream* output, bool heap) : DCmd(output, heap) { }
 161   static const char* name() { return "JVMTI.data_dump"; }
 162   static const char* description() {
 163     return "Signal the JVM to do a data-dump request for JVMTI.";
 164   }
 165   static const char* impact() {
 166     return "High";
 167   }
 168   static const JavaPermission permission() {
 169     JavaPermission p = {"java.lang.management.ManagementPermission",
 170                         "monitor", NULL};
 171     return p;
 172   }
 173   static int num_arguments() { return 0; }
 174   virtual void execute(DCmdSource source, TRAPS);
 175 };
 176 
 177 class VMDynamicLibrariesDCmd : public DCmd {
 178 public:
 179   VMDynamicLibrariesDCmd(outputStream* output, bool heap);
 180   static const char* name() {
 181     return "VM.dynlibs";
 182   }
 183   static const char* description() {
 184     return "Print loaded dynamic libraries.";
 185   }
 186   static const char* impact() {
 187     return "Low";
 188   }
 189   static const JavaPermission permission() {
 190     JavaPermission p = {"java.lang.management.ManagementPermission",
 191                         "monitor", NULL};
 192     return p;
 193   }
 194   static int num_arguments() {
 195     return 0;
 196   };
 197   virtual void execute(DCmdSource source, TRAPS);
 198 };
 199 
 200 class VMUptimeDCmd : public DCmdWithParser {
 201 protected:
 202   DCmdArgument<bool> _date;
 203 public:
 204   VMUptimeDCmd(outputStream* output, bool heap);
 205   static const char* name() { return "VM.uptime"; }
 206   static const char* description() {
 207     return "Print VM uptime.";
 208   }
 209   static const char* impact() {
 210     return "Low";
 211   }
 212   static int num_arguments();
 213   virtual void execute(DCmdSource source, TRAPS);
 214 };
 215 
 216 class SystemGCDCmd : public DCmd {
 217 public:
 218   SystemGCDCmd(outputStream* output, bool heap) : DCmd(output, heap) { }
 219     static const char* name() { return "GC.run"; }
 220     static const char* description() {
 221       return "Call java.lang.System.gc().";
 222     }
 223     static const char* impact() {
 224       return "Medium: Depends on Java heap size and content.";
 225     }
 226     static int num_arguments() { return 0; }
 227     virtual void execute(DCmdSource source, TRAPS);
 228 };
 229 
 230 class RunFinalizationDCmd : public DCmd {
 231 public:
 232   RunFinalizationDCmd(outputStream* output, bool heap) : DCmd(output, heap) { }
 233     static const char* name() { return "GC.run_finalization"; }
 234     static const char* description() {
 235       return "Call java.lang.System.runFinalization().";
 236     }
 237     static const char* impact() {
 238       return "Medium: Depends on Java content.";
 239     }
 240     static int num_arguments() { return 0; }
 241     virtual void execute(DCmdSource source, TRAPS);
 242 };
 243 
 244 class HeapInfoDCmd : public DCmd {
 245 public:
 246   HeapInfoDCmd(outputStream* output, bool heap) : DCmd(output, heap) { }
 247   static const char* name() { return "GC.heap_info"; }
 248   static const char* description() {
 249     return "Provide generic Java heap information.";
 250   }
 251   static const char* impact() {
 252     return "Medium";
 253   }
 254   static int num_arguments() { return 0; }
 255   static const JavaPermission permission() {
 256     JavaPermission p = {"java.lang.management.ManagementPermission",
 257       "monitor", NULL};
 258       return p;
 259   }
 260 
 261   virtual void execute(DCmdSource source, TRAPS);
 262 };
 263 
 264 class FinalizerInfoDCmd : public DCmd {
 265 public:
 266   FinalizerInfoDCmd(outputStream* output, bool heap) : DCmd(output, heap) { }
 267   static const char* name() { return "GC.finalizer_info"; }
 268   static const char* description() {
 269     return "Provide information about Java finalization queue.";
 270   }
 271   static const char* impact() {
 272     return "Medium";
 273   }
 274   static int num_arguments() { return 0; }
 275   static const JavaPermission permission() {
 276     JavaPermission p = {"java.lang.management.ManagementPermission",
 277       "monitor", NULL};
 278       return p;
 279   }
 280 
 281   virtual void execute(DCmdSource source, TRAPS);
 282 };
 283 
 284 #if INCLUDE_SERVICES   // Heap dumping supported
 285 // See also: dump_heap in attachListener.cpp
 286 class HeapDumpDCmd : public DCmdWithParser {
 287 protected:
 288   DCmdArgument<char*> _filename;
 289   DCmdArgument<bool>  _all;
 290 public:
 291   HeapDumpDCmd(outputStream* output, bool heap);
 292   static const char* name() {
 293     return "GC.heap_dump";
 294   }
 295   static const char* description() {
 296     return "Generate a HPROF format dump of the Java heap.";
 297   }
 298   static const char* impact() {
 299     return "High: Depends on Java heap size and content. "
 300            "Request a full GC unless the '-all' option is specified.";
 301   }
 302   static const JavaPermission permission() {
 303     JavaPermission p = {"java.lang.management.ManagementPermission",
 304                         "monitor", NULL};
 305     return p;
 306   }
 307   static int num_arguments();
 308   virtual void execute(DCmdSource source, TRAPS);
 309 };
 310 #endif // INCLUDE_SERVICES
 311 
 312 // See also: inspectheap in attachListener.cpp
 313 class ClassHistogramDCmd : public DCmdWithParser {
 314 protected:
 315   DCmdArgument<bool> _all;
 316 public:
 317   ClassHistogramDCmd(outputStream* output, bool heap);
 318   static const char* name() {
 319     return "GC.class_histogram";
 320   }
 321   static const char* description() {
 322     return "Provide statistics about the Java heap usage.";
 323   }
 324   static const char* impact() {
 325     return "High: Depends on Java heap size and content.";
 326   }
 327   static const JavaPermission permission() {
 328     JavaPermission p = {"java.lang.management.ManagementPermission",
 329                         "monitor", NULL};
 330     return p;
 331   }
 332   static int num_arguments();
 333   virtual void execute(DCmdSource source, TRAPS);
 334 };
 335 
 336 class ClassStatsDCmd : public DCmdWithParser {
 337 protected:
 338   DCmdArgument<bool> _all;
 339   DCmdArgument<bool> _csv;
 340   DCmdArgument<bool> _help;
 341   DCmdArgument<char*> _columns;
 342 public:
 343   ClassStatsDCmd(outputStream* output, bool heap);
 344   static const char* name() {
 345     return "GC.class_stats";
 346   }
 347   static const char* description() {
 348     return "Provide statistics about Java class meta data. Requires -XX:+UnlockDiagnosticVMOptions.";
 349   }
 350   static const char* impact() {
 351     return "High: Depends on Java heap size and content.";
 352   }
 353   static int num_arguments();
 354   virtual void execute(DCmdSource source, TRAPS);
 355 };
 356 
 357 
 358 class ClassHierarchyDCmd : public DCmdWithParser {
 359 protected:
 360   DCmdArgument<bool> _print_interfaces; // true if inherited interfaces should be printed.
 361   DCmdArgument<bool> _print_subclasses; // true if subclasses of the specified classname should be printed.
 362   DCmdArgument<char*> _classname; // Optional single class name whose hierarchy should be printed.
 363 public:
 364   ClassHierarchyDCmd(outputStream* output, bool heap);
 365   static const char* name() {
 366     return "VM.class_hierarchy";
 367   }
 368   static const char* description() {
 369     return "Print a list of all loaded classes, indented to show the class hiearchy. "
 370            "The name of each class is followed by the ClassLoaderData* of its ClassLoader, "
 371            "or \"null\" if loaded by the bootstrap class loader.";
 372   }
 373   static const char* impact() {
 374       return "Medium: Depends on number of loaded classes.";
 375   }
 376   static const JavaPermission permission() {
 377     JavaPermission p = {"java.lang.management.ManagementPermission",
 378                         "monitor", NULL};
 379     return p;
 380   }
 381   static int num_arguments();
 382   virtual void execute(DCmdSource source, TRAPS);
 383 };
 384 
 385 class TouchedMethodsDCmd : public DCmdWithParser {
 386 public:
 387   TouchedMethodsDCmd(outputStream* output, bool heap);
 388   static const char* name() {
 389     return "VM.print_touched_methods";
 390   }
 391   static const char* description() {
 392     return "Print all methods that have ever been touched during the lifetime of this JVM.";
 393   }
 394   static const char* impact() {
 395     return "Medium: Depends on Java content.";
 396   }
 397   static int num_arguments();
 398   virtual void execute(DCmdSource source, TRAPS);
 399 };
 400 
 401 // See also: thread_dump in attachListener.cpp
 402 class ThreadDumpDCmd : public DCmdWithParser {
 403 protected:
 404   DCmdArgument<bool> _locks;
 405 public:
 406   ThreadDumpDCmd(outputStream* output, bool heap);
 407   static const char* name() { return "Thread.print"; }
 408   static const char* description() {
 409     return "Print all threads with stacktraces.";
 410   }
 411   static const char* impact() {
 412     return "Medium: Depends on the number of threads.";
 413   }
 414   static const JavaPermission permission() {
 415     JavaPermission p = {"java.lang.management.ManagementPermission",
 416                         "monitor", NULL};
 417     return p;
 418   }
 419   static int num_arguments();
 420   virtual void execute(DCmdSource source, TRAPS);
 421 };
 422 
 423 // Enhanced JMX Agent support
 424 
 425 class JMXStartRemoteDCmd : public DCmdWithParser {
 426 
 427   // Explicitly list all properties that could be
 428   // passed to Agent.startRemoteManagementAgent()
 429   // com.sun.management is omitted
 430 
 431   DCmdArgument<char *> _config_file;
 432   DCmdArgument<char *> _jmxremote_port;
 433   DCmdArgument<char *> _jmxremote_rmi_port;
 434   DCmdArgument<char *> _jmxremote_ssl;
 435   DCmdArgument<char *> _jmxremote_registry_ssl;
 436   DCmdArgument<char *> _jmxremote_authenticate;
 437   DCmdArgument<char *> _jmxremote_password_file;
 438   DCmdArgument<char *> _jmxremote_access_file;
 439   DCmdArgument<char *> _jmxremote_login_config;
 440   DCmdArgument<char *> _jmxremote_ssl_enabled_cipher_suites;
 441   DCmdArgument<char *> _jmxremote_ssl_enabled_protocols;
 442   DCmdArgument<char *> _jmxremote_ssl_need_client_auth;
 443   DCmdArgument<char *> _jmxremote_ssl_config_file;
 444 
 445   // JDP support
 446   // Keep autodiscovery char* not bool to pass true/false
 447   // as property value to java level.
 448   DCmdArgument<char *> _jmxremote_autodiscovery;
 449   DCmdArgument<jlong>  _jdp_port;
 450   DCmdArgument<char *> _jdp_address;
 451   DCmdArgument<char *> _jdp_source_addr;
 452   DCmdArgument<jlong>  _jdp_ttl;
 453   DCmdArgument<jlong>  _jdp_pause;
 454   DCmdArgument<char *> _jdp_name;
 455 
 456 public:
 457   JMXStartRemoteDCmd(outputStream *output, bool heap_allocated);
 458 
 459   static const char *name() {
 460     return "ManagementAgent.start";
 461   }
 462 
 463   static const char *description() {
 464     return "Start remote management agent.";
 465   }
 466 
 467   static int num_arguments();
 468 
 469   virtual void execute(DCmdSource source, TRAPS);
 470 
 471 };
 472 
 473 class JMXStartLocalDCmd : public DCmd {
 474 
 475   // Explicitly request start of local agent,
 476   // it will not be started by start dcmd
 477 
 478 
 479 public:
 480   JMXStartLocalDCmd(outputStream *output, bool heap_allocated);
 481 
 482   static const char *name() {
 483     return "ManagementAgent.start_local";
 484   }
 485 
 486   static const char *description() {
 487     return "Start local management agent.";
 488   }
 489 
 490   virtual void execute(DCmdSource source, TRAPS);
 491 
 492 };
 493 
 494 class JMXStopRemoteDCmd : public DCmd {
 495 public:
 496   JMXStopRemoteDCmd(outputStream *output, bool heap_allocated) :
 497   DCmd(output, heap_allocated) {
 498     // Do Nothing
 499   }
 500 
 501   static const char *name() {
 502     return "ManagementAgent.stop";
 503   }
 504 
 505   static const char *description() {
 506     return "Stop remote management agent.";
 507   }
 508 
 509   virtual void execute(DCmdSource source, TRAPS);
 510 };
 511 
 512 // Print the JMX system status
 513 class JMXStatusDCmd : public DCmd {
 514 public:
 515   JMXStatusDCmd(outputStream *output, bool heap_allocated);
 516 
 517   static const char *name() {
 518     return "ManagementAgent.status";
 519   }
 520 
 521   static const char *description() {
 522     return "Print the management agent status.";
 523   }
 524 
 525   static const JavaPermission permission() {
 526     JavaPermission p = {"java.lang.management.ManagementPermission",
 527                         "monitor", NULL};
 528     return p;
 529   }
 530 
 531   virtual void execute(DCmdSource source, TRAPS);
 532 
 533 };
 534 
 535 class RotateGCLogDCmd : public DCmd {
 536 public:
 537   RotateGCLogDCmd(outputStream* output, bool heap) : DCmd(output, heap) {}
 538   static const char* name() { return "GC.rotate_log"; }
 539   static const char* description() {
 540     return "Force the GC log file to be rotated.";
 541   }
 542   static const char* impact() { return "Low"; }
 543   virtual void execute(DCmdSource source, TRAPS);
 544   static int num_arguments() { return 0; }
 545   static const JavaPermission permission() {
 546     JavaPermission p = {"java.lang.management.ManagementPermission",
 547                         "control", NULL};
 548     return p;
 549   }
 550 };
 551 
 552 class CompileQueueDCmd : public DCmd {
 553 public:
 554   CompileQueueDCmd(outputStream* output, bool heap) : DCmd(output, heap) {}
 555   static const char* name() {
 556     return "Compiler.queue";
 557   }
 558   static const char* description() {
 559     return "Print methods queued for compilation.";
 560   }
 561   static const char* impact() {
 562     return "Low";
 563   }
 564   static const JavaPermission permission() {
 565     JavaPermission p = {"java.lang.management.ManagementPermission",
 566                         "monitor", NULL};
 567     return p;
 568   }
 569   static int num_arguments() { return 0; }
 570   virtual void execute(DCmdSource source, TRAPS);
 571 };
 572 
 573 class CodeListDCmd : public DCmd {
 574 public:
 575   CodeListDCmd(outputStream* output, bool heap) : DCmd(output, heap) {}
 576   static const char* name() {
 577     return "Compiler.codelist";
 578   }
 579   static const char* description() {
 580     return "Print all compiled methods in code cache that are alive";
 581   }
 582   static const char* impact() {
 583     return "Medium";
 584   }
 585   static const JavaPermission permission() {
 586     JavaPermission p = {"java.lang.management.ManagementPermission",
 587                         "monitor", NULL};
 588     return p;
 589   }
 590   static int num_arguments() { return 0; }
 591   virtual void execute(DCmdSource source, TRAPS);
 592 };
 593 
 594 
 595 class CodeCacheDCmd : public DCmd {
 596 public:
 597   CodeCacheDCmd(outputStream* output, bool heap) : DCmd(output, heap) {}
 598   static const char* name() {
 599     return "Compiler.codecache";
 600   }
 601   static const char* description() {
 602     return "Print code cache layout and bounds.";
 603   }
 604   static const char* impact() {
 605     return "Low";
 606   }
 607   static const JavaPermission permission() {
 608     JavaPermission p = {"java.lang.management.ManagementPermission",
 609                         "monitor", NULL};
 610     return p;
 611   }
 612   static int num_arguments() { return 0; }
 613   virtual void execute(DCmdSource source, TRAPS);
 614 };
 615 
 616 #endif // SHARE_VM_SERVICES_DIAGNOSTICCOMMAND_HPP