1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245
|
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
package netscape.jsdebug;
/*
* jband - 03/19/97
*
* This is an 'abstracted version of netscape.debug.ThreadState
*
* The methods that were 'native' there are 'abstract' here.
* Changed 'private' data to 'protected' (though native access is immune)
* Changed 'private' resume0() to 'protected'
* Removed ThreadHook referneces
*
*/
/**
* When a hook is hit, the debugger records the state of the
* thread before the hook in a ThreadState object. This object
* is then passed to any hook methods that are called, and can
* be used to change the state of the thread when it resumes from the
* hook.
*
* @author John Bandhauer
* @author Nick Thompson
* @version 1.0
* @since 1.0
*/
public abstract class ThreadStateBase {
protected Thread thread;
protected boolean valid;
protected boolean runningHook;
protected boolean resumeWhenDone;
protected int status;
protected int continueState;
protected StackFrameInfo[] stack; /* jband - 03/19/97 - had no access modifier */
protected Object returnValue;
protected Throwable currentException;
protected int currentFramePtr; /* used internally */
protected ThreadStateBase previous;
/**
* <B><font color="red">Not Implemented.</font></B>
* Always throws <code>InternalError("unimplemented")</code>
*/
public static ThreadStateBase getThreadState(Thread t)
throws InvalidInfoException
{
throw new InternalError("unimplemented");
}
/**
* Get the Thread that this ThreadState came from.
*/
public Thread getThread() {
return thread;
}
/**
* Return true if the Thread hasn't been resumed since this ThreadState
* was made.
*/
public boolean isValid() {
return valid;
}
/**
* Return true if the thread is currently running a hook
* for this ThreadState
*/
public boolean isRunningHook() {
return runningHook;
}
/**
* partial list of thread states from sun.debug.ThreadInfo.
* XXX some of these don't apply.
*/
public final static int THR_STATUS_UNKNOWN = 0x01;
public final static int THR_STATUS_ZOMBIE = 0x02;
public final static int THR_STATUS_RUNNING = 0x03;
public final static int THR_STATUS_SLEEPING = 0x04;
public final static int THR_STATUS_MONWAIT = 0x05;
public final static int THR_STATUS_CONDWAIT = 0x06;
public final static int THR_STATUS_SUSPENDED = 0x07;
public final static int THR_STATUS_BREAK = 0x08;
/**
* Get the state of the thread at the time it entered debug mode.
* This can't be modified directly.
*/
public int getStatus() {
return status;
}
/**
* Get the count of the stackframes
*/
public abstract int countStackFrames()
throws InvalidInfoException;
/**
* Get the 'top' stackframe; i.e. the one with the current instruction
*/
public abstract StackFrameInfo getCurrentFrame()
throws InvalidInfoException;
/**
* Get the thread's stack as an array. stack[stack.length-1] is the
* current frame, and stack[0] is the beginning of the stack.
*/
public synchronized StackFrameInfo[] getStack()
throws InvalidInfoException {
// XXX check valid?
if (stack == null) {
stack = new StackFrameInfo[countStackFrames()];
}
if (stack.length == 0)
return stack;
StackFrameInfo frame = getCurrentFrame();
stack[stack.length - 1] = frame;
for (int i = stack.length - 2; i >= 0; i--) {
frame = frame.getCaller();
stack[i] = frame;
}
// should really be read-only for safety
return stack;
}
/**
* Leave the thread in a suspended state when the hook method(s)
* finish. This can be undone by calling resume(). This is the
* default only if the break was the result of
* DebugController.sendInterrupt().
*/
public void leaveSuspended() {
resumeWhenDone = false;
}
/**
* Resume the thread. This is the default unless the break was the result
* of DebugController.sendInterrupt(). This method may be called from a
* hook method, in which case the thread will resume when the
* method returns.
* Alternatively, if there is no active hook method and
* the thread is suspended around in the DebugFrame, this resumes it
* immediately.
*/
public synchronized void resume() {
if (runningHook)
resumeWhenDone = true;
else
resume0();
}
protected abstract void resume0();
/**
* if the continueState is DEAD, the thread cannot
* be restarted.
*/
public final static int DEBUG_STATE_DEAD = 0x01;
/**
* if the continueState is RUN, the thread will
* proceed to the next program counter value when it resumes.
*/
public final static int DEBUG_STATE_RUN = 0x02;
/**
* if the continueState is RETURN, the thread will
* return from the current method with the value in getReturnValue()
* when it resumes.
*/
public final static int DEBUG_STATE_RETURN = 0x03;
/**
* if the continueState is THROW, the thread will
* throw an exception (accessible with getException()) when it
* resumes.
*/
public final static int DEBUG_STATE_THROW = 0x04;
/**
* This gets the current continue state of the debug frame, which
* will be one of the DEBUG_STATE_* values above.
*/
public int getContinueState() {
return continueState;
}
public int setContinueState(int state) {
int old = continueState;
continueState = state;
return old;
}
/**
* If the thread was stopped while in the process of returning
* a value, this call returns an object representing that value.
* non-Object values are wrapped as in the java.lang.reflect api.
* This is only relevant if the continue state is RETURN, and the
* method throws an IllegalStateException otherwise.
*/
public Object getReturnValue() throws IllegalStateException {
if (continueState != DEBUG_STATE_RETURN)
throw new IllegalStateException("no value being returned");
return returnValue;
}
/**
* If the thread was stopped while in the process of throwing an
* exception, this call returns that exception.
* This is only relevant if the continue state is THROW, and it
* throws an IllegalStateException otherwise.
*/
public Throwable getException() throws IllegalStateException {
if (continueState != DEBUG_STATE_THROW)
throw new IllegalStateException("no exception throw in progress");
return currentException;
}
}
|