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