Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add v8_inspector support #6792

Closed
wants to merge 5 commits into from
Closed

Add v8_inspector support #6792

wants to merge 5 commits into from

Conversation

@ofrobots
Copy link
Contributor

@ofrobots ofrobots commented May 16, 2016

For background see: #2546 (comment)

This PR brings in v8_inspector support to Node.js (currently behind a compile time flag.) This means Node.js can now be debugged and profiled via the Chrome Debugging Protocol, which enables inspection via Chrome DevTools and other tools & IDEs. So far, v8_inspector includes support for the following protocol domains: Debugger, Profiler, Runtime, HeapProfiler

In the Chrome DevTools client, the following is now available:

  • Complete breakpoint debugging, stepping w/ blackboxing
  • Source maps for transpiled code
  • LiveEdit: JavaScript hot-swap evaluation w/ V8
  • Console evaluation with ES6 feature/object support and custom object formatting
  • Sampling JavaScript profiler w/ flamechart
  • Heap snapshot inspection, heap allocation timeline, allocation profiling
  • Asynchronous stacks for native promises

There is more functionality that could be implemented, but we've reached a good point to get input from the community on the feature set and on the integration with Node.js core.

This PR has two logical sets of changes:

Bring in v8_inspector as a dependency

v8_inspector used to be part of Blink. We have removed almost all of the dependencies on Blink and are working on getting this code merged directly into V8 – the biggest piece remaining is integrating the DevTools tests into the V8 test infrastructure. However, this work will likely complete in V8 5.3 / 5.4 timeframe. If we wait for this upstream change, it would mean the improved debugging experience would not be available to Node.js v6.x LTS users.

In the meantime, we propose to bring the v8_inspector dependency directly into Node.js. This dependency can be dropped once v8_inspector merges upstream into V8 (in Node.js v7.x timeframe).

Node.js support for the v8_inspector protocol

The support for talking to v8_inspector protocol is primarily in node_inspector.cc. We also needed support for a subset of the websockets protocol to be able to talk to DevTools. We have implemented this based on the websockets implementation from Chromium. We are calling it the 'inspector socket protocol' as it is not a complete websockets implementation, although it could be extended. This protocol is not available to userspace JavaScript code, and is accessible only to internal C++ code in core.

The implementation is behind a compile time flag controlled by the --with-inspector configure flag.

Usage

$ make -j8
$ ./node --inspect benchmark/http_simple.js
Debugger listening on port 5858. To start debugging, open following URL in Chrome:

chrome-devtools://devtools/remote/serve_file/@4604d24a75168768584760ba56d175507941852f/inspector.html?experiments=true&v8only=true&ws=localhost:5858/node

You can attach Chrome DevTools by opening the printed url in a Chrome browser.

2016-05-16

By default, the debugging port is 5858. You can optionally specify an alternate port via the --inspect=9229 flag. If you want the debugger to pause on application start, you can additional pass the --debug-brk flag. For example:

$ ./node --inspect=9229 --debug-brk benchmark/http_simple.js
Debugger listening on port 9229. To start debugging, open following URL in Chrome:

chrome-devtools://devtools/remote/serve_file/@4604d24a75168768584760ba56d175507941852f/inspector.html?experiments=true&v8only=true&ws=localhost:9229/node

Getting this merged into Node.js would allow people to test the DevTools integration and allow proper debugging to be well-tested and stable well in time for the release of the 6.x LTS. It would also enable third-party debug tool writers to start building other debugging and profiling tools that work with Node.js.

Thanks for the review.

/cc @repenaxa, @eugeneo, @paulirish

@@ -0,0 +1,2 @@
# v8_inspector
# v8_inspector

This comment has been minimized.

@jasnell

jasnell May 16, 2016
Member

Useful README is Useful ;-)


void PrintDebuggerReadyMessage(int port) {
fprintf(stderr, "Debugger listening on port %d. "
"To start debugging, open following URL in Chrome:\n"

This comment has been minimized.

@mscdex

mscdex May 16, 2016
Contributor

nit: s/open following/open the following/

@mscdex
Copy link
Contributor

@mscdex mscdex commented May 16, 2016

Awesome! Thanks everyone that helped put all this together and made it possible!

@MylesBorins
Copy link
Member

@MylesBorins MylesBorins commented May 16, 2016

@ofrobots I'm a bit late to the party so sorry if this has been covered in the other thread... Would this PR landing change anything in regards to the current debugger?

@jasnell
Copy link
Member

@jasnell jasnell commented May 16, 2016

Great to see this come through. Looking forward to playing around with it.

@ofrobots
Copy link
Contributor Author

@ofrobots ofrobots commented May 16, 2016

@thealphanerd The old debugger is not affected, and still works as-is. v8_inspector debugger gets enabled only when the --inspect option is provided.

@cjihrig
Copy link
Contributor

@cjihrig cjihrig commented May 16, 2016

My initial reaction is that this is fantastic. Thank you.

@sam-github
Copy link
Contributor

@sam-github sam-github commented May 16, 2016

@ofrobots

v8_inspector debugger gets enabled only when the --inspect option is provided.

It would be great if it could be enabled/disabled at runtime using a v8.debugOn/Off() js API call.

@trevnorris
Copy link
Contributor

@trevnorris trevnorris commented May 16, 2016

@ofrobots Why import the entire inspector?

@jasnell
Copy link
Member

@jasnell jasnell commented May 16, 2016

Why import the entire inspector?

Was wondering that myself...

@pavelfeldman
Copy link
Contributor

@pavelfeldman pavelfeldman commented May 16, 2016

Why import the entire inspector?

What do you mean by entire inspector?

It would be great if it could be enabled/disabled at runtime using a v8.debugOn/Off() js API call.

Does present debugger allow that? We were aiming at feature parity before we start adding features. Enabling dynamically means that we would bind port at runtime. Other than that, debugger can be enabled/disabled at any moment, no technical limitations there.

@Qard
Copy link
Member

@Qard Qard commented May 16, 2016

Nice work!

So the intent is for this to get merged to v6 and then removed again at v7 when it's baked into V8? Why not just wait until v7 when it's built-in? Certainly it's valuable work and would benefit v6 greatly, but this is a rather large chunk of stuff to review only to remove it again in a few months.

What does the plan look like for merging with V8? I assume the user-facing surface of it would stay the same when we reach v7? (Other than maybe not needing the build flag anymore?)

@jasnell
Copy link
Member

@jasnell jasnell commented May 16, 2016

What do you mean by entire inspector?

The second commit -> a7f339b

@ofrobots
Copy link
Contributor Author

@ofrobots ofrobots commented May 16, 2016

This PR is not bringing in the DevTools inspector. It only brings in the v8_inspector part, which is an implementation of the DevTools debug protocol.

It would be great if it could be enabled/disabled at runtime using a v8.debugOn/Off() js API call.

This would be a good follow-on. Once this PR lands, it would be easier to work on the ergonomics & integration.

but this is a rather large chunk of stuff to review only to remove it again in a few months.

The review is needed on 0995140. This integrates the inspector protocol into Node-core. This code is is not going to be removed in a few months. Once this is reviewed and merged, it would be an independent question whether this should merge into v6.x. Part of the answer depends on whether this is a semver major change.

The other, larger, commit is a dependency that is needed until the dependency merges upstream into V8. Here's the upstream repository: https://chromium.googlesource.com/chromium/src/third_party/WebKit/Source/platform/v8_inspector/. This commit, like other dependency rolls, doesn't really need an in-depth review.

EDIT: fix link.

@jkrems
Copy link
Contributor

@jkrems jkrems commented May 16, 2016

Thanks so much for all this work! Really looking forward to having a "real"/modern debugger protocol for node.

I assume that since the --inspector flag already is disabled by default, it might be possible to enable --with-inspector by default during the lifetime of node 6? Getting a "real" debugger that is part of all the binary distributions of node as part of the next LTS would be great.

The above ("what will become the next LTS") is also, imo, a good reason for bringing it into node 6 and to not wait until all the inspector pieces landed in v8 itself.

@Fishrock123
Copy link
Member

@Fishrock123 Fishrock123 commented May 16, 2016

Hmmm, when we were originally discussing this I was under the impression we'd only have the hooks for the v8 debugger but not actually ship the v8 debugger?

IIRC the v8 (chrome?) debugger is very version agnostic so there wasn't any great need for it to ship in core, and shipping in core is pretty awkward as we see with npm. e.g. you're never quite on the version you want to be. Plus it's a ton of extra source code.

This is assuming the v8/chrome debugger doesn't need native compilation, if it does, that is probably going to be a whole other issue.

Another question: is this intending to replace the default node debugger?

@ofrobots
Copy link
Contributor Author

@ofrobots ofrobots commented May 16, 2016

Hmmm, when we were originally discussing this I was under the impression we'd only have the hooks for the v8 debugger but not actually ship the v8 debugger?

This PR does not include the Devtools debugger. It only includes the debugger protocol implementation. When you run with --inspect you see the following on the command line:

chrome-devtools://devtools/remote/serve_file/@4604d24a75168768584760ba56d175507941852f/inspector.html?experiments=true&v8only=true&ws=localhost:5858/node

Chrome will load the version of inspector identified by the id, served from the DevTools web hosts. The only thing Node is doing, is implementing a debug server that 'talks' the protocol expected by the Devtools debugger.

Another question: is this intending to replace the default node debugger?

No.

@Fishrock123
Copy link
Member

@Fishrock123 Fishrock123 commented May 16, 2016

Wow, I'm really surprised that it is this large given that it's just the hooks...

@jasnell
Copy link
Member

@jasnell jasnell commented May 16, 2016

Ok, so it's the hooks + the protocol, that makes sense. Will have to spend some time digging into that second commit. The size is a bit concerning but not too bad.

@ofrobots
Copy link
Contributor Author

@ofrobots ofrobots commented May 16, 2016

BTW, there are other debuggers that already talk the same protocol, for example: https://github.com/Microsoft/vscode-chrome-debug. It is conceivable that these debuggers could be extended to support Node.js debugging.

@Qard
Copy link
Member

@Qard Qard commented May 16, 2016

Sorry, I was a bit vague. I meant to ask specifically about if the dependency would get removed in v7 (due to being integrated in V8).

Merging 0995140 seems reasonable to me. It's just a7f339b that I'm a bit wary of, since it'd be a bunch of churn to add it and then remove it again. Am I understanding the plan right? The dep get added in v6, then hopefully merged into V8 and removed again for probably v7?

@Qard
Copy link
Member

@Qard Qard commented May 16, 2016

FWIW, I'm leaning more toward just merging it for the sake of making debugging in v6 LTS much nicer. I'm just a bit unsure of the semver-minor-ness of this and the extra work to pull the dep in and maintain it, if we already know we're going to need to remove it again later and get it through the V8 dep.

@jasnell
Copy link
Member

@jasnell jasnell commented May 16, 2016

@ofrobots ... are the jinja and markupsafe dependencies really necessary? What are those being used for? (I could keep digging and find out but figured it would be easier to ask ;-) ..)

@MylesBorins
Copy link
Member

@MylesBorins MylesBorins commented May 16, 2016

If there is push back on a7f339b due to size, could it be brought in similar to the way we were handling icu before?

@pavelfeldman
Copy link
Contributor

@pavelfeldman pavelfeldman commented May 16, 2016

are the jinja and markupsafe dependencies really necessary?

those are build-time dependencies, we are using jinja to generate native protocol dispatcher and protocol data structures off protocol.json.

shimaore added a commit to shimaore/test-pouchdb-memleak that referenced this pull request Oct 19, 2016
I'll be using --inspect from nodejs/node#6792
@leofab86
Copy link

@leofab86 leofab86 commented Nov 17, 2016

I cant print to chrome console on Windows. Macbook works fine. Anyone else having this issue?

@uMaxmaxmaximus
Copy link

@uMaxmaxmaximus uMaxmaxmaximus commented Nov 18, 2016

how to autostart chrome devtool when i write node --inspect app.js ?

@uMaxmaxmaximus
Copy link

@uMaxmaxmaximus uMaxmaxmaximus commented Nov 18, 2016

@FredyC

Extention throw error:

Could not launch debugger
Invalid devtools URL in
[ { "description": "node.js instance", "devtoolsFrontendUrl": "chrome-devtools://devtools/bundled/inspector.html?experiments=true&v8only=true&ws=127.0.0.1:9229/74dec2d8-aca4-4725-85af-f292cb39ad13", "faviconUrl": "https://nodejs.org/static/favicon.ico", "id": "74dec2d8-aca4-4725-85af-f292cb39ad13", "title": "./build/server", "type": "node", "url": "file://C:_localhost_taxi_build_server", "webSocketDebuggerUrl": "ws://127.0.0.1:9229/74dec2d8-aca4-4725-85af-f292cb39ad13" } ]
@FredyC
Copy link

@FredyC FredyC commented Nov 18, 2016

@uMaxmaxmaximus Sorry, I am not the author of that extension and I don't think this is a right place to try to solve the issue ... https://github.com/continuationlabs/node-v8-inspector

@uMaxmaxmaximus
Copy link

@uMaxmaxmaximus uMaxmaxmaximus commented Nov 18, 2016

@FredyC
I've tried it, it does not work unfortunately. Maybe there is some way to intercept the link of std.output using node.js? Then I would have written a module that automatically opens a browser to this link.

Maybe link active debugger put to global.__inspectorUrl__ ?
Or create debugger object like this, to control debug from runtime script:

global.debug = {
  url: 'bla bla',
  port: 'bla bla',
  next: function(){ [native code] },
  stepInto: function(){ [native code] },
  e.t.c
}
@FredyC
Copy link

@FredyC FredyC commented Nov 18, 2016

@uMaxmaxmaximus I don't know, it works for me (on Windows as well). There is another alternative you might try ... https://github.com/jaridmargolin/inspect-process

@june07
Copy link

@june07 june07 commented Dec 20, 2016

@uMaxmaxmaximus http://june07.com/nim will manage DevTools (including auto launch).

@alysson-pina
Copy link

@alysson-pina alysson-pina commented Mar 29, 2017

Hi @ofrobots and team. Can we debug Node.js code written in TypeScript (.ts file) rather than regular JS?

@eugeneo
Copy link
Contributor

@eugeneo eugeneo commented Mar 29, 2017

@alysson-pina it should not matter as long as V8 can run the code. One thing you may need is to generate in-line source maps.

@alysson-pina
Copy link

@alysson-pina alysson-pina commented Mar 29, 2017

@eugeneo
Copy link
Contributor

@eugeneo eugeneo commented Mar 29, 2017

Where do you see the error? How do you run the Node to debug TypeScript?

@alysson-pina
Copy link

@alysson-pina alysson-pina commented Mar 29, 2017

@eugeneo
Copy link
Contributor

@eugeneo eugeneo commented Mar 29, 2017

@alysson-pina
Copy link

@alysson-pina alysson-pina commented Mar 29, 2017

@rafraph
Copy link

@rafraph rafraph commented Apr 27, 2017

So the final conclusion is that there is no way to debug node written in TypeScript?

@styfle
Copy link
Member

@styfle styfle commented Apr 27, 2017

@rafraph This is probably not the place to ask how to debug TypeScript. Lookup Debugging with Source Maps, I'm sure there are lots of tutorials. If you get stuck, ask on https://StackOverflow.com

@rafraph
Copy link

@rafraph rafraph commented Apr 27, 2017

I'm not asking how to debug typescript. From reading this thread it seems that debugging node written in TypeScript is not supported in Chrome. After @alysson-pina asked his question, it seems from the answers that this is not supported, so I just want to know if this is the final conclusion.
BTW, I asked it in StackOverflow.com and someone send me to here, so this is an infinite loop :-)

@alysson-pina
Copy link

@alysson-pina alysson-pina commented Apr 27, 2017

@rafraph
Copy link

@rafraph rafraph commented Apr 27, 2017

What do you mean by "the same"? the traspiled code is totaly different and not really readable.

@FredyC
Copy link

@FredyC FredyC commented Apr 27, 2017

@rafraph And that's where source maps comes in :) #6792 (comment)

@finchalyzer finchalyzer mentioned this pull request May 31, 2017
11 of 11 tasks complete
@wzup
Copy link

@wzup wzup commented Jan 15, 2018

Is it true that live debug is impossible with this feature? I mean, debug an app with nodemon, for example, when nodemon restarts the server on every save Ctrl + S?

Currently Chrome Devtools breaks down when I save changes in my app:

dev tools

How to deal with it? How to make Devtools reconnect automatically?

@eugeneo
Copy link
Contributor

@eugeneo eugeneo commented Jan 18, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked issues

Successfully merging this pull request may close these issues.

None yet