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