mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-21 11:34:38 +02:00
8059038: Create new launcher for SA tools
Proivide jhsdb command to launch sa based tools Reviewed-by: sspitsyn, jbachorik
This commit is contained in:
parent
5f06b60fa1
commit
d83e080bf4
2 changed files with 521 additions and 0 deletions
162
hotspot/agent/src/share/classes/sun/jvm/hotspot/SAGetopt.java
Normal file
162
hotspot/agent/src/share/classes/sun/jvm/hotspot/SAGetopt.java
Normal file
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
359
hotspot/agent/src/share/classes/sun/jvm/hotspot/SALauncher.java
Normal file
359
hotspot/agent/src/share/classes/sun/jvm/hotspot/SALauncher.java
Normal file
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue