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