Path: blob/master/test/hotspot/jtreg/vmTestbase/nsk/share/jdwp/Debugee.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.jdwp;2425import nsk.share.*;26import nsk.share.jpda.*;2728import java.util.*;29import java.io.*;3031/**32* This class is used to interact with debugee VM using JDWP features.33* <p>34* This class is an mirror of debugee VM that is constructed by35* <code>Binder</code> and uses <code>Transport</code> object36* to interact with debugee VM.37* <p>38* In addition to the general abities to control of debugee VM process,39* provided by the base class <code>DebugeeProcess</code>, this class40* adds some service methods that uses JDWP protocol to simplify interaction41* with debugee VM (such as finding classes, setting breakpoints,42* handling events, and so on.).43*44* @see Binder45* @see Transport46* @see DebugeeProcess47*/48abstract public class Debugee extends DebugeeProcess {4950/** Binder that creates this debugee. */51protected Binder binder = null;5253protected LinkedList<EventPacket> eventQueue = new LinkedList<EventPacket>();5455protected Transport transport = null;5657/** Make new <code>Debugee</code> object for the given binder. */58protected Debugee (Binder binder) {59super(binder);60this.argumentHandler = binder.getArgumentHandler();61this.binder = binder;62prefix = "Debugee> ";63}6465/** Return <code>Binder</code> of the debugee object. */66public Binder getBinder() {67return binder;68}6970/** Return <code>Transport</code> of the debugee object. */71public Transport getTransport() {72return transport;73}7475/**76* Prepare transport object for establishing connection.77* This may change connection options in <code>argumentHandler</code>.78*79* @return specific address string if listening has started or null otherwise80*/81public String prepareTransport(ArgumentHandler argumentHandler) {82String address = null;83try {84if (argumentHandler.isSocketTransport()) {85SocketTransport socket_transport = new SocketTransport(log);86if (argumentHandler.isListeningConnector()) {87int port = 0;88if (argumentHandler.isTransportAddressDynamic()) {89port = socket_transport.bind(0);90// argumentHandler.setTransportPortNumber(port);91} else {92port = argumentHandler.getTransportPortNumber();93socket_transport.bind(port);94}95address = argumentHandler.getTestHost() + ":" + port;96}97transport = socket_transport;98/*99} else if (argumentHandler.isShmemTransport()) {100ShmemTransport shmem_transport = new ShmemTransport(log);101if (argumentHandler.isListeningConnector()) {102String sharedName = agrHandler.getTransportSharedName();103shmem_transport.bind(sharedName);104address = sharedName;105}106transport = shmem_transport;107*/108} else {109throw new TestBug("Unexpected transport type: "110+ argumentHandler.getTransportType());111}112113} catch (IOException e) {114e.printStackTrace(log.getOutStream());115throw new Failure("Caught IOException while preparing for JDWP transport connection:\n\t"116+ e);117}118119return address;120}121122/**123* Establish connection to debugee VM.124*/125public Transport connect() {126if (transport == null) {127throw new Failure("Attemt to establish JDWP connection for not prepared transport");128}129130try {131if (argumentHandler.isSocketTransport()) {132display("Establishing JDWP socket connection");133SocketTransport socket_transport = (SocketTransport)transport;134int transportPort = argumentHandler.getTransportPortNumber();135if (argumentHandler.isAttachingConnector()) {136String debugeeHost = argumentHandler.getDebugeeHost();137display("Attaching to debugee: " + debugeeHost + ":" + transportPort);138socket_transport.attach(debugeeHost, transportPort);139} else if (argumentHandler.isListeningConnector()) {140display("Listening from debugee");141socket_transport.accept();142} else {143throw new TestBug("Unexpected connector type: "144+ argumentHandler.getConnectorType());145}146/*147} else if (argumentHandler.isShmemTransport()) {148display("Establishing JDWP shared-memory connection");149ShmemTransport shmem_transport = (ShmemTransport)transport;150String sharedName = argumentHandler.getTransportSharedName();151if (argumentHandler.isAttachingConnector()) {152display("Attaching to debugee: " + sharedName);153shmem_transport.attach(sharedName);154} else if (argumentHandler.isListeningConnector()) {155display("Listening from debugee");156shmem_transport.accept();157} else {158throw new TestBug("Unexpected connector type: "159+ argumentHandler.getConnectorType());160}161*/162} else {163throw new TestBug("Unexpected transport type: "164+ argumentHandler.getTransportType());165}166167transport.handshake();168169} catch (IOException e) {170e.printStackTrace(log.getOutStream());171throw new Failure("Caught IOException while establishing JDWP transport connection:\n\t"172+ e);173}174return transport;175}176177// --------------------------------------------------- //178179/**180* Waits for VM_INIT event from debugee VM.181*/182public void waitForVMInit() {183String eventName = "VirtualMachine.VM_START";184EventPacket packet = receiveEventFor(JDWP.EventKind.VM_START, eventName);185// String versionInfo = getVersionInfo();186// display("Target VM started:\n" + versionInfo);187}188189/**190* Waits for VM_DEATH event from debugee VM.191*/192public void waitForVMDeath() {193String eventName = "VirtualMachine.VM_DEATH";194EventPacket packet = receiveEventFor(JDWP.EventKind.VM_DEATH, eventName);195}196197/**198* Wait for class loaded on debugee start up and return its classID.199* Debuggee should be initially suspended and it will also left suspended200* by the CLASS_PREPARE event request.201*/202public long waitForClassLoaded(String className, byte suspendPolicy) {203// make request for CLASS_PREPARE_EVENT for this class name204int requestID = requestClassPrepareEvent(className, suspendPolicy);205// resume initially suspended debugee206resume();207// wait for CLASS_PREPARE_EVENT208return waitForClassPrepareEvent(requestID, className);209}210211/**212* Wait for classes loaded on debugee start up and return their classIDs.213* Debuggee should be initially suspended and it will also left suspended214* by the CLASS_PREPARE event request.215*/216public long[] waitForClassesLoaded(String classNames[], byte suspendPolicy) {217int count = classNames.length;218219// make requests for CLASS_PREPARE_EVENT for these class names220int[] requestIDs = new int[count];221for (int i = 0; i < count; i++) {222requestIDs[i] = requestClassPrepareEvent(classNames[i], suspendPolicy);223}224225// resume initially suspended debugee226resume();227228return waitForClassPrepareEvents(requestIDs, classNames);229}230231/**232* Wait for breakpoint reached and return threadIDs.233* Debuggee should be initially suspended and it will also left suspended234* by the BREAKPOINT event request.235*/236public long waitForBreakpointReached(long classID, String methodName,237int line, byte suspendPolicy) {238// query debuggee for methodID239long methodID = getMethodID(classID, methodName, true);240// create BREAKPOINT event request241int requestID = requestBreakpointEvent(JDWP.TypeTag.CLASS, classID, methodID,242line, suspendPolicy);243// resume initially suspended debugee244resume();245// wait for BREAKPOINT event246return waitForBreakpointEvent(requestID);247}248249// --------------------------------------------------- //250251/**252* Wait for CLASS_PREPARE event made by given request received253* and return classID.254* Debuggee will be left suspended by the CLASS_PREPARE event.255*/256public long waitForClassPrepareEvent(int requestID, String className) {257String error = "Error occured while waiting for CLASS_PREPARE event for class:\n\t"258+ className;259260String signature = "L" + className.replace('.', '/') + ";";261long classID = 0;262263// wait for CLASS_PREPARE event264for(;;) {265EventPacket event = receiveEvent();266byte eventSuspendPolicy = 0;267long eventThreadID = 0;268try {269eventSuspendPolicy = event.getByte();270int events = event.getInt();271for (int i = 0; i < events; i++) {272// check event kind273byte eventKind = event.getByte();274if (eventKind == JDWP.EventKind.VM_DEATH) {275complain("Unexpected VM_DEATH event received: " + eventKind276+ " (expected: " + JDWP.EventKind.CLASS_PREPARE +")");277throw new Failure(error);278} else if (eventKind != JDWP.EventKind.CLASS_PREPARE) {279complain("Unexpected event kind received: " + eventKind280+ " (expected: " + JDWP.EventKind.CLASS_PREPARE +")");281throw new Failure(error);282}283284// extract CLASS_PREPARE event specific data285int eventRequestID = event.getInt();286eventThreadID = event.getObjectID();287byte eventRefTypeTag = event.getByte();288long eventClassID = event.getReferenceTypeID();289String eventClassSignature = event.getString();290int eventClassStatus = event.getInt();291292// check if event was single293if (events > 1) {294complain("Not single CLASS_PREPARE event received for class:\n\t"295+ eventClassSignature);296throw new Failure(error);297}298299// check if event is for expected class300if (eventClassSignature.equals(signature)) {301302// check if event is because of expected request303if (eventRequestID != requestID) {304complain("CLASS_PREPARE event with unexpected requestID ("305+ eventRequestID + ") received for class:\n\t"306+ eventClassSignature);307throw new Failure(error);308}309310// remove event request311clearEventRequest(JDWP.EventKind.CLASS_PREPARE, requestID);312313return eventClassID;314} else {315complain("Unexpected CLASS_PREPARE event received with class signature:\n"316+ " " + eventClassSignature);317}318319}320321} catch (BoundException e) {322complain("Unable to extract data from event packet while waiting for CLASS_PREPARE event:\n\t"323+ e.getMessage() + "\n" + event);324throw new Failure(error);325}326327// resume debuggee according to event suspend policy328resumeEvent(eventSuspendPolicy, eventThreadID);329}330}331332/**333* Wait for CLASS_PREPARE events made by given requests received334* and return classIDs.335* Debuggee will be left suspended by the CLASS_PREPARE event.336*/337public long[] waitForClassPrepareEvents(int requestIDs[], String classNames[]) {338int count = classNames.length;339String error = "Error occured while waiting for " + count + " CLASS_PREPARE events";340341// prepare expected class signatures342String[] signatures = new String[count];343for (int i = 0; i < count; i++) {344signatures[i] = "L" + classNames[i].replace('.', '/') + ";";345}346347// clear list of classIDs348long[] classIDs = new long[count];349for (int i = 0; i < count; i++) {350classIDs[i] = 0;351}352353// wait for all expected CLASS_PREPARE events354int received = 0;355for(;;) {356EventPacket event = receiveEvent();357byte eventSuspendPolicy = 0;358long eventThreadID = 0;359try {360eventSuspendPolicy = event.getByte();361int events = event.getInt();362for (int i = 0; i < events; i++) {363// check event kind364byte eventKind = event.getByte();365if (eventKind == JDWP.EventKind.VM_DEATH) {366complain("Unexpected VM_DEATH event received: " + eventKind367+ " (expected: " + JDWP.EventKind.CLASS_PREPARE +")");368throw new Failure(error);369} else if (eventKind != JDWP.EventKind.CLASS_PREPARE) {370complain("Unexpected event kind received: " + eventKind371+ " (expected: " + JDWP.EventKind.CLASS_PREPARE +")");372throw new Failure(error);373}374375// extracy CLASS_PREPARE event specific data376int eventRequestID = event.getInt();377eventThreadID = event.getObjectID();378byte eventRefTypeTag = event.getByte();379long eventClassID = event.getReferenceTypeID();380String eventClassSignature = event.getString();381int eventClassStatus = event.getInt();382383// check if event was single384if (events > 1) {385complain("Not single CLASS_PREPARE event received for class:\n\t"386+ eventClassSignature);387}388389// find appropriate class by signature390boolean found = false;391for (int j = 0; j < count; j++) {392if (eventClassSignature.equals(signatures[j])) {393found = true;394395// check if event is not duplicated396if (classIDs[j] != 0) {397complain("Extra CLASS_PREPARE event recieved for class:\n\t"398+ eventClassSignature);399} else {400classIDs[j] = eventClassID;401received ++;402}403404// check if event is because of expected request405if (eventRequestID != requestIDs[j]) {406complain("CLASS_PREPARE event with unexpected requestID ("407+ requestIDs[j] + ") received for class:\n\t"408+ eventClassSignature);409} else {410clearEventRequest(JDWP.EventKind.CLASS_PREPARE, requestIDs[j]);411}412}413}414if (!found) {415log.complain("Unexpected CLASS_PREPARE event received with class signature:\n"416+ " " + eventClassSignature);417}418}419} catch (BoundException e) {420complain("Unable to extract data from event packet while waiting for CLASS_PREPARE event:\n\t"421+ e.getMessage() + "\n" + event);422throw new Failure(error);423}424425// if all events received return without resuming426if (received >= count)427return classIDs;428429// resume debuggee according to events suspend policy430resumeEvent(eventSuspendPolicy, eventThreadID);431}432}433434/**435* Wait for BREAKPOINT event made by the given request and return threadID.436* Debuggee will be left suspended by the BREAKPOINT event.437*/438public long waitForBreakpointEvent(int requestID) {439String error = "Error occured while waiting for BREAKPOINT event for ";440441for(;;) {442EventPacket event = receiveEvent();443byte eventSuspendPolicy = 0;444long eventThreadID = 0;445try {446eventSuspendPolicy = event.getByte();447int events = event.getInt();448for (int i = 0; i < events; i++) {449// check event kind450byte eventKind = event.getByte();451if (eventKind == JDWP.EventKind.VM_DEATH) {452complain("Unexpected VM_DEATH event received: " + eventKind453+ " (expected: " + JDWP.EventKind.BREAKPOINT +")");454throw new Failure(error);455} else if (eventKind != JDWP.EventKind.BREAKPOINT) {456complain("Unexpected event kind received: " + eventKind457+ " (expected: " + JDWP.EventKind.BREAKPOINT +")");458throw new Failure(error);459}460461// extrack specific BREAKPOINT event data462int eventRequestID = event.getInt();463eventThreadID = event.getObjectID();464JDWP.Location eventLocation = event.getLocation();465466if (eventRequestID == requestID) {467clearEventRequest(JDWP.EventKind.BREAKPOINT, requestID);468return eventThreadID;469} else {470complain("Unexpected BREAKPOINT event received with requestID: "471+ eventRequestID + " (expected: " + requestID + ")");472}473}474} catch (BoundException e) {475complain("Unable to extract data from event packet while waiting for BREAKPOINT event:\n\t"476+ e.getMessage() + "\n" + event);477throw new Failure(error);478}479480resumeEvent(eventSuspendPolicy, eventThreadID);481}482}483484/**485* Resume debuggee according given event suspend policy.486*/487public void resumeEvent(byte suspendPolicy, long threadID) {488if (suspendPolicy == JDWP.SuspendPolicy.NONE) {489// do nothing490} else if (suspendPolicy == JDWP.SuspendPolicy.EVENT_THREAD) {491resumeThread(threadID);492} else if (suspendPolicy == JDWP.SuspendPolicy.ALL) {493resume();494} else {495throw new Failure("Unexpected event suspend policy while resuming debuggee: "496+ suspendPolicy);497}498}499500// --------------------------------------------------- //501502/**503* Query target VM for version info.504*/505public String getVersionInfo() {506String commandName = "VirtualMachine.Version";507CommandPacket command =508new CommandPacket(JDWP.Command.VirtualMachine.Version);509ReplyPacket reply = receiveReplyFor(command, commandName);510511try {512String description = reply.getString();513int jdwpMajor = reply.getInt();514int jdwpMinor = reply.getInt();515String vmVersion = reply.getString();516String vmName = reply.getString();517return description;518} catch (BoundException e) {519complain("Unable to parse reply packet for " + commandName + " command:\n\t"520+ e.getMessage());521display("Reply packet:\n" + reply);522throw new Failure("Error occured while getting JDWP and VM version info");523}524}525526/**527* Query target VM about VM dependent ID sizes.528*/529public void queryForIDSizes() {530String commandName = "VirtualMachine.IDSizes";531CommandPacket command = new CommandPacket(JDWP.Command.VirtualMachine.IDSizes);532ReplyPacket reply = receiveReplyFor(command);533try {534reply.resetPosition();535JDWP.TypeSize.FIELD_ID = reply.getInt();536JDWP.TypeSize.METHOD_ID = reply.getInt();537JDWP.TypeSize.OBJECT_ID = reply.getInt();538JDWP.TypeSize.REFERENCE_TYPE_ID = reply.getInt();539JDWP.TypeSize.FRAME_ID = reply.getInt();540} catch (BoundException e) {541complain("Unable to parse reply packet for " + commandName + " command:\n\t"542+ e.getMessage());543display("Reply packet:\n" + reply);544throw new Failure("Error occured while getting VM dependent ID sizes");545}546JDWP.TypeSize.CalculateSizes();547}548549// --------------------------------------------------- //550551/**552* Suspend the debugee VM by sending VirtualMachine.Suspend command.553*/554public void suspend() {555String commandName = "VirtualMachine.Suspend";556CommandPacket command = new CommandPacket(JDWP.Command.VirtualMachine.Suspend);557ReplyPacket reply = receiveReplyFor(command, commandName);558}559560/**561* Resume the debugee VM by sending VirtualMachine.Resume command.562*/563public void resume() {564String commandName = "VirtualMachine.Resume";565CommandPacket command = new CommandPacket(JDWP.Command.VirtualMachine.Resume);566ReplyPacket reply = receiveReplyFor(command, commandName);567}568569/**570* Dispose the debugee VM by sending VirtualMachine.Dispose command.571*/572public void dispose() {573String commandName = "VirtualMachine.Dispose";574CommandPacket command = new CommandPacket(JDWP.Command.VirtualMachine.Dispose);575ReplyPacket reply = receiveReplyFor(command, commandName);576}577578// --------------------------------------------------- //579580/**581* Sends JDWP command packet.582*/583public void sendCommand(CommandPacket packet, String commandName) {584try {585transport.write(packet);586} catch (IOException e) {587e.printStackTrace(log.getOutStream());588complain("Caught IOException while sending command packet for "589+ commandName + ":\n\t" + e);590display("Command packet:\n" + packet);591throw new Failure("Error occured while sending command: " + commandName);592}593}594595/**596* Receive next JDWP packet.597*/598/*599public Packet receivePacket() {600try {601ReplyPacket packet = new ReplyPacket();602transport.read(packet);603return packet;604} catch (IOException e) {605e.printStackTrace(log.getOutStream());606throw new Failure("Caught IOException while receiving reply packet:\n\t" + e);607}608}609*/610/**611* Receive next JDWP reply packet.612*/613public ReplyPacket receiveReply() {614try {615for (;;) {616Packet packet = new Packet();617transport.read(packet);618619if (packet.getFlags() == JDWP.Flag.REPLY_PACKET) {620ReplyPacket reply = new ReplyPacket(packet);621return reply;622}623624EventPacket event = new EventPacket(packet);625display("Placing received event packet into queue");626eventQueue.add(event);627}628} catch (IOException e) {629e.printStackTrace(log.getOutStream());630throw new Failure("Caught IOException while receiving reply packet:\n\t" + e);631}632}633634/**635* Get next JDWP event packet by reading from transport or getting stored636* event in the event queue.637*/638public EventPacket getEventPacket() throws IOException {639// check events queue first640if (!eventQueue.isEmpty()) {641EventPacket event = (EventPacket)(eventQueue.removeFirst());642return event;643}644645// read from transport646Packet packet = new Packet();647transport.read(packet);648649EventPacket event = new EventPacket(packet);650return event;651}652653/**654* Get next JDWP event packet by reading from transport for specified timeout655* or getting stored event in the event queue.656*/657public EventPacket getEventPacket(long timeout) throws IOException {658transport.setReadTimeout(timeout);659return getEventPacket();660}661662/**663* Receive next JDWP event packet.664*/665public EventPacket receiveEvent() {666EventPacket packet = null;667try {668packet = getEventPacket();669} catch (IOException e) {670e.printStackTrace(log.getOutStream());671throw new Failure("Caught IOException while receiving event packet:\n\t" + e);672}673674if (packet.getFlags() == JDWP.Flag.REPLY_PACKET) {675ReplyPacket reply = new ReplyPacket(packet);676log.complain("Unexpected reply packet received with id: "677+ reply.getPacketID());678log.display("Reply packet:\n" + reply);679throw new Failure("Unexpected reply packet received instead of event packet");680}681682return packet;683}684685/**686* Send specified command packet, receive and check reply packet.687*688* @throws Failure if exception caught in sending and reading packets689*/690public ReplyPacket receiveReplyFor(CommandPacket command) {691return receiveReplyFor(command, Packet.toHexString(command.getCommand(), 4));692}693694/**695* Send specified command packet, receive and check reply packet.696*697* @throws Failure if exception caught in sending and reading packets698*/699public ReplyPacket receiveReplyFor(CommandPacket command, String commandName) {700ReplyPacket reply = null;701sendCommand(command, commandName);702reply = receiveReply();703try {704reply.checkHeader(command.getPacketID());705} catch (BoundException e) {706complain("Wrong header of reply packet for command "+ commandName + ":\n\t"707+ e.getMessage());708display("Reply packet:\n" + reply);709throw new Failure("Wrong reply packet received for command: " + commandName);710}711return reply;712}713714/**715* Receive and check event packet for specified event kind.716*717* @throws Failure if exception caught in sending and reading packets718*/719public EventPacket receiveEventFor(int eventKind, String eventName) {720EventPacket event = null;721event = receiveEvent();722try {723event.checkHeader(eventKind);724} catch (BoundException e) {725complain("Wrong header of event packet for expected "+ eventName + " event:\n\t"726+ e.getMessage());727display("Event packet:\n" + event);728throw new Failure("Wrong event packet received for expected event: " + eventName);729}730return event;731}732733// --------------------------------------------------- //734735/**736* Check common VM capability.737*/738public boolean getCapability(int capability, String name) {739String commandName = "VirtualMachine.Capabilities";740741int count = JDWP.Capability.CAN_GET_MONITOR_INFO + 1;742if (capability < 0 || capability >= count) {743throw new TestBug("Illegal capability number (" + capability744+ ") while checking for VM capability: " + name);745}746747CommandPacket command =748new CommandPacket(JDWP.Command.VirtualMachine.Capabilities);749ReplyPacket reply = receiveReplyFor(command, commandName);750751try {752reply.resetPosition();753754for (int i = 0; i < count; i++) {755byte value = reply.getByte();756if (i == capability) {757return (value != 0);758}759}760761} catch (BoundException e) {762complain("Unable to parse reply packet for " + commandName + " command:\n\t"763+ e.getMessage());764display("Reply packet:\n" + reply);765throw new Failure("Error occured while getting VM capability: "766+ name);767}768769throw new TestBug("Illegal capability number (" + capability770+ ") while checking for VM capability: " + name);771}772773/**774* Check new VM capability (since JDWP version 1.4).775*/776public boolean getNewCapability(int capability, String name) {777String commandName = "VirtualMachine.CapabilitiesNew";778int count = JDWP.Capability.CAN_SET_DEFAULT_STRATUM + 1;779780if (capability < 0 || capability >= count) {781throw new TestBug("Illegal capability number (" + capability782+ ") while checking for VM new capability: " + name);783}784785CommandPacket command =786new CommandPacket(JDWP.Command.VirtualMachine.CapabilitiesNew);787ReplyPacket reply = receiveReplyFor(command, commandName);788789try {790reply.resetPosition();791792for (int i = 0; i < count; i++) {793byte value = reply.getByte();794if (i == capability) {795return (value != 0);796}797}798} catch (BoundException e) {799complain("Unable to parse reply packet for " + commandName + " command:\n\t"800+ e.getMessage());801display("Reply packet:\n" + reply);802throw new Failure("Error occured while getting VM new capability: "803+ name);804}805806throw new TestBug("Illegal capability number (" + capability807+ ") while checking for VM new capability: " + name);808}809810// --------------------------------------------------- //811812/**813* Return ReferenceTypeID for requested class by given signature.814*/815public long getReferenceTypeID(String classSignature) {816String commandName = "VirtualMachine.ClassesBySignature";817CommandPacket command =818new CommandPacket(JDWP.Command.VirtualMachine.ClassesBySignature);819command.addString(classSignature);820command.setLength();821ReplyPacket reply = receiveReplyFor(command, commandName);822823long typeID = 0;824825try {826reply.resetPosition();827828int classes = reply.getInt();829for (int i = 0; i < classes; i++) {830byte refTypeTag = reply.getByte();831typeID = reply.getReferenceTypeID();832int status = reply.getInt();833}834835if (classes < 0) {836throw new Failure("Negative number (" + classes837+ ") of referenceTypeIDs received for signature: "838+ classSignature);839}840841if (classes == 0) {842throw new Failure("No any referenceTypeID received for signature: "843+ classSignature);844}845846if (classes > 1) {847throw new Failure("Too many (" + classes848+ ") referenceTypeIDs received for signature: "849+ classSignature);850}851852} catch (BoundException e) {853complain("Unable to parse reply packet for " + commandName + " command:\n\t"854+ e.getMessage());855display("Reply packet:\n" + reply);856throw new Failure("Error occured while getting referenceTypeID for signature: "857+ classSignature);858}859860return typeID;861}862863// --------------------------------------------------- //864865866/**867* Get list of IDs of supertypes (interfaces and classes) for given class.868*/869public long[] getSupertypes(long classID, boolean declared) {870Vector<Long> vector = new Vector<Long>();871addSupertypes(classID, vector, null, null, false, declared);872return makeListOfLongValues(vector);873}874875/**876* Get list of IDs of superclasses for given class.877*/878public long[] getSuperclasses(long classID, boolean declared) {879Vector<Long> vector = new Vector<Long>();880addSupertypes(classID, null, null, vector, false, declared);881return makeListOfLongValues(vector);882}883884/**885* Get list of IDs of implemented interfaces for given class.886*/887public long[] getImplementedInterfaces(long classID, boolean declared) {888Vector<Long> vector = new Vector<Long>();889addSupertypes(classID, null, vector, null, false, declared);890return makeListOfLongValues(vector);891}892893/**894* Get list of IDs of superinterfaces for given interface.895*/896public long[] getSuperinterfaces(long interfaceID, boolean declared) {897Vector<Long> vector = new Vector<Long>();898addSupertypes(interfaceID, null, vector, null, true, declared);899return makeListOfLongValues(vector);900}901902// --------------------------------------------------- //903904/**905* Get list of IDs of methods of given class.906*/907public long[] getMethodIDs(long classID, boolean declared) {908Vector<Long> list = new Vector<Long>();909addMethods(classID, list, null, null, null, false, declared);910return makeListOfLongValues(list);911}912913/**914* Get list of names of methods of given class.915*/916public String[] getMethodNames(long classID, boolean declared) {917Vector<String> list = new Vector<String>();918addMethods(classID, null, list, null, null, false, declared);919return makeListOfStringValues(list);920}921922/**923* Get list of signatures of methods of given class.924*/925public String[] getMethodSignatures(long classID, boolean declared) {926Vector<String> list = new Vector<String>();927addMethods(classID, null, null, list, null, false, declared);928return makeListOfStringValues(list);929}930931/**932* Get ID of a method of given class by name.933*/934public long getMethodID(long classID, String name, boolean declared) {935Vector<Long> IDs = new Vector<Long>();936Vector<String> names = new Vector<String>();937addMethods(classID, IDs, names, null, null, false, declared);938int count = names.size();939for (int i = 0; i < count; i++) {940if (name.equals(names.elementAt(i))) {941return (IDs.elementAt(i)).longValue();942}943}944throw new Failure("Method \"" + name + "\" not found for classID: " + classID);945}946947// --------------------------------------------------- //948949/**950* Get list of IDs of static fields of given class.951*/952public long[] getClassFieldIDs(long classID, boolean declared) {953Vector<Long> list = new Vector<Long>();954addFields(classID, list, null, null, null, false, declared);955return makeListOfLongValues(list);956}957958/**959* Get list of names of static fields of given class.960*/961public String[] getClassFieldNames(long classID, boolean declared) {962Vector<String> list = new Vector<String>();963addFields(classID, null, list, null, null, false, declared);964return makeListOfStringValues(list);965}966967/**968* Get list of signatures of static fields of given class.969*/970public String[] getClassFieldSignatures(long classID, boolean declared) {971Vector<String> list = new Vector<String>();972addFields(classID, null, null, list, null, false, declared);973return makeListOfStringValues(list);974}975976/**977* Get ID of a static field of given class by name.978*/979public long getClassFieldID(long classID, String name, boolean declared) {980Vector<Long> IDs = new Vector<Long>();981Vector<String> names = new Vector<String>();982addFields(classID, IDs, names, null, null, false, declared);983int count = names.size();984for (int i = 0; i < count; i++) {985if (name.equals((String)names.elementAt(i))) {986return ((Long)IDs.elementAt(i)).longValue();987}988}989throw new Failure("Static field \"" + name + "\" not found for classID: " + classID);990}991992// --------------------------------------------------- //993994/**995* Get value of a static field of given class.996*/997public JDWP.Value getStaticFieldValue(long typeID, long fieldID) {998String commandName = "ReferenceType.GetValues";999CommandPacket command =1000new CommandPacket(JDWP.Command.ReferenceType.GetValues);1001command.addReferenceTypeID(typeID);1002command.addInt(1);1003command.addFieldID(fieldID);10041005ReplyPacket reply = receiveReplyFor(command, commandName);1006JDWP.Value value = null;10071008try {1009reply.resetPosition();10101011int count = reply.getInt();1012if (count < 1) {1013throw new Failure("No values returned for static fieldID: " + fieldID);1014}1015value = reply.getValue();10161017} catch (BoundException e) {1018complain("Unable to parse reply packet for " + commandName +" command:\n\t"1019+ e.getMessage());1020display("Reply packet:\n" + reply);1021throw new Failure("Error occured while getting value of static field: " +1022+ fieldID);1023}1024return value;1025}10261027/**1028* Get value of particular type from a static field of given class.1029*/1030public JDWP.Value getStaticFieldValue(long typeID, String fieldName, byte tag) {1031long fieldID = getClassFieldID(typeID, fieldName, true);1032JDWP.Value value = getStaticFieldValue(typeID, fieldID);10331034if (value.getTag() != tag) {1035complain("unexpedted value tag returned from debuggee: " + value.getTag()1036+ " (expected: " + tag + ")");1037throw new Failure("Error occured while getting value from static field: "1038+ fieldName);1039}1040return value;1041}10421043/**1044* Set value of a static field of given class.1045*/1046public void setStaticFieldValue(long typeID, long fieldID, JDWP.Value value) {1047String commandName = "ClassType.SetValues";1048CommandPacket command =1049new CommandPacket(JDWP.Command.ClassType.SetValues);1050command.addReferenceTypeID(typeID);1051command.addInt(1);1052command.addFieldID(fieldID);1053command.addUntaggedValue(value, value.getTag());10541055ReplyPacket reply = receiveReplyFor(command, commandName);1056}10571058/**1059* Get value of a field of given object.1060*/1061public JDWP.Value getObjectFieldValue(long objectID, long fieldID) {1062String commandName = "ObjectReference.GetValues";1063CommandPacket command =1064new CommandPacket(JDWP.Command.ObjectReference.GetValues);1065command.addObjectID(objectID);1066command.addInt(1);1067command.addFieldID(fieldID);10681069ReplyPacket reply = receiveReplyFor(command, commandName);1070JDWP.Value value = null;10711072try {1073reply.resetPosition();10741075int count = reply.getInt();1076if (count < 1) {1077throw new Failure("No values returned for object fieldID: " + fieldID);1078}1079value = reply.getValue();10801081} catch (BoundException e) {1082complain("Unable to parse reply packet for " + commandName + " command:\n\t"1083+ e.getMessage());1084display("Reply packet:\n" + reply);1085throw new Failure("Error occured while getting value of object field: " +1086+ fieldID);1087}1088return value;1089}10901091/**1092* Set value of a static field of given class.1093*/1094public void setObjectFieldValue(long objectID, long fieldID, JDWP.Value value) {1095String commandName = "ObjectReference.SetValues";1096CommandPacket command =1097new CommandPacket(JDWP.Command.ObjectReference.SetValues);1098command.addObjectID(objectID);1099command.addInt(1);1100command.addFieldID(fieldID);1101command.addUntaggedValue(value, value.getTag());11021103ReplyPacket reply = receiveReplyFor(command, commandName);1104}11051106// --------------------------------------------------- //11071108/**1109* Find threadID for given thread name among all active threads.1110*/1111public long getThreadID(String name) {1112// request list of all threadIDs1113int threads = 0;1114long threadIDs[] = null;1115{1116String commandName = "VirtualMachine.AllThreads";1117CommandPacket command = new CommandPacket(JDWP.Command.VirtualMachine.AllThreads);1118ReplyPacket reply = receiveReplyFor(command, commandName);1119reply.resetPosition();1120try {1121threads = reply.getInt();1122threadIDs = new long[threads];11231124for (int i = 0; i < threads; i++) {1125threadIDs[i] = reply.getObjectID();1126}1127} catch (BoundException e) {1128complain("Unable to parse reply packet for " + commandName + " command:\n\t"1129+ e.getMessage());1130display("Reply packet:\n" + reply);1131throw new Failure("Error occured while getting threadID for thread name: "1132+ name);1133}1134}11351136// request name for each threadID1137for (int i = 0; i < threads; i++) {1138String commandName = "ThreadReference.Name";1139CommandPacket command = new CommandPacket(JDWP.Command.ThreadReference.Name);1140command.addObjectID(threadIDs[i]);1141ReplyPacket reply = receiveReplyFor(command, commandName);1142try {1143reply.resetPosition();1144String threadName = reply.getString();1145if (threadName.equals(name)) {1146return threadIDs[i];1147}1148} catch (BoundException e) {1149complain("Unable to parse reply packet for " + commandName + " command:\n\t"1150+ e.getMessage());1151display("Reply packet:\n" + reply);1152throw new Failure("Error occured while getting name for threadID: "1153+ threadIDs[i]);1154}1155}11561157throw new Failure("No threadID found for thread name: " + name);1158}11591160/**1161* Return thread name for the given threadID.1162*/1163public String getThreadName(long threadID) {1164String commandName = "ThreadReference.Name";1165CommandPacket command = new CommandPacket(JDWP.Command.ThreadReference.Name);1166command.addObjectID(threadID);1167ReplyPacket reply = receiveReplyFor(command, commandName);1168try {1169reply.resetPosition();1170String threadName = reply.getString();1171return threadName;1172} catch (BoundException e) {1173complain("Unable to parse reply packet for " + commandName + " command:\n\t"1174+ e.getMessage());1175display("Reply packet:\n" + reply);1176throw new Failure("Error occured while getting name for threadID: "1177+ threadID);1178}1179}11801181/**1182* Suspend thread for the given threadID.1183*/1184public void suspendThread(long threadID) {1185String commandName = "ThreadReference.Suspend";1186CommandPacket command = new CommandPacket(JDWP.Command.ThreadReference.Suspend);1187command.addObjectID(threadID);11881189ReplyPacket reply = receiveReplyFor(command, commandName);1190}11911192/**1193* Resume thread for the given threadID.1194*/1195public void resumeThread(long threadID) {1196String commandName = "ThreadReference.resume";1197CommandPacket command = new CommandPacket(JDWP.Command.ThreadReference.Resume);1198command.addObjectID(threadID);11991200ReplyPacket reply = receiveReplyFor(command, commandName);1201}12021203/**1204* Return frameID for the current frame of the thread.1205* Thread must be suspended.1206*/1207public long getCurrentFrameID(long threadID) {1208String commandName = "ThreadReference.Frames";1209CommandPacket command = new CommandPacket(JDWP.Command.ThreadReference.Frames);1210command.addObjectID(threadID); // threadID1211command.addInt(0); // startFrame1212command.addInt(1); // length12131214ReplyPacket reply = receiveReplyFor(command, commandName);1215try {1216reply.resetPosition();1217int frames = reply.getInt();1218if (frames != 1) {1219throw new Failure("Not only one current frame returned for threadID "1220+ threadID + ": " + frames);1221}1222long frameID = reply.getFrameID();1223JDWP.Location location = reply.getLocation();1224return frameID;1225} catch (BoundException e) {1226complain("Unable to parse reply packet for " + commandName + " command:\n\t"1227+ e.getMessage());1228display("Reply packet:\n" + reply);1229throw new Failure("Error occured while getting current frame for threadID: "1230+ threadID);1231}1232}12331234// --------------------------------------------------- //12351236/**1237* Find line number for the given location from the method line table.1238* If <code>approximate</code> is <it>true</i> the found line should begin1239* with code index of the given location. Otherwise, the found line will1240* just cover code index of the given location.1241*/1242public int getLineNumber(JDWP.Location location, boolean approximate) {1243String commandName = "Method.LineTable";1244CommandPacket command = new CommandPacket(JDWP.Command.Method.LineTable);1245command.addReferenceTypeID(location.getClassID());1246command.addMethodID(location.getMethodID());1247long index = location.getIndex();1248ReplyPacket reply = receiveReplyFor(command, commandName);1249String msg = "Error occured while getting line number for location: " + location;1250try {1251reply.resetPosition();1252long start = reply.getLong();1253if (index < start) {1254complain("Location index (" + index1255+ ") is less than start method index (" + start);1256throw new Failure(msg);1257}1258long end = reply.getLong();1259if (index > end) {1260complain("Location index (" + index1261+ ") is greater than end method index (" + end);1262throw new Failure(msg);1263}1264int lines = reply.getInt();1265if (!approximate) {1266for (int i = 0; i < lines; i++) {1267long lineCodeIndex = reply.getLong();1268int lineNumber = reply.getInt();1269if (lineCodeIndex == index) {1270return lineNumber;1271}1272}1273throw new Failure("No exact line number exactly for location: " + location);1274} else {1275int prevLine = -1;1276for (int i = 0; i < lines; i++) {1277long lineCodeIndex = reply.getLong();1278int lineNumber = reply.getInt();1279if (lineCodeIndex == index) {1280return lineNumber;1281} else if (lineCodeIndex > index) {1282break;1283}1284prevLine = lineNumber;1285}1286if (prevLine < 0)1287throw new Failure("No approximate line number found for location: " + location);1288return prevLine;1289}1290} catch (BoundException e) {1291complain("Unable to parse reply packet for " + commandName + " command:\n\t"1292+ e.getMessage());1293display("Reply packet:\n" + reply);1294throw new Failure(msg);1295}1296}12971298/**1299* Find line index for the given line number from the method line table.1300*/1301public long getCodeIndex(long classID, long methodID, int lineNumber) {1302String commandName = "Method.LineTable";1303CommandPacket command = new CommandPacket(JDWP.Command.Method.LineTable);1304command.addReferenceTypeID(classID);1305command.addMethodID(methodID);1306ReplyPacket reply = receiveReplyFor(command, commandName);1307String msg = "Error occured while getting code index for line number: " + lineNumber;1308try {1309reply.resetPosition();1310long start = reply.getLong();1311long end = reply.getLong();1312int lines = reply.getInt();1313for (int i = 0; i < lines; i++) {1314long lineCodeIndex = reply.getLong();1315int line = reply.getInt();1316if (lineNumber == line) {1317return lineCodeIndex;1318}1319}1320} catch (BoundException e) {1321complain("Unable to parse reply packet for " + commandName + " command:\n\t"1322+ e.getMessage());1323display("Reply packet:\n" + reply);1324throw new Failure(msg);1325}13261327throw new Failure("No code index found for line number: " + lineNumber);1328}13291330// --------------------------------------------------- //13311332/**1333* Make the specified event request into debuggee.1334*/1335public int requestEvent(CommandPacket requestCommand, String name) {1336String commandName = "EventRequest.Set";1337ReplyPacket reply = receiveReplyFor(requestCommand, name);13381339try {1340reply.resetPosition();13411342int requestID = reply.getInt();1343return requestID;13441345} catch (BoundException e) {1346complain("Unable to parse reply packet for " + commandName + " command:\n\t"1347+ e.getMessage());1348display("Request command packet:\n" + requestCommand);1349display("Reply packet:\n" + reply);1350throw new Failure("Error occured while making event request: " + name);1351}1352}13531354/**1355* Remove existing event request from debuggee.1356*/1357public void clearEventRequest(byte eventKind, int requestID) {1358String commandName = "EventRequest.Clear";1359CommandPacket command = new CommandPacket(JDWP.Command.EventRequest.Clear);1360command.addByte(eventKind);1361command.addInt(requestID);1362ReplyPacket reply = receiveReplyFor(command, commandName);1363}13641365/**1366* Make request for CLASS_PREPARE event for specified class into debuggee.1367*/1368public int requestClassPrepareEvent(String className, byte suspendPolicy) {1369CommandPacket command = new CommandPacket(JDWP.Command.EventRequest.Set);1370command.addByte(JDWP.EventKind.CLASS_PREPARE);1371command.addByte(suspendPolicy);1372command.addInt(1);1373command.addByte(JDWP.EventModifierKind.CLASS_MATCH);1374command.addString(className);13751376return requestEvent(command, "CLASS_PREPARE");1377}13781379/**1380* Make request for BREAKPOINT event for the specified location into debuggee.1381*/1382public int requestBreakpointEvent(JDWP.Location location, byte suspendPolicy) {1383CommandPacket command = new CommandPacket(JDWP.Command.EventRequest.Set);1384command.addByte(JDWP.EventKind.BREAKPOINT);1385command.addByte(suspendPolicy);1386command.addInt(1);1387command.addByte(JDWP.EventModifierKind.LOCATION_ONLY);1388command.addLocation(location);1389return requestEvent(command, "BREAKPOINT");1390}13911392/**1393* Make request for BREAKPOINT event for the specified line of the given method.1394*/1395public int requestBreakpointEvent(byte typeTag, long classID, long methodID,1396int lineNumber, byte suspendPolicy) {1397long codeIndex = getCodeIndex(classID, methodID, lineNumber);1398JDWP.Location location = new JDWP.Location(typeTag, classID, methodID, codeIndex);1399return requestBreakpointEvent(location, suspendPolicy);1400}14011402/**1403* Remove all existing BREAKPOINT event requests from debuggee.1404*/1405public void clearAllBreakpoints() {1406String commandName = "EventRequest.ClearAllBreakpoints";1407CommandPacket command = new CommandPacket(JDWP.Command.EventRequest.ClearAllBreakpoints);1408ReplyPacket reply = receiveReplyFor(command, commandName);1409}14101411// --------------------------------------------------- //14121413/**1414* Add IDs of supertypes (interfaces and classes) for given class to the lists.1415*/1416private void addSupertypes(long referenceTypeID, Vector<Long> supertypes,1417Vector<Long> interfaces, Vector<Long> superclasses,1418boolean interfaceOnly, boolean declared) {14191420if (supertypes != null || interfaces != null) {14211422// obtain list of direct implemented interfaces1423String commandName = "ReferenceType.Interfaces";1424CommandPacket command = new CommandPacket(JDWP.Command.ReferenceType.Interfaces);1425command.addReferenceTypeID(referenceTypeID);1426ReplyPacket reply = receiveReplyFor(command, commandName);14271428try {1429reply.resetPosition();14301431int count = reply.getInt();1432if (count < 0) {1433throw new Failure("Negative number (" + count1434+ ") of declared interfaces received for referenceTypeID: "1435+ referenceTypeID);1436}14371438for (int i = 0; i < count; i++) {1439long typeID = reply.getReferenceTypeID();1440if (!declared) {1441addSupertypes(typeID, supertypes, interfaces, superclasses,1442true, declared);1443}1444Long value = Long.valueOf(typeID);1445if (supertypes != null) {1446supertypes.add(value);1447}1448if (interfaces != null) {1449interfaces.add(value);1450}1451}14521453} catch (BoundException e) {1454complain("Unable to parse reply packet for " + commandName + " command:\n\t"1455+ e.getMessage());1456display("Reply packet:\n" + reply);1457throw new Failure("Error occured while getting interfeceIDs for referenceTypeID: " +1458+ referenceTypeID);1459}14601461}14621463if (!interfaceOnly) {14641465String commandName = "ClassType.Superclasses";1466CommandPacket command = new CommandPacket(JDWP.Command.ClassType.Superclass);1467command.addReferenceTypeID(referenceTypeID);1468ReplyPacket reply = receiveReplyFor(command, commandName);14691470try {1471reply.resetPosition();14721473long typeID = reply.getReferenceTypeID();1474if (typeID != 0) {1475if (!declared) {1476addSupertypes(typeID, supertypes, interfaces, superclasses,1477false, declared);1478}1479Long value = Long.valueOf(typeID);1480if (supertypes != null) {1481supertypes.add(value);1482}1483if (superclasses != null) {1484superclasses.add(value);1485}1486}1487} catch (BoundException e) {1488complain("Unable to parse reply packet for " + commandName + " command:\n\t"1489+ e.getMessage());1490display("Reply packet:\n" + reply);1491throw new Failure("Error occured while getting superclass ID for classID: " +1492+ referenceTypeID);1493}14941495}1496}14971498/**1499* Add attributes of fields of given class to the lists.1500*/1501private void addFields(long referenceTypeID, Vector<Long> IDs, Vector<String> names,1502Vector<String> signatures, Vector<Integer> modifiers,1503boolean interfaceOnly, boolean declared) {15041505if (!declared) {1506Vector<Long> supertypes = new Vector<Long>();1507addSupertypes(referenceTypeID, supertypes, null, null, interfaceOnly, declared);1508int count = supertypes.size();1509for (int i = 0; i < count; i++) {1510long typeID = (supertypes.elementAt(i)).longValue();1511addFields(typeID, IDs, names, signatures, modifiers,1512interfaceOnly, declared);1513}1514}15151516String commandName = "ReferenceType.Fields";1517CommandPacket command = new CommandPacket(JDWP.Command.ReferenceType.Fields);1518command.addReferenceTypeID(referenceTypeID);1519ReplyPacket reply = receiveReplyFor(command, commandName);15201521try {1522reply.resetPosition();15231524int count = reply.getInt();1525if (count < 0) {1526throw new Failure("Negative number (" + count1527+ ") of declared fields received for referenceTypeID: "1528+ referenceTypeID);1529}15301531for (int i = 0; i < count; i++) {1532long id = reply.getFieldID();1533String name = reply.getString();1534String signature = reply.getString();1535int modBits = reply.getInt();15361537if (IDs != null)1538IDs.add(Long.valueOf(id));1539if (names != null)1540names.add(name);1541if (signatures != null)1542signatures.add(signature);1543if (modifiers != null)1544modifiers.add(Integer.valueOf(modBits));1545}15461547} catch (BoundException e) {1548complain("Unable to parse reply packet for " + commandName + " command:\n\t"1549+ e.getMessage());1550display("Reply packet:\n" + reply);1551throw new Failure("Error occured while getting fieldIDs for referenceTypeID: " +1552+ referenceTypeID);1553}1554}15551556/**1557* Add attributes of methods of given class to the lists.1558*/1559private void addMethods(long referenceTypeID, Vector<Long> IDs, Vector<String> names,1560Vector<String> signatures, Vector<Integer> modifiers,1561boolean interfaceOnly, boolean declared) {15621563if (!declared) {1564Vector<Long> supertypes = new Vector<Long>();1565addSupertypes(referenceTypeID, supertypes, null, null, interfaceOnly, declared);1566int count = supertypes.size();1567for (int i = 0; i < count; i++) {1568long typeID = (supertypes.elementAt(i)).longValue();1569addMethods(typeID, IDs, names, signatures, modifiers,1570interfaceOnly, declared);1571}1572}15731574String commandName = "ReferenceType.Methods";1575CommandPacket command = new CommandPacket(JDWP.Command.ReferenceType.Methods);1576command.addReferenceTypeID(referenceTypeID);1577ReplyPacket reply = receiveReplyFor(command, commandName);15781579try {1580reply.resetPosition();15811582int count = reply.getInt();1583if (count < 0) {1584throw new Failure("Negative number (" + count1585+ ") of declared fields received for referenceTypeID: "1586+ referenceTypeID);1587}15881589for (int i = 0; i < count; i++) {1590long id = reply.getMethodID();1591String name = reply.getString();1592String signature = reply.getString();1593int modBits = reply.getInt();15941595if (IDs != null)1596IDs.add(Long.valueOf(id));1597if (names != null)1598names.add(name);1599if (signatures != null)1600signatures.add(signature);1601if (modifiers != null)1602modifiers.add(Integer.valueOf(modBits));1603}16041605} catch (BoundException e) {1606complain("Unable to parse reply packet for " + commandName + " command:\n\t"1607+ e.getMessage());1608display("Reply packet:\n" + reply);1609throw new Failure("Error occured while getting methodIDs for referenceTypeID: " +1610+ referenceTypeID);1611}1612}16131614// --------------------------------------------------- //16151616private static long[] makeListOfLongValues(Vector<Long> vector) {1617int count = vector.size();1618long[] list = new long[count];1619for (int i = 0; i < count; i++) {1620list[i] = (vector.elementAt(i)).longValue();1621}1622return list;1623}16241625private static String[] makeListOfStringValues(Vector<String> vector) {1626int count = vector.size();1627String[] list = new String[count];1628for (int i = 0; i < count; i++) {1629list[i] = vector.elementAt(i);1630}1631return list;1632}16331634// --------------------------------------------------- //16351636/**1637* Force debugge VM to exit using JDWP connection if possible.1638*/1639protected void killDebugee() {1640// ignore1641}16421643/**1644* Close transport channel and kill the debugee VM if it is not terminated yet.1645*/1646public void close() {1647if (transport != null) {1648try {1649transport.close();1650} catch (IOException e) {1651log.display("WARNING: Caught IOException while closing JDWP connection:\n\t"1652+ e);1653}1654}1655super.close();1656}16571658}165916601661