--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/SAGetopt.java Thu Jul 23 16:36:36 2015 +0000
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package sun.jvm.hotspot;
+
+import java.util.Arrays;
+import java.util.List;
+
+public class SAGetopt {
+
+ private String[] _argv;
+
+ private int _optind; // index in arguments array
+ private int _optopt; // index within an argument
+ private String _optarg; // last option argument
+ private boolean _optreset; // special handling of first call
+
+ public SAGetopt(String[] args) {
+ _argv = args;
+ _optind = 0;
+ _optopt = 1;
+ _optarg = null;
+ _optreset = true;
+ }
+
+ public String getOptarg() {
+ return _optarg;
+ }
+
+ public int getOptind() {
+ return _optind;
+ }
+
+ private void extractOptarg(String opt) {
+ // Argument expected
+ if (_optind > _argv.length) {
+ throw new RuntimeException("Not enough arguments for '" + opt + "'");
+ }
+
+ if (! _argv[_optind].isEmpty() && _argv[_optind].charAt(0) == '-') {
+ throw new RuntimeException("Argument is expected for '" + opt + "'");
+ }
+
+ _optarg = _argv[_optind];
+ _optind += 1;
+ }
+
+ private String processLongOptions(String carg, String[] longOptStr) {
+ List<String> los = Arrays.asList(longOptStr);
+ String[] ca = carg.split("=", 2);
+
+ if (los.contains(ca[0])) {
+ if (ca.length > 1) {
+ throw new RuntimeException("Argument is not expected for '" + ca[0] + "'");
+ }
+ return carg;
+ }
+
+ if (los.contains(ca[0] + "=")) {
+ if (ca.length > 1) {
+ // GNU style options --file=name
+ _optarg = ca[1];
+ }
+ else {
+ // Mixed style options --file name
+ extractOptarg(ca[0]);
+ }
+
+ return ca[0];
+ }
+
+ throw new RuntimeException("Invalid option '" + ca[0] + "'");
+ }
+
+ public String next(String optStr, String[] longOptStr) {
+
+ if (_optind >= _argv.length || _argv[_optind] == null) {
+ // All arguments processed
+ return null;
+ }
+
+ String carg = _argv[_optind];
+ _optarg = null;
+
+ if (_optreset) {
+ // End of option batch like '-abc' reached, expect option to start from '-'
+
+ if (carg.isEmpty() || carg.charAt(0) != '-' || carg.equals("--")) {
+ // Stop processing on -- or first non-option argument;
+ return null;
+ }
+
+ if (carg.startsWith("--")) {
+ // Handle long options, it can't be combined so it's simple
+ if (longOptStr == null || longOptStr.length == 0) {
+ // No long options expected, stop options processing
+ return null;
+ }
+ ++ _optind;
+
+ // at this point carg contains at least one character besides --
+ carg = carg.substring(2);
+ return processLongOptions(carg, longOptStr);
+ }
+
+ if (optStr == null || optStr.length() == 0) {
+ // No short options
+ return null;
+ }
+
+ // At this point carg[0] contains '-'
+ _optreset = false;
+ _optopt = 1;
+ }
+
+ char ch = carg.charAt(_optopt);
+
+ // adjust pointer to next character
+ _optopt += 1;
+
+ // Okay, ready to process options like
+ // -abc -d bla -ef
+
+ int chIndex = optStr.indexOf(ch);
+ if (chIndex == -1) {
+ throw new RuntimeException("Invalid option '" + ch + "'");
+ }
+
+ if (_optopt >= carg.length()) {
+ _optind += 1;
+ _optreset = true;
+ }
+
+ if (chIndex < optStr.length()-1 && optStr.charAt(chIndex+1) == ':') {
+ // Argument expected
+ extractOptarg(String.valueOf(ch));
+ }
+
+ return String.valueOf(ch);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/SALauncher.java Thu Jul 23 16:36:36 2015 +0000
@@ -0,0 +1,359 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package sun.jvm.hotspot;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+
+import sun.jvm.hotspot.tools.JStack;
+import sun.jvm.hotspot.tools.JMap;
+import sun.jvm.hotspot.tools.JInfo;
+
+public class SALauncher {
+
+ private static boolean launcherHelp() {
+ System.out.println(" clhsdb \tcommand line debugger");
+ System.out.println(" hsdb \tui debugger");
+ System.out.println(" jstack --help\tto get more information");
+ System.out.println(" jmap --help\tto get more information");
+ System.out.println(" jinfo --help\tto get more information");
+ return false;
+ }
+
+ private static boolean commonHelp() {
+ // --pid <pid>
+ // --exe <exe>
+ // --core <core>
+ System.out.println(" --exe\texecutable image name");
+ System.out.println(" --core\tpath to coredump");
+ System.out.println(" --pid\tpid of process to attach");
+ return false;
+ }
+
+ private static boolean jinfoHelp() {
+ // --flags -> -flags
+ // --sysprops -> -sysprops
+ System.out.println(" --flags\tto print VM flags");
+ System.out.println(" --sysprops\tto print Java System properties");
+ System.out.println(" <no option>\tto print both of the above");
+ return commonHelp();
+ }
+
+ private static boolean jmapHelp() {
+ // --heap -> -heap
+ // --binaryheap -> -heap:format=b
+ // --histo -> -histo
+ // --clstats -> -clstats
+ // --finalizerinfo -> -finalizerinfo
+
+ System.out.println(" <no option>\tto print same info as Solaris pmap");
+ System.out.println(" --heap\tto print java heap summary");
+ System.out.println(" --binaryheap\tto dump java heap in hprof binary format");
+ System.out.println(" --histo\tto print histogram of java object heap");
+ System.out.println(" --clstats\tto print class loader statistics");
+ System.out.println(" --finalizerinfo\tto print information on objects awaiting finalization");
+ return commonHelp();
+ }
+
+ private static boolean jstackHelp() {
+ // --locks -> -l
+ // --mixed -> -m
+ System.out.println(" --locks\tto print java.util.concurrent locks");
+ System.out.println(" --mixed\tto print both java and native frames (mixed mode)");
+ return commonHelp();
+ }
+
+ private static boolean toolHelp(String toolName) {
+ if (toolName.equals("jstack")) {
+ return jstackHelp();
+ }
+ if (toolName.equals("jinfo")) {
+ return jinfoHelp();
+ }
+ if (toolName.equals("jmap")) {
+ return jmapHelp();
+ }
+ if (toolName.equals("hsdb") || toolName.equals("clhsdb")) {
+ return commonHelp();
+ }
+ return launcherHelp();
+ }
+
+ private static void runCLHSDB(String[] oldArgs) {
+ SAGetopt sg = new SAGetopt(oldArgs);
+ String[] longOpts = {"exe=", "core=", "pid="};
+
+ ArrayList<String> newArgs = new ArrayList();
+ String exeORpid = null;
+ String core = null;
+ String s = null;
+
+ while((s = sg.next(null, longOpts)) != null) {
+ if (s.equals("exe")) {
+ exeORpid = sg.getOptarg();
+ continue;
+ }
+ if (s.equals("core")) {
+ core = sg.getOptarg();
+ continue;
+ }
+ if (s.equals("pid")) {
+ exeORpid = sg.getOptarg();
+ continue;
+ }
+ }
+
+ if (exeORpid != null) {
+ newArgs.add(exeORpid);
+ if (core != null) {
+ newArgs.add(core);
+ }
+ }
+ CLHSDB.main(newArgs.toArray(new String[newArgs.size()]));
+ }
+
+ private static void runHSDB(String[] oldArgs) {
+ SAGetopt sg = new SAGetopt(oldArgs);
+ String[] longOpts = {"exe=", "core=", "pid="};
+
+ ArrayList<String> newArgs = new ArrayList();
+ String exeORpid = null;
+ String core = null;
+ String s = null;
+
+ while((s = sg.next(null, longOpts)) != null) {
+ if (s.equals("exe")) {
+ exeORpid = sg.getOptarg();
+ continue;
+ }
+ if (s.equals("core")) {
+ core = sg.getOptarg();
+ continue;
+ }
+ if (s.equals("pid")) {
+ exeORpid = sg.getOptarg();
+ continue;
+ }
+ }
+
+ if (exeORpid != null) {
+ newArgs.add(exeORpid);
+ if (core != null) {
+ newArgs.add(core);
+ }
+ }
+ HSDB.main(newArgs.toArray(new String[newArgs.size()]));
+ }
+
+ private static void runJSTACK(String[] oldArgs) {
+ SAGetopt sg = new SAGetopt(oldArgs);
+ String[] longOpts = {"exe=", "core=", "pid=",
+ "mixed", "locks"};
+
+ ArrayList<String> newArgs = new ArrayList();
+ String exeORpid = null;
+ String core = null;
+ String s = null;
+
+ while((s = sg.next(null, longOpts)) != null) {
+ if (s.equals("exe")) {
+ exeORpid = sg.getOptarg();
+ continue;
+ }
+ if (s.equals("core")) {
+ core = sg.getOptarg();
+ continue;
+ }
+ if (s.equals("pid")) {
+ exeORpid = sg.getOptarg();
+ continue;
+ }
+ if (s.equals("mixed")) {
+ newArgs.add("-m");
+ continue;
+ }
+ if (s.equals("locks")) {
+ newArgs.add("-l");
+ continue;
+ }
+ }
+
+ if (exeORpid != null) {
+ newArgs.add(exeORpid);
+ if (core != null) {
+ newArgs.add(core);
+ }
+ }
+
+ JStack.main(newArgs.toArray(new String[newArgs.size()]));
+ }
+
+ private static void runJMAP(String[] oldArgs) {
+ SAGetopt sg = new SAGetopt(oldArgs);
+ String[] longOpts = {"exe=", "core=", "pid=",
+ "heap", "binaryheap", "histo", "clstats", "finalizerinfo"};
+
+ ArrayList<String> newArgs = new ArrayList();
+ String exeORpid = null;
+ String core = null;
+ String s = null;
+
+ while((s = sg.next(null, longOpts)) != null) {
+ if (s.equals("exe")) {
+ exeORpid = sg.getOptarg();
+ continue;
+ }
+ if (s.equals("core")) {
+ core = sg.getOptarg();
+ continue;
+ }
+ if (s.equals("pid")) {
+ exeORpid = sg.getOptarg();
+ continue;
+ }
+ if (s.equals("heap")) {
+ newArgs.add("-heap");
+ continue;
+ }
+ if (s.equals("binaryheap")) {
+ newArgs.add("-heap:format=b");
+ continue;
+ }
+ if (s.equals("histo")) {
+ newArgs.add("-histo");
+ continue;
+ }
+ if (s.equals("clstats")) {
+ newArgs.add("-clstats");
+ continue;
+ }
+ if (s.equals("finalizerinfo")) {
+ newArgs.add("-finalizerinfo");
+ continue;
+ }
+ }
+
+ if (exeORpid != null) {
+ newArgs.add(exeORpid);
+ if (core != null) {
+ newArgs.add(core);
+ }
+ }
+
+ JMap.main(newArgs.toArray(new String[newArgs.size()]));
+ }
+
+ private static void runJINFO(String[] oldArgs) {
+ SAGetopt sg = new SAGetopt(oldArgs);
+ String[] longOpts = {"exe=", "core=", "pid=",
+ "flags", "sysprops"};
+
+ ArrayList<String> newArgs = new ArrayList();
+ String exeORpid = null;
+ String core = null;
+ String s = null;
+
+ while((s = sg.next(null, longOpts)) != null) {
+ if (s.equals("exe")) {
+ exeORpid = sg.getOptarg();
+ continue;
+ }
+ if (s.equals("core")) {
+ core = sg.getOptarg();
+ continue;
+ }
+ if (s.equals("pid")) {
+ exeORpid = sg.getOptarg();
+ continue;
+ }
+ if (s.equals("flags")) {
+ newArgs.add("-flags");
+ continue;
+ }
+ if (s.equals("sysprops")) {
+ newArgs.add("-sysprops");
+ continue;
+ }
+ }
+
+ if (exeORpid != null) {
+ newArgs.add(exeORpid);
+ if (core != null) {
+ newArgs.add(core);
+ }
+ }
+
+ JInfo.main(newArgs.toArray(new String[newArgs.size()]));
+ }
+
+ public static void main(String[] args) {
+ // Provide a help
+ if (args.length == 0) {
+ launcherHelp();
+ return;
+ }
+ // No arguments imply help for jstack, jmap, jinfo but launch clhsdb and hsdb
+ if (args.length == 1 && !args[0].equals("clhsdb") && !args[0].equals("hsdb")) {
+ toolHelp(args[0]);
+ return;
+ }
+
+ for (String arg : args) {
+ if (arg.equals("-h") || arg.equals("-help") || arg.equals("--help")) {
+ toolHelp(args[0]);
+ return;
+ }
+ }
+
+ String[] oldArgs = Arrays.copyOfRange(args, 1, args.length);
+
+ // Run SA interactive mode
+ if (args[0].equals("clhsdb")) {
+ runCLHSDB(oldArgs);
+ return;
+ }
+
+ if (args[0].equals("hsdb")) {
+ runHSDB(oldArgs);
+ return;
+ }
+
+ // Run SA tmtools mode
+ if (args[0].equals("jstack")) {
+ runJSTACK(oldArgs);
+ return;
+ }
+
+ if (args[0].equals("jmap")) {
+ runJMAP(oldArgs);
+ return;
+ }
+
+ if (args[0].equals("jinfo")) {
+ runJINFO(oldArgs);
+ return;
+ }
+ }
+}