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

REPL crashes after let process; #6802

Closed
mik-jozef opened this issue May 17, 2016 · 20 comments
Closed

REPL crashes after let process; #6802

mik-jozef opened this issue May 17, 2016 · 20 comments
Labels
confirmed-bug Issues with confirmed bugs. repl Issues and PRs related to the REPL subsystem.

Comments

@mik-jozef
Copy link

mik-jozef commented May 17, 2016

  • Version: v6.0.0
  • Platform: Windows 10 64bit
  • Subsystem: REPL

Steps to replicate:

  1. Open REPL
  2. Type "let process;"

Node crashes instead of displaying something like TypeError: Identifier 'process' has already been declared.

@addaleax addaleax added child_process Issues and PRs related to the child_process subsystem. repl Issues and PRs related to the REPL subsystem. and removed child_process Issues and PRs related to the child_process subsystem. labels May 17, 2016
@bnoordhuis
Copy link
Member

let process is basically equivalent to process = undefined because it runs in the top-level (i.e., global) scope.

The REPL (and node in general) will let you do that but it won't end well. let Object or let Array have the same issue. I don't know if I'd say this is an actual bug, just mildly unexpected behavior.

@mik-jozef
Copy link
Author

But why crash instead of displaying an error as if I typed "let x" two times?

@Fishrock123
Copy link
Contributor

Interesting. var process; doesn't crash. Here's the stack:

> var process
undefined
> let process
undefined
domain.js:99
        process._emittingTopLevelDomainError = false;
                                             ^

TypeError: Cannot set property '_emittingTopLevelDomainError' of undefined
    at Domain.errorHandler [as _errorHandler] (domain.js:99:46)
    at process._fatalException (node.js:265:33)

@jasnell
Copy link
Member

jasnell commented May 17, 2016

More interesting is that var process; does not actually redefine process

> var process;
undefined
> process;
{ process object output }

As @bnoordhuis indicates, I don't think this is an actual bug but it is rather odd.

@Fishrock123
Copy link
Contributor

cc @nodejs/v8 probably

@Fishrock123 Fishrock123 added the v8 engine Issues and PRs related to the V8 dependency. label May 17, 2016
@bnoordhuis
Copy link
Member

More interesting is that var process; does not actually redefine process

That's consistent with var semantics, it reuses the existing 'slot' if there is one.

The undefined return value that the REPL prints is because var process; is a statement that doesn't produce a value.

@addaleax
Copy link
Member

Confirmed that this would be fixed by #5703 while going through the open PRs.

@lance
Copy link
Member

lance commented May 18, 2016

This does not seem like a bug to me.

> let process;

This creates a process variable in the current lexical environment, shadowing the global process object. It's uninitialized, therefore undefined, but node depends on the process object, and now it's undefined. There is no way to recover from this.

@mik-jozef what would you suggest, display an error and then what? There's no way to continue with process now undefined. You could isolate this assignment in its own lexical environment, similar to this below, but there is no way at the top level to set process to something else and expect it to not be broken.

> function foo() {
... let process;
... console.log(process.nextTick);
... }
undefined
> console.log(process.nextTick);
[Function: nextTick]
undefined
> foo();
TypeError: Cannot read property 'nextTick' of undefined
    at foo (repl:3:20)
    at repl:1:1
    at REPLServer.defaultEval (repl.js:272:27)
    at bound (domain.js:280:14)
    at REPLServer.runBound [as eval] (domain.js:293:12)
    at REPLServer.<anonymous> (repl.js:441:10)
    at emitOne (events.js:101:20)
    at REPLServer.emit (events.js:188:7)
    at REPLServer.Interface._onLine (readline.js:219:10)
    at REPLServer.Interface._line (readline.js:561:8)
>  console.log(process.nextTick)
[Function: nextTick]
undefined
>

As for var process, as @bnoordhuis said, this is how var works. From the ES2015 spec, "Within the scope of any VariableEnvironment a common BindingIdentifier may appear in more than one VariableDeclaration but those declarations collective define only one variable." So just typing var process doesn't do anything at all, really. Try typing var process = undefined and you'll find that the behavior is the same as that of let because now that common variable name has been redefined.

@addaleax I'm not sure how #5703 would affect this. In fact, all of the examples I've shown in this comment were run on that branch. Can you help me understand what would be different here?

@cjihrig
Copy link
Contributor

cjihrig commented May 18, 2016

By not using the global context, you can define a variable named process without overwriting Node's global.

@lance
Copy link
Member

lance commented May 18, 2016

@cjihrig ok that makes sense, of course. I'll take a look at the PR and write a test.

@bnoordhuis bnoordhuis removed the v8 engine Issues and PRs related to the V8 dependency. label Jun 27, 2016
@bnoordhuis
Copy link
Member

I'm closing this as not-a-bug for now, reopen if you feel that is mistaken. #5703, if/when it lands, should alleviate this gotcha.

lance added a commit that referenced this issue Jun 30, 2016
Documentation for REPL states that the default value of `useGlobal` is
`false`. It makes no distinction between a REPL that is created
programmatically, and the one a user is dropped into on the command line
by executing `node` with no arguments. This change ensures that the CLI
REPL uses a default value of `false`.

Fixes: #5659
Ref: #6802
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
PR-URL: #5703
Fishrock123 pushed a commit that referenced this issue Jul 5, 2016
Documentation for REPL states that the default value of `useGlobal` is
`false`. It makes no distinction between a REPL that is created
programmatically, and the one a user is dropped into on the command line
by executing `node` with no arguments. This change ensures that the CLI
REPL uses a default value of `false`.

Fixes: #5659
Ref: #6802
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
PR-URL: #5703
@cjihrig
Copy link
Contributor

cjihrig commented Jul 21, 2016

#5703 was just reverted, so I'm going to reopen this. @bnoordhuis (or anyone else), if you think this should remain closed, feel free.

@cjihrig cjihrig reopened this Jul 21, 2016
@jasnell jasnell added the confirmed-bug Issues with confirmed bugs. label May 30, 2017
@benjamingr
Copy link
Member

I wonder, if we define process with a const binding in the process it should and not a var binding, basically, kind of like doing:

> const _p = process;
undefined
> const process = _p;
undefined
> let process
SyntaxError: Identifier 'process' has already been declared

What do you think about fixing this ad-hoc for process?

@gibfahn
Copy link
Member

gibfahn commented Jul 17, 2017

What do you think about fixing this ad-hoc for process?

I guess the only argument against doing that is that there might be a legitimate reason for someone to modify/overwrite the process object. IDK if there is one.

@TimothyGu
Copy link
Member

@benjamingr Huh? Is that related to this issue?

@benjamingr
Copy link
Member

@TimothyGu sorry - wrong PR :D

@benjamingr
Copy link
Member

I guess the only argument against doing that is that there might be a legitimate reason for someone to modify/overwrite the process object. IDK if there is one.

The possibility kind of sways me from warning to fix this. Just like we don't guard against people modifying process or anything else inside Node - I don't think the REPL should be special - and while ES scoping rules are quirky here they are ES scoping rules.

@gibfahn
Copy link
Member

gibfahn commented Jul 20, 2017

Maybe the repl could just print a warning if you change any of the built-in objects, e.g.:

Doing this overwrites a global object, which can destroy this REPL instance. I hope you know what you're doing!

We could also in theory have an Are you sure you want to do this? Enter/Ctrl+C prompt, but I think I'd be -1 on that, it'd be a pain, and reopening the repl isn't exactly a big problem.

I'm assuming the issue is people not realising that process is a built-in object, so printing a warning should be enough.

@lance
Copy link
Member

lance commented Nov 21, 2017

My instinct is to consider this not a bug and leave it as-is. There is no way to recover if the user sets or undefines the global process object. It would be possible check for this assignment in the REPL code and recover somewhat gracefully by printing a warning, as you suggest @gibfahn. Naively, that would mean adding code to the REPL to parse each line looking for the assignment. But why should code in the REPL be treated differently than in a standard runtime? I don't think it's a good idea.

The only reasonable approach, IMO is to define global.process as a const at startup. The process object is created here and set in the environment through a series of macros. Unwinding all of that and treating process differently is perhaps beyond my pay grade at the moment. :)

I recommend closing this issue.

addaleax added a commit to addaleax/node that referenced this issue Nov 21, 2017
Share `process` through the module wrapper rather than relying
on nobody messing with `global.process`.

Fixes: nodejs#6802
@addaleax
Copy link
Member

@lance Thanks for commenting here – I think this might actually be easily fixed now that we have a different module wrapper for built-ins? PR to try it out @ #17198

apapirovski pushed a commit to apapirovski/node that referenced this issue Feb 26, 2018
Share `process` through the module wrapper rather than relying
on nobody messing with `global.process`.

PR-URL: nodejs#17198
Fixes: nodejs#6802
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Lance Ball <lball@redhat.com>
Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Alexey Orlenko <eaglexrlnk@gmail.com>
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Timothy Gu <timothygu99@gmail.com>
Reviewed-By: Refael Ackermann <refack@gmail.com>
addaleax added a commit that referenced this issue Feb 26, 2018
Share `process` through the module wrapper rather than relying
on nobody messing with `global.process`.

Backport-PR-URL: #19006
PR-URL: #17198
Fixes: #6802
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Lance Ball <lball@redhat.com>
Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Alexey Orlenko <eaglexrlnk@gmail.com>
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Timothy Gu <timothygu99@gmail.com>
Reviewed-By: Refael Ackermann <refack@gmail.com>
addaleax added a commit that referenced this issue Feb 26, 2018
Share `process` through the module wrapper rather than relying
on nobody messing with `global.process`.

Backport-PR-URL: #19006
PR-URL: #17198
Fixes: #6802
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Lance Ball <lball@redhat.com>
Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Alexey Orlenko <eaglexrlnk@gmail.com>
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Timothy Gu <timothygu99@gmail.com>
Reviewed-By: Refael Ackermann <refack@gmail.com>
MylesBorins pushed a commit that referenced this issue Feb 26, 2018
Share `process` through the module wrapper rather than relying
on nobody messing with `global.process`.

Backport-PR-URL: #19006
PR-URL: #17198
Fixes: #6802
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Lance Ball <lball@redhat.com>
Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Alexey Orlenko <eaglexrlnk@gmail.com>
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Timothy Gu <timothygu99@gmail.com>
Reviewed-By: Refael Ackermann <refack@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
confirmed-bug Issues with confirmed bugs. repl Issues and PRs related to the REPL subsystem.
Projects
None yet
Development

No branches or pull requests

10 participants