Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 337183

Summary: (Remote Rhino) ArrayIndexOutOfBoundsException when stepping into a function that was moved since setting the breakpint
Product: [WebTools] JSDT Reporter: Enrico Magen <enricomagen>
Component: DebugAssignee: Michael Rennie <Michael_Rennie>
Status: RESOLVED FIXED QA Contact: Michael Rennie <Michael_Rennie>
Severity: major    
Priority: P1 CC: david_williams, enricomagen, simon_kaegi, thatnitind
Version: 3.3   
Target Milestone: 3.3 M6   
Hardware: PC   
OS: Windows 7   
Whiteboard:
Attachments:
Description Flags
proposed fix none

Description Enrico Magen CLA 2011-02-15 02:31:49 EST
Build Identifier: 20100917-0705

When debugging a remote JavaScript invocation that's being run using Rhino. Debugging using the Rhino attaching connector.
If you set a breakpoint in a script, then change the script and have the server update to these changes. the debugging process has problem as described in the steps to reproduce.

Reproducible: Always

Steps to Reproduce:
1. Compile a script on a server running with a rhino debugger attached to the context. Have it compiled so that the client recognizes the source.
2. Connect to remote rhino debugger.
3. In Eclipse, set a breakpoint in a line that contains an invocation of another function. (see script under these steps with (bp))
4. Have the server run goo(). When stopping on the BP try "step into" – see that it works fine.
5. Add 10-15 lines between the breakpoint and the called function (you can fill them with comments)
6. Have the server compile the new script under the same script name.
7. Have the server run goo() again.
8. When stopping on the BP try stepping into foo() again. -> results in ArrayIndexOutOfBoundsException: x (Where x is the line where foo was moved to.)

My guess is that since foo() moved since the breakpoint was set, it causes a lot of problems.

function goo() {
      var d = 1;
      var c = 2;
  (bp)return foo();
}

function foo() {
      return “something”;
}
Comment 1 Michael Rennie CLA 2011-02-15 10:24:15 EST
(In reply to comment #0)

> 8. When stopping on the BP try stepping into foo() again. -> results in
> ArrayIndexOutOfBoundsException: x (Where x is the line where foo was moved to.)

Can you attach the exception trace from your log (the error log or your workspace .log file)?
Comment 2 Enrico Magen CLA 2011-02-15 10:26:57 EST
Actually the exception is thrown from the debugger running on the server, not in the client. This is my server's log.

java.lang.ArrayIndexOutOfBoundsException: 100
	at org.eclipse.wst.jsdt.debug.internal.rhino.debugger.ScriptSource.getBreakpoint(ScriptSource.java:304)
	at org.eclipse.wst.jsdt.debug.internal.rhino.debugger.ContextData.pushFrame(ContextData.java:106)
	at org.eclipse.wst.jsdt.debug.internal.rhino.debugger.StackFrame.onEnter(StackFrame.java:122)
	at org.mozilla.javascript.Interpreter.enterFrame(Interpreter.java:4478)
	at org.mozilla.javascript.Interpreter.initFrame(Interpreter.java:4433)
	at org.mozilla.javascript.Interpreter.interpretLoop(Interpreter.java:3255)
	at org.mozilla.javascript.Interpreter.interpret(Interpreter.java:2487)
	at org.mozilla.javascript.InterpretedFunction.call(InterpretedFunction.java:164)
	at org.mozilla.javascript.ContextFactory.doTopCall(ContextFactory.java:398)
	at org.mozilla.javascript.ScriptRuntime.doTopCall(ScriptRuntime.java:3065)
	at org.mozilla.javascript.InterpretedFunction.call(InterpretedFunction.java:162)
	at com.worklight.integration.js.JavaScriptManager.callFunction(JavaScriptManager.java:157)
	....

The rest of the stack trace is WorkLight classes.
Comment 3 Enrico Magen CLA 2011-02-15 10:50:50 EST
Here's a scenario that's easier to reproduce, without breakpoints:

0. Make sure your ContextFactory has a debugger listener attached.

1. compile the following script with script name 'x':

function goo() {
    var v = foo();
    return v;
}

function foo(){
	return "something---------------";
}

2. run it on the server.
3. without restarting the server / stopping the debugger compile the following script:

function goo() {
    var v = foo();
    return v;
}

// comment 1
// comment 2
// comment 3
// comment 4
function foo(){
	return "something---------------";
}

4. run the script again. This is my server's output when I run the script again:

java.lang.ArrayIndexOutOfBoundsException: 23
	at org.eclipse.wst.jsdt.debug.internal.rhino.debugger.ScriptSource.getBreakpoint(ScriptSource.java:304)
	at org.eclipse.wst.jsdt.debug.internal.rhino.debugger.ContextData.pushFrame(ContextData.java:106)
	at org.eclipse.wst.jsdt.debug.internal.rhino.debugger.StackFrame.onEnter(StackFrame.java:122)
	at org.mozilla.javascript.Interpreter.enterFrame(Interpreter.java:4478)
	at org.mozilla.javascript.Interpreter.initFrame(Interpreter.java:4433)
	at org.mozilla.javascript.Interpreter.interpretLoop(Interpreter.java:3255)
	at org.mozilla.javascript.Interpreter.interpret(Interpreter.java:2487)
	at org.mozilla.javascript.InterpretedFunction.call(InterpretedFunction.java:164)
	at org.mozilla.javascript.ContextFactory.doTopCall(ContextFactory.java:398)
	at org.mozilla.javascript.ScriptRuntime.doTopCall(ScriptRuntime.java:3065)
	at org.mozilla.javascript.InterpretedFunction.call(InterpretedFunction.java:162)
	at com.worklight.integration.js.JavaScriptManager.callFunction(JavaScriptManager.java:157)
	...
Comment 4 Michael Rennie CLA 2011-02-15 11:31:30 EST
Thanks for the traces. 

The offending code is:

if(functionNames != null) {
 int index = functionNames.indexOf(functionName);
 FunctionSource func = functionAt(index);
 if(func != null && lines[func.linenumber()] != null) {
  return lines[func.linenumber()].breakpoint;
 }
}

but the underlying problem is that the source of a script is being swapped (via re-compilation) and we are not updating our local - debugger side, not client side - model properly

Upping the importance, it is quite common that scripts be re-compiled and if our model is failing to process these updates that is a major problem.
Comment 5 David Williams CLA 2011-02-23 12:56:39 EST
According to our conventions, is this bug really "critical"? (causing data loss, crashes?)  Or, perhaps "major"? (loss of function) 

See 
http://wiki.eclipse.org/WTP_Bugs%2C_Workflow_and_Conventions#Meaning_of_Priority_and_Severity

If it accurately categorized, that's fine, but 
I ask since we are getting ready to release 3.2.3 and want to be sure our standard bug queries look right. 

Thanks,
Comment 7 Michael Rennie CLA 2011-02-23 14:28:51 EST
(In reply to comment #5)
> According to our conventions, is this bug really "critical"? (causing data
> loss, crashes?)  Or, perhaps "major"? (loss of function) 
> 

As the Rhino debugger bundle is typically deployed to server to hook script loads, and appears to be completely ignoring script recompilation, I would say that is critical, but it can just as easily be major.

> I ask since we are getting ready to release 3.2.3 and want to be sure our
> standard bug queries look right. 

Ok, although this bug is not targeted for 3.2.x, unless I am missing the point of this sentence...
Comment 8 David Williams CLA 2011-02-23 16:08:25 EST
> 
> Ok, although this bug is not targeted for 3.2.x, unless I am missing the point
> of this sentence...

Basically, just making sure it shouldn't be. I'll assume only in 3.3.x stream. Thanks.
Comment 9 Enrico Magen CLA 2011-02-24 03:32:53 EST
It's a shame you won't fix this bug for 3.2.x. Here at WorkLight this bug is the only thing stopping our server side debugger feature from entering our next version. It's a very powerful feature made possible by your plugin and is completely disabled right now as the bug is listed as "critical" in our system...(for us critical means "feature not functional")

When is 3.3.x due?

Thanks.
Comment 10 Simon Kaegi CLA 2011-02-24 10:30:05 EST
> It's a shame you won't fix this bug for 3.2.x. Here at WorkLight this bug is
> the only thing stopping our server side debugger feature from entering our next
> version.

Enrico, if its critical to you would it be possible for you to start taking a look at fixing it. Even if contributing is a problem at your company if you could perform a relatively deep analysis of what's going on under the covers that would be tremendously helpful.

> 
> When is 3.3.x due?

June 2012 - the entire Eclipse release train ships once at the same time every year.
Comment 11 Michael Rennie CLA 2011-02-24 10:57:47 EST
(In reply to comment #10)
> > 
> > When is 3.3.x due?
> 
> June 2012 - the entire Eclipse release train ships once at the same time every
> year.

I think you meant June 2011.
Comment 12 Michael Rennie CLA 2011-02-24 15:25:02 EST
I think the fix to this is a lot simpler than it sounds. 

In bug 306832 we added the ability to clone a ScriptSource reference expressly for the purpose of not re-doing a pile of work in the re-compilation case. The problem seems to be in the ScriptSource#clone method, where we copy over the line table as well - we should not copy the line table, as this bug shows, it might not be the same after a re-compilation.
Comment 13 Michael Rennie CLA 2011-02-24 15:26:09 EST
Created attachment 189743 [details]
proposed fix

This patch prevents the line table from being copied over to the new script from the existing one.
Comment 14 Michael Rennie CLA 2011-02-25 15:07:10 EST
The fix for this bug has been applied with the fix for bug 328531