Path: blob/master/test/hotspot/jtreg/vmTestbase/nsk/share/jdi/ArgumentHandler.java
41161 views
/*1* Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223package nsk.share.jdi;2425import nsk.share.*;26import nsk.share.jpda.*;2728import com.sun.jdi.VirtualMachine;2930/**31* Parser for JDI test's specific command-line arguments.32* <p>33* <code>ArgumentHandler</code> handles JDI test's specific34* arguments related to launching debugee VM using JDI features35* in addition to general arguments recognized by36* <code>DebugeeArgumentHandler</code> and <code>ArgumentParser</code>.37* <p>38* Following is the list of specific options recognized by39* <code>AgrumentHandler</code>:40* <ul>41* <li> <code>-connector=[launching|attaching|listening|default]</code> -42* JDI connector type43* <li> <code>-transport=[socket|shmem|default]</code> -44* JDWP transport kind45* <li> <code>-jdi.trace=[none|all|events|sends|receives|reftypes|objrefs]</code> -46* JDI trace mode for debugee VM47* </ul>48* <p>49* See also list of arguments recognized by the base <code>DebugeeArgumentHandler</code>50* and <code>ArgumentParser</code> classes.51* <p>52* See also description of <code>ArgumentParser</code> how to work with53* command line arguments and options.54*55* @see ArgumentParser56* @see DebugeeArgumentHandler57*/58public class ArgumentHandler extends DebugeeArgumentHandler {5960static private String JDI_CONNECTOR_NAME_PREFIX = "com.sun.jdi.";6162/**63* Keep a copy of raw command-line arguments and parse them;64* but throw an exception on parsing error.65*66* @param args Array of the raw command-line arguments.67*68* @throws NullPointerException If <code>args==null</code>.69* @throws IllegalArgumentException If Binder or Log options70* are set incorrectly.71*72* @see #setRawArguments(String[])73*/74public ArgumentHandler(String args[]) {75super(args);76// parseArguments();77}7879/**80* Overriden method returns transport type for JDWP connection, specified by81* <code>-transport</code> command line option, or <i>"default"</i> value82* by default.83*84* @see #getTransportName()85* @see #isSocketTransport()86* @see #isShmemTransport()87* @see #isDefaultTransport()88* @see #setRawArguments(String[])89*/90public String getTransportType() {91return options.getProperty("transport", "default");92}9394/**95* Overriden method returns <i>true</i> if <code>socket</code> transport96* is used either as specified or as a platform default transport.97*98* @see #getTransportType()99*/100public boolean isSocketTransport() {101String transport = getTransportType();102if (transport.equals("socket"))103return true;104if (transport.equals("shmem"))105return false;106if (transport.equals("default")) {107String arch = getArch();108if (arch == null)109if (System.getProperty("os.arch").equals("windows-i586"))110return false;111else112return true;113else if (arch.equals("windows-i586"))114return false;115else116return true;117}118throw new TestBug("Bad value of argument transport: " + transport);119}120121/**122* Overriden method returns <i>true</i> if <code>shmem</code> transport is used123* either as specified or as a platform default transport.124*125* @see #getTransportType()126*/127public boolean isShmemTransport() {128return ! isSocketTransport();129}130131/**132* Overriden method returns <i>true</i> if transport type is <code>default</code>.133*134* @see #getTransportType()135*/136public boolean isDefaultTransport() {137String transport = getTransportType();138return transport.equals("default");139}140141/**142* Overriden methos returns JDI connector type, specified by143* <code>-connector</code>. or <i>"default"</i> value by default.144*145* @see #getConnectorName()146* @see #isLaunchingConnector()147* @see #isAttachingConnector()148* @see #isListeningConnector()149* @see #isDefaultConnector()150* @see #setRawArguments(String[])151*/152public String getConnectorType() {153return options.getProperty("connector", "default");154}155156/**157* Overriden method returns full connector name corresponding to158* the used connector and transport types.159*160* @see #getConnectorType()161* @see #getTransportType()162*/163public String getConnectorName() {164if (isLaunchingConnector()) {165if (isRawLaunchingConnector())166return JDI_CONNECTOR_NAME_PREFIX + "RawCommandLineLaunch";167return JDI_CONNECTOR_NAME_PREFIX + "CommandLineLaunch";168}169if (isAttachingConnector()) {170if (isSocketTransport())171return JDI_CONNECTOR_NAME_PREFIX + "SocketAttach";172if (isShmemTransport())173return JDI_CONNECTOR_NAME_PREFIX + "SharedMemoryAttach";174return JDI_CONNECTOR_NAME_PREFIX + "SocketAttach";175}176if (isListeningConnector()) {177if (isSocketTransport())178return JDI_CONNECTOR_NAME_PREFIX + "SocketListen";179if (isShmemTransport())180return JDI_CONNECTOR_NAME_PREFIX + "SharedMemoryListen";181return JDI_CONNECTOR_NAME_PREFIX + "SocketListen";182}183throw new Failure("Unable to find full name of connector \"" + getConnectorType()184+ "\" for transport \"" + getTransportType() + "\"");185}186187/**188* Overriden method returns <i>true</i> if connector type is <code>default</code>.189*190* @see #getConnectorType()191*/192public boolean isDefaultConnector() {193return getConnectorType().equals("default");194}195196/**197* Return <i>true</i> if connector type is <code>launching</code>198* <code>rawlaunching<code> or <code>default</code>.199*200* @see #getConnectorType()201*/202public boolean isLaunchingConnector() {203return getConnectorType().equals("launching")204|| getConnectorType().equals("rawlaunching")205|| getConnectorType().equals("default");206}207208/**209* Return <i>true</i> if connector type is <code>rawlaunching</code>.210*211* @see #getConnectorType()212*/213public boolean isRawLaunchingConnector() {214return getConnectorType().equals("rawlaunching");215}216217/**218* Return string representation of debug trace mode, specified by219* <code>-jdi.trace</code> command line option, or <i>"none"</i>220* value by default.221* <p>222* Possible values for this option are the same as symbolic constants names223* in <code>com.sun.jdi.VirtualMachine</code> interface:224* <br> <code>"all"</code>, or225* <br> <code>"events"</code>, or226* <br> <code>"none"</code>, or227* <br> <code>"objrefs"</code>, or228* <br> <code>"receives"</code>, or229* <br> <code>"reftypes"</code>, or230* <br> <code>"sends"</code>.231*232* @see #getTraceMode()233* @see #setRawArguments(String[])234*/235public String getTraceModeString() {236return options.getProperty("jdi.trace", "none");237}238239/**240* Return integer code corresponding to debug trace mode, specified by241* <code>-jdi.trace</code> command line option, or <i>VirtualMachine.TRACE_NONE</i>242* value by default.243* <p>244* Possible values are the same as symbolic constant values245* in <code>com.sun.jdi.VirtualMachine</code> interface:246* <ul>247* <li><code>VirtualMachine.TRACE_ALL</code>248* <li><code>VirtualMachine.TRACE_EVENTS</code>249* <li><code>VirtualMachine.TRACE_NONE</code>250* <li><code>VirtualMachine.TRACE_OBJREFS</code>251* <li><code>VirtualMachine.TRACE_RECEIVES</code>252* <li><code>VirtualMachine.TRACE_REFTYPES</code>253* <li><code>VirtualMachine.TRACE_SENDS</code>254* </ul>255*256* @see #getTraceModeString()257* @see #setRawArguments(String[])258*/259public int getTraceMode() {260String val = getTraceModeString();261if (val == null)262return VirtualMachine.TRACE_NONE;263if (val.equals("none"))264return VirtualMachine.TRACE_NONE;265if (val.equals("all"))266return VirtualMachine.TRACE_ALL;267if (val.equals("events"))268return VirtualMachine.TRACE_EVENTS;269if (val.equals("objrefs"))270return VirtualMachine.TRACE_OBJREFS;271if (val.equals("receives"))272return VirtualMachine.TRACE_RECEIVES;273if (val.equals("reftypes"))274return VirtualMachine.TRACE_REFTYPES;275if (val.equals("sends"))276return VirtualMachine.TRACE_SENDS;277throw new TestBug("Unknown JDI trace mode string: " + val);278}279280// delay between connection attempts, used in connectors tests281public int getConnectionDelay() {282String value = options.getProperty("connectionDelay", "4000");283try {284return Integer.parseInt(value);285} catch (NumberFormatException e) {286throw new TestBug("Not integer value of \"connectionDelay\" argument: " + value);287}288}289290291/**292* Return <i>true</i> if the test should pass in any case i.e.293* an entity specified by the arguments <code>entry[]</code> is294* not implemented on the tested platform. Name of the tested295* platform is resolved from the "<code>-arch</code>" option.296*297* @param entry Array with the arguments which are specifing298* the entity.299*300* @throws Oddity If test parameter<code>-arch</code>301* has not been set.302*303* @see #setRawArguments(String[])304*/305public boolean shouldPass(String entry[]) {306String arch;307boolean found = false;308309if ((arch=getArch()) == null)310throw new Oddity("Test parameter -arch should be set");311312for (int i=0; i < CheckedFeatures.notImplemented.length; i++) {313if (CheckedFeatures.notImplemented[i][0].equals(arch) &&314CheckedFeatures.notImplemented[i].length == (entry.length+1)) {315for (int j=1; j < (entry.length+1); j++) {316if (CheckedFeatures.notImplemented[i][j].equals(entry[j-1]))317found = true;318else {319found = false;320break;321}322}323if (found) return true; // the entry[] is not implemented324}325}326327return false; // the entry[] is implemented328}329330/**331* Return <i>true</i> if the test should pass in any case i.e.332* an entity specified by the argument <code>entry</code> is333* not implemented on the tested platform. Name of the tested334* platform is resolved from the "<code>-arch</code>" option.335*336* @param entry String with the argument which is specifing337* the entity.338*339* @throws Oddity If test parameter<code>-arch</code>340* has not been set.341*342* @see #setRawArguments(String[])343*/344public boolean shouldPass(String entry) {345return (shouldPass(new String[] {entry}));346}347348/**349* Return <i>true</i> if the test should pass in any case i.e.350* an entity specified by the arguments <code>entry1</code> and351* <code>entry2</code> is not implemented on the tested platform.352* The entry is considered to be not implemented if exact entry353* "entry1, entry2" or its main entry "entry1" is not implemented.354*355* Name of the tested platform is resolved from the "<code>-arch</code>"356* option.357*358* @param entry1 String with the argument 1 which is specifing359* the entity.360*361* @param entry2 String with the argument 2 which is specifing362* the entity.363*364* @throws Oddity If test parameter<code>-arch</code>365* has not been set.366*367* @see #setRawArguments(String[])368*/369public boolean shouldPass(String entry1, String entry2) {370return ( shouldPass(new String[] {entry1, entry2}) ||371shouldPass(new String[] {entry1}) );372}373374/**375* Check if an option is admissible and has proper value.376* This method is invoked by <code>parseArguments()</code>377*378* @param option option name379* @param value string representation of value (could be an empty string)380* null if this option has no value381* @return <i>true</i> if option is admissible and has proper value382* <i>false</i> if otion is not admissible383*384* @throws <i>BadOption</i> if option has illegal value385*386* @see #parseArguments()387*/388protected boolean checkOption(String option, String value) {389390// check options with enumerated values391392if (option.equals("connectionDelay")) {393try {394int number = Integer.parseInt(value);395if (number <= 0) {396throw new BadOption(option + ": must be a positive integer");397}398} catch (NumberFormatException e) {399throw new BadOption(option + ": must be an integer");400}401402return true;403}404405if (option.equals("connector")) {406if ((!value.equals("launching"))407&& (!value.equals("rawlaunching"))408&& (!value.equals("attaching"))409&& (!value.equals("listening"))410&& (!value.equals("default"))) {411throw new BadOption(option + ": value must be one of: "412+ "launching, attaching, listening, default");413}414return true;415}416417if (option.equals("transport")) {418if ((!value.equals("socket"))419&& (!value.equals("shmem"))420&& (!value.equals("default"))) {421throw new BadOption(option + ": must be one of: "422+ "socket, shmem, default");423}424return true;425}426427if (option.equals("jdi.trace")) {428if ((!value.equals("all"))429&& (!value.equals("none"))430&& (!value.equals("events"))431&& (!value.equals("receives"))432&& (!value.equals("sends"))433&& (!value.equals("reftypes"))434&& (!value.equals("objrefs"))) {435throw new BadOption(option + ": value must be one of: "436+ "none, all, events, receives, sends, reftypes, objrefs");437}438return true;439}440441return super.checkOption(option, value);442}443444/**445* Check options against inconcistence.446* This method is invoked by <code>parseArguments()</code>447*448* @see #parseArguments()449*/450protected void checkOptions() {451/*452if (isTransportAddressDynamic() &&453(!isDefaultConnector() && isRawLaunchingConnector())) {454throw new BadOption("-transport.address=dynamic should NOT be used with"455+ " -connector=rawlaunching");456}457*/458459if (! isLaunchedLocally() && ! isDefaultDebugeeSuspendMode()) {460throw new BadOption("inconsistent options: "461+ "-debugee.launch=" + getLaunchMode()462+ " and -debugee.suspend=" + getDebugeeSuspendMode());463}464465if (! isLaunchedLocally() && isLaunchingConnector()) {466throw new BadOption("inconsistent options: "467+ "-debugee.launch=" + getLaunchMode()468+ " and -connector=" + getConnectorType());469}470471if (isLaunchingConnector() && ! isDefaultTransport()) {472throw new BadOption("inconsistent options: "473+ "-connector=" + getConnectorType()474+ " and -transport=" + getTransportType());475}476477if (! isLaunchingConnector() && isDefaultTransport()) {478throw new BadOption("inconsistent options: "479+ "-connector=" + getConnectorType()480+ " and -transport=" + getTransportType());481}482483if (! isDefaultJVMDIStrictMode()) {484throw new BadOption("unsupported options: "485+ "jvmdi.strict: non default JVMDI strict mode is not supported now" + getJVMDIStrictMode());486}487488/*489if (! isLaunchedLocally() && ! isDefaultJVMDIStrictMode()) {490throw new BadOption("inconsistent options: "491+ "-launch.mode=" + getLaunchMode()492+ " and -jvmdi.strict=" + getJVMDIStrictMode());493}494*/495496super.checkOptions();497}498}499500/**501* This is an auxiliary class intended for <code>ArgumentHandler</code>.502* The following information is used by the <code>ArgumentHandler</code>503* for resolving features (i.e., JDI connectors and transport names)504* which are not implemented on given platform (the first column).505* This list is actual for JDK 1.3.x, 1.4.x, 1.5.0, 1.6.0.506*507* @see ArgumentHandler508*/509class CheckedFeatures {510511static final String[][] notImplemented = {512513// attaching connectors514/*515* From docs/technotes/guides/jpda/conninv.html:516* "517* This connector can be used by a debugger application to attach to518* a currently running target VM through the shared memory transport. It is519* available only on the Microsoft Windows platform.520* "521*/522{"linux-i586", "com.sun.jdi.SharedMemoryAttach"},523{"linux-ia64", "com.sun.jdi.SharedMemoryAttach"},524{"linux-amd64", "com.sun.jdi.SharedMemoryAttach"},525{"linux-x64", "com.sun.jdi.SharedMemoryAttach"},526{"linux-aarch64", "com.sun.jdi.SharedMemoryAttach"},527{"linux-arm", "com.sun.jdi.SharedMemoryAttach"},528{"linux-ppc64", "com.sun.jdi.SharedMemoryAttach"},529{"linux-ppc64le", "com.sun.jdi.SharedMemoryAttach"},530{"linux-s390x", "com.sun.jdi.SharedMemoryAttach"},531{"macosx-amd64", "com.sun.jdi.SharedMemoryAttach"},532{"mac-x64", "com.sun.jdi.SharedMemoryAttach"},533{"macosx-aarch64", "com.sun.jdi.SharedMemoryAttach"},534{"mac-aarch64", "com.sun.jdi.SharedMemoryAttach"},535{"aix-ppc64", "com.sun.jdi.SharedMemoryAttach"},536537// listening connectors538/*539* From docs/technotes/guides/jpda/conninv.html:540* "541* This connector can be used by a debugger application to accept a542* connection from a separately invoked target VM through the shared memory543* transport.544* It is available only on the Microsoft Windows platform.545* "546*/547{"linux-i586", "com.sun.jdi.SharedMemoryListen"},548{"linux-ia64", "com.sun.jdi.SharedMemoryListen"},549{"linux-amd64", "com.sun.jdi.SharedMemoryListen"},550{"linux-x64", "com.sun.jdi.SharedMemoryListen"},551{"linux-aarch64", "com.sun.jdi.SharedMemoryListen"},552{"linux-arm", "com.sun.jdi.SharedMemoryListen"},553{"linux-ppc64", "com.sun.jdi.SharedMemoryListen"},554{"linux-ppc64le", "com.sun.jdi.SharedMemoryListen"},555{"linux-s390x", "com.sun.jdi.SharedMemoryListen"},556{"macosx-amd64", "com.sun.jdi.SharedMemoryListen"},557{"mac-x64", "com.sun.jdi.SharedMemoryListen"},558{"macosx-aarch64", "com.sun.jdi.SharedMemoryListen"},559{"mac-aarch64", "com.sun.jdi.SharedMemoryListen"},560{"aix-ppc64", "com.sun.jdi.SharedMemoryListen"},561562// launching connectors563/*564* From docs/technotes/guides/jpda/conninv.html:565* "566* Sun Command Line Launching Connector567* This connector can be used by a debugger application to launch a568* Sun VM or any other VM which supports the same invocation options with569* respect to debugging. The details of launching the VM and specifying the570* necessary debug options are handled by the connector. The underlying571* transport used by this connector depends on the platform. On Microsoft572* Windows, the shared memory transport is used. On Linux the socket transport is used.573* "574*/575{"linux-i586", "com.sun.jdi.CommandLineLaunch", "dt_shmem"},576{"linux-i586", "com.sun.jdi.RawCommandLineLaunch", "dt_shmem"},577578{"linux-ia64", "com.sun.jdi.CommandLineLaunch", "dt_shmem"},579{"linux-ia64", "com.sun.jdi.RawCommandLineLaunch", "dt_shmem"},580581{"linux-amd64", "com.sun.jdi.CommandLineLaunch", "dt_shmem"},582{"linux-amd64", "com.sun.jdi.RawCommandLineLaunch", "dt_shmem"},583584{"linux-x64", "com.sun.jdi.CommandLineLaunch", "dt_shmem"},585{"linux-x64", "com.sun.jdi.RawCommandLineLaunch", "dt_shmem"},586587{"linux-aarch64", "com.sun.jdi.CommandLineLaunch", "dt_shmem"},588{"linux-aarch64", "com.sun.jdi.RawCommandLineLaunch", "dt_shmem"},589590{"linux-arm", "com.sun.jdi.CommandLineLaunch", "dt_shmem"},591{"linux-arm", "com.sun.jdi.RawCommandLineLaunch", "dt_shmem"},592593{"linux-ppc64", "com.sun.jdi.CommandLineLaunch", "dt_shmem"},594{"linux-ppc64", "com.sun.jdi.RawCommandLineLaunch", "dt_shmem"},595596{"linux-ppc64le", "com.sun.jdi.CommandLineLaunch", "dt_shmem"},597{"linux-ppc64le", "com.sun.jdi.RawCommandLineLaunch", "dt_shmem"},598599{"linux-s390x", "com.sun.jdi.CommandLineLaunch", "dt_shmem"},600{"linux-s390x", "com.sun.jdi.RawCommandLineLaunch", "dt_shmem"},601602{"windows-i586", "com.sun.jdi.CommandLineLaunch", "dt_socket"},603{"windows-i586", "com.sun.jdi.RawCommandLineLaunch", "dt_socket"},604605{"windows-ia64", "com.sun.jdi.CommandLineLaunch", "dt_socket"},606{"windows-ia64", "com.sun.jdi.RawCommandLineLaunch", "dt_socket"},607608{"windows-amd64", "com.sun.jdi.CommandLineLaunch", "dt_socket"},609{"windows-amd64", "com.sun.jdi.RawCommandLineLaunch", "dt_socket"},610611{"windows-x64", "com.sun.jdi.CommandLineLaunch", "dt_socket"},612{"windows-x64", "com.sun.jdi.RawCommandLineLaunch", "dt_socket"},613614{"macosx-amd64", "com.sun.jdi.CommandLineLaunch", "dt_shmem"},615{"macosx-amd64", "com.sun.jdi.RawCommandLineLaunch", "dt_shmem"},616617{"mac-x64", "com.sun.jdi.CommandLineLaunch", "dt_shmem"},618{"mac-x64", "com.sun.jdi.RawCommandLineLaunch", "dt_shmem"},619620{"macosx-aarch64", "com.sun.jdi.CommandLineLaunch", "dt_shmem"},621{"macosx-aarch64", "com.sun.jdi.RawCommandLineLaunch", "dt_shmem"},622623{"mac-aarch64", "com.sun.jdi.CommandLineLaunch", "dt_shmem"},624{"mac-aarch64", "com.sun.jdi.RawCommandLineLaunch", "dt_shmem"},625626{"aix-ppc64", "com.sun.jdi.CommandLineLaunch", "dt_shmem"},627{"aix-ppc64", "com.sun.jdi.RawCommandLineLaunch", "dt_shmem"},628629// shared memory transport is implemented only on windows platform630{"linux-i586", "dt_shmem"},631{"linux-ia64", "dt_shmem"},632{"linux-amd64", "dt_shmem"},633{"linux-x64", "dt_shmem"},634{"linux-aarch64", "dt_shmem"},635{"linux-arm", "dt_shmem"},636{"linux-ppc64", "dt_shmem"},637{"linux-ppc64le", "dt_shmem"},638{"linux-s390x", "dt_shmem"},639{"macosx-amd64", "dt_shmem"},640{"mac-x64", "dt_shmem"},641{"macosx-aarch64", "dt_shmem"},642{"mac-aarch64", "dt_shmem"},643{"aix-ppc64", "dt_shmem"},644};645}646647648