jde.debugger
Class Jdebug

java.lang.Object
  |
  +--java.lang.Thread
        |
        +--jde.debugger.Jdebug

public class Jdebug
extends java.lang.Thread
implements Protocol

Jdebug.java

This class is the main link between jdebug and jde. It has methods that allow communication between jde and jdebug, as well as a store of all the applications currently active. Commands that have valid app_ids interpret get passed on to the corresponding applications. If not, corresponding errors are sent on the pipe.

Look here for the command/response formats, and here for information about handling of events, including event set formats

Note that for each command sent by jde, there *has* to be a reply. (either a result or an error) For example, in case we're launching a thread, we should return true, even if the thread might bomb later on.

Handshake Since JDI supports different kinds of connections, (for example, it being possible to "launch" a debugger once an uncaught exception is raised), we should probably have some sort of a handshake mechanism preceding a debugging session, for each new vm.

For example, if the debugee vm is already running, during the handshake we might specify its address. On the other hand, if we want the debugger to *launch* a vm, we can do that during the handshake.

The purpose of the handshake is to establish the debugee_vm_id <-> debugee VM binding. It is guaranteed that no events will be raised from jdebug for a debugee VM for which the handshake is not yet complete.

Created: Wed Jul 7 20:49:16 1999

Since:
0.1

Field Summary
(package private)  java.util.Map applications
          All the active applications are kept in a map of app_id -> app.
(package private)  java.io.BufferedReader in
           
static java.lang.Integer my_id
          The ID of jdebug.
(package private)  java.io.PrintWriter out
           
private  java.util.Collection pendingCommands
          Each command has a command id associated with it, that is used by jde, to match with the corresponding result/error.
 
Fields inherited from class java.lang.Thread
contextClassLoader, daemon, eetop, group, inheritedAccessControlContext, MAX_PRIORITY, MIN_PRIORITY, name, NORM_PRIORITY, priority, single_step, stillborn, stopThreadPermission, target, threadInitNumber, threadQ, values
 
Fields inherited from interface jde.debugger.Protocol
ATTACH_SHMEM, ATTACH_SOCKET, BR, BREAK, CANCEL_TRACE_CLASSES, CANCEL_TRACE_METHODS, CANCEL_TRACE_THREADS, CLEAR, COMMAND_ERROR, COMMAND_RESULT, CONNECTED_TO_VM, DEBUG, ERROR, EVALUATE, EVENT_BREAKPOINT_HIT, EVENT_CLASS_PREPARE, EVENT_CLASS_UNLOAD, EVENT_EXCEPTION, EVENT_METHOD_ENTRY, EVENT_METHOD_EXIT, EVENT_OTHER, EVENT_STEP_COMPLETED, EVENT_THREAD_DEATH, EVENT_THREAD_START, EVENT_VM_DEATH, EVENT_VM_DISCONNECT, EVENT_VM_START, EVENT_WATCHPOINT_HIT, EVENTSET, EXIT, FINISH, GET_ARRAY, GET_LOADED_CLASSES, GET_LOCALS, GET_OBJECT, GET_OBJECT_MONITORS, GET_PATH_INFORMATION, GET_STRING, GET_THREAD, GET_THREADS, INTERRUPT, INVALID, JDE_BUG, JDE_INIT_DEBUG_SESSION, KILL_THREAD, LAUNCH, LISTEN_SHMEM, LISTEN_SOCKET, MESSAGE, QUIT, REPORT_IDS_IN_USE, RESUME, RUN, SPEC_RESOLVED, STEP, SUSPEND, TRACE_CLASSES, TRACE_EXCEPTIONS, TRACE_METHODS, TRACE_THREADS, WARNING, WATCH
 
Constructor Summary
Jdebug()
           
 
Method Summary
private  void doAttach(java.lang.String type, java.lang.Integer cmd_id, java.util.List args)
          'attach_socket' and 'attach_shmem' commands.
private  void doLaunch(java.lang.Integer cmd_id, java.util.List args)
          'launch' command.
private  void doListen(java.lang.String type, java.lang.Integer cmd_id, java.util.List args)
          'listen_socket' and 'listen_shmem' commands.
private  void doQuit(java.lang.Integer cmd_id, java.util.List arguments)
          'quit' command.
private  void handleAppCommand(java.lang.Integer app_id, java.lang.Integer cmd_id, java.lang.String command, java.util.List arguments)
          Commands received from Jdebug that don't have app_id == -1 get funneled to handleAppCommand.
private  void handleGeneralCommand(java.lang.Integer cmd_id, java.lang.String command, java.util.List arguments)
          Commands that are not meant for any particular app/vm are funneled to this method.
private  void initApplication(java.lang.String category, java.lang.Integer cmd_id, java.util.List args)
          This method is actually called by doLaunch, doAttach, and doListen and does all the ugly work.
 void removeApplication(java.lang.Integer app_id)
          called by Application.shutdown() to remove it's own entry from the applications collection here
 void run()
          Jdebug is a thread: it reads a line at a time and executes the command therein
private  void setSyntax(java.io.StreamTokenizer st)
          Sets the syntax of the input stream.
private  void shutdown()
          Shuts down all the applications prior to exiting
 void signal(java.lang.Integer app_id, java.lang.String type, java.lang.Object obj)
          Send an arbitrary lisp function across.
 void signalCommandError(java.lang.Integer app_id, java.lang.Integer cmd_id, java.lang.Object obj)
          reply to a command with an error.
 void signalCommandResult(java.lang.Integer app_id, java.lang.Integer cmd_id)
          send the result of a command.
 void signalCommandResult(java.lang.Integer app_id, java.lang.Integer cmd_id, java.lang.Object obj)
          the result of a command.
private  void signalReply(java.lang.Integer app_id, java.lang.Integer cmd_id, java.lang.Object obj, java.lang.String type)
          Signal a reply: a result or an error
 java.lang.String stringRep(java.lang.Object obj)
          Returns a string representation of the object.
 
Methods inherited from class java.lang.Thread
, activeCount, checkAccess, countStackFrames, currentThread, destroy, dumpStack, enumerate, exit, getContextClassLoader, getName, getPriority, getThreadGroup, init, interrupt, interrupt0, interrupted, isAlive, isDaemon, isInterrupted, isInterrupted, join, join, join, nextThreadNum, registerNatives, resume, resume0, setContextClassLoader, setDaemon, setName, setPriority, setPriority0, sleep, sleep, start, stop, stop, stop0, suspend, suspend0, toString, yield
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

in

java.io.BufferedReader in

out

java.io.PrintWriter out

applications

java.util.Map applications
All the active applications are kept in a map of app_id -> app. The app_id uniquely idenifies the application: it's the duty of the app to nicely remove itself from the map once it's finished

pendingCommands

private java.util.Collection pendingCommands
Each command has a command id associated with it, that is used by jde, to match with the corresponding result/error. jdebug maintains the pending command ids in this collection (as does Application, see Application.pendingCommands), and removes them once the command processing is over.
Hence, the command id can actually be reused.

Note that in case the command is actually meant for one of the apps (ie as ascertained by matching the app_id), the id isn't stored in our Collection, but the applications. This means that, in fact, it is the tuple (app_id, cmd_id) that need be unique (assuming that a "general" command has a app_id of -1


my_id

public static final java.lang.Integer my_id
The ID of jdebug. This is used by jde when issuing commands that are not specific to any particular vm, for instance, 'quit', or the command used to launch new application/vms.
It is the Integer -1.
Constructor Detail

Jdebug

public Jdebug()
       throws java.io.IOException
Method Detail

setSyntax

private void setSyntax(java.io.StreamTokenizer st)
Sets the syntax of the input stream. We want the input to be broken into lines, with whitespaces separating tokens

run

public void run()
Jdebug is a thread: it reads a line at a time and executes the command therein
Overrides:
run in class java.lang.Thread

handleGeneralCommand

private void handleGeneralCommand(java.lang.Integer cmd_id,
                                  java.lang.String command,
                                  java.util.List arguments)
Commands that are not meant for any particular app/vm are funneled to this method.
Parameters:
cmd_id - The ID of the command sent. The app_id was -1
command - The command itself
arguments - And the arguments of the command

handleAppCommand

private void handleAppCommand(java.lang.Integer app_id,
                              java.lang.Integer cmd_id,
                              java.lang.String command,
                              java.util.List arguments)
Commands received from Jdebug that don't have app_id == -1 get funneled to handleAppCommand. We have to check if the app_id is valid and if it corresponds to a valid app. If not, we send a general error message back to jde, with my_id=1 and cmd_id=-1 since app_id is not valid anyway
Parameters:
app_id - The ID of the application for which the command is intended
cmd_id - ID of the command
command - The command
arguments - And a list of the arguments of the command

initApplication

private void initApplication(java.lang.String category,
                             java.lang.Integer cmd_id,
                             java.util.List args)
                      throws JDEException
This method is actually called by doLaunch, doAttach, and doListen and does all the ugly work. The 3 above are separated for documentation purposes

The real reason is that I realised too late that they share the same code :-(


doLaunch

private void doLaunch(java.lang.Integer cmd_id,
                      java.util.List args)
               throws JDEException
'launch' command. Launches a new application.

Syntax:

 launch app_id [-use_executable javax] classname [args]
 
Comments:

doAttach

private void doAttach(java.lang.String type,
                      java.lang.Integer cmd_id,
                      java.util.List args)
               throws JDEException
'attach_socket' and 'attach_shmem' commands. Attaches to an already running application through a socket/shared memory.

Syntax:

 attach_socket app_id -port p_value [-host h_value]
 attach_shmem  app_id name
 
Comments:

doListen

private void doListen(java.lang.String type,
                      java.lang.Integer cmd_id,
                      java.util.List args)
               throws JDEException
'listen_socket' and 'listen_shmem' commands. Listenes for an incoming debuggee connection

Syntax:

 listen_socket app_id port 
 listen_shmem  app_id name
 

doQuit

private void doQuit(java.lang.Integer cmd_id,
                    java.util.List arguments)
             throws JDEException
'quit' command.

Syntax:

 quit
 

removeApplication

public void removeApplication(java.lang.Integer app_id)
called by Application.shutdown() to remove it's own entry from the applications collection here

shutdown

private void shutdown()
               throws JDEException
Shuts down all the applications prior to exiting

stringRep

public java.lang.String stringRep(java.lang.Object obj)
Returns a string representation of the object. Here is the logic:

signal

public void signal(java.lang.Integer app_id,
                   java.lang.String type,
                   java.lang.Object obj)
Send an arbitrary lisp function across.
Parameters:
app_id - The application ID
type - The function name. JDE_BUG gets added to its beginning
obj - An arbitrary object. If a string, it's just printed out, if a list, each of its elements is printed out, with a space after each.

signalReply

private void signalReply(java.lang.Integer app_id,
                         java.lang.Integer cmd_id,
                         java.lang.Object obj,
                         java.lang.String type)
Signal a reply: a result or an error

signalCommandResult

public void signalCommandResult(java.lang.Integer app_id,
                                java.lang.Integer cmd_id)
send the result of a command. indicates a positive completion of the command. this could of course be provisional: eg. in case of provisional breakpoints

signalCommandResult

public void signalCommandResult(java.lang.Integer app_id,
                                java.lang.Integer cmd_id,
                                java.lang.Object obj)
the result of a command. if it's a string, just send it across, else it should be a list. each element is sent across, just doing a toString() -> ie, if you want to send (... 23 "some string" 45), you need to put in the quotes (ie "") yourself: else what will be sent will be (... 23 some string 45), obviously wrong.

signalCommandError

public void signalCommandError(java.lang.Integer app_id,
                               java.lang.Integer cmd_id,
                               java.lang.Object obj)
reply to a command with an error.
Parameters:
obj - Is usually a string explaining what went wrong.