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

NODE_V8_COVERAGE broken on OSX (perhaps other platforms) #25287

Closed
bcoe opened this issue Dec 30, 2018 · 9 comments
Closed

NODE_V8_COVERAGE broken on OSX (perhaps other platforms) #25287

bcoe opened this issue Dec 30, 2018 · 9 comments
Assignees

Comments

@bcoe
Copy link
Contributor

bcoe commented Dec 30, 2018

#25127 seems to break coverage on OSX:

NODE_V8_COVERAGE=.coverage ./node ./test/parallel/test-v8-coverage.js 

TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be one of type string, Buffer, or URL. Received type undefined
    at mkdirSync (fs.js:766:3)
    at process.writeCoverage (internal/process/coverage.js:16:5)
    at process.emit (events.js:193:15)

My guess is that coverage might be initialized either before the inspector is running, or before the process.env object has been populated.

Not sure why this wouldn't have been caught in the linux test suite.

I believe this is the root cause of nodejs/node-v8#97

CC: @nodejs/build

@cjihrig
Copy link
Contributor

cjihrig commented Dec 30, 2018

Initializing coverage, relies on path.resolve(), which uses process.cwd(), which hasn't been setup yet. The following patch seems to fix the problem on my machine, which is macOS:

diff --git a/lib/internal/process/coverage.js b/lib/internal/process/coverage.js
index 5c5d0c2b61..e3cf74f395 100644
--- a/lib/internal/process/coverage.js
+++ b/lib/internal/process/coverage.js
@@ -76,9 +76,10 @@ function setup() {
   }));
 
   try {
+    const { cwd } = internalBinding('process_methods');
     const { resolve } = require('path');
     coverageDirectory = process.env.NODE_V8_COVERAGE =
-      resolve(process.env.NODE_V8_COVERAGE);
+      resolve(cwd(), process.env.NODE_V8_COVERAGE);
   } catch (err) {
     console.error(err);
   }

It might just be simpler to move the coverage setup until after the process object is setup in lib/internal/bootstrap/node.js though.

EDIT: It's also worth noting that the existing code without this patch does throw an exception, but console.error() is not set up yet either, which might be a stronger case for moving this to lib/internal/bootstrap/node.js.

@addaleax
Copy link
Member

Thanks for investigating! Joyee probably has an easier time digging in as she’s on OSX as well (I think).

before the process.env object has been populated.

This happens very early during bootstrap, so I assume it’s not that.

@cjihrig
Copy link
Contributor

cjihrig commented Dec 30, 2018

Here is an alternative approach that moves the coverage setup to a later point in the bootstrapping process. It sacrifices a bit of core internals coverage, but the process is in a much more usable state:

diff --git a/lib/internal/bootstrap/loaders.js b/lib/internal/bootstrap/loaders.js
index 93fb186574..d8d0827e2d 100644
--- a/lib/internal/bootstrap/loaders.js
+++ b/lib/internal/bootstrap/loaders.js
@@ -353,12 +353,6 @@ NativeModule.prototype.cache = function() {
   NativeModule._cache[this.id] = this;
 };
 
-// Coverage must be turned on early, so that we can collect
-// it for Node.js' own internal libraries.
-if (process.env.NODE_V8_COVERAGE) {
-  NativeModule.require('internal/process/coverage').setup();
-}
-
 function internalBindingWhitelistHas(name) {
   if (!internalBindingWhitelistSet) {
     const { SafeSet } = NativeModule.require('internal/safe_globals');
diff --git a/lib/internal/bootstrap/node.js b/lib/internal/bootstrap/node.js
index 3c14d4851a..87fd2076f3 100644
--- a/lib/internal/bootstrap/node.js
+++ b/lib/internal/bootstrap/node.js
@@ -141,7 +141,11 @@ function startup() {
     NativeModule.require('internal/process/write-coverage').setup();
 
   if (process.env.NODE_V8_COVERAGE) {
-    NativeModule.require('internal/process/coverage').setupExitHooks();
+    const { setup, setupExitHooks } =
+      NativeModule.require('internal/process/coverage');
+
+    setup();
+    setupExitHooks();
   }
 
   if (process.config.variables.v8_enable_inspector) {

@bcoe
Copy link
Contributor Author

bcoe commented Dec 30, 2018

@cjihrig my preference would be to keep the bootstrapping is early as possible, assuming we can actually raise a build failure if we have a regression like this. If we move initialization too late, it makes it difficult to use NODE_V8_COVERAGE for Node's own test coverage, defeating the motivation for a lot of this work -- perhaps we just need to do without the console.error message.

@devsnek
Copy link
Member

devsnek commented Dec 31, 2018

i'm in favor of the first patch.

@bcoe i think you can use process._rawDebug instead of console.error

@joyeecheung
Copy link
Member

For now, using methods that are available earlier during bootstrap sounds good to me (thanks @cjihrig !) though I wonder whether we should postpone the setup to some point later, or move setup() to C++. It's hard to imagine how to keep this working if we are going to pursue the snapshot - ideally none of per_context.js, loaders.js nor the early part of node.js should have execution flows that depend on CLI flags or environment variables in order to have a point to create a stable snapshot that can be loaded consistently later. Also when snapshots do happen I believe the coverage can not cover the JS code run before the snapshot capture anyways.

@joyeecheung
Copy link
Member

joyeecheung commented Dec 31, 2018

Another way to fix the particular issue at hand is to postpone the coverageDirectory initialization to a later point - IIUC, the only thing that needs to happen as early as possible is the Profiler.startPreciseCoverage dispatch. The initialization of coverageDirectory can at least be be postpone to any point prior to user code execution, and that's the only part that has transitive dependency on many other modules.

@bcoe
Copy link
Contributor Author

bcoe commented Dec 31, 2018

@joyeecheung you are correct that the Profiler.startPreciseCoverage is what needs to have run as early as possible.

Unrelated, shouldn't this have broken tests? we should make sure that our regression tests actually work before we land a fix.

@cjihrig
Copy link
Contributor

cjihrig commented Dec 31, 2018

Unrelated, shouldn't this have broken tests? we should make sure that our regression tests actually work before we land a fix.

I updated the coverage test in #25289, so this should be caught moving forward.

cjihrig added a commit to cjihrig/node that referenced this issue Jan 2, 2019
console is not ready to use at this point in the bootstrapping
process, so switch to process._rawDebug() instead.

PR-URL: nodejs#25289
Fixes: nodejs#25287
Reviewed-By: Anna Henningsen <[email protected]>
Reviewed-By: Gus Caplan <[email protected]>
Reviewed-By: Yuta Hiroto <[email protected]>
Reviewed-By: Joyee Cheung <[email protected]>
Reviewed-By: Luigi Pinca <[email protected]>
Reviewed-By: James M Snell <[email protected]>
cjihrig added a commit to cjihrig/node that referenced this issue Jan 2, 2019
During coverage setup, path.resolve() is called.
path.resolve() can potentially call process.cwd(), which
hasn't been bootstrapped yet. This commit passes the
current working directory directly so that path.resolve()
doesn't attempt to compute it.

PR-URL: nodejs#25289
Fixes: nodejs#25287
Reviewed-By: Anna Henningsen <[email protected]>
Reviewed-By: Gus Caplan <[email protected]>
Reviewed-By: Yuta Hiroto <[email protected]>
Reviewed-By: Joyee Cheung <[email protected]>
Reviewed-By: Luigi Pinca <[email protected]>
Reviewed-By: James M Snell <[email protected]>
cjihrig added a commit to cjihrig/node that referenced this issue Jan 2, 2019
Update the coverage test to verify that nothing is printed to
stderr (which happens when coverage errors happen). Also add a
test case to verify that non-absolute coverage paths work.

PR-URL: nodejs#25289
Fixes: nodejs#25287
Reviewed-By: Anna Henningsen <[email protected]>
Reviewed-By: Gus Caplan <[email protected]>
Reviewed-By: Yuta Hiroto <[email protected]>
Reviewed-By: Joyee Cheung <[email protected]>
Reviewed-By: Luigi Pinca <[email protected]>
Reviewed-By: James M Snell <[email protected]>
refack pushed a commit to refack/node that referenced this issue Jan 14, 2019
console is not ready to use at this point in the bootstrapping
process, so switch to process._rawDebug() instead.

PR-URL: nodejs#25289
Fixes: nodejs#25287
Reviewed-By: Anna Henningsen <[email protected]>
Reviewed-By: Gus Caplan <[email protected]>
Reviewed-By: Yuta Hiroto <[email protected]>
Reviewed-By: Joyee Cheung <[email protected]>
Reviewed-By: Luigi Pinca <[email protected]>
Reviewed-By: James M Snell <[email protected]>
refack pushed a commit to refack/node that referenced this issue Jan 14, 2019
During coverage setup, path.resolve() is called.
path.resolve() can potentially call process.cwd(), which
hasn't been bootstrapped yet. This commit passes the
current working directory directly so that path.resolve()
doesn't attempt to compute it.

PR-URL: nodejs#25289
Fixes: nodejs#25287
Reviewed-By: Anna Henningsen <[email protected]>
Reviewed-By: Gus Caplan <[email protected]>
Reviewed-By: Yuta Hiroto <[email protected]>
Reviewed-By: Joyee Cheung <[email protected]>
Reviewed-By: Luigi Pinca <[email protected]>
Reviewed-By: James M Snell <[email protected]>
refack pushed a commit to refack/node that referenced this issue Jan 14, 2019
Update the coverage test to verify that nothing is printed to
stderr (which happens when coverage errors happen). Also add a
test case to verify that non-absolute coverage paths work.

PR-URL: nodejs#25289
Fixes: nodejs#25287
Reviewed-By: Anna Henningsen <[email protected]>
Reviewed-By: Gus Caplan <[email protected]>
Reviewed-By: Yuta Hiroto <[email protected]>
Reviewed-By: Joyee Cheung <[email protected]>
Reviewed-By: Luigi Pinca <[email protected]>
Reviewed-By: James M Snell <[email protected]>
addaleax pushed a commit to addaleax/node that referenced this issue Jan 14, 2019
console is not ready to use at this point in the bootstrapping
process, so switch to process._rawDebug() instead.

PR-URL: nodejs#25289
Fixes: nodejs#25287
Reviewed-By: Anna Henningsen <[email protected]>
Reviewed-By: Gus Caplan <[email protected]>
Reviewed-By: Yuta Hiroto <[email protected]>
Reviewed-By: Joyee Cheung <[email protected]>
Reviewed-By: Luigi Pinca <[email protected]>
Reviewed-By: James M Snell <[email protected]>
addaleax pushed a commit to addaleax/node that referenced this issue Jan 14, 2019
During coverage setup, path.resolve() is called.
path.resolve() can potentially call process.cwd(), which
hasn't been bootstrapped yet. This commit passes the
current working directory directly so that path.resolve()
doesn't attempt to compute it.

PR-URL: nodejs#25289
Fixes: nodejs#25287
Reviewed-By: Anna Henningsen <[email protected]>
Reviewed-By: Gus Caplan <[email protected]>
Reviewed-By: Yuta Hiroto <[email protected]>
Reviewed-By: Joyee Cheung <[email protected]>
Reviewed-By: Luigi Pinca <[email protected]>
Reviewed-By: James M Snell <[email protected]>
addaleax pushed a commit to addaleax/node that referenced this issue Jan 14, 2019
Update the coverage test to verify that nothing is printed to
stderr (which happens when coverage errors happen). Also add a
test case to verify that non-absolute coverage paths work.

PR-URL: nodejs#25289
Fixes: nodejs#25287
Reviewed-By: Anna Henningsen <[email protected]>
Reviewed-By: Gus Caplan <[email protected]>
Reviewed-By: Yuta Hiroto <[email protected]>
Reviewed-By: Joyee Cheung <[email protected]>
Reviewed-By: Luigi Pinca <[email protected]>
Reviewed-By: James M Snell <[email protected]>
addaleax pushed a commit that referenced this issue Jan 15, 2019
console is not ready to use at this point in the bootstrapping
process, so switch to process._rawDebug() instead.

PR-URL: #25289
Fixes: #25287
Reviewed-By: Anna Henningsen <[email protected]>
Reviewed-By: Gus Caplan <[email protected]>
Reviewed-By: Yuta Hiroto <[email protected]>
Reviewed-By: Joyee Cheung <[email protected]>
Reviewed-By: Luigi Pinca <[email protected]>
Reviewed-By: James M Snell <[email protected]>

Backport-PR-URL: #25496
addaleax pushed a commit that referenced this issue Jan 15, 2019
During coverage setup, path.resolve() is called.
path.resolve() can potentially call process.cwd(), which
hasn't been bootstrapped yet. This commit passes the
current working directory directly so that path.resolve()
doesn't attempt to compute it.

PR-URL: #25289
Fixes: #25287
Reviewed-By: Anna Henningsen <[email protected]>
Reviewed-By: Gus Caplan <[email protected]>
Reviewed-By: Yuta Hiroto <[email protected]>
Reviewed-By: Joyee Cheung <[email protected]>
Reviewed-By: Luigi Pinca <[email protected]>
Reviewed-By: James M Snell <[email protected]>

Backport-PR-URL: #25496
addaleax pushed a commit that referenced this issue Jan 15, 2019
Update the coverage test to verify that nothing is printed to
stderr (which happens when coverage errors happen). Also add a
test case to verify that non-absolute coverage paths work.

PR-URL: #25289
Fixes: #25287
Reviewed-By: Anna Henningsen <[email protected]>
Reviewed-By: Gus Caplan <[email protected]>
Reviewed-By: Yuta Hiroto <[email protected]>
Reviewed-By: Joyee Cheung <[email protected]>
Reviewed-By: Luigi Pinca <[email protected]>
Reviewed-By: James M Snell <[email protected]>

Backport-PR-URL: #25496
BridgeAR pushed a commit to BridgeAR/node that referenced this issue Jan 16, 2019
console is not ready to use at this point in the bootstrapping
process, so switch to process._rawDebug() instead.

PR-URL: nodejs#25289
Fixes: nodejs#25287
Reviewed-By: Anna Henningsen <[email protected]>
Reviewed-By: Gus Caplan <[email protected]>
Reviewed-By: Yuta Hiroto <[email protected]>
Reviewed-By: Joyee Cheung <[email protected]>
Reviewed-By: Luigi Pinca <[email protected]>
Reviewed-By: James M Snell <[email protected]>

Backport-PR-URL: nodejs#25496
BridgeAR pushed a commit to BridgeAR/node that referenced this issue Jan 16, 2019
During coverage setup, path.resolve() is called.
path.resolve() can potentially call process.cwd(), which
hasn't been bootstrapped yet. This commit passes the
current working directory directly so that path.resolve()
doesn't attempt to compute it.

PR-URL: nodejs#25289
Fixes: nodejs#25287
Reviewed-By: Anna Henningsen <[email protected]>
Reviewed-By: Gus Caplan <[email protected]>
Reviewed-By: Yuta Hiroto <[email protected]>
Reviewed-By: Joyee Cheung <[email protected]>
Reviewed-By: Luigi Pinca <[email protected]>
Reviewed-By: James M Snell <[email protected]>

Backport-PR-URL: nodejs#25496
BridgeAR pushed a commit to BridgeAR/node that referenced this issue Jan 16, 2019
Update the coverage test to verify that nothing is printed to
stderr (which happens when coverage errors happen). Also add a
test case to verify that non-absolute coverage paths work.

PR-URL: nodejs#25289
Fixes: nodejs#25287
Reviewed-By: Anna Henningsen <[email protected]>
Reviewed-By: Gus Caplan <[email protected]>
Reviewed-By: Yuta Hiroto <[email protected]>
Reviewed-By: Joyee Cheung <[email protected]>
Reviewed-By: Luigi Pinca <[email protected]>
Reviewed-By: James M Snell <[email protected]>

Backport-PR-URL: nodejs#25496
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants