| 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 */  | 
 | 
 | 
 | 
package com.sun.tools.jdi;  | 
 | 
 | 
 | 
import java.io.IOException;  | 
 | 
import java.io.UnsupportedEncodingException;  | 
 | 
import java.util.Map;  | 
 | 
import java.util.Properties;  | 
 | 
 | 
 | 
import com.sun.jdi.Bootstrap;  | 
 | 
import com.sun.jdi.VirtualMachine;  | 
 | 
import com.sun.jdi.connect.*;  | 
 | 
import com.sun.jdi.connect.spi.*;  | 
 | 
 | 
 | 
/*  | 
 | 
 * An AttachingConnector that connects to a debuggee by specifying the process  | 
 | 
 * id (pid) as the connector argument. If the process is a debuggee listening  | 
 | 
 * on a transport address then this connector reads the transport address  | 
 | 
 * and attempts to attach to it using the appropriate transport.  | 
 | 
 */  | 
 | 
 | 
 | 
public class ProcessAttachingConnector  | 
 | 
        extends ConnectorImpl implements AttachingConnector  | 
 | 
{ | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    static final String ARG_PID = "pid";  | 
 | 
    static final String ARG_TIMEOUT = "timeout";  | 
 | 
 | 
 | 
    com.sun.tools.attach.VirtualMachine vm;  | 
 | 
    Transport transport;  | 
 | 
 | 
 | 
    public ProcessAttachingConnector() { | 
 | 
        addStringArgument(  | 
 | 
            ARG_PID,  | 
 | 
            getString("process_attaching.pid.label"), | 
 | 
            getString("process_attaching.pid"), | 
 | 
            "",  | 
 | 
            true);  | 
 | 
 | 
 | 
        addIntegerArgument(  | 
 | 
            ARG_TIMEOUT,  | 
 | 
            getString("generic_attaching.timeout.label"),        | 
 | 
            getString("generic_attaching.timeout"),              | 
 | 
            "",  | 
 | 
            false,  | 
 | 
            0, Integer.MAX_VALUE);  | 
 | 
 | 
 | 
        transport = new Transport() { | 
 | 
            public String name() { | 
 | 
                return "local";  | 
 | 
            }  | 
 | 
        };  | 
 | 
    }  | 
 | 
 | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    public VirtualMachine attach(Map<String,? extends Connector.Argument> args)  | 
 | 
                throws IOException, IllegalConnectorArgumentsException  | 
 | 
    { | 
 | 
        String pid = argument(ARG_PID, args).value();  | 
 | 
        String t = argument(ARG_TIMEOUT, args).value();  | 
 | 
        int timeout = 0;  | 
 | 
        if (t.length() > 0) { | 
 | 
            timeout = Integer.decode(t).intValue();  | 
 | 
        }  | 
 | 
 | 
 | 
        // Use Attach API to attach to target VM and read value of  | 
 | 
        // sun.jdwp.listenAddress property.  | 
 | 
 | 
 | 
        String address = null;  | 
 | 
        com.sun.tools.attach.VirtualMachine vm = null;  | 
 | 
        try { | 
 | 
            vm = com.sun.tools.attach.VirtualMachine.attach(pid);  | 
 | 
            Properties props = vm.getAgentProperties();  | 
 | 
            address = props.getProperty("sun.jdwp.listenerAddress"); | 
 | 
        } catch (Exception x) { | 
 | 
            throw new IOException(x.getMessage());  | 
 | 
        } finally { | 
 | 
            if (vm != null) vm.detach();  | 
 | 
        }  | 
 | 
 | 
 | 
        // check that the property value is formatted correctly  | 
 | 
 | 
 | 
        if (address == null) { | 
 | 
            throw new IOException("Not a debuggee, or not listening for debugger to attach"); | 
 | 
        }  | 
 | 
        int pos = address.indexOf(':'); | 
 | 
        if (pos < 1) { | 
 | 
            throw new IOException("Unable to determine transport endpoint"); | 
 | 
        }  | 
 | 
 | 
 | 
        // parse into transport library name and address  | 
 | 
 | 
 | 
        final String lib = address.substring(0, pos);  | 
 | 
        address = address.substring(pos+1, address.length());  | 
 | 
 | 
 | 
        TransportService ts = null;  | 
 | 
        if (lib.equals("dt_socket")) { | 
 | 
            ts = new SocketTransportService();  | 
 | 
        } else { | 
 | 
            if (lib.equals("dt_shmem")) { | 
 | 
                try { | 
 | 
                    Class<?> c = Class.forName("com.sun.tools.jdi.SharedMemoryTransportService"); | 
 | 
                    ts = (TransportService)c.newInstance();  | 
 | 
                } catch (Exception x) { } | 
 | 
            }  | 
 | 
        }  | 
 | 
        if (ts == null) { | 
 | 
            throw new IOException("Transport " + lib + " not recognized"); | 
 | 
        }  | 
 | 
 | 
 | 
        // connect to the debuggee  | 
 | 
 | 
 | 
        Connection connection = ts.attach(address, timeout, 0);  | 
 | 
        return Bootstrap.virtualMachineManager().createVirtualMachine(connection);  | 
 | 
    }  | 
 | 
 | 
 | 
    public String name() { | 
 | 
        return "com.sun.jdi.ProcessAttach";  | 
 | 
    }  | 
 | 
 | 
 | 
    public String description() { | 
 | 
        return getString("process_attaching.description"); | 
 | 
    }  | 
 | 
 | 
 | 
    public Transport transport() { | 
 | 
        if (transport == null) { | 
 | 
            return new Transport() { | 
 | 
                public String name() { | 
 | 
                    return "local";  | 
 | 
                }  | 
 | 
            };  | 
 | 
        }  | 
 | 
        return transport;  | 
 | 
    }  | 
 | 
 | 
 | 
}  |