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

Line numbers reported from code in new Function are incorrect #32688

Closed
connor4312 opened this issue Apr 6, 2020 · 8 comments
Closed

Line numbers reported from code in new Function are incorrect #32688

connor4312 opened this issue Apr 6, 2020 · 8 comments
Labels
inspector Issues and PRs related to the V8 inspector protocol

Comments

@connor4312
Copy link
Contributor

connor4312 commented Apr 6, 2020

  • Version: 13.12.0
  • Platform: Windows
  • Subsystem: unsure

What steps will reproduce the bug?

Copied from microsoft/vscode#94437

  1. Create a file containing
const code = `    console.log(arg1);
    const a = arg1 + 1;
    console.log(a);
    return a;`;

const fn = new Function('arg1', code);
console.log(process.version);
const result = fn(1);
console.log('result', result);

2 Either in Chrome devtools attached to the process, or a debugger like VS Code, set a breakpoint on const result = fn(1);
3. Step into and through the evaluated function

How often does it reproduce? Is there a required condition?

Every time

What is the expected behavior?

The debugger should show the line being evaluated currently

What do you see instead?

The debugger is two lines off (notice '1' is logged even though I haven't gotten there yet)

This does not happen when running the code directly Chrome or Chrome Canary; it seems to be Node-specific behavior.

Additional information

Looking in CDP, this is the data I see:

{
  "method": "Debugger.paused",
  "params": {
    "callFrames": [
      {
        "callFrameId": "{\"ordinal\":0,\"injectedScriptId\":1}",
        "functionName": "",
        "functionLocation": {
          "scriptId": "130",
          "lineNumber": -2,   // <- this part is weird!
          "columnNumber": 19
        },
        {
          "scriptId": "130",
          "lineNumber": 0, // <- should be 2, not 0
          "columnNumber": 4
        }
        "url": "",
        
        // ...

It seems like Node.js offsets the evaluated code so that the generated function head is before the 'start' of the file, I assume so that stacktraces show the right line. However, this messes up debuggers. Some suggestions:

  • Make the function header a single line prefixing the user's function, like the module wrapper, so that line numbers are identical.
  • In the Debugger.scriptParsed event, set the startLine to compensate for the header. I think this should make all debuggers 'just work' provided they deal with the lineNumber as a signed integer.
  • Don't send the wrapper code in Debugger.getScriptSource
@addaleax addaleax added the inspector Issues and PRs related to the V8 inspector protocol label Apr 6, 2020
@devsnek
Copy link
Member

devsnek commented Apr 6, 2020

the generated function here is expected and spec compliant, we should not change that.

@connor4312
Copy link
Contributor Author

connor4312 commented Apr 6, 2020

To clarify on the first suggestion, that would be changing the prefix from (function anonymous(arg1\n) {\n to (function anonymous(arg1) {. It shouldn't have any negative runtime side-effects, but I'm not versed enough to know whether doing so would violate spec 🙂

Thinking about it more the second approach--to send the range in scriptParsed--is probably better, that would let the debugger also be smart about what code is shown. I could hide or grey out the generated wrapper, whereas changing the prefix would cause it to still be shown to the user.

@devsnek
Copy link
Member

devsnek commented Apr 6, 2020

To clarify on the first suggestion, that would be changing the prefix from (function anonymous(arg1\n) {\n to (function anonymous(arg1) {. It shouldn't have any negative runtime side-effects, but I'm not versed enough to know whether doing so would violate spec 🙂

It would violate the spec, as I said above.

It looks like CDP is expecting VSC to perform certain offset calculations that it is not. This doesn't seem to be a bug in node.

@connor4312
Copy link
Contributor Author

connor4312 commented Apr 6, 2020

Chrome (incl Canary) do not exhibit this behavior, and it causes a 'bug' in the Chrome devtools as well if you inspect a Node.js process via chrome://inspect. If it is a matter of not following CDP, it would be quite surprising to me that the Chrome devtools would have the same behavior.

If I were to correct this on VS Code side, I'm not sure what code I would need to write other than special casing the Node version and eval'd script, because there's nothing I can see in the protocol coming from Node that would indicate that this specific script starts at a negative line number. This also increases my doubt that it's a bug on the VS Code side, but I could be missing something...

When running the code in Chrome and using its protocol monitor, it puts the functionLocation at line 0 and the paused location is correctly at lineNumber 2.

@targos
Copy link
Member

targos commented Apr 6, 2020

I can reproduce this and the reason it works in Chrome may be that it was fixed in a recent version of V8.

We should check if it works with a nightly build of Node.js master. I'm trying to download the latest one but not sure I'll be able to with the current infra issues.

@targos
Copy link
Member

targos commented Apr 6, 2020

Okay, I confirm it works correctly with v14.0.0-nightly2020040504b71848af.
I'll try to bisect v8-canary later this week.

@targos
Copy link
Member

targos commented Apr 8, 2020

So... I managed to reduce the range of V8 commits to v8/v8@6987ee4...63da839

This one looks like a really good candidate: v8/v8@dc3a90b

I do not have time to try and backport this to v13.x. Anyone feel free to do it!

targos added a commit to targos/node that referenced this issue Apr 12, 2020
Original commit message:

    [debug] Revert to old line number behavior for new Function()

    Reverting https://chromium-review.googlesource.com/c/v8/v8/+/1741660

    This fixed one bug but caused a lot of others and on balance I think
    reverting it is the lesser evil.

    This also fixed generator-relocation.js because
    (function*(){}).constructor is the function constructor and we try to
    set a breakpoint on line 3.

    Bug: chromium:109362, chromium:1028689
    Fixes: v8:9721
    Change-Id: I1bfe6ec57ce77ea7292df91266311f5c0194947e
    Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1940259
    Commit-Queue: Peter Marshall <[email protected]>
    Reviewed-by: Yang Guo <[email protected]>
    Cr-Commit-Position: refs/heads/master@{#65232}

Refs: v8/v8@dc3a90b

Revert "assert: fix line number calculation after V8 upgrade"

This reverts commit 5981fb7.

Fixes: nodejs#32688
targos added a commit that referenced this issue Apr 28, 2020
Original commit message:

    [debug] Revert to old line number behavior for new Function()

    Reverting https://chromium-review.googlesource.com/c/v8/v8/+/1741660

    This fixed one bug but caused a lot of others and on balance I think
    reverting it is the lesser evil.

    This also fixed generator-relocation.js because
    (function*(){}).constructor is the function constructor and we try to
    set a breakpoint on line 3.

    Bug: chromium:109362, chromium:1028689
    Fixes: v8:9721
    Change-Id: I1bfe6ec57ce77ea7292df91266311f5c0194947e
    Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1940259
    Commit-Queue: Peter Marshall <[email protected]>
    Reviewed-by: Yang Guo <[email protected]>
    Cr-Commit-Position: refs/heads/master@{#65232}

Refs: v8/v8@dc3a90b

Revert "assert: fix line number calculation after V8 upgrade"

This reverts commit 5981fb7.

Fixes: #32688

PR-URL: #32795
Reviewed-By: Ben Noordhuis <[email protected]>
@connor4312
Copy link
Contributor Author

This is no longer an issue on Node 16

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
inspector Issues and PRs related to the V8 inspector protocol
Projects
None yet
Development

No branches or pull requests

4 participants