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_port; 450 DCmdArgument<char *> _jmxremote_rmi_port; 451 DCmdArgument<char *> _jmxremote_ssl; 452 DCmdArgument<char *> _jmxremote_registry_ssl; 453 DCmdArgument<char *> _jmxremote_authenticate; 454 DCmdArgument<char *> _jmxremote_password_file; 455 DCmdArgument<char *> _jmxremote_access_file; 456 DCmdArgument<char *> _jmxremote_login_config; 457 DCmdArgument<char *> _jmxremote_ssl_enabled_cipher_suites; 458 DCmdArgument<char *> _jmxremote_ssl_enabled_protocols; 459 DCmdArgument<char *> _jmxremote_ssl_need_client_auth; 460 DCmdArgument<char *> _jmxremote_ssl_config_file; 461 462 // JDP support 463 // Keep autodiscovery char* not bool to pass true/false 464 // as property value to java level. 465 DCmdArgument<char *> _jmxremote_autodiscovery; 466 DCmdArgument<jlong> _jdp_port; 467 DCmdArgument<char *> _jdp_address; 468 DCmdArgument<char *> _jdp_source_addr; 469 DCmdArgument<jlong> _jdp_ttl; 470 DCmdArgument<jlong> _jdp_pause; 471 DCmdArgument<char *> _jdp_name; 472 473 public: 474 JMXStartRemoteDCmd(outputStream *output, bool heap_allocated); 475 476 static const char *name() { 477 return "ManagementAgent.start"; 478 } 479 480 static const char *description() { 481 return "Start remote management agent."; 482 } 483 484 static int num_arguments(); 485 486 virtual void execute(DCmdSource source, TRAPS); 487 488 }; 489 490 class JMXStartLocalDCmd : public DCmd { 491 492 // Explicitly request start of local agent, 493 // it will not be started by start dcmd 494 495 496 public: 497 JMXStartLocalDCmd(outputStream *output, bool heap_allocated); 498 499 static const char *name() { 500 return "ManagementAgent.start_local"; 501 } 502 503 static const char *description() { 504 return "Start local management agent."; 505 } 506 507 virtual void execute(DCmdSource source, TRAPS); 508 509 }; 510 511 class JMXStopRemoteDCmd : public DCmd { 512 public: 513 JMXStopRemoteDCmd(outputStream *output, bool heap_allocated) : 514 DCmd(output, heap_allocated) { 515 // Do Nothing 516 } 517 518 static const char *name() { 519 return "ManagementAgent.stop"; 520 } 521 522 static const char *description() { 523 return "Stop remote management agent."; 524 } 525 526 virtual void execute(DCmdSource source, TRAPS); 527 }; 528 529 // Print the JMX system status 530 class JMXStatusDCmd : public DCmd { 531 public: 532 JMXStatusDCmd(outputStream *output, bool heap_allocated); 533 534 static const char *name() { 535 return "ManagementAgent.status"; 536 } 537 538 static const char *description() { 539 return "Print the management agent status."; 540 } 541 542 static const JavaPermission permission() { 543 JavaPermission p = {"java.lang.management.ManagementPermission", 544 "monitor", NULL}; 545 return p; 546 } 547 548 virtual void execute(DCmdSource source, TRAPS); 549 550 }; 551 552 class RotateGCLogDCmd : public DCmd { 553 public: 554 RotateGCLogDCmd(outputStream* output, bool heap) : DCmd(output, heap) {} 555 static const char* name() { return "GC.rotate_log"; } 556 static const char* description() { 557 return "Force the GC log file to be rotated."; 558 } 559 static const char* impact() { return "Low"; } 560 virtual void execute(DCmdSource source, TRAPS); 561 static int num_arguments() { return 0; } 562 static const JavaPermission permission() { 563 JavaPermission p = {"java.lang.management.ManagementPermission", 564 "control", NULL}; 565 return p; 566 } 567 }; 568 569 class CompileQueueDCmd : public DCmd { 570 public: 571 CompileQueueDCmd(outputStream* output, bool heap) : DCmd(output, heap) {} 572 static const char* name() { 573 return "Compiler.queue"; 574 } 575 static const char* description() { 576 return "Print methods queued for compilation."; 577 } 578 static const char* impact() { 579 return "Low"; 580 } 581 static const JavaPermission permission() { 582 JavaPermission p = {"java.lang.management.ManagementPermission", 583 "monitor", NULL}; 584 return p; 585 } 586 static int num_arguments() { return 0; } 587 virtual void execute(DCmdSource source, TRAPS); 588 }; 589 590 class CodeListDCmd : public DCmd { 591 public: 592 CodeListDCmd(outputStream* output, bool heap) : DCmd(output, heap) {} 593 static const char* name() { 594 return "Compiler.codelist"; 595 } 596 static const char* description() { 597 return "Print all compiled methods in code cache that are alive"; 598 } 599 static const char* impact() { 600 return "Medium"; 601 } 602 static const JavaPermission permission() { 603 JavaPermission p = {"java.lang.management.ManagementPermission", 604 "monitor", NULL}; 605 return p; 606 } 607 static int num_arguments() { return 0; } 608 virtual void execute(DCmdSource source, TRAPS); 609 }; 610 611 612 class CodeCacheDCmd : public DCmd { 613 public: 614 CodeCacheDCmd(outputStream* output, bool heap) : DCmd(output, heap) {} 615 static const char* name() { 616 return "Compiler.codecache"; 617 } 618 static const char* description() { 619 return "Print code cache layout and bounds."; 620 } 621 static const char* impact() { 622 return "Low"; 623 } 624 static const JavaPermission permission() { 625 JavaPermission p = {"java.lang.management.ManagementPermission", 626 "monitor", NULL}; 627 return p; 628 } 629 static int num_arguments() { return 0; } 630 virtual void execute(DCmdSource source, TRAPS); 631 }; 632 633 class CompilerDirectivesPrintDCmd : public DCmd { 634 public: 635 CompilerDirectivesPrintDCmd(outputStream* output, bool heap) : DCmd(output, heap) {} 636 static const char* name() { 637 return "Compiler.directives_print"; 638 } 639 static const char* description() { 640 return "Print all active compiler directives."; 641 } 642 static const char* impact() { 643 return "Low"; 644 } 645 static const JavaPermission permission() { 646 JavaPermission p = {"java.lang.management.ManagementPermission", 647 "monitor", NULL}; 648 return p; 649 } 650 static int num_arguments() { return 0; } 651 virtual void execute(DCmdSource source, TRAPS); 652 }; 653 654 class CompilerDirectivesRemoveDCmd : public DCmd { 655 public: 656 CompilerDirectivesRemoveDCmd(outputStream* output, bool heap) : DCmd(output, heap) {} 657 static const char* name() { 658 return "Compiler.directives_remove"; 659 } 660 static const char* description() { 661 return "Remove latest added compiler directive."; 662 } 663 static const char* impact() { 664 return "Low"; 665 } 666 static const JavaPermission permission() { 667 JavaPermission p = {"java.lang.management.ManagementPermission", 668 "monitor", NULL}; 669 return p; 670 } 671 static int num_arguments() { return 0; } 672 virtual void execute(DCmdSource source, TRAPS); 673 }; 674 675 class CompilerDirectivesAddDCmd : public DCmdWithParser { 676 protected: 677 DCmdArgument<char*> _filename; 678 public: 679 CompilerDirectivesAddDCmd(outputStream* output, bool heap); 680 static const char* name() { 681 return "Compiler.directives_add"; 682 } 683 static const char* description() { 684 return "Add compiler directives from file."; 685 } 686 static const char* impact() { 687 return "Low"; 688 } 689 static const JavaPermission permission() { 690 JavaPermission p = {"java.lang.management.ManagementPermission", 691 "monitor", NULL}; 692 return p; 693 } 694 static int num_arguments(); 695 virtual void execute(DCmdSource source, TRAPS); 696 }; 697 698 class CompilerDirectivesClearDCmd : public DCmd { 699 public: 700 CompilerDirectivesClearDCmd(outputStream* output, bool heap) : DCmd(output, heap) {} 701 static const char* name() { 702 return "Compiler.directives_clear"; 703 } 704 static const char* description() { 705 return "Remove all compiler directives."; 706 } 707 static const char* impact() { 708 return "Low"; 709 } 710 static const JavaPermission permission() { 711 JavaPermission p = {"java.lang.management.ManagementPermission", 712 "monitor", NULL}; 713 return p; 714 } 715 static int num_arguments() { return 0; } 716 virtual void execute(DCmdSource source, TRAPS); 717 }; 718 719 #endif // SHARE_VM_SERVICES_DIAGNOSTICCOMMAND_HPP