📄 debuggerlistener.java
字号:
/* * Copyright (c) 2000 Sun Microsystems, Inc., 901 San Antonio Road, * Palo Alto, CA 94303, U.S.A. All Rights Reserved. * * Sun Microsystems, Inc. has intellectual property rights relating * to the technology embodied in this software. In particular, and * without limitation, these intellectual property rights may include * one or more U.S. patents, foreign patents, or pending * applications. Sun, Sun Microsystems, the Sun logo, Java, KJava, * and all Sun-based and Java-based marks are trademarks or * registered trademarks of Sun Microsystems, Inc. in the United * States and other countries. * * This software is distributed under licenses restricting its use, * copying, distribution, and decompilation. No part of this * software may be reproduced in any form by any means without prior * written authorization of Sun and its licensors, if any. * * FEDERAL ACQUISITIONS: Commercial Software -- Government Users * Subject to Standard License Terms and Conditions */package kdp;import kdp.classparser.*;import kdp.classparser.attributes.*;import java.util.*;import java.net.*;import java.io.*;class DebuggerListener extends ProxyListener implements VMConstants { static final int UseClassParser = 0x01; SocketConnection connDebugger; ProxyListener KVMListener; ClassManager manager = null; Packet replyPacket; Options options; boolean Ready = false; ServerSocket serverSocket = null; Socket acceptSocket = null; public DebuggerListener(Options opt) { super(); this.options = opt; } public void set(ProxyListener KVMListener, ClassManager manager) { this.KVMListener = KVMListener; this.manager = manager; } /* * Sends packet to our output socket */ public synchronized void send(Packet p) throws IOException{ synchronized(this) { while (!Ready) { try { this.wait(); } catch (InterruptedException e) { } } } String id = String.valueOf(p.id); synchronized(waitingQueue) { if ((p.flags & Packet.Reply) == 0 && p.id < 0) waitingQueue.put(id, p); } connDebugger.send(p); } public void quit() { boolean oldtimeToQuit = timeToQuit; timeToQuit = true; if (oldtimeToQuit != timeToQuit) { KVMListener.quit(); try { if (acceptSocket != null) {// acceptSocket.shutdownInput();// acceptSocket.shutdownOutput(); acceptSocket.close(); } if (serverSocket != null) serverSocket.close(); } catch (IOException e) {} } } public void run() { boolean handled; Packet p=null; String classname=null, methodname=null; PacketStream ps=null; PacketStream in=null; try { System.out.println("Waiting for debugger on port " + options.getLocalPort()); serverSocket = new ServerSocket(options.getLocalPort()); acceptSocket = serverSocket.accept(); connDebugger = new SocketConnection(this, acceptSocket); System.out.println("Connection received."); } catch (IOException e) { System.out.println("DebuggerListener: " + e.getMessage()); Runtime.getRuntime().exit(1); } catch (SecurityException e) { System.out.println("DebuggerListener: " + e.getMessage()); Runtime.getRuntime().exit(1); } byte [] handshake = new String("JDWP-Handshake").getBytes(); // debugger -> kvm try { for (int i=0; i < handshake.length; i++) connDebugger.receiveByte(); // debugger <- kvm for (int i=0; i < handshake.length; i++) connDebugger.sendByte(handshake[i]); } catch (IOException e) { } synchronized(this) { Ready = true; this.notify(); } new Thread(connDebugger).start(); try { while (!timeToQuit) { ClassFile cf; int cid; handled = false; p = waitForPacket(); /* wait for a packet */ if (p == null) break; // must be time to quit if ((p.flags & Packet.Reply) == 0 && (options.getUseClassParser()) == true) { // must want to in = new PacketStream(this, p); switch (p.cmdSet) { case VIRTUALMACHINE_CMDSET: switch(p.cmd) { case SENDVERSION_CMD: ps = new PacketStream(this, in.id, Packet.Reply, Packet.ReplyNoError); ps.writeString("Version 1.0"); ps.writeInt(1); /* major version */ ps.writeInt(0); /* minor version */ ps.writeString("1.0.3"); ps.writeString("KVM"); ps.send(); handled = true; break; case CLASSESBYSIG_CMD: String classToMatch = in.readString(); Log.LOGN(3, "ClassBySig: class " + classToMatch); ps = new PacketStream(this, in.id, Packet.Reply, Packet.ReplyNoError); Iterator iter = ClassManager.classMap.values().iterator(); while (iter.hasNext()) { try { cf = (ClassFile)iter.next(); if (cf == null) throw new Exception("Couldn't find classFile object"); if (classToMatch.compareTo(cf.getClassSignature()) == 0) { Log.LOGN(3, "ClassBySig matched " + cf.getClassName()); Log.LOGN(6, "Class Signature: "+ cf.getClassSignature()); ps.writeInt(1); ps.writeByte(cf.getJDWPTypeTag()); ps.writeInt(cf.getClassID()); ps.writeInt(cf.getClassStatus()); ps.send(); handled = true; break; } } catch (Exception e) { System.out.println("ClassesBySig command failed with " + e); ps = new PacketStream(this, in.id, Packet.Reply, NOTFOUND_ERROR); ps.send(); handled = true; } } if (!handled) { ps = new PacketStream(this, in.id, Packet.Reply, Packet.ReplyNoError); ps.writeInt(0); ps.send(); handled = true; } break; case ALL_CLASSES_CMD: { String className; int classStatus; byte typeTag; /* we intercept all the statuses and then just pass it on */ Log.LOGN(3, "All_Classes command"); ps = new PacketStream(KVMListener, VIRTUALMACHINE_CMDSET, ALL_CLASSES_CMD); PacketStream ps2 = new PacketStream(this, in.id, Packet.Reply, Packet.ReplyNoError); ps.send(); try { ps.waitForReply(); } catch (Exception e) { ps2.writeInt(0); ps2.send(); handled = true; break; } int numClasses = ps.readInt(); // get number of classes ps2.writeInt(numClasses); for (int i = 0; i < numClasses; i++) { typeTag = ps.readByte(); // typeTag cid = ps.readInt(); // ID className = ps.readString(); classStatus = ps.readInt(); // pass the info on up to the debugger ps2.writeByte(typeTag); ps2.writeInt(cid); ps2.writeString(className); ps2.writeInt(classStatus); if (typeTag != TYPE_TAG_ARRAY) { // strip off leading 'L' and trailing ';' className = new String(className.substring(1, className.length() - 1)); } Log.LOGN(3, "AllClasses: " + className + ", ID = " + Integer.toHexString(cid)); if ((cf = (ClassFile)ClassManager.classMap.get(new Integer(cid))) == null) { cf = manager.findClass(typeTag, className); if (cf != null) { ClassManager.classMap.put(new Integer(cid), cf); cf.setClassID(cid); cf.setClassStatus(classStatus); } else { System.out.println("ALL_CLASSES_CMD: couldn't find classfile object"); ps2 = new PacketStream(this, in.id, Packet.Reply,NOTFOUND_ERROR); ps2.send(); handled = true; break; } } else { cf.setClassStatus(classStatus); } } ps2.send(); handled = true; } break; case TOPLEVELTHREADGROUP_CMD: ps = new PacketStream(this, in.id, Packet.Reply, Packet.ReplyNoError); ps.writeInt(1); ps.writeInt(ONLY_THREADGROUP_ID); ps.send(); handled = true; break; case DISPOSE_CMD: ps = new PacketStream(KVMListener, VIRTUALMACHINE_CMDSET, EXIT_CMD); ps.writeInt(0); ps.send(); PacketStream ps2 = new PacketStream(this, in.id, Packet.Reply, Packet.ReplyNoError); ps2.send(); handled = true; quit(); break; case IDSIZES_CMD: ps = new PacketStream(this, in.id, Packet.Reply, Packet.ReplyNoError); ps.writeInt(8); // sizeof field ID in KVM ps.writeInt(4); // sizeof method ID in KVM ps.writeInt(4); // sizeof object ID in KVM ps.writeInt(4); // sizeof reference ID in KVM ps.writeInt(4); // sizeof frame ID in KVM ps.send(); handled = true; break; case CAPABILITIES_CMD: ps = new PacketStream(this, in.id, Packet.Reply, Packet.ReplyNoError); ps.writeBoolean(false); ps.writeBoolean(false); ps.writeBoolean(true); // can get bytecodes ps.writeBoolean(false); ps.writeBoolean(false); ps.writeBoolean(false); ps.writeBoolean(false); ps.send(); handled = true; break; case CLASSPATHS_CMD: ps = new PacketStream(this, in.id, Packet.Reply, Packet.ReplyNoError); ps.writeString(""); ps.writeInt(0); // # of paths in classpath ps.writeInt(0); // # of paths in bootclasspath ps.send(); handled = true; break; case DISPOSE_OBJECTS_CMD: Log.LOGN(3, "Dispose Objects: "); ps = new PacketStream(this, in.id, Packet.Reply, Packet.ReplyNoError); ps.send(); handled = true;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -