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 VMInfoDCmd : public DCmd { 217 public: 218 VMInfoDCmd(outputStream* output, bool heap) : DCmd(output, heap) { } 219 static const char* name() { return "VM.info"; } 220 static const char* description() { 221 return "Print information about JVM environment and status."; 222 } 223 static const char* impact() { return "Low"; } 224 static const JavaPermission permission() { 225 JavaPermission p = {"java.lang.management.ManagementPermission", 226 "monitor", NULL}; 227 return p; 228 } 229 static int num_arguments() { return 0; } 230 virtual void execute(DCmdSource source, TRAPS); 231 }; 232 233 class SystemGCDCmd : public DCmd { 234 public: 235 SystemGCDCmd(outputStream* output, bool heap) : DCmd(output, heap) { } 236 static const char* name() { return "GC.run"; } 237 static const char* description() { 238 return "Call java.lang.System.gc()."; 239 } 240 static const char* impact() { 241 return "Medium: Depends on Java heap size and content."; 242 } 243 static int num_arguments() { return 0; } 244 virtual void execute(DCmdSource source, TRAPS); 245 }; 246 247 class RunFinalizationDCmd : public DCmd { 248 public: 249 RunFinalizationDCmd(outputStream* output, bool heap) : DCmd(output, heap) { } 250 static const char* name() { return "GC.run_finalization"; } 251 static const char* description() { 252 return "Call java.lang.System.runFinalization()."; 253 } 254 static const char* impact() { 255 return "Medium: Depends on Java content."; 256 } 257 static int num_arguments() { return 0; } 258 virtual void execute(DCmdSource source, TRAPS); 259 }; 260 261 class HeapInfoDCmd : public DCmd { 262 public: 263 HeapInfoDCmd(outputStream* output, bool heap) : DCmd(output, heap) { } 264 static const char* name() { return "GC.heap_info"; } 265 static const char* description() { 266 return "Provide generic Java heap information."; 267 } 268 static const char* impact() { 269 return "Medium"; 270 } 271 static int num_arguments() { return 0; } 272 static const JavaPermission permission() { 273 JavaPermission p = {"java.lang.management.ManagementPermission", 274 "monitor", NULL}; 275 return p; 276 } 277 278 virtual void execute(DCmdSource source, TRAPS); 279 }; 280 281 class FinalizerInfoDCmd : public DCmd { 282 public: 283 FinalizerInfoDCmd(outputStream* output, bool heap) : DCmd(output, heap) { } 284 static const char* name() { return "GC.finalizer_info"; } 285 static const char* description() { 286 return "Provide information about Java finalization queue."; 287 } 288 static const char* impact() { 289 return "Medium"; 290 } 291 static int num_arguments() { return 0; } 292 static const JavaPermission permission() { 293 JavaPermission p = {"java.lang.management.ManagementPermission", 294 "monitor", NULL}; 295 return p; 296 } 297 298 virtual void execute(DCmdSource source, TRAPS); 299 }; 300 301 #if INCLUDE_SERVICES // Heap dumping supported 302 // See also: dump_heap in attachListener.cpp 303 class HeapDumpDCmd : public DCmdWithParser { 304 protected: 305 DCmdArgument<char*> _filename; 306 DCmdArgument<bool> _all; 307 public: 308 HeapDumpDCmd(outputStream* output, bool heap); 309 static const char* name() { 310 return "GC.heap_dump"; 311 } 312 static const char* description() { 313 return "Generate a HPROF format dump of the Java heap."; 314 } 315 static const char* impact() { 316 return "High: Depends on Java heap size and content. " 317 "Request a full GC unless the '-all' option is specified."; 318 } 319 static const JavaPermission permission() { 320 JavaPermission p = {"java.lang.management.ManagementPermission", 321 "monitor", NULL}; 322 return p; 323 } 324 static int num_arguments(); 325 virtual void execute(DCmdSource source, TRAPS); 326 }; 327 #endif // INCLUDE_SERVICES 328 329 // See also: inspectheap in attachListener.cpp 330 class ClassHistogramDCmd : public DCmdWithParser { 331 protected: 332 DCmdArgument<bool> _all; 333 public: 334 ClassHistogramDCmd(outputStream* output, bool heap); 335 static const char* name() { 336 return "GC.class_histogram"; 337 } 338 static const char* description() { 339 return "Provide statistics about the Java heap usage."; 340 } 341 static const char* impact() { 342 return "High: Depends on Java heap size and content."; 343 } 344 static const JavaPermission permission() { 345 JavaPermission p = {"java.lang.management.ManagementPermission", 346 "monitor", NULL}; 347 return p; 348 } 349 static int num_arguments(); 350 virtual void execute(DCmdSource source, TRAPS); 351 }; 352 353 class ClassStatsDCmd : public DCmdWithParser { 354 protected: 355 DCmdArgument<bool> _all; 356 DCmdArgument<bool> _csv; 357 DCmdArgument<bool> _help; 358 DCmdArgument<char*> _columns; 359 public: 360 ClassStatsDCmd(outputStream* output, bool heap); 361 static const char* name() { 362 return "GC.class_stats"; 363 } 364 static const char* description() { 365 return "Provide statistics about Java class meta data. Requires -XX:+UnlockDiagnosticVMOptions."; 366 } 367 static const char* impact() { 368 return "High: Depends on Java heap size and content."; 369 } 370 static int num_arguments(); 371 virtual void execute(DCmdSource source, TRAPS); 372 }; 373 374 375 class ClassHierarchyDCmd : public DCmdWithParser { 376 protected: 377 DCmdArgument<bool> _print_interfaces; // true if inherited interfaces should be printed. 378 DCmdArgument<bool> _print_subclasses; // true if subclasses of the specified classname should be printed. 379 DCmdArgument<char*> _classname; // Optional single class name whose hierarchy should be printed. 380 public: 381 ClassHierarchyDCmd(outputStream* output, bool heap); 382 static const char* name() { 383 return "VM.class_hierarchy"; 384 } 385 static const char* description() { 386 return "Print a list of all loaded classes, indented to show the class hiearchy. " 387 "The name of each class is followed by the ClassLoaderData* of its ClassLoader, " 388 "or \"null\" if loaded by the bootstrap class loader."; 389 } 390 static const char* impact() { 391 return "Medium: Depends on number of loaded classes."; 392 } 393 static const JavaPermission permission() { 394 JavaPermission p = {"java.lang.management.ManagementPermission", 395 "monitor", NULL}; 396 return p; 397 } 398 static int num_arguments(); 399 virtual void execute(DCmdSource source, TRAPS); 400 }; 401 402 class TouchedMethodsDCmd : public DCmdWithParser { 403 public: 404 TouchedMethodsDCmd(outputStream* output, bool heap); 405 static const char* name() { 406 return "VM.print_touched_methods"; 407 } 408 static const char* description() { 409 return "Print all methods that have ever been touched during the lifetime of this JVM."; 410 } 411 static const char* impact() { 412 return "Medium: Depends on Java content."; 413 } 414 static int num_arguments(); 415 virtual void execute(DCmdSource source, TRAPS); 416 }; 417 418 // See also: thread_dump in attachListener.cpp 419 class ThreadDumpDCmd : public DCmdWithParser { 420 protected: 421 DCmdArgument<bool> _locks; 422 public: 423 ThreadDumpDCmd(outputStream* output, bool heap); 424 static const char* name() { return "Thread.print"; } 425 static const char* description() { 426 return "Print all threads with stacktraces."; 427 } 428 static const char* impact() { 429 return "Medium: Depends on the number of threads."; 430 } 431 static const JavaPermission permission() { 432 JavaPermission p = {"java.lang.management.ManagementPermission", 433 "monitor", NULL}; 434 return p; 435 } 436 static int num_arguments(); 437 virtual void execute(DCmdSource source, TRAPS); 438 }; 439 440 // Enhanced JMX Agent support 441 442 class JMXStartRemoteDCmd : public DCmdWithParser { 443 444 // Explicitly list all properties that could be 445 // passed to Agent.startRemoteManagementAgent() 446 // com.sun.management is omitted 447 448 DCmdArgument<char *> _config_file; 449 DCmdArgument<char *> _jmxremote_host; 450 DCmdArgument<char *> _jmxremote_port; 451 DCmdArgument<char *> _jmxremote_rmi_port; 452 DCmdArgument<char *> _jmxremote_ssl; 453 DCmdArgument<char *> _jmxremote_registry_ssl; 454 DCmdArgument<char *> _jmxremote_authenticate; 455 DCmdArgument<char *> _jmxremote_password_file; 456 DCmdArgument<char *> _jmxremote_access_file; 457 DCmdArgument<char *> _jmxremote_login_config; 458 DCmdArgument<char *> _jmxremote_ssl_enabled_cipher_suites; 459 DCmdArgument<char *> _jmxremote_ssl_enabled_protocols; 460 DCmdArgument<char *> _jmxremote_ssl_need_client_auth; 461 DCmdArgument<char *> _jmxremote_ssl_config_file; 462 463 // JDP support 464 // Keep autodiscovery char* not bool to pass true/false 465 // as property value to java level. 466 DCmdArgument<char *> _jmxremote_autodiscovery; 467 DCmdArgument<jlong> _jdp_port; 468 DCmdArgument<char *> _jdp_address; 469 DCmdArgument<char *> _jdp_source_addr; 470 DCmdArgument<jlong> _jdp_ttl; 471 DCmdArgument<jlong> _jdp_pause; 472 DCmdArgument<char *> _jdp_name; 473 474 public: 475 JMXStartRemoteDCmd(outputStream *output, bool heap_allocated); 476 477 static const char *name() { 478 return "ManagementAgent.start"; 479 } 480 481 static const char *description() { 482 return "Start remote management agent."; 483 } 484 485 static int num_arguments(); 486 487 virtual void execute(DCmdSource source, TRAPS); 488 489 }; 490 491 class JMXStartLocalDCmd : public DCmd { 492 493 // Explicitly request start of local agent, 494 // it will not be started by start dcmd 495 496 497 public: 498 JMXStartLocalDCmd(outputStream *output, bool heap_allocated); 499 500 static const char *name() { 501 return "ManagementAgent.start_local"; 502 } 503 504 static const char *description() { 505 return "Start local management agent."; 506 } 507 508 virtual void execute(DCmdSource source, TRAPS); 509 510 }; 511 512 class JMXStopRemoteDCmd : public DCmd { 513 public: 514 JMXStopRemoteDCmd(outputStream *output, bool heap_allocated) : 515 DCmd(output, heap_allocated) { 516 // Do Nothing 517 } 518 519 static const char *name() { 520 return "ManagementAgent.stop"; 521 } 522 523 static const char *description() { 524 return "Stop remote management agent."; 525 } 526 527 virtual void execute(DCmdSource source, TRAPS); 528 }; 529 530 // Print the JMX system status 531 class JMXStatusDCmd : public DCmd { 532 public: 533 JMXStatusDCmd(outputStream *output, bool heap_allocated); 534 535 static const char *name() { 536 return "ManagementAgent.status"; 537 } 538 539 static const char *description() { 540 return "Print the management agent status."; 541 } 542 543 static const JavaPermission permission() { 544 JavaPermission p = {"java.lang.management.ManagementPermission", 545 "monitor", NULL}; 546 return p; 547 } 548 549 virtual void execute(DCmdSource source, TRAPS); 550 551 }; 552 553 class CompileQueueDCmd : public DCmd { 554 public: 555 CompileQueueDCmd(outputStream* output, bool heap) : DCmd(output, heap) {} 556 static const char* name() { 557 return "Compiler.queue"; 558 } 559 static const char* description() { 560 return "Print methods queued for compilation."; 561 } 562 static const char* impact() { 563 return "Low"; 564 } 565 static const JavaPermission permission() { 566 JavaPermission p = {"java.lang.management.ManagementPermission", 567 "monitor", NULL}; 568 return p; 569 } 570 static int num_arguments() { return 0; } 571 virtual void execute(DCmdSource source, TRAPS); 572 }; 573 574 class CodeListDCmd : public DCmd { 575 public: 576 CodeListDCmd(outputStream* output, bool heap) : DCmd(output, heap) {} 577 static const char* name() { 578 return "Compiler.codelist"; 579 } 580 static const char* description() { 581 return "Print all compiled methods in code cache that are alive"; 582 } 583 static const char* impact() { 584 return "Medium"; 585 } 586 static const JavaPermission permission() { 587 JavaPermission p = {"java.lang.management.ManagementPermission", 588 "monitor", NULL}; 589 return p; 590 } 591 static int num_arguments() { return 0; } 592 virtual void execute(DCmdSource source, TRAPS); 593 }; 594 595 596 class CodeCacheDCmd : public DCmd { 597 public: 598 CodeCacheDCmd(outputStream* output, bool heap) : DCmd(output, heap) {} 599 static const char* name() { 600 return "Compiler.codecache"; 601 } 602 static const char* description() { 603 return "Print code cache layout and bounds."; 604 } 605 static const char* impact() { 606 return "Low"; 607 } 608 static const JavaPermission permission() { 609 JavaPermission p = {"java.lang.management.ManagementPermission", 610 "monitor", NULL}; 611 return p; 612 } 613 static int num_arguments() { return 0; } 614 virtual void execute(DCmdSource source, TRAPS); 615 }; 616 617 class CompilerDirectivesPrintDCmd : public DCmd { 618 public: 619 CompilerDirectivesPrintDCmd(outputStream* output, bool heap) : DCmd(output, heap) {} 620 static const char* name() { 621 return "Compiler.directives_print"; 622 } 623 static const char* description() { 624 return "Print all active compiler directives."; 625 } 626 static const char* impact() { 627 return "Low"; 628 } 629 static const JavaPermission permission() { 630 JavaPermission p = {"java.lang.management.ManagementPermission", 631 "monitor", NULL}; 632 return p; 633 } 634 static int num_arguments() { return 0; } 635 virtual void execute(DCmdSource source, TRAPS); 636 }; 637 638 class CompilerDirectivesRemoveDCmd : public DCmd { 639 public: 640 CompilerDirectivesRemoveDCmd(outputStream* output, bool heap) : DCmd(output, heap) {} 641 static const char* name() { 642 return "Compiler.directives_remove"; 643 } 644 static const char* description() { 645 return "Remove latest added compiler directive."; 646 } 647 static const char* impact() { 648 return "Low"; 649 } 650 static const JavaPermission permission() { 651 JavaPermission p = {"java.lang.management.ManagementPermission", 652 "monitor", NULL}; 653 return p; 654 } 655 static int num_arguments() { return 0; } 656 virtual void execute(DCmdSource source, TRAPS); 657 }; 658 659 class CompilerDirectivesAddDCmd : public DCmdWithParser { 660 protected: 661 DCmdArgument<char*> _filename; 662 public: 663 CompilerDirectivesAddDCmd(outputStream* output, bool heap); 664 static const char* name() { 665 return "Compiler.directives_add"; 666 } 667 static const char* description() { 668 return "Add compiler directives from file."; 669 } 670 static const char* impact() { 671 return "Low"; 672 } 673 static const JavaPermission permission() { 674 JavaPermission p = {"java.lang.management.ManagementPermission", 675 "monitor", NULL}; 676 return p; 677 } 678 static int num_arguments(); 679 virtual void execute(DCmdSource source, TRAPS); 680 }; 681 682 class CompilerDirectivesClearDCmd : public DCmd { 683 public: 684 CompilerDirectivesClearDCmd(outputStream* output, bool heap) : DCmd(output, heap) {} 685 static const char* name() { 686 return "Compiler.directives_clear"; 687 } 688 static const char* description() { 689 return "Remove all compiler directives."; 690 } 691 static const char* impact() { 692 return "Low"; 693 } 694 static const JavaPermission permission() { 695 JavaPermission p = {"java.lang.management.ManagementPermission", 696 "monitor", NULL}; 697 return p; 698 } 699 static int num_arguments() { return 0; } 700 virtual void execute(DCmdSource source, TRAPS); 701 }; 702 703 #endif // SHARE_VM_SERVICES_DIAGNOSTICCOMMAND_HPP