Adding Debugging Support to a Truffle Language
Beside the great performance after just-in-time compilation, the Truffle Language implementation framework provides a few other highly interesting features to language implementers. One of them is the instrumentation framework, which includes a REPL, profiler, and debugger.
To support debugging, an interpreter needs to provide only a few tags on its AST nodes, instruct the framework to make them instrumentable, and have the debugger tool jar on the classpath. In this post, I’ll only point at the basics, of course for a perfectly working debugger, a language needs to carefully decide which elements should be considered for breakpoints, how values are displayed, are how to evaluate arbitrary code during debugging.
The most relevant aspect is tagging. In order to hide implementation details of the AST from users of a tool, only relevant Truffle nodes are tagged for the use by a specific tool. For debugging support, we need to override the isTaggedWith(cls)
method to indicate that all elements, which correspond to a statement at which a debugger could stop, return true
for the StatementTag
. Based on this information, the debugger can then instrument AST nodes to realize breakpoints, stepping execution, etc. In addition, we also need to make sure that a node has a proper source section attached, but that’s something a parser should already be taking care of.
To instrument nodes, they are essentially wrapped by the framework. To allow Truffle to wrap a node, its class, or one of the super classes, needs to be marked as @Instrumentable
. This annotation can be used to generate the necessary wrapper classes and allow wrapping of such nodes. In most cases, this should work directly without requiring any custom code.
Before the tool is going to be useable, a language needs to explicitly declare that it supports the necessary tags by listing them on its subclass of TruffleLanguage
using the @ProvidedTags
annotation.
And lastly, we need to have the truffle-debug.jar on the classpath. With this, languages that use the mx
build system, it should be possible to access the REPL with mx build
, which then also allows debugging.
With a little bit more work, one could also adapt my prototype for a web-based debugger interface from SOMns. This prototype is language independent, but requires a few more tags to support syntax highlighting. Perhaps more on that in another post.
Below, you can see a brief demo of the debugger for SOMns: