1 /* 2 * Copyright (c) 2011, 2023, 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_SERVICES_DIAGNOSTICCOMMAND_HPP 26 #define SHARE_SERVICES_DIAGNOSTICCOMMAND_HPP 27 28 #include "classfile/stringTable.hpp" 29 #include "classfile/symbolTable.hpp" 30 #include "classfile/systemDictionary.hpp" 31 #include "classfile/vmSymbols.hpp" 32 #include "runtime/arguments.hpp" 33 #include "runtime/os.hpp" 34 #include "runtime/vmThread.hpp" 35 #include "services/diagnosticArgument.hpp" 36 #include "services/diagnosticCommand.hpp" 37 #include "services/diagnosticFramework.hpp" 38 #include "utilities/macros.hpp" 39 #include "utilities/ostream.hpp" 40 #include "oops/method.hpp" 41 42 class HelpDCmd : public DCmdWithParser { 43 protected: 44 DCmdArgument<bool> _all; 45 DCmdArgument<char*> _cmd; 46 public: 47 static int num_arguments() { return 2; } 48 HelpDCmd(outputStream* output, bool heap); 49 static const char* name() { return "help"; } 50 static const char* description() { 51 return "For more information about a specific command use 'help <command>'. " 52 "With no argument this will show a list of available commands. " 53 "'help all' will show help for all commands."; 54 } 55 static const char* impact() { return "Low"; } 56 virtual void execute(DCmdSource source, TRAPS); 57 }; 58 59 class VersionDCmd : public DCmd { 60 public: 61 VersionDCmd(outputStream* output, bool heap) : DCmd(output,heap) { } 62 static const char* name() { return "VM.version"; } 63 static const char* description() { 64 return "Print JVM version information."; 65 } 66 static const char* impact() { return "Low"; } 67 static const JavaPermission permission() { 68 JavaPermission p = {"java.util.PropertyPermission", 69 "java.vm.version", "read"}; 70 return p; 71 } 72 virtual void execute(DCmdSource source, TRAPS); 73 }; 74 75 class CommandLineDCmd : public DCmd { 76 public: 77 CommandLineDCmd(outputStream* output, bool heap) : DCmd(output, heap) { } 78 static const char* name() { return "VM.command_line"; } 79 static const char* description() { 80 return "Print the command line used to start this VM instance."; 81 } 82 static const char* impact() { return "Low"; } 83 static const JavaPermission permission() { 84 JavaPermission p = {"java.lang.management.ManagementPermission", 85 "monitor", nullptr}; 86 return p; 87 } 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 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 static int num_arguments() { return 1; } 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", nullptr}; 129 return p; 130 } 131 virtual void execute(DCmdSource source, TRAPS); 132 }; 133 134 class SetVMFlagDCmd : public DCmdWithParser { 135 protected: 136 DCmdArgument<char*> _flag; 137 DCmdArgument<char*> _value; 138 139 public: 140 static int num_arguments() { return 2; } 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", nullptr}; 152 return p; 153 } 154 virtual void execute(DCmdSource source, TRAPS); 155 }; 156 157 class JVMTIDataDumpDCmd : public DCmd { 158 public: 159 JVMTIDataDumpDCmd(outputStream* output, bool heap) : DCmd(output, heap) { } 160 static const char* name() { return "JVMTI.data_dump"; } 161 static const char* description() { 162 return "Signal the JVM to do a data-dump request for JVMTI."; 163 } 164 static const char* impact() { 165 return "High"; 166 } 167 static const JavaPermission permission() { 168 JavaPermission p = {"java.lang.management.ManagementPermission", 169 "monitor", nullptr}; 170 return p; 171 } 172 virtual void execute(DCmdSource source, TRAPS); 173 }; 174 175 #if INCLUDE_SERVICES 176 #if INCLUDE_JVMTI 177 class JVMTIAgentLoadDCmd : public DCmdWithParser { 178 protected: 179 DCmdArgument<char*> _libpath; 180 DCmdArgument<char*> _option; 181 public: 182 static int num_arguments() { return 2; } 183 JVMTIAgentLoadDCmd(outputStream* output, bool heap); 184 static const char* name() { return "JVMTI.agent_load"; } 185 static const char* description() { 186 return "Load JVMTI native agent."; 187 } 188 static const char* impact() { return "Low"; } 189 static const JavaPermission permission() { 190 JavaPermission p = {"java.lang.management.ManagementPermission", 191 "control", nullptr}; 192 return p; 193 } 194 virtual void execute(DCmdSource source, TRAPS); 195 }; 196 #endif // INCLUDE_JVMTI 197 #endif // INCLUDE_SERVICES 198 199 class VMDynamicLibrariesDCmd : public DCmd { 200 public: 201 VMDynamicLibrariesDCmd(outputStream* output, bool heap); 202 static const char* name() { 203 return "VM.dynlibs"; 204 } 205 static const char* description() { 206 return "Print loaded dynamic libraries."; 207 } 208 static const char* impact() { 209 return "Low"; 210 } 211 static const JavaPermission permission() { 212 JavaPermission p = {"java.lang.management.ManagementPermission", 213 "monitor", nullptr}; 214 return p; 215 } 216 virtual void execute(DCmdSource source, TRAPS); 217 }; 218 219 class VMUptimeDCmd : public DCmdWithParser { 220 protected: 221 DCmdArgument<bool> _date; 222 public: 223 static int num_arguments() { return 1; } 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 virtual void execute(DCmdSource source, TRAPS); 233 }; 234 235 class VMInfoDCmd : public DCmd { 236 public: 237 VMInfoDCmd(outputStream* output, bool heap) : DCmd(output, heap) { } 238 static const char* name() { return "VM.info"; } 239 static const char* description() { 240 return "Print information about JVM environment and status."; 241 } 242 static const char* impact() { return "Low"; } 243 static const JavaPermission permission() { 244 JavaPermission p = {"java.lang.management.ManagementPermission", 245 "monitor", nullptr}; 246 return p; 247 } 248 virtual void execute(DCmdSource source, TRAPS); 249 }; 250 251 class SystemGCDCmd : public DCmd { 252 public: 253 SystemGCDCmd(outputStream* output, bool heap) : DCmd(output, heap) { } 254 static const char* name() { return "GC.run"; } 255 static const char* description() { 256 return "Call java.lang.System.gc()."; 257 } 258 static const char* impact() { 259 return "Medium: Depends on Java heap size and content."; 260 } 261 virtual void execute(DCmdSource source, TRAPS); 262 }; 263 264 class RunFinalizationDCmd : public DCmd { 265 public: 266 RunFinalizationDCmd(outputStream* output, bool heap) : DCmd(output, heap) { } 267 static const char* name() { return "GC.run_finalization"; } 268 static const char* description() { 269 return "Call java.lang.System.runFinalization()."; 270 } 271 static const char* impact() { 272 return "Medium: Depends on Java content."; 273 } 274 virtual void execute(DCmdSource source, TRAPS); 275 }; 276 277 class HeapInfoDCmd : public DCmd { 278 public: 279 HeapInfoDCmd(outputStream* output, bool heap) : DCmd(output, heap) { } 280 static const char* name() { return "GC.heap_info"; } 281 static const char* description() { 282 return "Provide generic Java heap information."; 283 } 284 static const char* impact() { 285 return "Medium"; 286 } 287 static const JavaPermission permission() { 288 JavaPermission p = {"java.lang.management.ManagementPermission", 289 "monitor", nullptr}; 290 return p; 291 } 292 293 virtual void execute(DCmdSource source, TRAPS); 294 }; 295 296 class FinalizerInfoDCmd : public DCmd { 297 public: 298 FinalizerInfoDCmd(outputStream* output, bool heap) : DCmd(output, heap) { } 299 static const char* name() { return "GC.finalizer_info"; } 300 static const char* description() { 301 return "Provide information about Java finalization queue."; 302 } 303 static const char* impact() { 304 return "Medium"; 305 } 306 static const JavaPermission permission() { 307 JavaPermission p = {"java.lang.management.ManagementPermission", 308 "monitor", nullptr}; 309 return p; 310 } 311 312 virtual void execute(DCmdSource source, TRAPS); 313 }; 314 315 #if INCLUDE_SERVICES // Heap dumping supported 316 // See also: dump_heap in attachListener.cpp 317 class HeapDumpDCmd : public DCmdWithParser { 318 protected: 319 DCmdArgument<char*> _filename; 320 DCmdArgument<bool> _all; 321 DCmdArgument<jlong> _gzip; 322 DCmdArgument<bool> _overwrite; 323 DCmdArgument<jlong> _parallel; 324 public: 325 static int num_arguments() { return 5; } 326 HeapDumpDCmd(outputStream* output, bool heap); 327 static const char* name() { 328 return "GC.heap_dump"; 329 } 330 static const char* description() { 331 return "Generate a HPROF format dump of the Java heap."; 332 } 333 static const char* impact() { 334 return "High: Depends on Java heap size and content. " 335 "Request a full GC unless the '-all' option is specified."; 336 } 337 static const JavaPermission permission() { 338 JavaPermission p = {"java.lang.management.ManagementPermission", 339 "monitor", nullptr}; 340 return p; 341 } 342 virtual void execute(DCmdSource source, TRAPS); 343 }; 344 #endif // INCLUDE_SERVICES 345 346 // See also: inspectheap in attachListener.cpp 347 class ClassHistogramDCmd : public DCmdWithParser { 348 protected: 349 DCmdArgument<bool> _all; 350 DCmdArgument<jlong> _parallel_thread_num; 351 public: 352 static int num_arguments() { return 2; } 353 ClassHistogramDCmd(outputStream* output, bool heap); 354 static const char* name() { 355 return "GC.class_histogram"; 356 } 357 static const char* description() { 358 return "Provide statistics about the Java heap usage."; 359 } 360 static const char* impact() { 361 return "High: Depends on Java heap size and content."; 362 } 363 static const JavaPermission permission() { 364 JavaPermission p = {"java.lang.management.ManagementPermission", 365 "monitor", nullptr}; 366 return p; 367 } 368 virtual void execute(DCmdSource source, TRAPS); 369 }; 370 371 class ClassHierarchyDCmd : public DCmdWithParser { 372 protected: 373 DCmdArgument<bool> _print_interfaces; // true if inherited interfaces should be printed. 374 DCmdArgument<bool> _print_subclasses; // true if subclasses of the specified classname should be printed. 375 DCmdArgument<char*> _classname; // Optional single class name whose hierarchy should be printed. 376 public: 377 static int num_arguments() { return 3; } 378 ClassHierarchyDCmd(outputStream* output, bool heap); 379 static const char* name() { 380 return "VM.class_hierarchy"; 381 } 382 static const char* description() { 383 return "Print a list of all loaded classes, indented to show the class hierarchy. " 384 "The name of each class is followed by the ClassLoaderData* of its ClassLoader, " 385 "or \"null\" if loaded by the bootstrap class loader."; 386 } 387 static const char* impact() { 388 return "Medium: Depends on number of loaded classes."; 389 } 390 static const JavaPermission permission() { 391 JavaPermission p = {"java.lang.management.ManagementPermission", 392 "monitor", nullptr}; 393 return p; 394 } 395 virtual void execute(DCmdSource source, TRAPS); 396 }; 397 398 class PrintClassLayoutDCmd : public DCmdWithParser { 399 protected: 400 DCmdArgument<char*> _classname; // lass name whose layout should be printed. 401 public: 402 PrintClassLayoutDCmd(outputStream* output, bool heap); 403 static const char* name() { 404 return "VM.class_print_layout"; 405 } 406 static const char* description() { 407 return "Print the layout of an instance of a class, including flat fields. " 408 "The name of each class is followed by the ClassLoaderData* of its ClassLoader, " 409 "or \"null\" if loaded by the bootstrap class loader."; 410 } 411 static const char* impact() { 412 return "Medium: Depends on number of loaded classes."; 413 } 414 static const JavaPermission permission() { 415 JavaPermission p = {"java.lang.management.ManagementPermission", 416 "monitor", nullptr}; 417 return p; 418 } 419 static int num_arguments(); 420 virtual void execute(DCmdSource source, TRAPS); 421 }; 422 423 #if INCLUDE_CDS 424 class DumpSharedArchiveDCmd: public DCmdWithParser { 425 protected: 426 DCmdArgument<char*> _suboption; // option of VM.cds 427 DCmdArgument<char*> _filename; // file name, optional 428 public: 429 static int num_arguments() { return 2; } 430 DumpSharedArchiveDCmd(outputStream* output, bool heap); 431 static const char* name() { 432 return "VM.cds"; 433 } 434 static const char* description() { 435 return "Dump a static or dynamic shared archive including all shareable classes"; 436 } 437 static const char* impact() { 438 return "Medium: Pause time depends on number of loaded classes"; 439 } 440 static const JavaPermission permission() { 441 JavaPermission p = {"java.lang.management.ManagementPermission", 442 "monitor", nullptr}; 443 return p; 444 } 445 virtual void execute(DCmdSource source, TRAPS); 446 }; 447 #endif // INCLUDE_CDS 448 449 // See also: thread_dump in attachListener.cpp 450 class ThreadDumpDCmd : public DCmdWithParser { 451 protected: 452 DCmdArgument<bool> _locks; 453 DCmdArgument<bool> _extended; 454 public: 455 static int num_arguments() { return 2; } 456 ThreadDumpDCmd(outputStream* output, bool heap); 457 static const char* name() { return "Thread.print"; } 458 static const char* description() { 459 return "Print all threads with stacktraces."; 460 } 461 static const char* impact() { 462 return "Medium: Depends on the number of threads."; 463 } 464 static const JavaPermission permission() { 465 JavaPermission p = {"java.lang.management.ManagementPermission", 466 "monitor", nullptr}; 467 return p; 468 } 469 virtual void execute(DCmdSource source, TRAPS); 470 }; 471 472 // Enhanced JMX Agent support 473 474 class JMXStartRemoteDCmd : public DCmdWithParser { 475 476 // Explicitly list all properties that could be 477 // passed to Agent.startRemoteManagementAgent() 478 // com.sun.management is omitted 479 480 DCmdArgument<char *> _config_file; 481 DCmdArgument<char *> _jmxremote_host; 482 DCmdArgument<char *> _jmxremote_port; 483 DCmdArgument<char *> _jmxremote_rmi_port; 484 DCmdArgument<char *> _jmxremote_ssl; 485 DCmdArgument<char *> _jmxremote_registry_ssl; 486 DCmdArgument<char *> _jmxremote_authenticate; 487 DCmdArgument<char *> _jmxremote_password_file; 488 DCmdArgument<char *> _jmxremote_access_file; 489 DCmdArgument<char *> _jmxremote_login_config; 490 DCmdArgument<char *> _jmxremote_ssl_enabled_cipher_suites; 491 DCmdArgument<char *> _jmxremote_ssl_enabled_protocols; 492 DCmdArgument<char *> _jmxremote_ssl_need_client_auth; 493 DCmdArgument<char *> _jmxremote_ssl_config_file; 494 495 // JDP support 496 // Keep autodiscovery char* not bool to pass true/false 497 // as property value to java level. 498 DCmdArgument<char *> _jmxremote_autodiscovery; 499 DCmdArgument<jlong> _jdp_port; 500 DCmdArgument<char *> _jdp_address; 501 DCmdArgument<char *> _jdp_source_addr; 502 DCmdArgument<jlong> _jdp_ttl; 503 DCmdArgument<jlong> _jdp_pause; 504 DCmdArgument<char *> _jdp_name; 505 506 public: 507 static int num_arguments() { return 21; } 508 509 JMXStartRemoteDCmd(outputStream *output, bool heap_allocated); 510 511 static const char *name() { 512 return "ManagementAgent.start"; 513 } 514 515 static const char *description() { 516 return "Start remote management agent."; 517 } 518 519 virtual void execute(DCmdSource source, TRAPS); 520 }; 521 522 class JMXStartLocalDCmd : public DCmd { 523 524 // Explicitly request start of local agent, 525 // it will not be started by start dcmd 526 527 528 public: 529 JMXStartLocalDCmd(outputStream *output, bool heap_allocated); 530 531 static const char *name() { 532 return "ManagementAgent.start_local"; 533 } 534 535 static const char *description() { 536 return "Start local management agent."; 537 } 538 539 virtual void execute(DCmdSource source, TRAPS); 540 541 }; 542 543 class JMXStopRemoteDCmd : public DCmd { 544 public: 545 JMXStopRemoteDCmd(outputStream *output, bool heap_allocated) : 546 DCmd(output, heap_allocated) { 547 // Do Nothing 548 } 549 550 static const char *name() { 551 return "ManagementAgent.stop"; 552 } 553 554 static const char *description() { 555 return "Stop remote management agent."; 556 } 557 558 virtual void execute(DCmdSource source, TRAPS); 559 }; 560 561 // Print the JMX system status 562 class JMXStatusDCmd : public DCmd { 563 public: 564 JMXStatusDCmd(outputStream *output, bool heap_allocated); 565 566 static const char *name() { 567 return "ManagementAgent.status"; 568 } 569 570 static const char *description() { 571 return "Print the management agent status."; 572 } 573 574 static const JavaPermission permission() { 575 JavaPermission p = {"java.lang.management.ManagementPermission", 576 "monitor", nullptr}; 577 return p; 578 } 579 580 virtual void execute(DCmdSource source, TRAPS); 581 582 }; 583 584 class CompileQueueDCmd : public DCmd { 585 public: 586 CompileQueueDCmd(outputStream* output, bool heap) : DCmd(output, heap) {} 587 static const char* name() { 588 return "Compiler.queue"; 589 } 590 static const char* description() { 591 return "Print methods queued for compilation."; 592 } 593 static const char* impact() { 594 return "Low"; 595 } 596 static const JavaPermission permission() { 597 JavaPermission p = {"java.lang.management.ManagementPermission", 598 "monitor", nullptr}; 599 return p; 600 } 601 virtual void execute(DCmdSource source, TRAPS); 602 }; 603 604 #ifdef LINUX 605 class PerfMapDCmd : public DCmd { 606 public: 607 PerfMapDCmd(outputStream* output, bool heap) : DCmd(output, heap) {} 608 static const char* name() { 609 return "Compiler.perfmap"; 610 } 611 static const char* description() { 612 return "Write map file for Linux perf tool."; 613 } 614 static const char* impact() { 615 return "Low"; 616 } 617 static const JavaPermission permission() { 618 JavaPermission p = {"java.lang.management.ManagementPermission", 619 "monitor", nullptr}; 620 return p; 621 } 622 virtual void execute(DCmdSource source, TRAPS); 623 }; 624 #endif // LINUX 625 626 class CodeListDCmd : public DCmd { 627 public: 628 CodeListDCmd(outputStream* output, bool heap) : DCmd(output, heap) {} 629 static const char* name() { 630 return "Compiler.codelist"; 631 } 632 static const char* description() { 633 return "Print all compiled methods in code cache that are alive"; 634 } 635 static const char* impact() { 636 return "Medium"; 637 } 638 static const JavaPermission permission() { 639 JavaPermission p = {"java.lang.management.ManagementPermission", 640 "monitor", nullptr}; 641 return p; 642 } 643 virtual void execute(DCmdSource source, TRAPS); 644 }; 645 646 class CodeCacheDCmd : public DCmd { 647 public: 648 CodeCacheDCmd(outputStream* output, bool heap) : DCmd(output, heap) {} 649 static const char* name() { 650 return "Compiler.codecache"; 651 } 652 static const char* description() { 653 return "Print code cache layout and bounds."; 654 } 655 static const char* impact() { 656 return "Low"; 657 } 658 static const JavaPermission permission() { 659 JavaPermission p = {"java.lang.management.ManagementPermission", 660 "monitor", nullptr}; 661 return p; 662 } 663 virtual void execute(DCmdSource source, TRAPS); 664 }; 665 666 //---< BEGIN >--- CodeHeap State Analytics. 667 class CodeHeapAnalyticsDCmd : public DCmdWithParser { 668 protected: 669 DCmdArgument<char*> _function; 670 DCmdArgument<jlong> _granularity; 671 public: 672 static int num_arguments() { return 2; } 673 CodeHeapAnalyticsDCmd(outputStream* output, bool heap); 674 static const char* name() { 675 return "Compiler.CodeHeap_Analytics"; 676 } 677 static const char* description() { 678 return "Print CodeHeap analytics"; 679 } 680 static const char* impact() { 681 return "Low: Depends on code heap size and content. " 682 "Holds CodeCache_lock during analysis step, usually sub-second duration."; 683 } 684 static const JavaPermission permission() { 685 JavaPermission p = {"java.lang.management.ManagementPermission", 686 "monitor", nullptr}; 687 return p; 688 } 689 virtual void execute(DCmdSource source, TRAPS); 690 }; 691 //---< END >--- CodeHeap State Analytics. 692 693 class CompilerDirectivesPrintDCmd : public DCmd { 694 public: 695 CompilerDirectivesPrintDCmd(outputStream* output, bool heap) : DCmd(output, heap) {} 696 static const char* name() { 697 return "Compiler.directives_print"; 698 } 699 static const char* description() { 700 return "Print all active compiler directives."; 701 } 702 static const char* impact() { 703 return "Low"; 704 } 705 static const JavaPermission permission() { 706 JavaPermission p = {"java.lang.management.ManagementPermission", 707 "monitor", nullptr}; 708 return p; 709 } 710 virtual void execute(DCmdSource source, TRAPS); 711 }; 712 713 class CompilerDirectivesRemoveDCmd : public DCmd { 714 public: 715 CompilerDirectivesRemoveDCmd(outputStream* output, bool heap) : DCmd(output, heap) {} 716 static const char* name() { 717 return "Compiler.directives_remove"; 718 } 719 static const char* description() { 720 return "Remove latest added compiler directive."; 721 } 722 static const char* impact() { 723 return "Low"; 724 } 725 static const JavaPermission permission() { 726 JavaPermission p = {"java.lang.management.ManagementPermission", 727 "control", nullptr}; 728 return p; 729 } 730 virtual void execute(DCmdSource source, TRAPS); 731 }; 732 733 class CompilerDirectivesAddDCmd : public DCmdWithParser { 734 protected: 735 DCmdArgument<char*> _filename; 736 public: 737 static int num_arguments() { return 1; } 738 CompilerDirectivesAddDCmd(outputStream* output, bool heap); 739 static const char* name() { 740 return "Compiler.directives_add"; 741 } 742 static const char* description() { 743 return "Add compiler directives from file."; 744 } 745 static const char* impact() { 746 return "Low"; 747 } 748 static const JavaPermission permission() { 749 JavaPermission p = {"java.lang.management.ManagementPermission", 750 "control", nullptr}; 751 return p; 752 } 753 virtual void execute(DCmdSource source, TRAPS); 754 }; 755 756 class CompilerDirectivesClearDCmd : public DCmd { 757 public: 758 CompilerDirectivesClearDCmd(outputStream* output, bool heap) : DCmd(output, heap) {} 759 static const char* name() { 760 return "Compiler.directives_clear"; 761 } 762 static const char* description() { 763 return "Remove all compiler directives."; 764 } 765 static const char* impact() { 766 return "Low"; 767 } 768 static const JavaPermission permission() { 769 JavaPermission p = {"java.lang.management.ManagementPermission", 770 "control", nullptr}; 771 return p; 772 } 773 virtual void execute(DCmdSource source, TRAPS); 774 }; 775 776 /////////////////////////////////////////////////////////////////////// 777 // 778 // jcmd command support for symbol table, string table and system dictionary dumping: 779 // VM.symboltable -verbose: for dumping the symbol table 780 // VM.stringtable -verbose: for dumping the string table 781 // VM.systemdictionary -verbose: for dumping the system dictionary table 782 // 783 class VM_DumpHashtable : public VM_Operation { 784 private: 785 outputStream* _out; 786 int _which; 787 bool _verbose; 788 public: 789 enum { 790 DumpSymbols = 1 << 0, 791 DumpStrings = 1 << 1, 792 DumpSysDict = 1 << 2 // not implemented yet 793 }; 794 VM_DumpHashtable(outputStream* out, int which, bool verbose) { 795 _out = out; 796 _which = which; 797 _verbose = verbose; 798 } 799 800 virtual VMOp_Type type() const { return VMOp_DumpHashtable; } 801 802 virtual void doit() { 803 switch (_which) { 804 case DumpSymbols: 805 SymbolTable::dump(_out, _verbose); 806 break; 807 case DumpStrings: 808 StringTable::dump(_out, _verbose); 809 break; 810 case DumpSysDict: 811 SystemDictionary::dump(_out, _verbose); 812 break; 813 default: 814 ShouldNotReachHere(); 815 } 816 } 817 }; 818 819 class SymboltableDCmd : public DCmdWithParser { 820 protected: 821 DCmdArgument<bool> _verbose; 822 public: 823 static int num_arguments() { return 1; } 824 SymboltableDCmd(outputStream* output, bool heap); 825 static const char* name() { 826 return "VM.symboltable"; 827 } 828 static const char* description() { 829 return "Dump symbol table."; 830 } 831 static const char* impact() { 832 return "Medium: Depends on Java content."; 833 } 834 static const JavaPermission permission() { 835 JavaPermission p = {"java.lang.management.ManagementPermission", 836 "monitor", nullptr}; 837 return p; 838 } 839 virtual void execute(DCmdSource source, TRAPS); 840 }; 841 842 class StringtableDCmd : public DCmdWithParser { 843 protected: 844 DCmdArgument<bool> _verbose; 845 public: 846 static int num_arguments() { return 1; } 847 StringtableDCmd(outputStream* output, bool heap); 848 static const char* name() { 849 return "VM.stringtable"; 850 } 851 static const char* description() { 852 return "Dump string table."; 853 } 854 static const char* impact() { 855 return "Medium: Depends on Java content."; 856 } 857 static const JavaPermission permission() { 858 JavaPermission p = {"java.lang.management.ManagementPermission", 859 "monitor", nullptr}; 860 return p; 861 } 862 virtual void execute(DCmdSource source, TRAPS); 863 }; 864 865 class SystemDictionaryDCmd : public DCmdWithParser { 866 protected: 867 DCmdArgument<bool> _verbose; 868 public: 869 static int num_arguments() { return 1; } 870 SystemDictionaryDCmd(outputStream* output, bool heap); 871 static const char* name() { 872 return "VM.systemdictionary"; 873 } 874 static const char* description() { 875 return "Prints the statistics for dictionary hashtable sizes and bucket length"; 876 } 877 static const char* impact() { 878 return "Medium: Depends on Java content."; 879 } 880 static const JavaPermission permission() { 881 JavaPermission p = {"java.lang.management.ManagementPermission", 882 "monitor", nullptr}; 883 return p; 884 } 885 virtual void execute(DCmdSource source, TRAPS); 886 }; 887 888 class ClassesDCmd : public DCmdWithParser { 889 protected: 890 DCmdArgument<bool> _verbose; 891 public: 892 static int num_arguments() { return 1; } 893 ClassesDCmd(outputStream* output, bool heap); 894 static const char* name() { 895 return "VM.classes"; 896 } 897 static const char* description() { 898 return "Print all loaded classes"; 899 } 900 static const char* impact() { 901 return "Medium: Depends on number of loaded classes."; 902 } 903 static const JavaPermission permission() { 904 JavaPermission p = {"java.lang.management.ManagementPermission", 905 "monitor", nullptr}; 906 return p; 907 } 908 virtual void execute(DCmdSource source, TRAPS); 909 }; 910 911 #if INCLUDE_JVMTI 912 class DebugOnCmdStartDCmd : public DCmd { 913 public: 914 DebugOnCmdStartDCmd(outputStream* output, bool heap) : DCmd(output, heap) {} 915 static const char* name() { 916 return "VM.start_java_debugging"; 917 } 918 static const char* description() { 919 return "Starts up the Java debugging if the jdwp agentlib was enabled with the option onjcmd=y."; 920 } 921 static const char* impact() { 922 return "High: Switches the VM into Java debug mode."; 923 } 924 static const JavaPermission permission() { 925 JavaPermission p = { "java.lang.management.ManagementPermission", "control", nullptr }; 926 return p; 927 } 928 virtual void execute(DCmdSource source, TRAPS); 929 }; 930 #endif // INCLUDE_JVMTI 931 932 class EventLogDCmd : public DCmdWithParser { 933 protected: 934 DCmdArgument<char*> _log; 935 DCmdArgument<char*> _max; 936 public: 937 static int num_arguments() { return 2; } 938 EventLogDCmd(outputStream* output, bool heap); 939 static const char* name() { 940 return "VM.events"; 941 } 942 static const char* description() { 943 return "Print VM event logs"; 944 } 945 static const char* impact() { 946 return "Low: Depends on event log size. "; 947 } 948 static const JavaPermission permission() { 949 JavaPermission p = {"java.lang.management.ManagementPermission", 950 "monitor", nullptr}; 951 return p; 952 } 953 virtual void execute(DCmdSource source, TRAPS); 954 }; 955 956 class ThreadDumpToFileDCmd : public DCmdWithParser { 957 private: 958 void dumpToFile(Symbol* name, Symbol* signature, const char* path, bool overwrite, TRAPS); 959 protected: 960 DCmdArgument<bool> _overwrite; 961 DCmdArgument<char*> _format; 962 DCmdArgument<char*> _filepath; 963 public: 964 static int num_arguments() { return 3; } 965 ThreadDumpToFileDCmd(outputStream *output, bool heap); 966 static const char *name() { 967 return "Thread.dump_to_file"; 968 } 969 static const char *description() { 970 return "Dump threads, with stack traces, to a file in plain text or JSON format."; 971 } 972 static const char* impact() { 973 return "Medium: Depends on the number of threads."; 974 } 975 static const JavaPermission permission() { 976 JavaPermission p = {"java.lang.management.ManagementPermission", "monitor", nullptr}; 977 return p; 978 } 979 virtual void execute(DCmdSource source, TRAPS); 980 }; 981 982 class CompilationMemoryStatisticDCmd: public DCmdWithParser { 983 protected: 984 DCmdArgument<bool> _human_readable; 985 DCmdArgument<MemorySizeArgument> _minsize; 986 public: 987 static int num_arguments() { return 2; } 988 CompilationMemoryStatisticDCmd(outputStream* output, bool heap); 989 static const char* name() { 990 return "Compiler.memory"; 991 } 992 static const char* description() { 993 return "Print compilation footprint"; 994 } 995 static const char* impact() { 996 return "Medium: Pause time depends on number of compiled methods"; 997 } 998 static const JavaPermission permission() { 999 JavaPermission p = {"java.lang.management.ManagementPermission", 1000 "monitor", nullptr}; 1001 return p; 1002 } 1003 virtual void execute(DCmdSource source, TRAPS); 1004 }; 1005 1006 #ifdef LINUX 1007 1008 class SystemMapDCmd : public DCmdWithParser { 1009 DCmdArgument<bool> _human_readable; 1010 public: 1011 static int num_arguments() { return 1; } 1012 SystemMapDCmd(outputStream* output, bool heap); 1013 static const char* name() { return "System.map"; } 1014 static const char* description() { 1015 return "Prints an annotated process memory map of the VM process (linux only)."; 1016 } 1017 static const char* impact() { return "Low"; } 1018 static const JavaPermission permission() { 1019 JavaPermission p = {"java.lang.management.ManagementPermission", 1020 "control", nullptr}; 1021 return p; 1022 } 1023 virtual void execute(DCmdSource source, TRAPS); 1024 }; 1025 1026 class SystemDumpMapDCmd : public DCmdWithParser { 1027 DCmdArgument<bool> _human_readable; 1028 DCmdArgument<char*> _filename; 1029 public: 1030 static int num_arguments() { return 2; } 1031 SystemDumpMapDCmd(outputStream* output, bool heap); 1032 static const char* name() { return "System.dump_map"; } 1033 static const char* description() { 1034 return "Dumps an annotated process memory map to an output file (linux only)."; 1035 } 1036 static const char* impact() { return "Low"; } 1037 static const JavaPermission permission() { 1038 JavaPermission p = {"java.lang.management.ManagementPermission", 1039 "control", nullptr}; 1040 return p; 1041 } 1042 virtual void execute(DCmdSource source, TRAPS); 1043 }; 1044 1045 #endif // LINUX 1046 1047 #endif // SHARE_SERVICES_DIAGNOSTICCOMMAND_HPP