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