1. added stepping debug support
2. added debugger error handling
This commit is contained in:
@@ -6,7 +6,7 @@
|
|||||||
<classpathentry kind="src" path="src/test/res"/>
|
<classpathentry kind="src" path="src/test/res"/>
|
||||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||||
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/3.8.1"/>
|
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/3.8.1"/>
|
||||||
<classpathentry kind="var" path="WTK_HOME/lib/cldcapi10.jar"/>
|
<classpathentry kind="var" path="WTK_HOME/lib/cldcapi11.jar"/>
|
||||||
<classpathentry kind="var" path="WTK_HOME/lib/midpapi20.jar"/>
|
<classpathentry kind="var" path="WTK_HOME/lib/midpapi20.jar"/>
|
||||||
<classpathentry kind="output" path="bin"/>
|
<classpathentry kind="output" path="bin"/>
|
||||||
</classpath>
|
</classpath>
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ import lua.StackState;
|
|||||||
import lua.addon.compile.LexState;
|
import lua.addon.compile.LexState;
|
||||||
import lua.debug.event.DebugEvent;
|
import lua.debug.event.DebugEvent;
|
||||||
import lua.debug.event.DebugEventBreakpoint;
|
import lua.debug.event.DebugEventBreakpoint;
|
||||||
|
import lua.debug.event.DebugEventError;
|
||||||
import lua.debug.event.DebugEventType;
|
import lua.debug.event.DebugEventType;
|
||||||
import lua.debug.request.DebugRequest;
|
import lua.debug.request.DebugRequest;
|
||||||
import lua.debug.request.DebugRequestLineBreakpointToggle;
|
import lua.debug.request.DebugRequestLineBreakpointToggle;
|
||||||
@@ -43,7 +44,6 @@ import lua.debug.response.DebugResponse;
|
|||||||
import lua.debug.response.DebugResponseCallgraph;
|
import lua.debug.response.DebugResponseCallgraph;
|
||||||
import lua.debug.response.DebugResponseSimple;
|
import lua.debug.response.DebugResponseSimple;
|
||||||
import lua.debug.response.DebugResponseStack;
|
import lua.debug.response.DebugResponseStack;
|
||||||
import lua.io.Closure;
|
|
||||||
import lua.io.LocVars;
|
import lua.io.LocVars;
|
||||||
import lua.io.Proto;
|
import lua.io.Proto;
|
||||||
import lua.value.LTable;
|
import lua.value.LTable;
|
||||||
@@ -51,15 +51,23 @@ import lua.value.LValue;
|
|||||||
|
|
||||||
public class DebugStackState extends StackState implements DebugRequestListener {
|
public class DebugStackState extends StackState implements DebugRequestListener {
|
||||||
|
|
||||||
private static final boolean DEBUG = false;
|
// stepping constants and stepping state
|
||||||
|
protected static final int STEP_NONE = 0;
|
||||||
|
protected static final int STEP_OVER = 1;
|
||||||
|
protected static final int STEP_INTO = 2;
|
||||||
|
protected static final int STEP_RETURN = 3;
|
||||||
|
protected int stepping = STEP_NONE;
|
||||||
|
protected boolean shouldPauseForStepping = false;
|
||||||
|
protected int steppingFrame = -1;
|
||||||
|
|
||||||
protected Hashtable breakpoints = new Hashtable();
|
protected Hashtable breakpoints = new Hashtable();
|
||||||
protected boolean exiting = false;
|
protected boolean exiting = false;
|
||||||
protected boolean suspended = false;
|
protected boolean suspended = false;
|
||||||
protected boolean stepping = false;
|
|
||||||
protected int lastline = -1;
|
protected int lastline = -1;
|
||||||
|
protected String lastSource;
|
||||||
protected DebugSupport debugSupport = null;
|
protected DebugSupport debugSupport = null;
|
||||||
|
|
||||||
|
|
||||||
public DebugStackState() {}
|
public DebugStackState() {}
|
||||||
|
|
||||||
public void setDebugSupport(DebugSupport debugSupport) throws IOException {
|
public void setDebugSupport(DebugSupport debugSupport) throws IOException {
|
||||||
@@ -104,7 +112,6 @@ public class DebugStackState extends StackState implements DebugRequestListener
|
|||||||
error(message, 1);
|
error(message, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void printLuaTrace() {
|
private void printLuaTrace() {
|
||||||
System.out.println( "Lua location: "+getFileLine(cc) );
|
System.out.println( "Lua location: "+getFileLine(cc) );
|
||||||
for ( int cindex=cc-1; cindex>=0; cindex-- )
|
for ( int cindex=cc-1; cindex>=0; cindex-- )
|
||||||
@@ -117,10 +124,15 @@ public class DebugStackState extends StackState implements DebugRequestListener
|
|||||||
super.exec();
|
super.exec();
|
||||||
} catch (AbortException e) {
|
} catch (AbortException e) {
|
||||||
// ignored. Client aborts the debugging session.
|
// ignored. Client aborts the debugging session.
|
||||||
}
|
} catch ( RuntimeException t ) {
|
||||||
// let other exceptions be processed
|
// let other exceptions be processed
|
||||||
// the same as the base class to minimize differences
|
// the same as the base class to minimize differences
|
||||||
// between the debug and non-debug behavior
|
// between the debug and non-debug behavior
|
||||||
|
|
||||||
|
debugSupport.notifyDebugEvent(new DebugEventError(t.getMessage()));
|
||||||
|
suspend();
|
||||||
|
throw t;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -131,41 +143,65 @@ public class DebugStackState extends StackState implements DebugRequestListener
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(DebugUtils.IS_DEBUG)
|
if(DebugUtils.IS_DEBUG)
|
||||||
DebugUtils.println("entered debugHook...");
|
DebugUtils.println("entered debugHook on pc=" + pc + "...");
|
||||||
|
|
||||||
synchronized ( this ) {
|
synchronized ( this ) {
|
||||||
|
CallInfo currentCallInfo = calls[cc];
|
||||||
|
Proto currentProto = currentCallInfo.closure.p;
|
||||||
|
|
||||||
// anytime the line doesn't change we keep going
|
// if we are not stepping, we keep going if the line doesn't change
|
||||||
int line = getLineNumber(calls[cc]);
|
int line = getLineNumber(currentCallInfo);
|
||||||
if ( !stepping && lastline == line ) {
|
String source = DebugUtils.getSourceFileName(currentProto.source);
|
||||||
|
if ( !isStepping() && lastline == line && source.equals(lastSource) ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(DebugUtils.IS_DEBUG)
|
if(DebugUtils.IS_DEBUG)
|
||||||
DebugUtils.println("debugHook - executing line: " + line);
|
DebugUtils.println("debugHook - executing line: " + line);
|
||||||
|
|
||||||
|
int i = currentProto.code[pc];
|
||||||
|
int opCode = StackState.GET_OPCODE(i);
|
||||||
|
if (isStepping() &&
|
||||||
|
opCode == StackState.OP_RETURN && cc == 0) {
|
||||||
|
cancelStepping();
|
||||||
|
} else if (shouldPauseForStepping) {
|
||||||
|
shouldPauseForStepping = false;
|
||||||
|
suspendOnStepping();
|
||||||
|
} else if ( stepping == STEP_INTO ) {
|
||||||
|
if (lastline != line){
|
||||||
|
suspendOnStepping();
|
||||||
|
} else if (opCode == StackState.OP_CALL) {
|
||||||
|
shouldPauseForStepping = true;
|
||||||
|
}
|
||||||
|
} else if (stepping == STEP_OVER) {
|
||||||
|
if ((lastline != line && steppingFrame == cc) || (steppingFrame > cc)) {
|
||||||
|
suspendOnStepping();
|
||||||
|
}
|
||||||
|
} else if (stepping == STEP_RETURN) {
|
||||||
|
if ((opCode == StackState.OP_RETURN && cc == this.steppingFrame) ||
|
||||||
|
(opCode == StackState.OP_TAILCALL && cc == this.steppingFrame)){
|
||||||
|
shouldPauseForStepping = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// check for a break point if we aren't suspended already
|
||||||
|
if ( !suspended && lastline != line) {
|
||||||
|
if (DebugUtils.IS_DEBUG)
|
||||||
|
DebugUtils.println("Source: " + currentProto.source);
|
||||||
|
|
||||||
|
String breakpointKey = constructBreakpointKey(source, line);
|
||||||
|
if (breakpoints.containsKey(breakpointKey)){
|
||||||
|
if(DebugUtils.IS_DEBUG)
|
||||||
|
DebugUtils.println("hitting breakpoint " + constructBreakpointKey(source, line));
|
||||||
|
|
||||||
|
debugSupport.notifyDebugEvent(new DebugEventBreakpoint(source, line));
|
||||||
|
suspended = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// save line in case next op is a step
|
// save line in case next op is a step
|
||||||
lastline = line;
|
lastline = line;
|
||||||
|
lastSource = source;
|
||||||
if ( stepping ) {
|
|
||||||
DebugUtils.println("suspended by stepping at pc=" + pc);
|
|
||||||
//TODO: notifyDebugEventListeners(new DebugEventStepping());
|
|
||||||
suspended = true;
|
|
||||||
} else if ( !suspended ) {
|
|
||||||
// check for a break point if we aren't suspended already
|
|
||||||
Proto p = calls[cc].closure.p;
|
|
||||||
String source = DebugUtils.getSourceFileName(p.source);
|
|
||||||
if ( breakpoints.containsKey(constructBreakpointKey(source, line))){
|
|
||||||
if(DebugUtils.IS_DEBUG) {
|
|
||||||
DebugUtils.println("hitting breakpoint " + constructBreakpointKey(source, line));
|
|
||||||
}
|
|
||||||
if (debugSupport != null) {
|
|
||||||
debugSupport.notifyDebugEvent(new DebugEventBreakpoint(source, line));
|
|
||||||
}
|
|
||||||
suspended = true;
|
|
||||||
} else {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// wait for a state change
|
// wait for a state change
|
||||||
while (suspended && !exiting ) {
|
while (suspended && !exiting ) {
|
||||||
@@ -180,6 +216,23 @@ public class DebugStackState extends StackState implements DebugRequestListener
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isStepping() {
|
||||||
|
return stepping != STEP_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void cancelStepping() {
|
||||||
|
debugSupport.notifyDebugEvent(new DebugEvent(DebugEventType.resumedOnSteppingEnd));
|
||||||
|
stepping = STEP_NONE;
|
||||||
|
steppingFrame = -1;
|
||||||
|
shouldPauseForStepping = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void suspendOnStepping() {
|
||||||
|
debugSupport.notifyDebugEvent(new DebugEvent(DebugEventType.suspendedOnStepping));
|
||||||
|
suspended = true;
|
||||||
|
steppingFrame = -1;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the current line number
|
* Get the current line number
|
||||||
* @param pc program counter
|
* @param pc program counter
|
||||||
@@ -199,7 +252,9 @@ public class DebugStackState extends StackState implements DebugRequestListener
|
|||||||
throw new IllegalStateException("DebugStackState is not equiped with DebugSupport.");
|
throw new IllegalStateException("DebugStackState is not equiped with DebugSupport.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (DebugUtils.IS_DEBUG)
|
||||||
DebugUtils.println("DebugStackState is handling request: " + request.toString());
|
DebugUtils.println("DebugStackState is handling request: " + request.toString());
|
||||||
|
|
||||||
DebugRequestType requestType = request.getType();
|
DebugRequestType requestType = request.getType();
|
||||||
if (DebugRequestType.start == requestType) {
|
if (DebugRequestType.start == requestType) {
|
||||||
DebugEvent event = new DebugEvent(DebugEventType.started);
|
DebugEvent event = new DebugEvent(DebugEventType.started);
|
||||||
@@ -234,8 +289,20 @@ public class DebugStackState extends StackState implements DebugRequestListener
|
|||||||
DebugRequestStack stackRequest = (DebugRequestStack) request;
|
DebugRequestStack stackRequest = (DebugRequestStack) request;
|
||||||
int index = stackRequest.getIndex();
|
int index = stackRequest.getIndex();
|
||||||
return new DebugResponseStack(getStack(index));
|
return new DebugResponseStack(getStack(index));
|
||||||
} else if (DebugRequestType.step == requestType) {
|
} else if (DebugRequestType.stepInto == requestType) {
|
||||||
step();
|
DebugEvent event = new DebugEvent(DebugEventType.resumedOnSteppingInto);
|
||||||
|
debugSupport.notifyDebugEvent(event);
|
||||||
|
stepInto();
|
||||||
|
return DebugResponseSimple.SUCCESS;
|
||||||
|
} else if (DebugRequestType.stepOver == requestType) {
|
||||||
|
DebugEvent event = new DebugEvent(DebugEventType.resumedOnSteppingOver);
|
||||||
|
debugSupport.notifyDebugEvent(event);
|
||||||
|
stepOver();
|
||||||
|
return DebugResponseSimple.SUCCESS;
|
||||||
|
} else if (DebugRequestType.stepReturn == requestType) {
|
||||||
|
DebugEvent event = new DebugEvent(DebugEventType.resumedOnSteppingReturn);
|
||||||
|
debugSupport.notifyDebugEvent(event);
|
||||||
|
stepReturn();
|
||||||
return DebugResponseSimple.SUCCESS;
|
return DebugResponseSimple.SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -248,7 +315,7 @@ public class DebugStackState extends StackState implements DebugRequestListener
|
|||||||
public void suspend() {
|
public void suspend() {
|
||||||
synchronized ( this ) {
|
synchronized ( this ) {
|
||||||
suspended = true;
|
suspended = true;
|
||||||
stepping = false;
|
stepping = STEP_NONE;
|
||||||
lastline = -1;
|
lastline = -1;
|
||||||
this.notify();
|
this.notify();
|
||||||
}
|
}
|
||||||
@@ -260,7 +327,7 @@ public class DebugStackState extends StackState implements DebugRequestListener
|
|||||||
public void resume() {
|
public void resume() {
|
||||||
synchronized ( this ) {
|
synchronized ( this ) {
|
||||||
suspended = false;
|
suspended = false;
|
||||||
stepping = false;
|
stepping = STEP_NONE;
|
||||||
this.notify();
|
this.notify();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -278,7 +345,7 @@ public class DebugStackState extends StackState implements DebugRequestListener
|
|||||||
debugSupport.stop();
|
debugSupport.stop();
|
||||||
debugSupport = null;
|
debugSupport = null;
|
||||||
}
|
}
|
||||||
}, 300);
|
}, 500);
|
||||||
|
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
@@ -298,9 +365,14 @@ public class DebugStackState extends StackState implements DebugRequestListener
|
|||||||
* @param N the line to set the breakpoint at
|
* @param N the line to set the breakpoint at
|
||||||
*/
|
*/
|
||||||
public void setBreakpoint(String source, int lineNumber) {
|
public void setBreakpoint(String source, int lineNumber) {
|
||||||
|
if (DebugUtils.IS_DEBUG) {
|
||||||
|
DebugUtils.print("source: " + source + " line:" + lineNumber);
|
||||||
DebugUtils.println("adding breakpoint " + constructBreakpointKey(source, lineNumber));
|
DebugUtils.println("adding breakpoint " + constructBreakpointKey(source, lineNumber));
|
||||||
|
}
|
||||||
|
|
||||||
synchronized ( this ) {
|
synchronized ( this ) {
|
||||||
breakpoints.put(constructBreakpointKey(source, lineNumber), Boolean.TRUE );
|
String normalizedFileName = DebugUtils.getSourceFileName(source);
|
||||||
|
breakpoints.put(constructBreakpointKey(normalizedFileName, lineNumber), Boolean.TRUE );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -315,7 +387,8 @@ public class DebugStackState extends StackState implements DebugRequestListener
|
|||||||
if(DebugUtils.IS_DEBUG)
|
if(DebugUtils.IS_DEBUG)
|
||||||
DebugUtils.println("removing breakpoint " + constructBreakpointKey(source, lineNumber));
|
DebugUtils.println("removing breakpoint " + constructBreakpointKey(source, lineNumber));
|
||||||
synchronized ( this ) {
|
synchronized ( this ) {
|
||||||
breakpoints.remove(constructBreakpointKey(source, lineNumber));
|
String normalizedFileName = DebugUtils.getSourceFileName(source);
|
||||||
|
breakpoints.remove(constructBreakpointKey(normalizedFileName, lineNumber));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -364,8 +437,10 @@ public class DebugStackState extends StackState implements DebugRequestListener
|
|||||||
LValue value = stack[callInfo.base + i];
|
LValue value = stack[callInfo.base + i];
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
int type = value.luaGetType();
|
int type = value.luaGetType();
|
||||||
|
if (DebugUtils.IS_DEBUG)
|
||||||
DebugUtils.print("\tType: " + Lua.TYPE_NAMES[type]);
|
DebugUtils.print("\tType: " + Lua.TYPE_NAMES[type]);
|
||||||
if (type == Lua.LUA_TTABLE) {
|
if (type == Lua.LUA_TTABLE) {
|
||||||
|
if (DebugUtils.IS_DEBUG)
|
||||||
DebugUtils.println(" (selected)");
|
DebugUtils.println(" (selected)");
|
||||||
variables.addElement(
|
variables.addElement(
|
||||||
new TableVariable(localVariableCount++,
|
new TableVariable(localVariableCount++,
|
||||||
@@ -374,6 +449,7 @@ public class DebugStackState extends StackState implements DebugRequestListener
|
|||||||
(LTable) value));
|
(LTable) value));
|
||||||
} else if (type != Lua.LUA_TFUNCTION &&
|
} else if (type != Lua.LUA_TFUNCTION &&
|
||||||
type != LUA_TTHREAD) {
|
type != LUA_TTHREAD) {
|
||||||
|
if (DebugUtils.IS_DEBUG)
|
||||||
DebugUtils.println(" (selected)");
|
DebugUtils.println(" (selected)");
|
||||||
variables.addElement(
|
variables.addElement(
|
||||||
new Variable(localVariableCount++,
|
new Variable(localVariableCount++,
|
||||||
@@ -381,12 +457,15 @@ public class DebugStackState extends StackState implements DebugRequestListener
|
|||||||
type,
|
type,
|
||||||
value.toString()));
|
value.toString()));
|
||||||
} else {
|
} else {
|
||||||
|
if (DebugUtils.IS_DEBUG)
|
||||||
DebugUtils.println("");
|
DebugUtils.println("");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
if (DebugUtils.IS_DEBUG)
|
||||||
DebugUtils.println("");
|
DebugUtils.println("");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
if (DebugUtils.IS_DEBUG)
|
||||||
DebugUtils.println("");
|
DebugUtils.println("");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -400,12 +479,42 @@ public class DebugStackState extends StackState implements DebugRequestListener
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* single step forward (go to next statement)
|
* step over to next line
|
||||||
*/
|
*/
|
||||||
public void step() {
|
public void stepOver() {
|
||||||
|
synchronized ( this ) {
|
||||||
|
if (DebugUtils.IS_DEBUG)
|
||||||
|
DebugUtils.println("stepOver on cc=" + cc + "...");
|
||||||
|
|
||||||
|
suspended = false;
|
||||||
|
stepping = STEP_OVER;
|
||||||
|
steppingFrame = cc;
|
||||||
|
this.notify();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* step a single statement
|
||||||
|
*/
|
||||||
|
public void stepInto() {
|
||||||
synchronized ( this ) {
|
synchronized ( this ) {
|
||||||
suspended = false;
|
suspended = false;
|
||||||
stepping = true;
|
stepping = STEP_INTO;
|
||||||
|
this.notify();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return from the method call
|
||||||
|
*/
|
||||||
|
public void stepReturn() {
|
||||||
|
synchronized ( this ) {
|
||||||
|
if (DebugUtils.IS_DEBUG)
|
||||||
|
DebugUtils.println("stepReturn on cc=" + cc + "...");
|
||||||
|
|
||||||
|
suspended = false;
|
||||||
|
stepping = STEP_RETURN;
|
||||||
|
steppingFrame = cc;
|
||||||
this.notify();
|
this.notify();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,8 +44,10 @@ public class DebugSupport implements DebugRequestListener, DebugEventListener {
|
|||||||
this.vm = vm;
|
this.vm = vm;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void releaseServer() {
|
protected void dispose() {
|
||||||
DebugUtils.println("shutting down the debug server...");
|
if (DebugUtils.IS_DEBUG)
|
||||||
|
DebugUtils.println("releasing the networkig resources...");
|
||||||
|
|
||||||
if (requestReader != null) {
|
if (requestReader != null) {
|
||||||
try {
|
try {
|
||||||
requestReader.close();
|
requestReader.close();
|
||||||
@@ -83,11 +85,8 @@ public class DebugSupport implements DebugRequestListener, DebugEventListener {
|
|||||||
|
|
||||||
this.requestWatcherThread = new Thread(new Runnable() {
|
this.requestWatcherThread = new Thread(new Runnable() {
|
||||||
public void run() {
|
public void run() {
|
||||||
if (getState() != STOPPED) {
|
loopForRequests();
|
||||||
handleRequest();
|
cleanup();
|
||||||
} else {
|
|
||||||
releaseServer();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.requestWatcherThread.start();
|
this.requestWatcherThread.start();
|
||||||
@@ -104,11 +103,12 @@ public class DebugSupport implements DebugRequestListener, DebugEventListener {
|
|||||||
* @see lua.debug.j2se.DebugSupport#stop()
|
* @see lua.debug.j2se.DebugSupport#stop()
|
||||||
*/
|
*/
|
||||||
public synchronized void stop() {
|
public synchronized void stop() {
|
||||||
|
if (DebugUtils.IS_DEBUG)
|
||||||
DebugUtils.println("stopping the debug support...");
|
DebugUtils.println("stopping the debug support...");
|
||||||
this.state = STOPPED;
|
this.state = STOPPED;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void handleRequest() {
|
protected void loopForRequests() {
|
||||||
try {
|
try {
|
||||||
while (getState() != STOPPED) {
|
while (getState() != STOPPED) {
|
||||||
int size = requestReader.readInt();
|
int size = requestReader.readInt();
|
||||||
@@ -116,6 +116,7 @@ public class DebugSupport implements DebugRequestListener, DebugEventListener {
|
|||||||
requestReader.readFully(data);
|
requestReader.readFully(data);
|
||||||
DebugRequest request
|
DebugRequest request
|
||||||
= (DebugRequest) SerializationHelper.deserialize(data);
|
= (DebugRequest) SerializationHelper.deserialize(data);
|
||||||
|
if (DebugUtils.IS_DEBUG)
|
||||||
DebugUtils.println("SERVER receives request: " + request.toString());
|
DebugUtils.println("SERVER receives request: " + request.toString());
|
||||||
|
|
||||||
DebugResponse response = handleRequest(request);
|
DebugResponse response = handleRequest(request);
|
||||||
@@ -123,22 +124,21 @@ public class DebugSupport implements DebugRequestListener, DebugEventListener {
|
|||||||
requestWriter.writeInt(data.length);
|
requestWriter.writeInt(data.length);
|
||||||
requestWriter.write(data);
|
requestWriter.write(data);
|
||||||
requestWriter.flush();
|
requestWriter.flush();
|
||||||
|
if (DebugUtils.IS_DEBUG)
|
||||||
DebugUtils.println("SERVER sends response: " + response);
|
DebugUtils.println("SERVER sends response: " + response);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getState() == STOPPED) {
|
|
||||||
cleanup();
|
|
||||||
}
|
|
||||||
} catch (EOFException e) {
|
} catch (EOFException e) {
|
||||||
cleanup();
|
// expected during shutdown
|
||||||
} catch (IOException e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void cleanup() {
|
private void cleanup() {
|
||||||
|
if (DebugUtils.IS_DEBUG)
|
||||||
DebugUtils.println("SERVER terminated...");
|
DebugUtils.println("SERVER terminated...");
|
||||||
releaseServer();
|
|
||||||
|
dispose();
|
||||||
System.exit(0);
|
System.exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,7 +160,9 @@ public class DebugSupport implements DebugRequestListener, DebugEventListener {
|
|||||||
* @param event
|
* @param event
|
||||||
*/
|
*/
|
||||||
protected void sendEvent(DebugEvent event) {
|
protected void sendEvent(DebugEvent event) {
|
||||||
|
if (DebugUtils.IS_DEBUG)
|
||||||
DebugUtils.println("SERVER sending event: " + event.toString());
|
DebugUtils.println("SERVER sending event: " + event.toString());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
byte[] data = SerializationHelper.serialize(event);
|
byte[] data = SerializationHelper.serialize(event);
|
||||||
eventWriter.writeInt(data.length);
|
eventWriter.writeInt(data.length);
|
||||||
|
|||||||
@@ -41,12 +41,12 @@ public class DebugUtils {
|
|||||||
|
|
||||||
public static String getSourceFileName(LString source) {
|
public static String getSourceFileName(LString source) {
|
||||||
String sourceStr = LoadState.getSourceName(source.toJavaString());
|
String sourceStr = LoadState.getSourceName(source.toJavaString());
|
||||||
|
return getSourceFileName(sourceStr);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getSourceFileName(String sourceStr) {
|
||||||
if (!LoadState.SOURCE_BINARY_STRING.equals(sourceStr)) {
|
if (!LoadState.SOURCE_BINARY_STRING.equals(sourceStr)) {
|
||||||
sourceStr = sourceStr.replace('\\', '/');
|
sourceStr = sourceStr.replace('\\', '/');
|
||||||
int index = sourceStr.lastIndexOf('/');
|
|
||||||
if (index != -1) {
|
|
||||||
sourceStr = sourceStr.substring(index + 1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return sourceStr;
|
return sourceStr;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import java.io.IOException;
|
|||||||
|
|
||||||
import lua.debug.event.DebugEvent;
|
import lua.debug.event.DebugEvent;
|
||||||
import lua.debug.event.DebugEventBreakpoint;
|
import lua.debug.event.DebugEventBreakpoint;
|
||||||
|
import lua.debug.event.DebugEventError;
|
||||||
import lua.debug.event.DebugEventType;
|
import lua.debug.event.DebugEventType;
|
||||||
import lua.debug.request.DebugRequest;
|
import lua.debug.request.DebugRequest;
|
||||||
import lua.debug.request.DebugRequestLineBreakpointToggle;
|
import lua.debug.request.DebugRequestLineBreakpointToggle;
|
||||||
@@ -60,6 +61,7 @@ public class SerializationHelper {
|
|||||||
static final int SERIAL_TYPE_DebugEventType = 11;
|
static final int SERIAL_TYPE_DebugEventType = 11;
|
||||||
static final int SERIAL_TYPE_DebugEvent = 12;
|
static final int SERIAL_TYPE_DebugEvent = 12;
|
||||||
static final int SERIAL_TYPE_DebugEventBreakpoint = 13;
|
static final int SERIAL_TYPE_DebugEventBreakpoint = 13;
|
||||||
|
static final int SERIAL_TYPE_DebugEventError = 14;
|
||||||
|
|
||||||
public static void serialize(Serializable object, DataOutputStream dout)
|
public static void serialize(Serializable object, DataOutputStream dout)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
@@ -102,6 +104,9 @@ public class SerializationHelper {
|
|||||||
} else if (object instanceof DebugEventBreakpoint) {
|
} else if (object instanceof DebugEventBreakpoint) {
|
||||||
dout.writeInt(SERIAL_TYPE_DebugEventBreakpoint);
|
dout.writeInt(SERIAL_TYPE_DebugEventBreakpoint);
|
||||||
DebugEventBreakpoint.serialize(dout, (DebugEventBreakpoint)object);
|
DebugEventBreakpoint.serialize(dout, (DebugEventBreakpoint)object);
|
||||||
|
} else if (object instanceof DebugEventError) {
|
||||||
|
dout.writeInt(SERIAL_TYPE_DebugEventError);
|
||||||
|
DebugEventError.serialize(dout, (DebugEventError)object);
|
||||||
} else if (object instanceof DebugEvent) {
|
} else if (object instanceof DebugEvent) {
|
||||||
dout.writeInt(SERIAL_TYPE_DebugEvent);
|
dout.writeInt(SERIAL_TYPE_DebugEvent);
|
||||||
DebugEvent.serialize(dout, (DebugEvent)object);
|
DebugEvent.serialize(dout, (DebugEvent)object);
|
||||||
@@ -155,6 +160,9 @@ public class SerializationHelper {
|
|||||||
case SERIAL_TYPE_DebugEventBreakpoint:
|
case SERIAL_TYPE_DebugEventBreakpoint:
|
||||||
object = DebugEventBreakpoint.deserialize(din);
|
object = DebugEventBreakpoint.deserialize(din);
|
||||||
break;
|
break;
|
||||||
|
case SERIAL_TYPE_DebugEventError:
|
||||||
|
object = DebugEventError.deserialize(din);
|
||||||
|
break;
|
||||||
case SERIAL_TYPE_DebugEvent:
|
case SERIAL_TYPE_DebugEvent:
|
||||||
object = DebugEvent.deserialize(din);
|
object = DebugEvent.deserialize(din);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -46,12 +46,11 @@ public class DebugEventError extends DebugEvent {
|
|||||||
|
|
||||||
public static void serialize(DataOutputStream out, DebugEventError object)
|
public static void serialize(DataOutputStream out, DebugEventError object)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
//TODO implement
|
out.writeUTF(object.getDetail());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static DebugEvent deserialize(DataInputStream in)
|
public static DebugEvent deserialize(DataInputStream in) throws IOException {
|
||||||
throws IOException {
|
String detail = in.readUTF();
|
||||||
//TODO implement
|
return new DebugEventError(detail);
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,10 +35,13 @@ public class DebugEventType extends EnumType {
|
|||||||
public static DebugEventType suspendedOnStepping = new DebugEventType("suspendedOnStepping", 4);
|
public static DebugEventType suspendedOnStepping = new DebugEventType("suspendedOnStepping", 4);
|
||||||
public static DebugEventType suspendedOnError = new DebugEventType("suspendedOnError", 5);
|
public static DebugEventType suspendedOnError = new DebugEventType("suspendedOnError", 5);
|
||||||
public static DebugEventType resumedByClient = new DebugEventType("resumedByClient", 6);
|
public static DebugEventType resumedByClient = new DebugEventType("resumedByClient", 6);
|
||||||
public static DebugEventType resumedOnStepping = new DebugEventType("resumedOnStepping", 7);
|
public static DebugEventType resumedOnSteppingInto = new DebugEventType("resumedOnSteppingInto", 7);
|
||||||
public static DebugEventType resumedOnError = new DebugEventType("resumedOnError", 8);
|
public static DebugEventType resumedOnSteppingOver = new DebugEventType("resumedOnSteppingOver", 8);
|
||||||
public static DebugEventType error = new DebugEventType("error", 9);
|
public static DebugEventType resumedOnSteppingReturn = new DebugEventType("resumedOnSteppingReturn", 9);
|
||||||
public static DebugEventType terminated = new DebugEventType("terminated", 10);
|
public static DebugEventType resumedOnSteppingEnd = new DebugEventType("resumedOnSteppingEnd", 10);
|
||||||
|
public static DebugEventType resumedOnError = new DebugEventType("resumedOnError", 11);
|
||||||
|
public static DebugEventType error = new DebugEventType("error", 12);
|
||||||
|
public static DebugEventType terminated = new DebugEventType("terminated", 13);
|
||||||
|
|
||||||
protected static DebugEventType[] ENUMS = new DebugEventType[] {
|
protected static DebugEventType[] ENUMS = new DebugEventType[] {
|
||||||
started,
|
started,
|
||||||
@@ -48,7 +51,10 @@ public class DebugEventType extends EnumType {
|
|||||||
suspendedOnStepping,
|
suspendedOnStepping,
|
||||||
suspendedOnError,
|
suspendedOnError,
|
||||||
resumedByClient,
|
resumedByClient,
|
||||||
resumedOnStepping,
|
resumedOnSteppingInto,
|
||||||
|
resumedOnSteppingOver,
|
||||||
|
resumedOnSteppingReturn,
|
||||||
|
resumedOnSteppingEnd,
|
||||||
resumedOnError,
|
resumedOnError,
|
||||||
error,
|
error,
|
||||||
terminated
|
terminated
|
||||||
@@ -62,7 +68,7 @@ public class DebugEventType extends EnumType {
|
|||||||
throws IOException {
|
throws IOException {
|
||||||
int ordinal = in.readInt();
|
int ordinal = in.readInt();
|
||||||
if (ordinal < 0 || ordinal >= ENUMS.length) {
|
if (ordinal < 0 || ordinal >= ENUMS.length) {
|
||||||
throw new RuntimeException("ordinal is out of the range.");
|
throw new RuntimeException("DebugEventType: ordinal is out of the range.");
|
||||||
}
|
}
|
||||||
return ENUMS[ordinal];
|
return ENUMS[ordinal];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import javax.microedition.io.ServerSocketConnection;
|
|||||||
import javax.microedition.io.SocketConnection;
|
import javax.microedition.io.SocketConnection;
|
||||||
|
|
||||||
import lua.debug.DebugSupport;
|
import lua.debug.DebugSupport;
|
||||||
import lua.debug.DebugUtils;
|
|
||||||
import lua.debug.event.DebugEvent;
|
import lua.debug.event.DebugEvent;
|
||||||
|
|
||||||
public class DebugSupportImpl extends DebugSupport {
|
public class DebugSupportImpl extends DebugSupport {
|
||||||
@@ -56,8 +55,8 @@ public class DebugSupportImpl extends DebugSupport {
|
|||||||
super.start();
|
super.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void releaseServer() {
|
protected void dispose() {
|
||||||
super.releaseServer();
|
super.dispose();
|
||||||
|
|
||||||
if (requestSocketConnection != null) {
|
if (requestSocketConnection != null) {
|
||||||
try {
|
try {
|
||||||
@@ -84,9 +83,9 @@ public class DebugSupportImpl extends DebugSupport {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void handleRequest() {
|
protected void loopForRequests() {
|
||||||
synchronized (requestSocketConnection) {
|
synchronized (requestSocketConnection) {
|
||||||
super.handleRequest();
|
super.loopForRequests();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ import java.net.ServerSocket;
|
|||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
|
|
||||||
import lua.debug.DebugSupport;
|
import lua.debug.DebugSupport;
|
||||||
import lua.debug.DebugUtils;
|
|
||||||
import lua.debug.event.DebugEvent;
|
import lua.debug.event.DebugEvent;
|
||||||
|
|
||||||
public class DebugSupportImpl extends DebugSupport {
|
public class DebugSupportImpl extends DebugSupport {
|
||||||
@@ -61,8 +60,8 @@ public class DebugSupportImpl extends DebugSupport {
|
|||||||
super.start();
|
super.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void releaseServer() {
|
protected void dispose() {
|
||||||
super.releaseServer();
|
super.dispose();
|
||||||
|
|
||||||
if (clientRequestSocket != null) {
|
if (clientRequestSocket != null) {
|
||||||
try {
|
try {
|
||||||
@@ -89,9 +88,9 @@ public class DebugSupportImpl extends DebugSupport {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void handleRequest() {
|
protected void loopForRequests() {
|
||||||
synchronized (clientRequestSocket) {
|
synchronized (clientRequestSocket) {
|
||||||
super.handleRequest();
|
super.loopForRequests();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,21 +28,24 @@ import lua.debug.EnumType;
|
|||||||
|
|
||||||
|
|
||||||
public class DebugRequestType extends EnumType {
|
public class DebugRequestType extends EnumType {
|
||||||
public static final DebugRequestType suspend = new DebugRequestType("suspend", 0);
|
public static final DebugRequestType start = new DebugRequestType("start", 0);
|
||||||
public static final DebugRequestType resume = new DebugRequestType("resume", 1);
|
public static final DebugRequestType resume = new DebugRequestType("resume", 1);
|
||||||
public static final DebugRequestType exit = new DebugRequestType("exit", 2);
|
public static final DebugRequestType suspend = new DebugRequestType("suspend", 2);
|
||||||
public static final DebugRequestType lineBreakpointSet = new DebugRequestType("lineBreakpointSet", 3);
|
public static final DebugRequestType exit = new DebugRequestType("exit", 3);
|
||||||
public static final DebugRequestType lineBreakpointClear = new DebugRequestType("lineBreakpointClear", 4);
|
public static final DebugRequestType lineBreakpointSet = new DebugRequestType("lineBreakpointSet", 4);
|
||||||
public static final DebugRequestType watchpointSet = new DebugRequestType("watchpointSet", 5);
|
public static final DebugRequestType lineBreakpointClear = new DebugRequestType("lineBreakpointClear", 5);
|
||||||
public static final DebugRequestType watchpointClear = new DebugRequestType("watchpointClear", 6);
|
public static final DebugRequestType watchpointSet = new DebugRequestType("watchpointSet", 6);
|
||||||
public static final DebugRequestType callgraph = new DebugRequestType("callgraph", 7);
|
public static final DebugRequestType watchpointClear = new DebugRequestType("watchpointClear", 7);
|
||||||
public static final DebugRequestType stack = new DebugRequestType("stack", 8);
|
public static final DebugRequestType callgraph = new DebugRequestType("callgraph", 8);
|
||||||
public static final DebugRequestType step = new DebugRequestType("step", 9);
|
public static final DebugRequestType stack = new DebugRequestType("stack", 9);
|
||||||
public static final DebugRequestType start = new DebugRequestType("start", 10);
|
public static final DebugRequestType stepInto = new DebugRequestType("stepInto", 10);
|
||||||
|
public static final DebugRequestType stepOver = new DebugRequestType("stepOver", 11);
|
||||||
|
public static final DebugRequestType stepReturn = new DebugRequestType("stepReturn", 12);
|
||||||
|
|
||||||
protected static final DebugRequestType[] ENUMS = new DebugRequestType[] {
|
protected static final DebugRequestType[] ENUMS = new DebugRequestType[] {
|
||||||
suspend,
|
start,
|
||||||
resume,
|
resume,
|
||||||
|
suspend,
|
||||||
exit,
|
exit,
|
||||||
lineBreakpointSet,
|
lineBreakpointSet,
|
||||||
lineBreakpointClear,
|
lineBreakpointClear,
|
||||||
@@ -50,8 +53,9 @@ public class DebugRequestType extends EnumType {
|
|||||||
watchpointClear,
|
watchpointClear,
|
||||||
callgraph,
|
callgraph,
|
||||||
stack,
|
stack,
|
||||||
step,
|
stepInto,
|
||||||
start
|
stepOver,
|
||||||
|
stepReturn
|
||||||
};
|
};
|
||||||
|
|
||||||
public DebugRequestType(String name, int ordinal) {
|
public DebugRequestType(String name, int ordinal) {
|
||||||
@@ -61,7 +65,7 @@ public class DebugRequestType extends EnumType {
|
|||||||
public static DebugRequestType deserialize(DataInputStream in) throws IOException {
|
public static DebugRequestType deserialize(DataInputStream in) throws IOException {
|
||||||
int ordinal = in.readInt();
|
int ordinal = in.readInt();
|
||||||
if (ordinal < 0 || ordinal >= ENUMS.length) {
|
if (ordinal < 0 || ordinal >= ENUMS.length) {
|
||||||
throw new RuntimeException("ordinal is out of the range.");
|
throw new RuntimeException("DebugRequestType: ordinal is out of the range.");
|
||||||
}
|
}
|
||||||
return ENUMS[ordinal];
|
return ENUMS[ordinal];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ public class DebugStackStateTest extends TestCase {
|
|||||||
|
|
||||||
// step for 5 steps
|
// step for 5 steps
|
||||||
for ( int i=0; i<5; i++ ) {
|
for ( int i=0; i<5; i++ ) {
|
||||||
state.step();
|
state.stepOver();
|
||||||
Thread.sleep(500);
|
Thread.sleep(500);
|
||||||
System.out.println("--- callgraph="+state.getCallgraph() );
|
System.out.println("--- callgraph="+state.getCallgraph() );
|
||||||
System.out.println("--- stack="+state.getStack(0) );
|
System.out.println("--- stack="+state.getStack(0) );
|
||||||
|
|||||||
Reference in New Issue
Block a user