Debugging polyglot Node.js, Ruby, R apps with GraalVM

Oleg Šelajev
May 3, 2018 · 5 min read

This post was written by Martin Entlicher and Oleg Šelajev.

In this post, we explore how to debug a polyglot JavaScript Node.js, Ruby, and R application using GraalVM and the Chrome Dev tools debugger.

GraalVM is an embeddable high-performance polyglot virtual machine that aims to run all programming languages very fast. It is a large and versatile project, and if you are interested in what else GraalVM can do for you, look at the “10 things GraalVM can do” blog post by Chris Seaton.

GraalVM plus Node.js and JavaScript

$ js
> 1 + 2
3
> print("Hello, polyglot world!")
Hello, polyglot world!

Besides running pure JavaScript, GraalVM can also run Node.js applications. The node in GraalVM relies on the native node implementation and replaces the JavaScript engine with its own.
So it can run node apps. If you start node with the —-jvm flag, your code will have access to the JDK classes out of the box.

$ node --jvm
> var BigInteger = Java.type(‘java.math.BigInteger’);
> console.log(BigInteger.valueOf(2).pow(100).toString(16));
10000000000000000000000000

On top of that, GraalVM comes with language agnostic tooling support, including debugger and profiler. Besides a debugger API, which is available for tool makers, GraalVM contains a backend implementation of the Chrome Inspector debugging protocol. That protocol, designed originally for JavaScript debugging, can be used to conveniently debug all GraalVM languages.

Demo polyglot application

  • Clone the graalvm/graalvm-demos repository and navigate to the functionGraphDemo directory.
  • run npm install to install the dependencies,
  • start the application: $GRAALVM_HOME/bin/node --polyglot --jvm --inspect server.js

It is a simple application that draws some graphs of various math functions. It uses JavaScript to handle the web communication, Ruby to verify the user input and R to parse the function and draw the function graph. Let’s use the debugger in Chrome developer tools to explore how it works.

Debugging in Chrome

The --inspectoption prints out a URL that is possible to paste into Chrome to attach the debugger. See Debugging Node.js with Google Chrome for instance, for the hints on how to use the Chrome client. When the debugger is attached, expand the file tree on the left side to explore the loaded scripts. You’ll see all node modules loaded under the node_modules folder and the main script server.js next to it. To intercept the web requests and start actual debugging, add a breakpoint to line 19, in the body of app.post().

Image for post
Image for post

Open http://localhost:8088/ in another browser window and writelog(x^2 + 1) to the function field. Press the “Draw Function” button and wait until the breakpoint is hit. Now you can use standard debugging actions to step through the application execution and tooltips to inspect the variable values.

Image for post
Image for post

You can see that from line 26 you can step into the Ruby code which does a primary verification of the function expression. It checks the input to prevent executing arbitrary code. When looking at the Call Stack, you can see a seamless transition from JavaScript to Ruby code. You can also navigate to all the frames on the stack, regardless of the particular language.

Image for post
Image for post

Now at line 28, step into the call to plotFunction call. This is R code that plots the function. Again, R data is available, together with the seamless call stack. All debugging features, including breakpoints, are available in all GraalVM languages.

Image for post
Image for post

On top of all that you can use the console to evaluate code written in the language of the current frame in focus.

Polyglot applications allow you to reuse the existing modules from any language ecosystem. Normally, it is a maintenance nightmare when you need to use different tooling to see what’s going on in the different components of the application you’re working on. With GraalVM’s language virtualization ability you can use one set of tools to debug all languages and libraries alike, without distracting yourself with the pesky details like what language a particular piece of code is written in.

Coverage Profiling in Chrome

Conclusion

The ability to seamlessly debug through the different languages simplifies development of polyglot apps and allows for enhanced productivity by using the existing libraries from any programming languages ecosystems.

If you would like to implement your own language-agnostic tool for GraalVM, the best starting point is the getting started with instruments on GraalVM page.


To try GraalVM go to https://www.graalvm.org/. There are links to downloads and documentation there, and more examples like we’ve shown in this blog post.

Try following the instructions here and adapting them to see what else you can do. Let us know how you’re experimenting with GraalVM in your application and send us any feedback, for example to shelajev.

graalvm

GraalVM team blog - https://www.graalvm.org

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch

Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore

Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store