mirror of
https://github.com/openRuyi-Project/gcc.git
synced 2026-10-15 10:25:39 +00:00
2006-08-14 Mark Wielaard <mark@klomp.org> Imported GNU Classpath 0.92 * HACKING: Add more importing hints. Update automake version requirement. * configure.ac (gconf-peer): New enable AC argument. Add --disable-gconf-peer and --enable-default-preferences-peer to classpath configure when gconf is disabled. * scripts/makemake.tcl: Set gnu/java/util/prefs/gconf and gnu/java/awt/dnd/peer/gtk to bc. Classify gnu/java/security/Configuration.java as generated source file. * gnu/java/lang/management/VMGarbageCollectorMXBeanImpl.java, gnu/java/lang/management/VMMemoryPoolMXBeanImpl.java, gnu/java/lang/management/VMClassLoadingMXBeanImpl.java, gnu/java/lang/management/VMRuntimeMXBeanImpl.java, gnu/java/lang/management/VMMemoryManagerMXBeanImpl.java, gnu/java/lang/management/VMThreadMXBeanImpl.java, gnu/java/lang/management/VMMemoryMXBeanImpl.java, gnu/java/lang/management/VMCompilationMXBeanImpl.java: New VM stub classes. * java/lang/management/VMManagementFactory.java: Likewise. * java/net/VMURLConnection.java: Likewise. * gnu/java/nio/VMChannel.java: Likewise. * java/lang/Thread.java (getState): Add stub implementation. * java/lang/Class.java (isEnum): Likewise. * java/lang/Class.h (isEnum): Likewise. * gnu/awt/xlib/XToolkit.java (getClasspathTextLayoutPeer): Removed. * javax/naming/spi/NamingManager.java: New override for StackWalker functionality. * configure, sources.am, Makefile.in, gcj/Makefile.in, include/Makefile.in, testsuite/Makefile.in: Regenerated. From-SVN: r116139
345 lines
9.2 KiB
Java
345 lines
9.2 KiB
Java
/* Jdwp.java -- Virtual machine to JDWP back-end programming interface
|
|
Copyright (C) 2005, 2006 Free Software Foundation
|
|
|
|
This file is part of GNU Classpath.
|
|
|
|
GNU Classpath is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2, or (at your option)
|
|
any later version.
|
|
|
|
GNU Classpath 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 for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with GNU Classpath; see the file COPYING. If not, write to the
|
|
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
02110-1301 USA.
|
|
|
|
Linking this library statically or dynamically with other modules is
|
|
making a combined work based on this library. Thus, the terms and
|
|
conditions of the GNU General Public License cover the whole
|
|
combination.
|
|
|
|
As a special exception, the copyright holders of this library give you
|
|
permission to link this library with independent modules to produce an
|
|
executable, regardless of the license terms of these independent
|
|
modules, and to copy and distribute the resulting executable under
|
|
terms of your choice, provided that you also meet, for each linked
|
|
terms of your choice, provided that you also meet, for each linked
|
|
independent module, the terms and conditions of the license of that
|
|
module. An independent module is a module which is not derived from
|
|
or based on this library. If you modify this library, you may extend
|
|
this exception to your version of the library, but you are not
|
|
obligated to do so. If you do not wish to do so, delete this
|
|
exception statement from your version. */
|
|
|
|
|
|
package gnu.classpath.jdwp;
|
|
|
|
import gnu.classpath.jdwp.event.Event;
|
|
import gnu.classpath.jdwp.event.EventManager;
|
|
import gnu.classpath.jdwp.event.EventRequest;
|
|
import gnu.classpath.jdwp.exception.JdwpException;
|
|
import gnu.classpath.jdwp.processor.PacketProcessor;
|
|
import gnu.classpath.jdwp.transport.ITransport;
|
|
import gnu.classpath.jdwp.transport.JdwpConnection;
|
|
import gnu.classpath.jdwp.transport.TransportException;
|
|
import gnu.classpath.jdwp.transport.TransportFactory;
|
|
|
|
import java.io.IOException;
|
|
import java.security.AccessController;
|
|
import java.util.HashMap;
|
|
|
|
/**
|
|
* Main interface from the virtual machine to the JDWP back-end.
|
|
*
|
|
* The thread created by this class is only used for initialization.
|
|
* Once it exits, the JDWP backend is fully initialized.
|
|
*
|
|
* @author Keith Seitz (keiths@redhat.com)
|
|
*/
|
|
public class Jdwp
|
|
extends Thread
|
|
{
|
|
// The single instance of the back-end
|
|
private static Jdwp _instance = null;
|
|
|
|
/**
|
|
* Are we debugging? Only true if debugging
|
|
* *and* initialized.
|
|
*/
|
|
public static boolean isDebugging = false;
|
|
|
|
// Packet processor
|
|
private PacketProcessor _packetProcessor;
|
|
private Thread _ppThread;
|
|
|
|
// JDWP configuration properties
|
|
private HashMap _properties;
|
|
|
|
// The suspend property of the configure string
|
|
// (-Xrunjdwp:..suspend=<boolean>)
|
|
private static final String _PROPERTY_SUSPEND = "suspend";
|
|
|
|
// Connection to debugger
|
|
private JdwpConnection _connection;
|
|
|
|
// Are we shutting down the current session?
|
|
private boolean _shutdown;
|
|
|
|
// A thread group for the JDWP threads
|
|
private ThreadGroup _group;
|
|
|
|
// Initialization synchronization
|
|
private Object _initLock = new Object ();
|
|
private int _initCount = 0;
|
|
|
|
/**
|
|
* constructor
|
|
*/
|
|
public Jdwp ()
|
|
{
|
|
_shutdown = false;
|
|
_instance = this;
|
|
}
|
|
|
|
/**
|
|
* Returns the JDWP back-end, creating an instance of it
|
|
* if one does not already exist.
|
|
*/
|
|
public static Jdwp getDefault ()
|
|
{
|
|
return _instance;
|
|
}
|
|
|
|
/**
|
|
* Get the thread group used by JDWP threads
|
|
*
|
|
* @return the thread group
|
|
*/
|
|
public ThreadGroup getJdwpThreadGroup()
|
|
{
|
|
return _group;
|
|
}
|
|
|
|
/**
|
|
* Should the virtual machine suspend on startup?
|
|
*/
|
|
public static boolean suspendOnStartup ()
|
|
{
|
|
Jdwp jdwp = getDefault ();
|
|
if (jdwp != null)
|
|
{
|
|
String suspend = (String) jdwp._properties.get (_PROPERTY_SUSPEND);
|
|
if (suspend != null && suspend.equals ("y"))
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Configures the back-end
|
|
*
|
|
* @param configArgs a string of configury options
|
|
*/
|
|
public void configure (String configArgs)
|
|
{
|
|
_processConfigury (configArgs);
|
|
}
|
|
|
|
// A helper function to initialize the transport layer
|
|
private void _doInitialization ()
|
|
throws TransportException
|
|
{
|
|
_group = new ThreadGroup ("JDWP threads");
|
|
// initialize transport
|
|
ITransport transport = TransportFactory.newInstance (_properties);
|
|
_connection = new JdwpConnection (_group, transport);
|
|
_connection.initialize ();
|
|
_connection.start ();
|
|
|
|
// Create processor
|
|
_packetProcessor = new PacketProcessor (_connection);
|
|
_ppThread = new Thread (_group, new Runnable ()
|
|
{
|
|
public void run ()
|
|
{
|
|
AccessController.doPrivileged (_packetProcessor);
|
|
}
|
|
}, "packet processor");
|
|
_ppThread.start ();
|
|
}
|
|
|
|
/**
|
|
* Shutdown the JDWP back-end
|
|
*
|
|
* NOTE: This does not quite work properly. See notes in
|
|
* run() on this subject (catch of InterruptedException).
|
|
*/
|
|
public void shutdown ()
|
|
{
|
|
if (!_shutdown)
|
|
{
|
|
_packetProcessor.shutdown ();
|
|
_ppThread.interrupt ();
|
|
_connection.shutdown ();
|
|
_shutdown = true;
|
|
isDebugging = false;
|
|
|
|
/* FIXME: probably need to check state of user's
|
|
program -- if it is suspended, we need to either
|
|
resume or kill them. */
|
|
|
|
interrupt ();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Notify the debugger of an event. This method should not
|
|
* be called if debugging is not active (but it would not
|
|
* cause any harm). Places where event notifications occur
|
|
* should check isDebugging before doing anything.
|
|
*
|
|
* The event is filtered through the event manager before being
|
|
* sent.
|
|
*
|
|
* FIXME: Probably need logic to send multiple events
|
|
* @param event the event to report
|
|
*/
|
|
public static void notify (Event event)
|
|
{
|
|
Jdwp jdwp = getDefault ();
|
|
if (jdwp != null)
|
|
{
|
|
EventManager em = EventManager.getDefault ();
|
|
EventRequest request = em.getEventRequest (event);
|
|
if (request != null)
|
|
{
|
|
try
|
|
{
|
|
System.out.println ("Jdwp.notify: sending event " + event);
|
|
sendEvent (request, event);
|
|
jdwp._enforceSuspendPolicy (request.getSuspendPolicy ());
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
/* Really not much we can do. For now, just print out
|
|
a warning to the user. */
|
|
System.out.println ("Jdwp.notify: caught exception: " + e);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Sends the event to the debugger.
|
|
*
|
|
* This method bypasses the event manager's filtering.
|
|
*
|
|
* @param request the debugger request for the event
|
|
* @param event the event to send
|
|
* @throws IOException if a communications failure occurs
|
|
*/
|
|
public static void sendEvent (EventRequest request, Event event)
|
|
throws IOException
|
|
{
|
|
Jdwp jdwp = getDefault ();
|
|
if (jdwp != null)
|
|
{
|
|
// !! May need to implement send queue?
|
|
synchronized (jdwp._connection)
|
|
{
|
|
jdwp._connection.sendEvent (request, event);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Helper function to enforce suspend policies on event notification
|
|
private void _enforceSuspendPolicy (byte suspendPolicy)
|
|
throws JdwpException
|
|
{
|
|
switch (suspendPolicy)
|
|
{
|
|
case EventRequest.SUSPEND_NONE:
|
|
// do nothing
|
|
break;
|
|
|
|
case EventRequest.SUSPEND_THREAD:
|
|
VMVirtualMachine.suspendThread (Thread.currentThread ());
|
|
break;
|
|
|
|
case EventRequest.SUSPEND_ALL:
|
|
VMVirtualMachine.suspendAllThreads ();
|
|
break;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Allows subcomponents to specify that they are
|
|
* initialized.
|
|
*
|
|
* Subcomponents include JdwpConnection and PacketProcessor.
|
|
*/
|
|
public void subcomponentInitialized ()
|
|
{
|
|
synchronized (_initLock)
|
|
{
|
|
++_initCount;
|
|
_initLock.notify ();
|
|
}
|
|
}
|
|
|
|
public void run ()
|
|
{
|
|
try
|
|
{
|
|
_doInitialization ();
|
|
|
|
/* We need a little internal synchronization here, so that
|
|
when this thread dies, the back-end will be fully initialized,
|
|
ready to start servicing the VM and debugger. */
|
|
synchronized (_initLock)
|
|
{
|
|
while (_initCount != 2)
|
|
_initLock.wait ();
|
|
}
|
|
_initLock = null;
|
|
}
|
|
catch (Throwable t)
|
|
{
|
|
System.out.println ("Exception in JDWP back-end: " + t);
|
|
System.exit (1);
|
|
}
|
|
|
|
/* Force creation of the EventManager. If the event manager
|
|
has not been created when isDebugging is set, it is possible
|
|
that the VM will call Jdwp.notify (which uses EventManager)
|
|
while the EventManager is being created (or at least this is
|
|
a problem with gcj/gij). */
|
|
EventManager.getDefault();
|
|
|
|
// Now we are finally ready and initialized
|
|
isDebugging = true;
|
|
}
|
|
|
|
// A helper function to process the configure string "-Xrunjdwp:..."
|
|
private void _processConfigury (String configString)
|
|
{
|
|
// Loop through configuration arguments looking for a
|
|
// transport name
|
|
_properties = new HashMap ();
|
|
String[] options = configString.split (",");
|
|
for (int i = 0; i < options.length; ++i)
|
|
{
|
|
String[] property = options[i].split ("=");
|
|
if (property.length == 2)
|
|
_properties.put (property[0], property[1]);
|
|
// ignore malformed options
|
|
}
|
|
}
|
|
}
|