Mercurial > hg > graal-jvmci-8
diff agent/src/share/classes/sun/jvm/hotspot/debugger/remote/RemoteDebuggerClient.java @ 0:a61af66fc99e jdk7-b24
Initial load
author | duke |
---|---|
date | Sat, 01 Dec 2007 00:00:00 +0000 |
parents | |
children | ba764ed4b6f2 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/agent/src/share/classes/sun/jvm/hotspot/debugger/remote/RemoteDebuggerClient.java Sat Dec 01 00:00:00 2007 +0000 @@ -0,0 +1,381 @@ +/* + * Copyright 2002-2004 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +package sun.jvm.hotspot.debugger.remote; + +import java.rmi.*; +import java.util.*; + +import sun.jvm.hotspot.debugger.*; +import sun.jvm.hotspot.debugger.cdbg.*; +import sun.jvm.hotspot.debugger.remote.sparc.*; +import sun.jvm.hotspot.debugger.remote.x86.*; +import sun.jvm.hotspot.debugger.remote.amd64.*; + +/** An implementation of Debugger which wraps a + RemoteDebugger, providing remote debugging via RMI. + This implementation provides caching of the remote process's + address space on the local machine where the user interface is + running. */ + +public class RemoteDebuggerClient extends DebuggerBase implements JVMDebugger { + private RemoteDebugger remoteDebugger; + private RemoteThreadFactory threadFactory; + private boolean unalignedAccessesOkay = false; + private static final int cacheSize = 16 * 1024 * 1024; // 16 MB + + public RemoteDebuggerClient(RemoteDebugger remoteDebugger) throws DebuggerException { + super(); + try { + this.remoteDebugger = remoteDebugger; + machDesc = remoteDebugger.getMachineDescription(); + utils = new DebuggerUtilities(machDesc.getAddressSize(), machDesc.isBigEndian()); + int cacheNumPages; + int cachePageSize; + String cpu = remoteDebugger.getCPU(); + // page size. (FIXME: should pick this up from the remoteDebugger.) + if (cpu.equals("sparc")) { + threadFactory = new RemoteSPARCThreadFactory(this); + cachePageSize = 8192; + cacheNumPages = parseCacheNumPagesProperty(cacheSize / cachePageSize); + } else if (cpu.equals("x86")) { + threadFactory = new RemoteX86ThreadFactory(this); + cachePageSize = 4096; + cacheNumPages = parseCacheNumPagesProperty(cacheSize / cachePageSize); + unalignedAccessesOkay = true; + } else if (cpu.equals("amd64")) { + threadFactory = new RemoteAMD64ThreadFactory(this); + cachePageSize = 4096; + cacheNumPages = parseCacheNumPagesProperty(cacheSize / cachePageSize); + unalignedAccessesOkay = true; + } else { + throw new DebuggerException("Thread access for CPU architecture " + cpu + " not yet supported"); + } + + // Cache portion of the remote process's address space. + initCache(cachePageSize, cacheNumPages); + + jbooleanSize = remoteDebugger.getJBooleanSize(); + jbyteSize = remoteDebugger.getJByteSize(); + jcharSize = remoteDebugger.getJCharSize(); + jdoubleSize = remoteDebugger.getJDoubleSize(); + jfloatSize = remoteDebugger.getJFloatSize(); + jintSize = remoteDebugger.getJIntSize(); + jlongSize = remoteDebugger.getJLongSize(); + jshortSize = remoteDebugger.getJShortSize(); + javaPrimitiveTypesConfigured = true; + } + catch (RemoteException e) { + throw new DebuggerException(e); + } + } + + public long[] getThreadIntegerRegisterSet(Address addr) { + try { + return remoteDebugger.getThreadIntegerRegisterSet(getAddressValue(addr), true); + } + catch (RemoteException e) { + throw new DebuggerException(e); + } + } + + public long[] getThreadIntegerRegisterSet(long id) { + try { + return remoteDebugger.getThreadIntegerRegisterSet(id, false); + } + catch (RemoteException e) { + throw new DebuggerException(e); + } + } + + /** Unimplemented in this class (remote remoteDebugger should already be attached) */ + public boolean hasProcessList() throws DebuggerException { + throw new DebuggerException("Should not be called on RemoteDebuggerClient"); + } + + /** Unimplemented in this class (remote remoteDebugger should already be attached) */ + public List getProcessList() throws DebuggerException { + throw new DebuggerException("Should not be called on RemoteDebuggerClient"); + } + + /** Unimplemented in this class (remote remoteDebugger should already be attached) */ + public void attach(int processID) throws DebuggerException { + throw new DebuggerException("Should not be called on RemoteDebuggerClient"); + } + + /** Unimplemented in this class (remote remoteDebugger should already be attached) */ + public void attach(String executableName, String coreFileName) throws DebuggerException { + throw new DebuggerException("Should not be called on RemoteDebuggerClient"); + } + + /** Unimplemented in this class (remote remoteDebugger can not be detached) */ + public boolean detach() { + throw new DebuggerException("Should not be called on RemoteDebuggerClient"); + } + + public Address parseAddress(String addressString) throws NumberFormatException { + long addr = utils.scanAddress(addressString); + if (addr == 0) { + return null; + } + return new RemoteAddress(this, addr); + } + + public String getOS() throws DebuggerException { + try { + return remoteDebugger.getOS(); + } + catch (RemoteException e) { + throw new DebuggerException(e); + } + } + + public String getCPU() { + try { + return remoteDebugger.getCPU(); + } + catch (RemoteException e) { + throw new DebuggerException(e); + } + } + + public boolean hasConsole() throws DebuggerException { + try { + return remoteDebugger.hasConsole(); + } catch (RemoteException e) { + throw new DebuggerException(e); + } + } + + public String consoleExecuteCommand(String cmd) throws DebuggerException { + try { + return remoteDebugger.consoleExecuteCommand(cmd); + } + catch (RemoteException e) { + throw new DebuggerException(e); + } + } + + public String getConsolePrompt() throws DebuggerException { + try { + return remoteDebugger.getConsolePrompt(); + } catch (RemoteException e) { + throw new DebuggerException(e); + } + } + + public CDebugger getCDebugger() throws DebuggerException { + return null; + } + + //-------------------------------------------------------------------------------- + // Implementation of SymbolLookup interface + + public Address lookup(String objectName, String symbol) { + try { + long addr = remoteDebugger.lookupInProcess(objectName, symbol); + if (addr == 0) { + return null; + } + return new RemoteAddress(this, addr); + } + catch (RemoteException e) { + throw new DebuggerException(e); + } + } + + public OopHandle lookupOop(String objectName, String symbol) { + try { + long addr = remoteDebugger.lookupInProcess(objectName, symbol); + if (addr == 0) { + return null; + } + return new RemoteOopHandle(this, addr); + } + catch (RemoteException e) { + throw new DebuggerException(e); + } + } + + /** Need to override this to relax alignment checks on x86. */ + public long readCInteger(long address, long numBytes, boolean isUnsigned) + throws UnmappedAddressException, UnalignedAddressException { + if (!unalignedAccessesOkay) { + utils.checkAlignment(address, numBytes); + } else { + // Only slightly relaxed semantics -- this is a hack, but is + // necessary on x86 where it seems the compiler is + // putting some global 64-bit data on 32-bit boundaries + if (numBytes == 8) { + utils.checkAlignment(address, 4); + } else { + utils.checkAlignment(address, numBytes); + } + } + byte[] data = readBytes(address, numBytes); + return utils.dataToCInteger(data, isUnsigned); + } + + // Overridden from DebuggerBase because we need to relax alignment + // constraints on x86 + public long readJLong(long address) + throws UnmappedAddressException, UnalignedAddressException { + // FIXME: allow this to be configurable. Undesirable to add a + // dependency on the runtime package here, though, since this + // package should be strictly underneath it. + if (unalignedAccessesOkay) { + utils.checkAlignment(address, jintSize); + } else { + utils.checkAlignment(address, jlongSize); + } + byte[] data = readBytes(address, jlongSize); + return utils.dataToJLong(data, jlongSize); + } + + + //-------------------------------------------------------------------------------- + // Implementation of JVMDebugger interface + // + + /** Unimplemented in this class (remote remoteDebugger should already be configured) */ + public void configureJavaPrimitiveTypeSizes(long jbooleanSize, + long jbyteSize, + long jcharSize, + long jdoubleSize, + long jfloatSize, + long jintSize, + long jlongSize, + long jshortSize) { + throw new DebuggerException("Should not be called on RemoteDebuggerClient"); + } + + public void setMachineDescription(MachineDescription machDesc) { + throw new DebuggerException("Should not be called on RemoteDebuggerClient"); + } + + public int getRemoteProcessAddressSize() { + throw new DebuggerException("Should not be called on RemoteDebuggerClient"); + } + + public String addressValueToString(long addr) { + return utils.addressValueToString(addr); + } + + public long getAddressValue(Address addr) throws DebuggerException { + if (addr == null) return 0; + return ((RemoteAddress) addr).getValue(); + } + + public Address newAddress(long value) { + if (value == 0) return null; + return new RemoteAddress(this, value); + } + + RemoteAddress readAddress(long address) + throws UnmappedAddressException, UnalignedAddressException { + long value = readAddressValue(address); + return (value == 0 ? null : new RemoteAddress(this, value)); + } + + RemoteOopHandle readOopHandle(long address) + throws UnmappedAddressException, UnalignedAddressException, NotInHeapException { + long value = readAddressValue(address); + return (value == 0 ? null : new RemoteOopHandle(this, value)); + } + + boolean areThreadsEqual(Address addr1, Address addr2) { + try { + return remoteDebugger.areThreadsEqual(getAddressValue(addr1), true, + getAddressValue(addr2), true); + } catch (RemoteException e) { + } + return false; + } + + boolean areThreadsEqual(long id1, long id2) { + try { + return remoteDebugger.areThreadsEqual(id1, false, id2, false); + } catch (RemoteException e) { + } + return false; + } + + boolean areThreadsEqual(Address addr1, long id2) { + try { + return remoteDebugger.areThreadsEqual(getAddressValue(addr1), true, id2, false); + } catch (RemoteException e) { + } + return false; + } + + boolean areThreadsEqual(long id1, Address addr2) { + try { + return remoteDebugger.areThreadsEqual(id1, false, getAddressValue(addr2), true); + } catch (RemoteException e) { + } + return false; + } + + int getThreadHashCode(Address a) { + try { + return remoteDebugger.getThreadHashCode(getAddressValue(a), true); + } catch (RemoteException e) { + } + return a.hashCode(); + } + + int getThreadHashCode(long id) { + try { + return remoteDebugger.getThreadHashCode(id, false); + } catch (RemoteException e) { + } + return (int) id; + } + + public ThreadProxy getThreadForIdentifierAddress(Address addr) { + return threadFactory.createThreadWrapper(addr); + } + + public ThreadProxy getThreadForThreadId(long id) { + return threadFactory.createThreadWrapper(id); + } + + public MachineDescription getMachineDescription() throws DebuggerException { + return machDesc; + } + + /** This reads bytes from the remote process. */ + public ReadResult readBytesFromProcess(long address, long numBytes) { + try { + return remoteDebugger.readBytesFromProcess(address, numBytes); + } + catch (RemoteException e) { + throw new DebuggerException(e); + } + } + + public void writeBytesToProcess(long a, long b, byte[] c) { + throw new DebuggerException("Unimplemented!"); + } +}