isolated-vm
isolated-vm copied to clipboard
Debug on VSCode?
I finally got my script running inside isolated-vm, but I can't seem to get the Chrome DevTools to work properly. I can see the code, but that is about it. I can't breakpoint or get source maps to work.
I get this warning for sourcemaps:
DevTools failed to load source map: Could not load content for file:///server.bundle.dev.js.map: Unknown error
There is no way to configure the location, its always looking at file:///<filename>.map
it doesn't even have the same path as I defined in my code, since the file sits in another folder.
Instead, how can we use VSCode to attach to the debugging used for let channel = isolate.createInspectorSession();
? I read that VSCode supports the DevTools debugging protocol, but it doesn't look like the JavaScript Debugger used by VSCode supports it after all?
Error: Could not connect to debug target at http://localhost:10000: Could not find any debuggable target
This is the error I see when I attempt to connect to the websocket. I recently switched from vm2
as they have officially abandoned their project. On vm2, I was able to get inline-source-maps, breakpoints, and watch inside VSCode from the same terminal I ran the vm. So I'm hoping to replicate the scenario with isolated-vm. Thanks.
Debugging in Chrome DevTools.
I did a bit more fiddling and was able to get sourcemaps and breakpoints working on a chrome tab with devtools.
- The correct URL to open in a Chrome tab is:
devtools://devtools/bundled/inspector.html?experiments=true&v8only=true&ws=127.0.0.1:10000
(change host/port to what your websocket server uses) - In the inspector-example.js both
channel.dispatchProtocolMessage
andws.send
should be usingmessage.toString()
. The pull request only had it on the dispatch. - In webpack, use
devtool: "inline-source-map"
. If you need a sourcemap file by itself i.e.,devtool: "source-map"
, you'll need to add pluginplugins: [new webpack.SourceMapDevToolPlugin()]
to webpack config for it to find the file properly, not sure why. - If you are on windows, you need to convert the filepath seperator
\\
to unix seperator/
. Chrome Dev Tools doesn't seem to like the backward slashes for filepaths. - ScriptOrigin.filename that you pass to
compileScript
should have the full path, i.e.file:///E:/GitHub/acos-games/memorize-up/builds/server/server.bundle.dev.js
. Note that I'm using unix seperator.
I am still struggling to get the stack trace from my vm script. I was only able to get the full stack trace once. 99.99% of the time I only get the stack message, and the trace only shows like the example below.
Example of my bad stack trace:
ReferenceError: test is not defined
at (<isolated-vm boundary>)
The ultimate scenario would still be to get it working on VSCode, but this will have to suffice until then.
Finally, I got VSCode Debugging working too!
VSCode's default NodeJS debugging uses a different connection schema http://
, so just had to use websocketAddress
to attach to the ws://
schema.
- Edit
launch.json
to include this:
{
"name": "Debug ACOS Game",
"type": "node",
"request": "attach",
"websocketAddress": "ws://127.0.0.1:10000",
"restart": true,
},
- In webpack use
devtool: "inline-source-map"
- Windows users, need to still convert filepath seperator from
\\
to/
- Run the
Debug ACOS Game
configuration to attach.
If you want to launch your main program that runs the VM and attach in one step, you can do this:
{
"command": "cd memorize-up && npm start",
"name": "Launch Memorize-Up",
"request": "launch",
"type": "node-terminal",
"serverReadyAction": {
"action": "startDebugging",
"name": "Debug ACOS Game",
"pattern": "Watching files"
}
},
Just edit pattern
to match any terminal output you want, for my example, it looks for "Watching files" in one of the log lines.
Still no luck with the stack trace though 😢
There is definitely something weird happening with stack traces.
Setting filename: "file:///fullpath"
is the right way, but full stack trace will not appear until you cause interference with breakpoints or some internal mechanism.
I don't think it's because I'm running the isolate from a worker thread, but it's becoming a bit unreliable to get the stack trace.
Also, breakpointing is unreliable, as it requires some fiddling to get working. Like I have to trigger at start of script with a debugger;
, but even then I have to set/unset the breakpoint several times to trigger a reliable breakpoint.
I tried following the c++ code, but it's a bit over my head as the filename disappears into the void somewhere.
Any help on these points would be appreciated. Thanks.
Edit:
At the moment, I can only recommend isolated-vm for production workloads, where security takes priority over debugging. I have since changed to using the vm
that is built into nodejs for local development of games, as debugging is within the same context as the main node script, making it more reliable.
May I ask if you are using isolated-vm to find an elegant debugging solution? The vm2 used before can be directly inserted into the debugger in the code, but it has not been able to be used in isolated-vm, and the usage examples will continue to have problems
May I ask if you are using isolated-vm to find an elegant debugging solution? The vm2 used before can be directly inserted into the debugger in the code, but it has not been able to be used in isolated-vm, and the usage examples will continue to have problems
@Mankvis No, I wanted to use isolated-vm for both production and local development. Games for my platform are coded on local environment in VSCode, and I was hoping I could use one solution for both. vm2 is oficially deprecated, so NPM and GitHub will cry about its vulnerabilities til the end of time. Node-vm, while very insecure, is fine for local development and I get full stack traces + instant debugging with breakpoints using sourcemaps.
Hey ya, a lil bit on the vscode and the debugging protocol context here.
For us we have to implement some simple http endpoint in order to achieve the similar experience as node.js debugging.
Mainly,
GET /json/list
which returns
[
{
description: '... instance',
devtoolsFrontendUrl: `devtools://devtools/bundled/js_app.html?experiments=true&v8only=true&ws=localhost:${this.port}/${this.uuid}`,
devtoolsFrontendUrlCompat: `evtools://devtools/bundled/inspector.html?experiments=true&v8only=true&ws=localhost:${this.port}/${this.uuid}`,
faviconUrl: 'https://nodejs.org/static/images/favicons/favicon.ico',
id: this.uuid,
title: this.filename,
type: 'javascript',
url: this.filename.includes('file://${filename}') ,
webSocketDebuggerUrl: `ws://localhost:${this.port}/${this.uuid}`,
},
]
GET /json/version
{
Browser: `node.js/${process.version}`,
'Protocol-Version': '1.1',
}
GET /json
-> list request
About stack traces, make sure when you call the eval/run/createScript/createModule
api, the filename and line offset are passed correctly.