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