GeezerVison is showing github.com — inspector: introduce the `--inspect-wait` flag · nodejs/node@8748dd6
File treeExpand file treeCollapse file tree Open diff view settings Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboardExpand all lines: doc/api/cli.md +16Lines changed: 16 additions & 0 deletions - Display the source diff
- Display the rich diff
| Original file line number | Diff line number | Diff line change |
|---|
@@ -1270,6 +1270,7 @@ Activate inspector on `host:port`. Default is `127.0.0.1:9229`. | 1270 | 1270 | V8 inspector integration allows tools such as Chrome DevTools and IDEs to debug | 1271 | 1271 | and profile Node.js instances. The tools attach to Node.js instances via a | 1272 | 1272 | tcp port and communicate using the [Chrome DevTools Protocol][]. | | 1273 | +See [V8 Inspector integration for Node.js][] for further explanation on Node.js debugger. | 1273 | 1274 |
| 1274 | 1275 | <!-- Anchor to make sure old links find a target --> | 1275 | 1276 |
| @@ -1300,6 +1301,8 @@ added: v7.6.0 | 1300 | 1301 | Activate inspector on `host:port` and break at start of user script. | 1301 | 1302 | Default `host:port` is `127.0.0.1:9229`. | 1302 | 1303 |
| | 1304 | +See [V8 Inspector integration for Node.js][] for further explanation on Node.js debugger. | | 1305 | + | 1303 | 1306 | ### `--inspect-port=[host:]port` | 1304 | 1307 |
| 1305 | 1308 | <!-- YAML | @@ -1321,6 +1324,17 @@ Specify ways of the inspector web socket url exposure. | 1321 | 1324 | By default inspector websocket url is available in stderr and under `/json/list` | 1322 | 1325 | endpoint on `http://host:port/json/list`. | 1323 | 1326 |
| | 1327 | +### `--inspect-wait[=[host:]port]` | | 1328 | + | | 1329 | +<!-- YAML | | 1330 | +added: REPLACEME | | 1331 | +--> | | 1332 | + | | 1333 | +Activate inspector on `host:port` and wait for debugger to be attached. | | 1334 | +Default `host:port` is `127.0.0.1:9229`. | | 1335 | + | | 1336 | +See [V8 Inspector integration for Node.js][] for further explanation on Node.js debugger. | | 1337 | + | 1324 | 1338 | ### `-i`, `--interactive` | 1325 | 1339 |
| 1326 | 1340 | <!-- YAML | @@ -2709,6 +2723,7 @@ one is included in the list below. | 2709 | 2723 | * `--inspect-brk` | 2710 | 2724 | * `--inspect-port`, `--debug-port` | 2711 | 2725 | * `--inspect-publish-uid` | | 2726 | +* `--inspect-wait` | 2712 | 2727 | * `--inspect` | 2713 | 2728 | * `--max-http-header-size` | 2714 | 2729 | * `--napi-modules` | @@ -3205,6 +3220,7 @@ node --stack-trace-limit=12 -p -e "Error.stackTraceLimit" # prints 12 | 3205 | 3220 | [ScriptCoverage]: https://chromedevtools.github.io/devtools-protocol/tot/Profiler#type-ScriptCoverage | 3206 | 3221 | [ShadowRealm]: https://github.com/tc39/proposal-shadowrealm | 3207 | 3222 | [Source Map]: https://sourcemaps.info/spec.html | | 3223 | +[V8 Inspector integration for Node.js]: debugger.md#v8-inspector-integration-for-nodejs | 3208 | 3224 | [V8 JavaScript code coverage]: https://v8project.blogspot.com/2017/12/javascript-code-coverage.html | 3209 | 3225 | [V8 code cache]: https://v8.dev/blog/code-caching-for-devs | 3210 | 3226 | [Web Crypto API]: webcrypto.md | |
Collapse file Copy file name to clipboardExpand all lines: doc/api/debugger.md +15-2Lines changed: 15 additions & 2 deletions - Display the source diff
- Display the rich diff
| Original file line number | Diff line number | Diff line change |
|---|
@@ -234,8 +234,21 @@ V8 Inspector can be enabled by passing the `--inspect` flag when starting a | 234 | 234 | Node.js application. It is also possible to supply a custom port with that flag, | 235 | 235 | e.g. `--inspect=9222` will accept DevTools connections on port 9222. | 236 | 236 |
| 237 | | -To break on the first line of the application code, pass the `--inspect-brk` | 238 | | -flag instead of `--inspect`. | | 237 | +Using the `--inspect` flag will execute the code immediately before debugger is connected. | | 238 | +This means that the code will start running before you can start debugging, which might | | 239 | +not be ideal if you want to debug from the very beginning. | | 240 | + | | 241 | +In such cases, you have two alternatives: | | 242 | + | | 243 | +1. `--inspect-wait` flag: This flag will wait for debugger to be attached before executing the code. | | 244 | + This allows you to start debugging right from the beginning of the execution. | | 245 | +2. `--inspect-brk` flag: Unlike `--inspect`, this flag will break on the first line of the code | | 246 | + as soon as debugger is attached. This is useful when you want to debug the code step by step | | 247 | + from the very beginning, without any code execution prior to debugging. | | 248 | + | | 249 | +So, when deciding between `--inspect`, `--inspect-wait`, and `--inspect-brk`, consider whether you want | | 250 | +the code to start executing immediately, wait for debugger to be attached before execution, | | 251 | +or break on the first line for step-by-step debugging. | 239 | 252 |
| 240 | 253 | ```console | 241 | 254 | $ node --inspect index.js | |
Collapse file Copy file name to clipboardExpand all lines: doc/node.1 +5Lines changed: 5 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| 281 | 281 | Default is | 282 | 282 | .Sy stderr,http . | 283 | 283 | . | | 284 | +.It Fl -inspect-wait Ns = Ns Ar [host:]port | | 285 | +Activate inspector on | | 286 | +.Ar host:port | | 287 | +and wait for debugger to be attached. | | 288 | +. | 284 | 289 | .It Fl -inspect Ns = Ns Ar [host:]port | 285 | 290 | Activate inspector on | 286 | 291 | .Ar host:port . | |
Collapse file Copy file name to clipboardExpand all lines: src/inspector_agent.cc +12-8Lines changed: 12 additions & 8 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -743,20 +743,24 @@ bool Agent::Start(const std::string& path, | 743 | 743 | }, parent_env_); | 744 | 744 |
| 745 | 745 | bool wait_for_connect = options.wait_for_connect(); | | 746 | + bool should_break_first_line = options.should_break_first_line(); | 746 | 747 | if (parent_handle_) { | 747 | | - wait_for_connect = parent_handle_->WaitForConnect(); | 748 | | - parent_handle_->WorkerStarted(client_->getThreadHandle(), wait_for_connect); | | 748 | + should_break_first_line = parent_handle_->WaitForConnect(); | | 749 | + parent_handle_->WorkerStarted(client_->getThreadHandle(), | | 750 | + should_break_first_line); | 749 | 751 | } else if (!options.inspector_enabled || !options.allow_attaching_debugger || | 750 | 752 | !StartIoThread()) { | 751 | 753 | return false; | 752 | 754 | } | 753 | 755 |
| 754 | | - // Patch the debug options to implement waitForDebuggerOnStart for | 755 | | - // the NodeWorker.enable method. | 756 | | - if (wait_for_connect) { | 757 | | - CHECK(!parent_env_->has_serialized_options()); | 758 | | - debug_options_.EnableBreakFirstLine(); | 759 | | - parent_env_->options()->get_debug_options()->EnableBreakFirstLine(); | | 756 | + if (wait_for_connect || should_break_first_line) { | | 757 | + // Patch the debug options to implement waitForDebuggerOnStart for | | 758 | + // the NodeWorker.enable method. | | 759 | + if (should_break_first_line) { | | 760 | + CHECK(!parent_env_->has_serialized_options()); | | 761 | + debug_options_.EnableBreakFirstLine(); | | 762 | + parent_env_->options()->get_debug_options()->EnableBreakFirstLine(); | | 763 | + } | 760 | 764 | client_->waitForFrontend(); | 761 | 765 | } | 762 | 766 | return true; | |
Collapse file Copy file name to clipboardExpand all lines: src/node_options.cc +8Lines changed: 8 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -331,6 +331,14 @@ DebugOptionsParser::DebugOptionsParser() { | 331 | 331 | Implies("--inspect-brk-node", "--inspect"); | 332 | 332 | AddAlias("--inspect-brk-node=", { "--inspect-port", "--inspect-brk-node" }); | 333 | 333 |
| | 334 | + AddOption( | | 335 | + "--inspect-wait", | | 336 | + "activate inspector on host:port and wait for debugger to be attached", | | 337 | + &DebugOptions::inspect_wait, | | 338 | + kAllowedInEnvvar); | | 339 | + Implies("--inspect-wait", "--inspect"); | | 340 | + AddAlias("--inspect-wait=", {"--inspect-port", "--inspect-wait"}); | | 341 | + | 334 | 342 | AddOption("--inspect-publish-uid", | 335 | 343 | "comma separated list of destinations for inspector uid" | 336 | 344 | "(default: stderr,http)", | |
Collapse file Copy file name to clipboardExpand all lines: src/node_options.h +6Lines changed: 6 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -71,6 +71,8 @@ class DebugOptions : public Options { | 71 | 71 | bool allow_attaching_debugger = true; | 72 | 72 | // --inspect | 73 | 73 | bool inspector_enabled = false; | | 74 | + // --inspect-wait | | 75 | + bool inspect_wait = false; | 74 | 76 | // --debug | 75 | 77 | bool deprecated_debug = false; | 76 | 78 | // --inspect-brk | @@ -93,6 +95,10 @@ class DebugOptions : public Options { | 93 | 95 | } | 94 | 96 |
| 95 | 97 | bool wait_for_connect() const { | | 98 | + return break_first_line || break_node_first_line || inspect_wait; | | 99 | + } | | 100 | + | | 101 | + bool should_break_first_line() const { | 96 | 102 | return break_first_line || break_node_first_line; | 97 | 103 | } | 98 | 104 |
| |
Collapse file Copy file name to clipboard +28Lines changed: 28 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| | 1 | +import * as common from '../common/index.mjs'; | | 2 | + | | 3 | +common.skipIfInspectorDisabled(); | | 4 | + | | 5 | +import assert from 'node:assert'; | | 6 | +import { NodeInstance } from '../common/inspector-helper.js'; | | 7 | + | | 8 | + | | 9 | +async function runTests() { | | 10 | + const child = new NodeInstance(['--inspect-wait=0'], 'console.log(0);'); | | 11 | + const session = await child.connectInspectorSession(); | | 12 | + await session.send({ method: 'NodeRuntime.enable' }); | | 13 | + await session.waitForNotification('NodeRuntime.waitingForDebugger'); | | 14 | + | | 15 | + // The execution should be paused until the debugger is attached | | 16 | + while (await child.nextStderrString() !== 'Debugger attached.'); | | 17 | + | | 18 | + await session.send({ 'method': 'Runtime.runIfWaitingForDebugger' }); | | 19 | + | | 20 | + // Wait for the execution to finish | | 21 | + while (await child.nextStderrString() !== 'Waiting for the debugger to disconnect...'); | | 22 | + | | 23 | + await session.send({ method: 'NodeRuntime.disable' }); | | 24 | + session.disconnect(); | | 25 | + assert.strictEqual((await child.expectShutdown()).exitCode, 0); | | 26 | +} | | 27 | + | | 28 | +runTests().then(common.mustCall()); |
|