denoland / deno

A modern runtime for JavaScript and TypeScript.
https://deno.com
MIT License
93.73k stars 5.21k forks source link

When `--inspect` is passed, wait until connection before running? #12417

Closed kitsonk closed 2 years ago

kitsonk commented 2 years ago

There are situations in vscode where when the code is launched with --inspect, Deno runs the program and exits before the vscode debugger can connect, causing problems with being able to debug code where a breakpoint is set. (see: denoland/vscode_deno#557)

Is there a logical way to not run code when --inspect is provided until a client is connected on the port? This is different than --inspect-brk where the code breaks at the first point, it would be to give time for a client to connect and provide break-points.

devmattrick commented 2 years ago

For me, even using --inspect-brk exits immediately in VSCode's debugger.

kitsonk commented 2 years ago

@devmattrick that does not sound like this issue, then.

bartlomieju commented 2 years ago

This is actually what Node.js does too, given:

// foo.js
console.log("foo");

Run in Node.js:

❯ node --inspect foo.js
Debugger listening on ws://127.0.0.1:9229/c1addda4-de08-4c12-a0ed-0e2a1284241a
For help, see: https://nodejs.org/en/docs/inspector
asdf

It runs code and exits immediately.

In comparison, run in Deno:

❯ deno run --inspect foo1.js
Debugger listening on ws://127.0.0.1:9229/ws/a50ae203-ad1d-4e0d-b82c-a4231be1dc35
foo

So I think the behavior is correct, but we need to investigate problems with --inspect-brk.

kitsonk commented 2 years ago

ok, need to check what the behaviour is when debugging NodeJS applications in VSCode and if not using --inspect-brk just "dumps" without starting the debug tools like it does in Deno then.

bartlomieju commented 2 years ago

I did some digging into this issue an here's what I found:

  1. I created 3 files (node.js, deno.js, deno.ts), each of the files just prints a console statement:
    console.log("Hello from {name}");
  2. For each of the files I opened debugger pane and clicked "Run and Debug", selecting default debugger options (either Node or Deno) Screenshot 2021-12-23 at 19 24 09
  3. The result are as follows:
    • node.js Screenshot 2021-12-23 at 19 25 02
    • deno.js Screenshot 2021-12-23 at 19 25 28
    • deno.ts Screenshot 2021-12-23 at 19 26 05

As can be seen in the screen shots, neither deno.js nor deno.ts print out the message to the console. I'm 90% sure this is caused by https://github.com/denoland/deno/issues/13006

bartlomieju commented 2 years ago

So I fixed the (IMO) underlying issue in https://github.com/denoland/deno/pull/13191 but when I try to run the same code in VSCode there's still no output. It does seem like the process is starting, but nothing shows up in the Debug console... @kitsonk do you have any idea if there's some special handling required for messages to show in that console? Maybe we need to redirect stdio of the spawned process somewhere?

kitsonk commented 2 years ago

I haven't tried the branch, but a recent build off master demonstrates that with --inspect-brk the console output gets sent to the console, just like with Node, so if it isn't behaving exactly like Node.js, something else is amiss.

ins_js_—_scratch

bartlomieju commented 2 years ago

It does work for me with --inspect-brk too (ie. breakpoint is set and execution pauses); what concerns me is that it doesn't work with just --inspect.

I will add debug logging to Deno's inspector and see what messages are being exchanged between the binary and VSCode.

kitsonk commented 2 years ago

I am sure it is the same if you use about:inspect in Chrome. With --inspect-brk I see Deno in about:inspect and can connect to it. I am going to try with --inspect.

bartlomieju commented 2 years ago

I am sure it is the same if you use about:inspect in Chrome. With --inspect-brk I see Deno in about:inspect and can connect to it. I am going to try with --inspect.

For both Node and Deno I don't see any targets in chrome://inspect - but that's expected IMO, since the code finishes immediately.

kitsonk commented 2 years ago

Ok, I checked out the branch... if I do this:

console.log("hello");

I don't get anything in the output, just like expected, but if I do:

console.log("hello");

await new Promise((res) => {
  setTimeout(() => {
    console.log("deno");
    res();
  }, 5000);
});

Then there is enough time to connect to the inspector port and get the information and I see both lines logged to the console. So I am not sure the waiting is actually working properly in #13191 or at least it isn't working in a way that exhibits the same behaviour as Node, or Deno is just that much faster.

bartlomieju commented 2 years ago

My other suspicion is that VSCode debugger integration requires some special handling, however I haven't found anything yet in the docs about it. Anyway, something to look into after Christmas.

kitsonk commented 2 years ago

Well it doesn't... because if the program takes a bit longer, then everything works fine. For example, on my local machine, using a build of #13191 this works:

console.log("hello");

await new Promise((res) => {
  setTimeout(() => {
    console.log("deno");
    res(undefined);
  }, 750);
});

But this behaves with the "blank" behaviour... the "red bar" never appears:

console.log("hello");

await new Promise((res) => {
  setTimeout(() => {
    console.log("deno");
    res(undefined);
  }, 500);
});

This is my launch.json:

{
  "version": "0.2.0",
  "configurations": [
    {
      "request": "launch",
      "name": "Launch Program",
      "type": "pwa-node",
      "program": "${workspaceFolder}/ins.ts",
      "cwd": "${workspaceFolder}",
      "runtimeExecutable": "deno",
      "runtimeArgs": [
        "run",
        "--inspect",
      ],
      "attachSimplePort": 9229
    }
  ]
}
bartlomieju commented 2 years ago

So, should we just agree that "we're too fast" in the simplest cases and this works as expected?

kitsonk commented 2 years ago

Yeah, because I just tried with Node 15 using:

{
  "version": "0.2.0",
  "configurations": [
    {
      "request": "launch",
      "name": "Launch Program",
      "type": "pwa-node",
      "program": "${workspaceFolder}/ins.mjs",
      "cwd": "${workspaceFolder}",
      "runtimeExecutable": "node",
      "runtimeArgs": [
        "--inspect",
      ],
      "attachSimplePort": 9229
    }
  ]
}

An got the same behaviour... a "blank" debug until I increased the timeout.

bartlomieju commented 2 years ago

Thanks for checking it. I will update the manual page accordingly and close this issue then.

bartlomieju commented 2 years ago

I'm going to close this issue now that denoland/manual#201 is open.