This section explains how to debug various parts of the Engine. By Engine, we
mean all the Java code located in the runtime SBT project, in engine
directory.
This subsection provides a guide how to debug a single Enso source file
evaluation. To evaluate a single source file, we use the Engine distribution
built with buildEngineDistribution command. Both of the following two options
starts the JVM in a debug mode. After the JVM is started in a debug mode, simply
attach the debugger to the JVM process at the specified port.
The first option is to invoke the engine distribution from SBT shell with:
sbt:enso> runEngineDistribution --debug --run ./test/Tests/src/Data/Numbers_Spec.ensoThe second options is to pass in special JVM arguments when launching the
bin/enso from the engine distribution:
enso$ JAVA_OPTS=-agentlib:jdwp=transport=dt_socket,server=n,address=5005 ./built-distribution/enso-engine-*/enso-*/bin/enso --run ./test/Tests/src/Data/Numbers_Spec.ensoThere is no simple mapping of the Enso source code to the engine's Java code, so if you try to debug a specific expression, it might be a bit tricky. However, the following steps should help you to skip all the irrelevant code and get to the code you are interested in:
- To debug a method called
foo, put a breakpoint inorg.enso.interpreter.node.ClosureRootNode#executewith a condition onthis.name.contains("foo") - To debug a specific expression, put some unique expression, like
Debug.eval "1+1", in front of it and put a breakpoint in a Truffle node corresponding to that unique expression, in this case that isorg.enso.interpreter.node.expression.builtin.debug.DebugEvalNode.
The Engine uses annotation processors to generate some of the Java code, e.g.,
the builtin methods with org.enso.interpreter.dsl.MethodProcessor, or JMH
benchmark sources with org.enso.benchmarks.processor.BenchProcessor.
Annotation processors are invoked by the Java compiler (javac), therefore, we
need special instructions to attach the debugger to them.
Let's debug org.enso.interpreter.dsl.MethodProcessor as an example. The
following are the commands invoked in the sbt shell:
project runtimeclean- Delete all the compiled class files along with all the generated sources by the annotation processor. This ensures that the annotation processor will be invoked.
set javacOptions += FrgaalJavaCompiler.debugArg- This sets a special flag that is passed to the frgaal Java compiler, which in turn waits for the debugger to attach. Note that this setting is not persisted and will be reset once the project is reloaded.
compile- Launches the Java compiler, which will wait for the debugger to attach. Put
a breakpoint in some class of
org.enso.interpreter.dslpackage. Wait for the message in the console instructing to attach the debugger.
- Launches the Java compiler, which will wait for the debugger to attach. Put
a breakpoint in some class of
- To reset the
javacOptionssetting, either runset javacOptions -= FrgaalJavaCompiler.debugArg, or reload the project withreload.