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 39 class HelpDCmd : public DCmdWithParser { 40 protected: 41 DCmdArgument<bool> _all; 42 DCmdArgument<char*> _cmd; 43 public: 44 HelpDCmd(outputStream* output, bool heap); 45 static const char* name() { return "help"; } 46 static const char* description() { 47 return "For more information about a specific command use 'help <command>'. " 48 "With no argument this will show a list of available commands. " 49 "'help all' will show help for all commands."; 50 } 51 static const char* impact() { return "Low"; } 52 static int num_arguments(); 53 virtual void execute(DCmdSource source, TRAPS); 54 }; 55 56 class VersionDCmd : public DCmd { 57 public: 58 VersionDCmd(outputStream* output, bool heap) : DCmd(output,heap) { } 59 static const char* name() { return "VM.version"; } 60 static const char* description() { 61 return "Print JVM version information."; 62 } 63 static const char* impact() { return "Low"; } 64 static const JavaPermission permission() { 65 JavaPermission p = {"java.util.PropertyPermission", 66 "java.vm.version", "read"}; 67 return p; 68 } 69 static int num_arguments() { return 0; } 70 virtual void execute(DCmdSource source, TRAPS); 71 }; 72 73 class CommandLineDCmd : public DCmd { 74 public: 75 CommandLineDCmd(outputStream* output, bool heap) : DCmd(output, heap) { } 76 static const char* name() { return "VM.command_line"; } 77 static const char* description() { 78 return "Print the command line used to start this VM instance."; 79 } 80 static const char* impact() { return "Low"; } 81 static const JavaPermission permission() { 82 JavaPermission p = {"java.lang.management.ManagementPermission", 83 "monitor", NULL}; 84 return p; 85 } 86 static int num_arguments() { return 0; } 87 virtual void execute(DCmdSource source, TRAPS) { 88 Arguments::print_on(_output); 89 } 90 }; 91 92 // See also: get_system_properties in attachListener.cpp 93 class PrintSystemPropertiesDCmd : public DCmd { 94 public: 95 PrintSystemPropertiesDCmd(outputStream* output, bool heap) : DCmd(output, heap) { } 96 static const char* name() { return "VM.system_properties"; } 97 static const char* description() { 98 return "Print system properties."; 99 } 100 static const char* impact() { 101 return "Low"; 102 } 103 static const JavaPermission permission() { 104 JavaPermission p = {"java.util.PropertyPermission", 105 "*", "read"}; 106 return p; 107 } 108 static int num_arguments() { return 0; } 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 PrintVMFlagsDCmd(outputStream* output, bool heap); 118 static const char* name() { return "VM.flags"; } 119 static const char* description() { 120 return "Print VM flag options and their current values."; 121 } 122 static const char* impact() { 123 return "Low"; 124 } 125 static const JavaPermission permission() { 126 JavaPermission p = {"java.lang.management.ManagementPermission", 127 "monitor", NULL}; 128 return p; 129 } 130 static int num_arguments(); 131 virtual void execute(DCmdSource source, TRAPS); 132 }; 133 134 class VMDynamicLibrariesDCmd : public DCmd { 135 public: 136 VMDynamicLibrariesDCmd(outputStream* output, bool heap); 137 static const char* name() { 138 return "VM.dynlibs"; 139 } 140 static const char* description() { 141 return "Print loaded dynamic libraries."; 142 } 143 static const char* impact() { 144 return "Low"; 145 } 146 static const JavaPermission permission() { 147 JavaPermission p = {"java.lang.management.ManagementPermission", 148 "monitor", NULL}; 149 return p; 150 } 151 static int num_arguments() { 152 return 0; 153 }; 154 virtual void execute(DCmdSource source, TRAPS); 155 }; 156 157 class VMUptimeDCmd : public DCmdWithParser { 158 protected: 159 DCmdArgument<bool> _date; 160 public: 161 VMUptimeDCmd(outputStream* output, bool heap); 162 static const char* name() { return "VM.uptime"; } 163 static const char* description() { 164 return "Print VM uptime."; 165 } 166 static const char* impact() { 167 return "Low"; 168 } 169 static int num_arguments(); 170 virtual void execute(DCmdSource source, TRAPS); 171 }; 172 173 class SystemGCDCmd : public DCmd { 174 public: 175 SystemGCDCmd(outputStream* output, bool heap) : DCmd(output, heap) { } 176 static const char* name() { return "GC.run"; } 177 static const char* description() { 178 return "Call java.lang.System.gc()."; 179 } 180 static const char* impact() { 181 return "Medium: Depends on Java heap size and content."; 182 } 183 static int num_arguments() { return 0; } 184 virtual void execute(DCmdSource source, TRAPS); 185 }; 186 187 class RunFinalizationDCmd : public DCmd { 188 public: 189 RunFinalizationDCmd(outputStream* output, bool heap) : DCmd(output, heap) { } 190 static const char* name() { return "GC.run_finalization"; } 191 static const char* description() { 192 return "Call java.lang.System.runFinalization()."; 193 } 194 static const char* impact() { 195 return "Medium: Depends on Java content."; 196 } 197 static int num_arguments() { return 0; } 198 virtual void execute(DCmdSource source, TRAPS); 199 }; 200 201 #if INCLUDE_SERVICES // Heap dumping supported 202 // See also: dump_heap in attachListener.cpp 203 class HeapDumpDCmd : public DCmdWithParser { 204 protected: 205 DCmdArgument<char*> _filename; 206 DCmdArgument<bool> _all; 207 public: 208 HeapDumpDCmd(outputStream* output, bool heap); 209 static const char* name() { 210 return "GC.heap_dump"; 211 } 212 static const char* description() { 213 return "Generate a HPROF format dump of the Java heap."; 214 } 215 static const char* impact() { 216 return "High: Depends on Java heap size and content. " 217 "Request a full GC unless the '-all' option is specified."; 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 virtual void execute(DCmdSource source, TRAPS); 226 }; 227 #endif // INCLUDE_SERVICES 228 229 // See also: inspectheap in attachListener.cpp 230 class ClassHistogramDCmd : public DCmdWithParser { 231 protected: 232 DCmdArgument<bool> _all; 233 public: 234 ClassHistogramDCmd(outputStream* output, bool heap); 235 static const char* name() { 236 return "GC.class_histogram"; 237 } 238 static const char* description() { 239 return "Provide statistics about the Java heap usage."; 240 } 241 static const char* impact() { 242 return "High: Depends on Java heap size and content."; 243 } 244 static const JavaPermission permission() { 245 JavaPermission p = {"java.lang.management.ManagementPermission", 246 "monitor", NULL}; 247 return p; 248 } 249 static int num_arguments(); 250 virtual void execute(DCmdSource source, TRAPS); 251 }; 252 253 class ClassStatsDCmd : public DCmdWithParser { 254 protected: 255 DCmdArgument<bool> _all; 256 DCmdArgument<bool> _csv; 257 DCmdArgument<bool> _help; 258 DCmdArgument<char*> _columns; 259 public: 260 ClassStatsDCmd(outputStream* output, bool heap); 261 static const char* name() { 262 return "GC.class_stats"; 263 } 264 static const char* description() { 265 return "Provide statistics about Java class meta data. Requires -XX:+UnlockDiagnosticVMOptions."; 266 } 267 static const char* impact() { 268 return "High: Depends on Java heap size and content."; 269 } 270 static int num_arguments(); 271 virtual void execute(DCmdSource source, TRAPS); 272 }; 273 274 275 class ClassHierarchyDCmd : public DCmdWithParser { 276 protected: 277 DCmdArgument<bool> _print_interfaces; // true if inherited interfaces should be printed. 278 DCmdArgument<bool> _print_subclasses; // true if subclasses of the specified classname should be printed. 279 DCmdArgument<char*> _classname; // Optional single class name whose hierarchy should be printed. 280 public: 281 ClassHierarchyDCmd(outputStream* output, bool heap); 282 static const char* name() { 283 return "VM.class_hierarchy"; 284 } 285 static const char* description() { 286 return "Print a list of all loaded classes, indented to show the class hiearchy. " 287 "The name of each class is followed by the ClassLoaderData* of its ClassLoader, " 288 "or \"null\" if loaded by the bootstrap class loader."; 289 } 290 static const char* impact() { 291 return "Medium: Depends on number of loaded classes."; 292 } 293 static const JavaPermission permission() { 294 JavaPermission p = {"java.lang.management.ManagementPermission", 295 "monitor", NULL}; 296 return p; 297 } 298 static int num_arguments(); 299 virtual void execute(DCmdSource source, TRAPS); 300 }; 301 302 // See also: thread_dump in attachListener.cpp 303 class ThreadDumpDCmd : public DCmdWithParser { 304 protected: 305 DCmdArgument<bool> _locks; 306 public: 307 ThreadDumpDCmd(outputStream* output, bool heap); 308 static const char* name() { return "Thread.print"; } 309 static const char* description() { 310 return "Print all threads with stacktraces."; 311 } 312 static const char* impact() { 313 return "Medium: Depends on the number of threads."; 314 } 315 static const JavaPermission permission() { 316 JavaPermission p = {"java.lang.management.ManagementPermission", 317 "monitor", NULL}; 318 return p; 319 } 320 static int num_arguments(); 321 virtual void execute(DCmdSource source, TRAPS); 322 }; 323 324 // Enhanced JMX Agent support 325 326 class JMXStartRemoteDCmd : public DCmdWithParser { 327 328 // Explicitly list all properties that could be 329 // passed to Agent.startRemoteManagementAgent() 330 // com.sun.management is omitted 331 332 DCmdArgument<char *> _config_file; 333 DCmdArgument<char *> _jmxremote_port; 334 DCmdArgument<char *> _jmxremote_rmi_port; 335 DCmdArgument<char *> _jmxremote_ssl; 336 DCmdArgument<char *> _jmxremote_registry_ssl; 337 DCmdArgument<char *> _jmxremote_authenticate; 338 DCmdArgument<char *> _jmxremote_password_file; 339 DCmdArgument<char *> _jmxremote_access_file; 340 DCmdArgument<char *> _jmxremote_login_config; 341 DCmdArgument<char *> _jmxremote_ssl_enabled_cipher_suites; 342 DCmdArgument<char *> _jmxremote_ssl_enabled_protocols; 343 DCmdArgument<char *> _jmxremote_ssl_need_client_auth; 344 DCmdArgument<char *> _jmxremote_ssl_config_file; 345 346 // JDP support 347 // Keep autodiscovery char* not bool to pass true/false 348 // as property value to java level. 349 DCmdArgument<char *> _jmxremote_autodiscovery; 350 DCmdArgument<jlong> _jdp_port; 351 DCmdArgument<char *> _jdp_address; 352 DCmdArgument<char *> _jdp_source_addr; 353 DCmdArgument<jlong> _jdp_ttl; 354 DCmdArgument<jlong> _jdp_pause; 355 DCmdArgument<char *> _jdp_name; 356 357 public: 358 JMXStartRemoteDCmd(outputStream *output, bool heap_allocated); 359 360 static const char *name() { 361 return "ManagementAgent.start"; 362 } 363 364 static const char *description() { 365 return "Start remote management agent."; 366 } 367 368 static int num_arguments(); 369 370 virtual void execute(DCmdSource source, TRAPS); 371 372 }; 373 374 class JMXStartLocalDCmd : public DCmd { 375 376 // Explicitly request start of local agent, 377 // it will not be started by start dcmd 378 379 380 public: 381 JMXStartLocalDCmd(outputStream *output, bool heap_allocated); 382 383 static const char *name() { 384 return "ManagementAgent.start_local"; 385 } 386 387 static const char *description() { 388 return "Start local management agent."; 389 } 390 391 virtual void execute(DCmdSource source, TRAPS); 392 393 }; 394 395 class JMXStopRemoteDCmd : public DCmd { 396 public: 397 JMXStopRemoteDCmd(outputStream *output, bool heap_allocated) : 398 DCmd(output, heap_allocated) { 399 // Do Nothing 400 } 401 402 static const char *name() { 403 return "ManagementAgent.stop"; 404 } 405 406 static const char *description() { 407 return "Stop remote management agent."; 408 } 409 410 virtual void execute(DCmdSource source, TRAPS); 411 }; 412 413 class RotateGCLogDCmd : public DCmd { 414 public: 415 RotateGCLogDCmd(outputStream* output, bool heap) : DCmd(output, heap) {} 416 static const char* name() { return "GC.rotate_log"; } 417 static const char* description() { 418 return "Force the GC log file to be rotated."; 419 } 420 static const char* impact() { return "Low"; } 421 virtual void execute(DCmdSource source, TRAPS); 422 static int num_arguments() { return 0; } 423 static const JavaPermission permission() { 424 JavaPermission p = {"java.lang.management.ManagementPermission", 425 "control", NULL}; 426 return p; 427 } 428 }; 429 430 class CompileQueueDCmd : public DCmd { 431 public: 432 CompileQueueDCmd(outputStream* output, bool heap) : DCmd(output, heap) {} 433 static const char* name() { 434 return "Compiler.queue"; 435 } 436 static const char* description() { 437 return "Print methods queued for compilation."; 438 } 439 static const char* impact() { 440 return "Low"; 441 } 442 static const JavaPermission permission() { 443 JavaPermission p = {"java.lang.management.ManagementPermission", 444 "monitor", NULL}; 445 return p; 446 } 447 static int num_arguments() { return 0; } 448 virtual void execute(DCmdSource source, TRAPS); 449 }; 450 451 class CodeListDCmd : public DCmd { 452 public: 453 CodeListDCmd(outputStream* output, bool heap) : DCmd(output, heap) {} 454 static const char* name() { 455 return "Compiler.codelist"; 456 } 457 static const char* description() { 458 return "Print all compiled methods in code cache that are alive"; 459 } 460 static const char* impact() { 461 return "Medium"; 462 } 463 static const JavaPermission permission() { 464 JavaPermission p = {"java.lang.management.ManagementPermission", 465 "monitor", NULL}; 466 return p; 467 } 468 static int num_arguments() { return 0; } 469 virtual void execute(DCmdSource source, TRAPS); 470 }; 471 472 473 class CodeCacheDCmd : public DCmd { 474 public: 475 CodeCacheDCmd(outputStream* output, bool heap) : DCmd(output, heap) {} 476 static const char* name() { 477 return "Compiler.codecache"; 478 } 479 static const char* description() { 480 return "Print code cache layout and bounds."; 481 } 482 static const char* impact() { 483 return "Low"; 484 } 485 static const JavaPermission permission() { 486 JavaPermission p = {"java.lang.management.ManagementPermission", 487 "monitor", NULL}; 488 return p; 489 } 490 static int num_arguments() { return 0; } 491 virtual void execute(DCmdSource source, TRAPS); 492 }; 493 494 #endif // SHARE_VM_SERVICES_DIAGNOSTICCOMMAND_HPP