mirror of
https://github.com/enso-org/enso.git
synced 2024-08-17 00:40:34 +03:00
Add Chrome devtools and DAP tools for debugging (#8344)
Adds chrome-inspector tool and Debug Adapter protocol tool for debugging Enso. # Important Notes The chrome devtools seems to be broken (tracked in https://github.com/oracle/graal/issues/7636). Even `graalpy --inspect ...` fails (Chrome devtools freezes after connecting to the server). This PR adds Debug adapter protocol tool for debugging as a workaround for chrome inspector. There is docs in [dap.md](https://github.com/enso-org/enso/pull/8344/files#diff-421574b50574cfe546e86d4b3d32d79b8b2087f2fe204f68e5cf2693af43bbe1)
This commit is contained in:
parent
f60836d9e1
commit
268e595ec1
@ -1428,7 +1428,9 @@ lazy val runtime = (project in file("engine/runtime"))
|
||||
GraalVM.modules.map(_.withConfigurations(Some(Runtime.name)))
|
||||
val langs =
|
||||
GraalVM.langsPkgs.map(_.withConfigurations(Some(Runtime.name)))
|
||||
necessaryModules ++ langs
|
||||
val tools =
|
||||
GraalVM.toolsPkgs.map(_.withConfigurations(Some(Runtime.name)))
|
||||
necessaryModules ++ langs ++ tools
|
||||
},
|
||||
Test / javaOptions ++= testLogProviderOptions ++ Seq(
|
||||
"-Dpolyglotimpl.DisableClassPathIsolation=true"
|
||||
|
@ -15,6 +15,8 @@ used by Enso, broken up as follows:
|
||||
Debugger.
|
||||
- [**Chrome devtools debugger:**](./chrome-devtools.md) A guide how to debug
|
||||
Enso code using Chrome devtools.
|
||||
- [**Debug adapter protocol:**](./dap.md) A guide how to debug Enso code using
|
||||
VSCode.
|
||||
- [**Debugging Enso and Java code at once:**](./mixed-debugging.md) A
|
||||
step-by-step guide how to debug both Enso and Java code in a single debugger.
|
||||
- [**Debugging Engine (Runtime) only Java code:**](./runtime-debugging.md) A
|
||||
|
31
docs/debugger/dap.md
Normal file
31
docs/debugger/dap.md
Normal file
@ -0,0 +1,31 @@
|
||||
# Debug Adapter Protocol
|
||||
|
||||
[Debug Adapter Protocol](https://www.graalvm.org/latest/tools/dap/) is yet
|
||||
another instrument available for a Truffle language. The DAP is a native
|
||||
protocol for VSCode and as such, works only via VSCode. To start Enso with DAP
|
||||
server waiting for a client to attach, launch enso via:
|
||||
|
||||
```
|
||||
env JAVA_OPTS='-Dpolyglot.dap' ./built-distribution/enso-engine-*/enso-*/bin/enso --run *.enso
|
||||
```
|
||||
|
||||
Once DAP server is started and ready for a client to be attached, the following
|
||||
output will be printed:
|
||||
|
||||
```
|
||||
[Graal DAP] Starting server and listening on /127.0.0.1:4711
|
||||
```
|
||||
|
||||
There is a
|
||||
[Launch configuration](https://code.visualstudio.com/docs/editor/debugging#_launch-configurations)
|
||||
in the repository in
|
||||
[.vscode/launch.json](https://github.com/enso-org/enso/blob/a123cd0d9f4b04d05aae7a5231efba554062188f/.vscode/launch.json#L13-L16)
|
||||
with name `Debug Adapter Protocol`, you can start debugging via
|
||||
[Run and Debug view](https://code.visualstudio.com/docs/editor/debugging#_run-and-debug-view)
|
||||
by selecting the `Debug adapter protocol` configuration and pressing play:
|
||||
![image](https://github.com/enso-org/enso/assets/14013887/7f15abfd-b4fa-45d3-a100-142c465b6444)
|
||||
|
||||
Another screenshot showing the DAP in action:
|
||||
![image](https://github.com/enso-org/enso/assets/14013887/41dd8b80-dbac-4a11-b3e2-97c99e42c507)
|
||||
|
||||
Note that the port 4711 is the default port for DAP.
|
@ -11,11 +11,11 @@ import org.enso.polyglot.{
|
||||
PolyglotContext,
|
||||
RuntimeOptions
|
||||
}
|
||||
import org.graalvm.polyglot.Engine
|
||||
import org.graalvm.polyglot.Context
|
||||
import org.graalvm.polyglot.{Context, Engine}
|
||||
import org.slf4j.event.Level
|
||||
|
||||
import java.io.{File, InputStream, OutputStream}
|
||||
import java.io.{ByteArrayOutputStream, File, InputStream, OutputStream}
|
||||
import scala.util.{Failure, Success, Using}
|
||||
|
||||
/** Utility class for creating Graal polyglot contexts.
|
||||
*/
|
||||
@ -131,14 +131,7 @@ class ContextFactory {
|
||||
if (graalpy.exists()) {
|
||||
builder.option("python.Executable", graalpy.getAbsolutePath());
|
||||
}
|
||||
if (
|
||||
Engine
|
||||
.newBuilder()
|
||||
.allowExperimentalOptions(true)
|
||||
.build()
|
||||
.getLanguages()
|
||||
.containsKey("java")
|
||||
) {
|
||||
if (engineHasJava()) {
|
||||
builder
|
||||
.option("java.ExposeNativeJavaVM", "true")
|
||||
.option("java.Polyglot", "true")
|
||||
@ -148,4 +141,24 @@ class ContextFactory {
|
||||
}
|
||||
new PolyglotContext(builder.build)
|
||||
}
|
||||
|
||||
/** Checks whether the polyglot engine has Espresso.
|
||||
*
|
||||
* Creates a temporary polyglot engine for that and makes sure that it is closed.
|
||||
*/
|
||||
private def engineHasJava(): Boolean = {
|
||||
Using(
|
||||
Engine
|
||||
.newBuilder()
|
||||
.allowExperimentalOptions(true)
|
||||
.out(new ByteArrayOutputStream())
|
||||
.err(new ByteArrayOutputStream())
|
||||
.build()
|
||||
) { engine =>
|
||||
engine.getLanguages.containsKey("java")
|
||||
} match {
|
||||
case Success(ret) => ret
|
||||
case Failure(ex) => throw new IllegalStateException("unreachable", ex)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -457,17 +457,20 @@ public class DebuggingEnsoTest {
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Ignore
|
||||
@Test
|
||||
public void testSteppingOver() {
|
||||
Source src = createEnsoSource("""
|
||||
baz x = x # 1
|
||||
bar x = baz x # 2
|
||||
foo x = # 3
|
||||
bar 42 # 4
|
||||
end = 0 # 5
|
||||
baz x = x # 1
|
||||
bar x = # 2
|
||||
ret = baz x # 3
|
||||
ret # 4
|
||||
foo x = # 5
|
||||
bar 42 # 6
|
||||
end = 0 # 7
|
||||
""");
|
||||
List<Integer> expectedLineNumbers = List.of(3, 4, 5);
|
||||
// Steps into line 2 - declaration of the method, which is fine.
|
||||
// (5, 6, 7) would be better.
|
||||
List<Integer> expectedLineNumbers = List.of(5, 6, 2, 7);
|
||||
Queue<SuspendedCallback> steps = createStepOverEvents(expectedLineNumbers.size());
|
||||
testStepping(src, "foo", new Object[]{0}, steps, expectedLineNumbers);
|
||||
}
|
||||
@ -475,6 +478,10 @@ public class DebuggingEnsoTest {
|
||||
/**
|
||||
* Use some methods from Vector in stdlib. Stepping over methods from different
|
||||
* modules might be problematic.
|
||||
*
|
||||
* TODO[pm] This test is ignored, because the current behavior of step over is that it first
|
||||
* steps into the declaration (name) of the method that is being stepped over and then
|
||||
* steps back. So there would be weird line numbers from std lib.
|
||||
*/
|
||||
@Ignore
|
||||
@Test
|
||||
|
@ -79,7 +79,11 @@ object GraalVM {
|
||||
"org.graalvm.tools" % "profiler-tool" % version
|
||||
)
|
||||
|
||||
val toolsPkgs = chromeInspectorPkgs
|
||||
val debugAdapterProtocolPkgs = Seq(
|
||||
"org.graalvm.tools" % "dap-tool" % version
|
||||
)
|
||||
|
||||
val toolsPkgs = chromeInspectorPkgs ++ debugAdapterProtocolPkgs
|
||||
|
||||
// TODO: Add graalvmPython
|
||||
val langsPkgs = jsPkgs
|
||||
|
@ -33,7 +33,7 @@ object JPMSUtils {
|
||||
* When invoking the `java` command, these modules need to be put on the module-path.
|
||||
*/
|
||||
val componentModules: Seq[ModuleID] =
|
||||
GraalVM.modules ++ GraalVM.langsPkgs ++ Seq(
|
||||
GraalVM.modules ++ GraalVM.langsPkgs ++ GraalVM.toolsPkgs ++ Seq(
|
||||
"org.slf4j" % "slf4j-api" % slf4jVersion,
|
||||
"ch.qos.logback" % "logback-classic" % logbackClassicVersion,
|
||||
"ch.qos.logback" % "logback-core" % logbackClassicVersion
|
||||
|
Loading…
Reference in New Issue
Block a user