Debugging with ClearScript

ClearScript is an open source library for using javascript code in C# application. It provides a wrapper around V8 engine to make to-and-from call between javascript and C# code.

During development, one of the major challenge – which no developer can deny –  is debugging. If you are writing a C# or C++ code, Visual Studio comes as savior when it comes to debugging. However, debugging pure dynamic, interpreted languages like javascript is not that straight froward. In this post I will discuss how can we debug C# and javascript code together when ClearScript & V8 engine are in action. If you are new to ClearScript or using javascript within C# application, I would recommend you to read my previous post – ClearScript : Step-by-Step – before proceeding further. This post is built on code example provided in the previous post.

Debugging With ClearScript & V8 :

V8 engine by design doesn’t support script debugging. However, it does support TCP/IP based debugging protocol. Any IDE that supports TCP/IP based debugging protocol can be used. One of the most convenient and easy way to debug the javascript V8 engine is using Eclipse. In this article we will use Eclipse IDE for javascript and Visual Studio for C# debugging.

So lets begin with following steps:

1. Install Eclipse : Get it from http://www.eclipse.org/downloads/ if you do not have it already.

2. Next we need a tool / plugin which supports V8 engine TCP/IP based debugging protocol. Google Chrome Developer Tools come handy for this purpose. So lets get the tool in eclipse by following below steps:

  •    Start Eclipse and go to “Help” -> “Install New Software…”.
  •    Paste the URL – http://chromedevtools.googlecode.com/svn/update/dev/ – into the “Work with:” field.
  •    Select “Google Chrome Developer Tools” and complete the dialog.Chrome Dev Tool
  •    Re-launch Eclipse.

3. In C# code, while creating the instance of V8Engine, set the debugging flag on.


//Create V8Engine with debugging flag enabled
V8ScriptEngine _v8Engine = new V8ScriptEngine( V8ScriptEngineFlags.EnableDebugging);

This enables the V8 engine TCP/IP- based debugging and initializes the debugging at default port number 9222. The application can choose a port by providing it in constructor as follows:


//Create V8Engine with custom debugging port number
int debugPort = 8888;

V8ScriptEngine _v8Engine = new V8ScriptEngine( V8ScriptEngineFlags.EnableDebugging, debugPort);

4. Start the C# application in debugging mode ( attached with Visual Studio ). Within visual studio, you can continue with your C# code debugging as usual. Once your C# code initializes the V8 engine, loads the javascript and also does the basic setup of call backs etc, switch to Eclipse IDE. For example, in previous post put a break point at HelloWorld call in C# Main method and execute until there in Visual Studio. At this point V8 engine is initialized and started with TCP/IP debugging enabled on port 9222. Also, it has the javascript content loaded from HelloWorld.js file and callback to C# registered.

5. In Eclipse, go to “Run” menu and select “Debug Configuration” option.
DebugConfiguration

6. Right Click on “Standalone V8 VM” and select “New” option.

7. In the screen, choose a configuration name ( e.g, DemoDebugConfiguration). Leave the port number as 9222 if you application has started with default TCP/IP debugging port number while creating V8Engine, otherwise provide the correct port number.

DebugConfigurationDetails

8. Click “Apply” followed by “Debug”.

This will add a new item in your project explorer with name DemoDebugConfiguration. Expand the item and you will see a couple of files with names “Script Document.chromium” etc. Each file contain the javascript snippet active with loaded V8 engine.

ScriptDocuments

Now, open any of the files and add break points to the places in code which you want to monitor during debug. Switch back to Visual Studio and resume debugging. Eclipse will automatically prompt when a break point in javascript code is hit.

DebugEclipse

At this point you can continue to debug in Eclipse and Visual Studio will automatically prompt if a call from javascript will hit a break point in C# code.

This way you can continue to switch between Visual Studio and Eclipse and keep a watch on whats happening with your C# and javascript code together.

 

ClearScript : Step-by-Step

Today, no big application goes through programming language monopoly. For some time, in recent past, C# programmers were mainly challenged with C++ native or COM interop. With Javascript becoming one of the most popular languages for both on UI and server side ( thanks to Angular JS & NodeJS respectively ), every C# developer will be facing C#-Javascript interop sooner or later.

I am sure there are more than one javascript library to achieve C# to javascript interop, but in this post I will focus on ClearScript mainly because :

  • It has Microsoft support ( officially or unofficially )
  • Small but active developer group contributing to CodePlex project.
  • It has simple syntax and returns strongly typed objects to C#.

This post will provide a basic guidance on :

  • Things you need before using ClearScript
  • Things to do before using ClearScript
  • Code to call javascript from C# and vice-versa

Pre-requisite :

Before we jump-in to code and start having fun with C# and JavaScript lets do some house keeping. Make sure we have the following in place:

  • Windows 7 or higher OS
  • Visual Studio 2012 or higher.
  • Internet Connectivity.
  • Willingness to try out.

Great! Now we are ready to get ClearScript and V8 engine. And yes, we are going to get the source code and build it on our own. ( Magic of open source in action now! )

 Be in self service mode:

1. Open your favorite browser and navigate to https://clearscript.codeplex.com/SourceControl/latest .

2. Download the latest source code by clicking on “download” link.

3. The download is a zip file. Extract the complete content in a directory ( e.g. C:\ClearScript ).

At this point you have ClearScript source code available within C:\ClearScript directory.

In the next steps we will be building the clearscript dlls which will be used in our C# application. ClearScript supports javascript via V8 and JScript. So lets get V8 engine now. To do this, install Subversion (http://subversion.apache.org/packages.html) and add it to your executable path. I recommend SlikSvn in the list.

Now you are just one step away before the magic begins.

Fire your visual studio developer command prompt and navigate to C:\ClearScript directory.

Run “V8Update.cmd Release” on command propmt. This command may take some time as it downloads around 2 GB of data from internet and builds V8 engine binaries.

Now we are ready to build ClearScript libraries. Open the ClearScript solution in Visual Studio.

NOTE: The first time you open the solution, Visual Studio may prompt you to upgrade one or more projects to the latest platform toolset or .NET Framework. Select “Cancel” or “Don’t Upgrade”.

Build the solution and we have all the binaries available at location – C:\ClearScript\bin\Debug .

 The Fun Begins:

If you have reached till here, I am sure you are serious about ClearScript. Boring things over, lets have some fun with C# and JavaScript now.

Lets write a simple C# code that will make a call in javascript file to call a HelloWorld function. This function will in turn call another method to print this message on console. At this time we will make C# hook in and actually process the console message in C# code. So this is what we are going to do :

C# [ call javascript HelloWorld] -> javascript [ call another javascript function SayHello] -> C# [ out put the message from SayHello ]

This will complete C# to javascript to C# call interop using ClearScript.

1. Create a C# console application in your visual studio.

2. Add a reference to clearscript.dll and clearscriptv8-32.dll you built in previous section.

3. Add a javascript file to your project ( with name HelloWorld.js ). This file contains the definition of ToCsharp and FromCSharp as follows:


//ToCSharp : The method SayHello will be overriden in C#.
var ToCSharp = {
SayHello : function (message) {
console.log(message);
}
}

//FromCSharp: The HelloWorld method is called from C#
var FromCSharp = {
HelloWorld: function () {
ToCSharp.SayHello("JavaScript says Hello to the C# world");
}
}

Our javascript content is ready. Lets C# next.

4. In programs.cs include section,  add :


using Microsoft.ClearScript.V8;

Lets create v8Engine in C# and initialize it with javascript content. in Main method add the following code:


//Create V8Engine
V8ScriptEngine _v8Engine = new V8ScriptEngine( V8ScriptEngineFlags.EnableDebugging);

string jsFilePath = @"..\..\HelloWorld.js";
string jsContents = File.ReadAllText(jsFilePath);

_v8Engine.Execute(jsContents);

At this point V8 engine is up and is loaded with contents of HelloWorld.js file. We can straight away make a call to FromCSharp.HelloWorld() function now, but since this function in-turn makes a call ToCSharp.SayHello, lets override the SayHello function and grab the console message in a C# object.

To override the SayHello function from javascript file, add the following in Main method:


//Any call to Console from javascript is handled by MyConsole object.
_v8Engine.AddHostObject("Console", new MyConsole());

//Override ToCSharp.SayHello function in javascript file.
string callBackScriptCode = @"ToCSharp.SayHello = function (message){
Console.WriteLine(message);
};";

_v8Engine.Execute(callBackScriptCode);

The above code tells simple thing to V8 engine : Any calls to ToCSharp.SayHello, please call this method I am overriding and any call on “Console” from javascript, please forward it to MyConsole class object registered with you. Simple!

So lets define how MyConsole class may look like in this scenario. Add a new class to you project with name MyConsole. Define the class as follows:


public class MyConsole
{
    public void WriteLine(string message)
    {
       Console.WriteLine(message);
    }
}

All set, now we are ready to make the call from c# to javascript. Add the following line to call FromCSharp.HelloWorld() function in javascript:


//C# to javascript call
_v8Engine.Script.FromCSharp.HelloWorld();

At the end your Main method in program.cs should look like like below:


static void Main(string[] args)
{
  //Create V8Engine
  V8ScriptEngine _v8Engine = new V8ScriptEngine( V8ScriptEngineFlags.EnableDebugging);

  string jsFilePath = @"..\..\HelloWorld.js";
  string jsContents = File.ReadAllText(jsFilePath);

  _v8Engine.Execute(jsContents);

  //Any call to Console from javascript is handled by MyConsole object.
  _v8Engine.AddHostObject("Console", new MyConsole());

  //Override ToCSharp.SayHello function in javascript file.
  string callBackScriptCode = @"ToCSharp.SayHello = function (message){
    Console.WriteLine(message);
  };";

  _v8Engine.Execute(callBackScriptCode);

  //C# to javascript call
  _v8Engine.Script.FromCSharp.HelloWorld();

}

Phewwww!!! That’s all we need. Build and run your project. You should see the following output on console:

ClearScriptOutput

Conclusion:

We have successfully built V8, clearscript libraries & a sample code to interop between C# and javascript using clearscript.

 

I have tried my best to keep the steps minimal and sufficient to get you going. Please provide you feedback/comments if you faced any issue or otherwise.

 

Coming Up Next : How to debug javascript and C# together?

3-Finger Salute

If you have ever used computers, I can safely assume you are aware of ctrl + alt + del keys combinations( Well, I am a step ahead to assume that you must have used Windows OS ). This key combination, also known as three finger salute, comes in as savior at times when you find yourself stuck while using your PC. Be it locking the screen, a password change or logging off from your PC, you tend to hit these keys more often than not. 

All is well until you started to work with multiple machines. 

We use Remote Desktop Connection to connect to a remote machine. Have you ever tried locking your remote machine with ctrl+alt+del? The moment you hit this magic key combination it is not your remote machine but your local machine will kick you out ( ooppss.. not violent… just that your local machine will be locked ).

So what’s the solution? It’s another 3 – keys magic!

 

CTRL + ALT +END !

Performance Measurement in .Net

During my regular work, I came across a situation where I had to measure the performance impact on existing .net dll API after adding a feature. I stumbled upon the various ways in which the performance calculation can be done. I am still amazed how in my previous projects the UI based application responsiveness were measured by using stopwatches of tester’s cell phone. Not sure about the accuracy of it but that was the way to do which we followed.
Now that my current project is not UI based, I have more programmatic and pragmatic possible ways of making the measurements and comparison. It was not difficult for me to choose StopWatch over DateTime.Now after reading some stackoverflow posts. Lets say the performance of API I wanted to measure is MyClass.DoThings(). The following code can be used to take the reading of time taken for performing the method execution:

class MyClass
    {
        static void Main(string[] args)
        {
            Stopwatch sw = Stopwatch.StartNew();
            MyClass.DoThings();
            sw.Stop();

            Console.WriteLine(sw.ElapsedMilliseconds);

        }

        private static void DoThings()
        {
            //The library logic
        }
    }

The measurement can be taken for the libraries with and without changes and comparison can be made. Sounds simple isn’t it?

However, there happened to be a twist in the story. For few runs, the number of milliseconds elapsed gave a false suggestion that performance was better with the added changes ( we expected it other way round as the added changes were supposed to perform some registry operations).

What went wrong?

It was the measurement process. In essence the Stopwatch, provided by .Net framework, provides a precise ticks of clock for the measurement and much better than DateTime but still it does not take the CPU usage of the process in account. So for the few executions, when CPU usage was high, the Stopwatch measurement showed a false improvement in performance opposite to our expectation.

What worked for us?

Idea is to calculate the average CPU utilization of the process while taking the measurement. The windows system provides a counter to make our life easy. There is a counter named “% Processor Time” available within performance counter category “Process”. This counter keeps track of current processor utilization of any given process on windows OS.

blog_processor_time

While the test application is under execution, the value of “% Processor Time’ is sampled ( e.g., on interval of a second) and stored in a list. The following code section shows the average CPU usage calculation for test process named “test1”.

 static List<double> processorUsage = new List<double>(1000000);
 PerformanceCounter counter = new PerformanceCounter("Process", "% Processor Time", "test1");

 while (testIsOn)
    {
         processorUsage.Add(counter.NextValue());
         Thread.Sleep(1000);
    }
 Console.WriteLine("the test process is finished");

 //Claculate average cpu% usage
 double sum = 0;
 for (int i = 0; i < processorUsage.Count; i++)
 {
      sum += processorUsage[i];
 }

double avgPercentageProcesorTime = sum / processorUsage.Count;

Once the average processor time and elapsed time by stopwatch is available after test execution, the effective time taken at 100% CPU utilization can be calculated as following:

Tn = (Ts * AvgCPU%)/100

Where –
Tn = Normalized time taken for execution at 100% processor utilization,
Ts = Time measured by Stopwatch, and
AvgCPU% = Average % Processor utilization during test execution.

The comparison of normalized time taken with and without changes in the library yield a fair result.

Please feel free provide your feedback/comments!

Hello world!

Hello World!

Trying to enter the world of blogging. My writings will be just the reflection of my thoughts, experiences and my life and nothing more.

public class MyBlog
{
  public static void Main()
  {
     Conosole.WriteLine("Hello World");
  }
}