8039080: "jinfo server_id@host" fails with "Invalid process identifier"
Reviewed-by: sla, sjiang, dsamersoff
This commit is contained in:
parent
d3af21b931
commit
cb5eb6cd31
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2006, 2014, 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
|
||||
@ -39,42 +39,73 @@ import sun.tools.attach.HotSpotVirtualMachine;
|
||||
* and decides if the command should be satisfied using the VM attach mechanism
|
||||
* or an SA tool.
|
||||
*/
|
||||
public class JInfo {
|
||||
final public class JInfo {
|
||||
private boolean useSA = false;
|
||||
private String[] args = null;
|
||||
|
||||
@SuppressWarnings("fallthrough")
|
||||
public static void main(String[] args) throws Exception {
|
||||
private JInfo(String[] args) throws IllegalArgumentException {
|
||||
if (args.length == 0) {
|
||||
usage(1); // no arguments
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
int argCopyIndex = 0;
|
||||
// First determine if we should launch SA or not
|
||||
boolean useSA = false;
|
||||
if (args[0].equals("-F")) {
|
||||
// delete the -F
|
||||
args = Arrays.copyOfRange(args, 1, args.length);
|
||||
argCopyIndex = 1;
|
||||
useSA = true;
|
||||
} else if (args[0].equals("-flags")
|
||||
|| args[0].equals("-sysprops"))
|
||||
|| args[0].equals("-sysprops"))
|
||||
{
|
||||
if (args.length == 2) {
|
||||
if (!args[1].matches("[0-9]+")) {
|
||||
if (!isPid(args[1])) {
|
||||
// If args[1] doesn't parse to a number then
|
||||
// it must be the SA debug server
|
||||
// (otherwise it is the pid)
|
||||
useSA = true;
|
||||
}
|
||||
}
|
||||
if (args.length == 3) {
|
||||
} else if (args.length == 3) {
|
||||
// arguments include an executable and a core file
|
||||
useSA = true;
|
||||
} else {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
} else if (!args[0].startsWith("-")) {
|
||||
if (args.length == 2) {
|
||||
// the only arguments are an executable and a core file
|
||||
useSA = true;
|
||||
} else if (args.length == 1) {
|
||||
if (!isPid(args[0])) {
|
||||
// The only argument is not a PID; it must be SA debug
|
||||
// server
|
||||
useSA = true;
|
||||
}
|
||||
} else {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
} else if (args[0].equals("-h")
|
||||
|| args[0].equals("-help")) {
|
||||
} else if (args[0].equals("-h") || args[0].equals("-help")) {
|
||||
if (args.length > 1) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
} else if (args[0].equals("-flag")) {
|
||||
if (args.length == 3) {
|
||||
if (!isPid(args[2])) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
} else {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
} else {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
this.args = Arrays.copyOfRange(args, argCopyIndex, args.length);
|
||||
}
|
||||
|
||||
@SuppressWarnings("fallthrough")
|
||||
private void execute() throws Exception {
|
||||
if (args[0].equals("-h")
|
||||
|| args[0].equals("-help")) {
|
||||
usage(0);
|
||||
}
|
||||
|
||||
@ -87,55 +118,69 @@ public class JInfo {
|
||||
}
|
||||
|
||||
// invoke SA which does it's own argument parsing
|
||||
runTool(args);
|
||||
runTool();
|
||||
|
||||
} else {
|
||||
// Now we can parse arguments for the non-SA case
|
||||
String pid = null;
|
||||
|
||||
switch(args[0]) {
|
||||
case "-flag":
|
||||
if (args.length != 3) {
|
||||
usage(1);
|
||||
}
|
||||
String option = args[1];
|
||||
pid = args[2];
|
||||
flag(pid, option);
|
||||
break;
|
||||
case "-flags":
|
||||
if (args.length != 2) {
|
||||
usage(1);
|
||||
}
|
||||
pid = args[1];
|
||||
flags(pid);
|
||||
break;
|
||||
case "-sysprops":
|
||||
if (args.length != 2) {
|
||||
usage(1);
|
||||
}
|
||||
pid = args[1];
|
||||
sysprops(pid);
|
||||
break;
|
||||
case "-help":
|
||||
case "-h":
|
||||
usage(0);
|
||||
// Fall through
|
||||
default:
|
||||
if (args.length == 1) {
|
||||
// no flags specified, we do -sysprops and -flags
|
||||
pid = args[0];
|
||||
sysprops(pid);
|
||||
System.out.println();
|
||||
flags(pid);
|
||||
} else {
|
||||
usage(1);
|
||||
}
|
||||
case "-flag":
|
||||
if (args.length != 3) {
|
||||
usage(1);
|
||||
}
|
||||
String option = args[1];
|
||||
pid = args[2];
|
||||
flag(pid, option);
|
||||
break;
|
||||
case "-flags":
|
||||
if (args.length != 2) {
|
||||
usage(1);
|
||||
}
|
||||
pid = args[1];
|
||||
flags(pid);
|
||||
break;
|
||||
case "-sysprops":
|
||||
if (args.length != 2) {
|
||||
usage(1);
|
||||
}
|
||||
pid = args[1];
|
||||
sysprops(pid);
|
||||
break;
|
||||
case "-help":
|
||||
case "-h":
|
||||
usage(0);
|
||||
// Fall through
|
||||
default:
|
||||
if (args.length == 1) {
|
||||
// no flags specified, we do -sysprops and -flags
|
||||
pid = args[0];
|
||||
sysprops(pid);
|
||||
System.out.println();
|
||||
flags(pid);
|
||||
} else {
|
||||
usage(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
JInfo jinfo = null;
|
||||
try {
|
||||
jinfo = new JInfo(args);
|
||||
jinfo.execute();
|
||||
} catch (IllegalArgumentException e) {
|
||||
usage(1);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isPid(String arg) {
|
||||
return arg.matches("[0-9]+");
|
||||
}
|
||||
|
||||
// Invoke SA tool with the given arguments
|
||||
private static void runTool(String args[]) throws Exception {
|
||||
private void runTool() throws Exception {
|
||||
String tool = "sun.jvm.hotspot.tools.JInfo";
|
||||
// Tool not available on this platform.
|
||||
Class<?> c = loadClass(tool);
|
||||
|
342
jdk/test/sun/tools/jinfo/JInfoLauncherTest.java
Normal file
342
jdk/test/sun/tools/jinfo/JInfoLauncherTest.java
Normal file
@ -0,0 +1,342 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import org.testng.annotations.Test;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import sun.tools.jinfo.JInfo;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Arrays;
|
||||
|
||||
import static org.testng.Assert.*;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8039080
|
||||
* @run testng JInfoLauncherTest
|
||||
* @summary Test JInfo launcher argument parsing
|
||||
*/
|
||||
@Test
|
||||
public class JInfoLauncherTest {
|
||||
public static final String VALIDATION_EXCEPTION_CLSNAME =
|
||||
IllegalArgumentException.class.getName();
|
||||
|
||||
private Constructor<JInfo> jInfoConstructor;
|
||||
private Field fldUseSA;
|
||||
|
||||
@BeforeClass
|
||||
public void setup() throws Exception {
|
||||
jInfoConstructor = JInfo.class.getDeclaredConstructor(String[].class);
|
||||
jInfoConstructor.setAccessible(true);
|
||||
fldUseSA = JInfo.class.getDeclaredField("useSA");
|
||||
fldUseSA.setAccessible(true);
|
||||
}
|
||||
|
||||
private JInfo newJInfo(String[] args) throws Exception {
|
||||
try {
|
||||
return jInfoConstructor.newInstance((Object) args);
|
||||
} catch (Exception e) {
|
||||
if (isValidationException(e.getCause())) {
|
||||
throw (Exception)e.getCause();
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean getUseSA(JInfo jinfo) throws Exception {
|
||||
return fldUseSA.getBoolean(jinfo);
|
||||
}
|
||||
|
||||
private void cmdPID(String cmd, String ... params) throws Exception {
|
||||
int offset = (cmd != null ? 1 : 0);
|
||||
String[] args = new String[offset + params.length];
|
||||
args[0] = cmd;
|
||||
System.arraycopy(params, 0, args, offset, params.length);
|
||||
JInfo j = newJInfo(args);
|
||||
assertFalse(getUseSA(j), "Local jinfo must not forward to SA");
|
||||
}
|
||||
|
||||
private void cmdCore(String cmd, String ... params) throws Exception {
|
||||
int offset = (cmd != null ? 1 : 0);
|
||||
String[] args = new String[offset + params.length];
|
||||
args[0] = cmd;
|
||||
System.arraycopy(params, 0, args, offset, params.length);
|
||||
JInfo j = newJInfo(args);
|
||||
assertTrue(getUseSA(j), "Core jinfo must forward to SA");
|
||||
}
|
||||
|
||||
private void cmdRemote(String cmd, String ... params) throws Exception {
|
||||
int offset = (cmd != null ? 1 : 0);
|
||||
String[] args = new String[offset + params.length];
|
||||
args[0] = cmd;
|
||||
System.arraycopy(params, 0, args, offset, params.length);
|
||||
JInfo j = newJInfo(args);
|
||||
assertTrue(getUseSA(j), "Remote jinfo must forward to SA");
|
||||
}
|
||||
|
||||
private void cmdExtraArgs(String cmd, int argsLen) throws Exception {
|
||||
String[] args = new String[argsLen + 1 + (cmd != null ? 1 : 0)];
|
||||
Arrays.fill(args, "a");
|
||||
if (cmd != null) {
|
||||
args[0] = cmd;
|
||||
} else {
|
||||
cmd = "default";
|
||||
}
|
||||
try {
|
||||
JInfo j = newJInfo(args);
|
||||
fail("\"" + cmd + "\" does not support more than " + argsLen +
|
||||
" arguments");
|
||||
} catch (Exception e) {
|
||||
if (!isValidationException(e)) {
|
||||
throw e;
|
||||
}
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
private void cmdMissingArgs(String cmd, int reqArgs) throws Exception {
|
||||
String[] args = new String[reqArgs - 1 + (cmd != null ? 1 : 0)];
|
||||
Arrays.fill(args, "a");
|
||||
if (cmd != null) {
|
||||
args[0] = cmd;
|
||||
} else {
|
||||
cmd = "default";
|
||||
}
|
||||
try {
|
||||
JInfo j = newJInfo(args);
|
||||
fail("\"" + cmd + "\" requires at least " + reqArgs + " argument");
|
||||
} catch (Exception e) {
|
||||
if (!isValidationException(e)) {
|
||||
throw e;
|
||||
}
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
public void testDefaultPID() throws Exception {
|
||||
cmdPID(null, "1234");
|
||||
}
|
||||
|
||||
public void testFlagsPID() throws Exception {
|
||||
cmdPID("-flags", "1234");
|
||||
}
|
||||
|
||||
public void testSyspropsPID() throws Exception {
|
||||
cmdPID("-sysprops", "1234");
|
||||
}
|
||||
|
||||
public void testReadFlagPID() throws Exception {
|
||||
cmdPID("-flag", "SomeManagementFlag", "1234");
|
||||
}
|
||||
|
||||
public void testSetFlag1PID() throws Exception {
|
||||
cmdPID("-flag", "+SomeManagementFlag", "1234");
|
||||
}
|
||||
|
||||
public void testSetFlag2PID() throws Exception {
|
||||
cmdPID("-flag", "-SomeManagementFlag", "1234");
|
||||
}
|
||||
|
||||
public void testSetFlag3PID() throws Exception {
|
||||
cmdPID("-flag", "SomeManagementFlag=314", "1234");
|
||||
}
|
||||
|
||||
public void testDefaultCore() throws Exception {
|
||||
cmdCore(null, "myapp.exe", "my.core");
|
||||
}
|
||||
|
||||
public void testFlagsCore() throws Exception {
|
||||
cmdCore("-flags", "myapp.exe", "my.core");
|
||||
}
|
||||
|
||||
public void testSyspropsCore() throws Exception {
|
||||
cmdCore("-sysprops", "myapp.exe", "my.core");
|
||||
}
|
||||
|
||||
public void testReadFlagCore() throws Exception {
|
||||
try {
|
||||
cmdCore("-flag", "SomeManagementFlag", "myapp.exe", "my.core");
|
||||
fail("Flags can not be read from core files");
|
||||
} catch (Exception e) {
|
||||
if (!isValidationException(e)) {
|
||||
throw e;
|
||||
}
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
public void testSetFlag1Core() throws Exception {
|
||||
try {
|
||||
cmdCore("-flag", "+SomeManagementFlag", "myapp.exe", "my.core");
|
||||
fail("Flags can not be set in core files");
|
||||
} catch (Exception e) {
|
||||
if (!isValidationException(e)) {
|
||||
throw e;
|
||||
}
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
public void testSetFlag2Core() throws Exception {
|
||||
try {
|
||||
cmdCore("-flag", "-SomeManagementFlag", "myapp.exe", "my.core");
|
||||
fail("Flags can not be set in core files");
|
||||
} catch (Exception e) {
|
||||
if (!isValidationException(e)) {
|
||||
throw e;
|
||||
}
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
public void testSetFlag3Core() throws Exception {
|
||||
try {
|
||||
cmdCore("-flag", "SomeManagementFlag=314", "myapp.exe", "my.core");
|
||||
fail("Flags can not be set in core files");
|
||||
} catch (Exception e) {
|
||||
if (!isValidationException(e)) {
|
||||
throw e;
|
||||
}
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
public void testDefaultRemote() throws Exception {
|
||||
cmdRemote(null, "serverid@host");
|
||||
}
|
||||
|
||||
public void testFlagsRemote() throws Exception {
|
||||
cmdRemote("-flags", "serverid@host");
|
||||
}
|
||||
|
||||
public void testSyspropsRemote() throws Exception {
|
||||
cmdRemote("-sysprops", "serverid@host");
|
||||
}
|
||||
|
||||
public void testReadFlagRemote() throws Exception {
|
||||
try {
|
||||
cmdCore("-flag", "SomeManagementFlag", "serverid@host");
|
||||
fail("Flags can not be read from SA server");
|
||||
} catch (Exception e) {
|
||||
if (!isValidationException(e)) {
|
||||
throw e;
|
||||
}
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
public void testSetFlag1Remote() throws Exception {
|
||||
try {
|
||||
cmdCore("-flag", "+SomeManagementFlag","serverid@host");
|
||||
fail("Flags can not be set on SA server");
|
||||
} catch (Exception e) {
|
||||
if (!isValidationException(e)) {
|
||||
throw e;
|
||||
}
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
public void testSetFlag2Remote() throws Exception {
|
||||
try {
|
||||
cmdCore("-flag", "-SomeManagementFlag", "serverid@host");
|
||||
fail("Flags can not be read set on SA server");
|
||||
} catch (Exception e) {
|
||||
if (!isValidationException(e)) {
|
||||
throw e;
|
||||
}
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
public void testSetFlag3Remote() throws Exception {
|
||||
try {
|
||||
cmdCore("-flag", "SomeManagementFlag=314", "serverid@host");
|
||||
fail("Flags can not be read set on SA server");
|
||||
} catch (Exception e) {
|
||||
if (!isValidationException(e)) {
|
||||
throw e;
|
||||
}
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
public void testDefaultExtraArgs() throws Exception {
|
||||
cmdExtraArgs(null, 2);
|
||||
}
|
||||
|
||||
public void testFlagsExtraArgs() throws Exception {
|
||||
cmdExtraArgs("-flags", 2);
|
||||
}
|
||||
|
||||
public void testSyspropsExtraArgs() throws Exception {
|
||||
cmdExtraArgs("-sysprops", 2);
|
||||
}
|
||||
|
||||
public void testFlagExtraArgs() throws Exception {
|
||||
cmdExtraArgs("-flag", 2);
|
||||
}
|
||||
|
||||
public void testHelp1ExtraArgs() throws Exception {
|
||||
cmdExtraArgs("-h", 0);
|
||||
}
|
||||
|
||||
public void testHelp2ExtraArgs() throws Exception {
|
||||
cmdExtraArgs("-help", 0);
|
||||
}
|
||||
|
||||
public void testDefaultMissingArgs() throws Exception {
|
||||
cmdMissingArgs(null, 1);
|
||||
}
|
||||
|
||||
public void testFlagsMissingArgs() throws Exception {
|
||||
cmdMissingArgs("-flags", 1);
|
||||
}
|
||||
|
||||
public void testSyspropsMissingArgs() throws Exception {
|
||||
cmdMissingArgs("-sysprops", 1);
|
||||
}
|
||||
|
||||
public void testFlagMissingArgs() throws Exception {
|
||||
cmdMissingArgs("-flag", 2);
|
||||
}
|
||||
|
||||
public void testUnknownCommand() throws Exception {
|
||||
try {
|
||||
JInfo j = newJInfo(new String[]{"-unknown_command"});
|
||||
fail("JInfo accepts unknown commands");
|
||||
} catch (Exception e) {
|
||||
if (!isValidationException(e)) {
|
||||
throw e;
|
||||
}
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isValidationException(Throwable e) {
|
||||
return e.getClass().getName().equals(VALIDATION_EXCEPTION_CLSNAME);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user