Retrieving javascript line index during execution

Feb 28, 2015 at 4:05 PM
Edited Feb 28, 2015 at 4:06 PM
Is it possible to get currently executing script line number without resorting to the debugger?
I would like to highlight certain lines whenever they are being executed. For example:
public class Test() {
    public void method1(string str){};
    public void method2(string str){};
}

var engine = new V8ScriptEngine(V8ScriptEngineFlags.EnableDebugging, port);
engine.AddHostObject("test", new Test());
engine.Execute("test_script", script_js);
script_js:
....
test.method1('foo');
....
test.method2('bar');
and I would like to retrieve the line number whenever the test.method1 or test.method2 is being executed (from within the host C# code).

What I have tried so far but without any success:
  1. V8ScriptEngine.getStackTrace() - Doesn't work since it essentially terminates the script execution.
  2. Adding
function getStackTrace(){ return new Error().stack; }
to the script and calling it from the host method e.g.
var st = (string)engine.Script.getStackTrace();
Doesn't work either. It seems to enter infinite recursive loop and just keeps calling the same host method over and over again.


Are there any other options available for V8ScriptEngine?
Coordinator
Feb 28, 2015 at 7:19 PM
Hello rovs,

The following test runs to completion without script termination or infinite recursion, and the output is exactly as expected:
public class Test {
    public ScriptEngine Engine { get; set; }
    public void Method1(int index) {
        Console.WriteLine("{0} {1}", index, Engine.GetStackTrace());
    }
    public void Method2(int index) {
        Console.WriteLine("{0} {1}", index, Engine.Script.getStackTrace());
    }
}
engine.AddHostObject("test", new Test { Engine = engine });
engine.Execute(@"
    function getStackTrace() { return new Error().stack; }
    for (var i = 0; i < 1000; i++) { test.Method1(i); }
    for (var i = 0; i < 1000; i++) { test.Method2(i); }
");
Is there something you're doing differently?

Thanks!
Mar 1, 2015 at 8:32 AM
Thank you!
Turns out the culprit was in some supporting code.
Both ScriptEngine.GetStackStrace() and JS method work as expected!
Mar 9, 2015 at 4:36 PM
Slight update in case anyone experiences same problem,

It turns out the problem wasn't in supporting code, but rather with the 5.4.0 version.

In 5.4.0 V8ScriptEngine.Script.getStackTrace() throws
RuntimeBinderException: 'Microsoft.ClearScript.V8.V8ScriptItem' does not contain a definition for 'EngineInternal'
In 5.4.1 it works properly. Something related to V8 debugging has changed in this version though so beware when upgrading (our custom debugger which was working fine on 5.4.0 doesn't work anymore)

P.S.
We are using assemblies from the ClearScript.Install NuGet package.
Coordinator
Mar 10, 2015 at 4:24 AM
Hi again,

In 5.4.0 V8ScriptEngine.Script.getStackTrace() throws
RuntimeBinderException: 'Microsoft.ClearScript.V8.V8ScriptItem' does not contain a definition for 'EngineInternal'

Actually exceptions like that are often thrown and handled internally during C# dynamic operations, with or without ClearScript's involvement. If you see an exception like that in the debugger, you should be able to continue safely.

Something related to V8 debugging has changed in this version though so beware when upgrading (our custom debugger which was working fine on 5.4.0 doesn't work anymore)

ClearScript 5.4.1 does have a new V8 debug agent. The old one was built into V8, but the V8 team removed it a while back. If you're encountering issues with the new one, we'd love to hear the details.

Thanks!
Mar 12, 2015 at 12:28 AM
Edited Mar 12, 2015 at 12:31 AM
Hi,

Could it be something has changed in the V8 debugging protocol in the new version?

We are having issues with setting breakpoints. In 5.4.1 V8 doesn't respond to any of setbreakpoint requests.

In v5.4.0 following request successfully sets a breakpoint
{"command":"setbreakpoint","arguments":{"type":"script","target":"myscript","line":1,"enabled":true},"seq":1,"type":"request"}"
response
{"seq":0,"request_seq":1,"type":"response","command":"setbreakpoint","success":true,"body":{"type":"scriptName","breakpoint":1,"script_name":"myscript","line":1,"column":null,"actual_locations":[]},"refs":[],"running":true}
All other commands such as continue, clearbreakpoint, etc work as well.

In v5.4.1 response never arrives for the above setbreakpoint request. I haven't had time yet to to test other commands nor debug it any further unfortunately.
The debugger itself seems to connect successfully though as I can see the welcome message with version info being sent back.
Coordinator
Mar 12, 2015 at 2:07 PM
Edited Mar 12, 2015 at 2:10 PM
Hello!

Hmm, we can't reproduce any issues setting breakpoints from Eclipse. Here's a sample from Eclipse's debugger network console:
> Sent to Chrome:
Content-Length:132

{"seq":7,"type":"request","command":"setbreakpoint","arguments":{"line":19,"column":0,"type":"scriptId","enabled":true,"target":58}}
> end of message

> Received from Chrome:
Content-Length:247

{"seq":7,"request_seq":7,"type":"response","command":"setbreakpoint","success":true,"body":{"type":"scriptId","breakpoint":1,"script_id":58,"line":19,"column":0,"actual_locations":[{"line":19,"column":36,"script_id":58}]},"refs":[],"running":true}
> end of message
ClearScript 5.4.1 is paired with a much newer V8 version (3.30 vs. 3.26. The removal of V8's built-in debug agent is the main reason why ClearScript was stuck using a relatively old version for a while. So while the protocol may have changed, perhaps inadvertently, it's more likely that there's some subtle difference between Eclipse's requests and yours.

Can you verify that the requests you're sending are well-formed and have correct content length headers?
Coordinator
Mar 18, 2015 at 2:02 PM
Hi again,

Is your project by any chance an ASP.NET web application? If so, you might be encountering this issue.

Thanks!