Repository: node
Issue: Implicit `process.execArgv` is not respected in nested worker_threads
Labels: worker

<!--
Thank you for reporting an issue.

This issue tracker is for bugs and issues found within Node.js core.
If you require more general support please file an issue on our help
repo. https://github.com/nodejs/help


Please fill in as much of the template below as you're able.

Version: output of `node -v`
Platform: output of `uname -a` (UNIX), or output of `"$([Environment]::OSVersion | ForEach-Object VersionString) $(if ([Environment]::Is64BitOperatingSystem) { "x64" } else { "x86" })"` in PowerShell console (Windows)
Subsystem: if known, please specify affected core module name
-->

* **Version**: v14.15.4
* **Platform**: Darwin 19.6.0 Darwin Kernel Version 19.6.0: Tue Jan 12 22:13:05 PST 2021; root:xnu-6153.141.16~1/RELEASE_X86_64 x86_64
* **Subsystem**: worker_threads

### What steps will reproduce the bug?
In script `a`, spawn a worker thread with script `b` with `--unhandled-rejections=strict` which spawns a worker thread with script `c`.  `c` creates a Promise which rejects.

Both `b` and `c` report that they are parameterized with `--unhandled-rejections=strict`.  `b` is explicitly parameterized and `c` is implicitly parameterized with b's value.

In spite of that, `c` exits 0 and the default `--unhandled-rejections=warn` behavior is used.
```
λ node -v
v14.15.4
λ cat a.js
const { Worker } = require("worker_threads");

const worker = new Worker("./b.js", {
  execArgv: [...process.execArgv, "--unhandled-rejections=strict"],
});
worker.on("error", (error) => {
  console.log("b error", error);
});
worker.on("exit", (exitCode) => {
  console.log("b exit", exitCode);
});
λ cat b.js
const { Worker } = require("worker_threads");

console.log("b process.execArgv", process.execArgv);

const worker = new Worker("./c.js", {
  // execArgv: process.execArgv,
});
worker.on("error", (error) => {
  console.log("c error", error);
});
worker.on("exit", (exitCode) => {
  console.log("c exit", exitCode);
});
λ cat c.js
console.log("c process.execArgv", process.execArgv);

Promise.reject(new Error("how do worker threads work, anyway?"));
λ node a.js
b process.execArgv [ '--unhandled-rejections=strict' ]
c process.execArgv [ '--unhandled-rejections=strict' ]
(node:30784) UnhandledPromiseRejectionWarning: Error: how do worker threads work, anyway?
    at Object.<anonymous> (/private/tmp/whatisasyncanyway/c.js:3:16)
    at Module._compile (internal/modules/cjs/loader.js:1063:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
    at Module.load (internal/modules/cjs/loader.js:928:32)
    at Function.Module._load (internal/modules/cjs/loader.js:769:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:72:12)
    at MessagePort.<anonymous> (internal/main/worker_thread.js:174:24)
    at MessagePort.[nodejs.internal.kHybridDispatch] (internal/event_target.js:354:41)
    at MessagePort.exports.emitMessage (internal/per_context/messageport.js:18:26)
(Use `node --trace-warnings ...` to show where the warning was created)
(node:30784) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
c exit 0
(node:30784) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
b exit 0
```

Now, uncomment the commented out line in `b`, and repeat.
```
λ cat b.js
const { Worker } = require("worker_threads");

console.log("b process.execArgv", process.execArgv);

const worker = new Worker("./c.js", {
  execArgv: process.execArgv,
});
worker.on("error", (error) => {
  console.log("c error", error);
});
worker.on("exit", (exitCode) => {
  console.log("c exit", exitCode);
});
λ node a.js
b process.execArgv [ '--unhandled-rejections=strict' ]
c process.execArgv [ '--unhandled-rejections=strict' ]
c error Error: how do worker threads work, anyway?
    at Object.<anonymous> (/private/tmp/whatisasyncanyway/c.js:3:16)
    at Module._compile (internal/modules/cjs/loader.js:1063:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
    at Module.load (internal/modules/cjs/loader.js:928:32)
    at Function.Module._load (internal/modules/cjs/loader.js:769:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:72:12)
    at MessagePort.<anonymous> (internal/main/worker_thread.js:174:24)
    at MessagePort.[nodejs.internal.kHybridDispatch] (internal/event_target.js:354:41)
    at MessagePort.exports.emitMessage (internal/per_context/messageport.js:18:26)
c exit 1
b exit 0
```
In spite of `c` reporting no difference in its `process.execArgv`, simply explicitly using `b`'s somehow makes it work.

<!--
Enter details about your bug, preferably a simple code snippet that can be
run using `node` directly without installing third-party dependencies.
-->

### How often does it reproduce? Is there a required condition?
This reproduces unconditionally.

### What is the expected behavior?
Worker threads obey their own stated `process.execArgv`.

<!--
If possible please provide textual output instead of screenshots.
-->

### What do you see instead?
See above.

<!--
If possible please provide textual output instead of screenshots.
-->

### Additional information
This only happens with nested workers.  If you replace `b.js` with `c.js` from the example above, and run `node --unhandled-rejections=strict a.js`, `b` respects that flag in spite of it being implicitly parameterized with `a`'s `process.execArgv` and exits 1.

Also, it requires that the main process not be started on the CLI with `--unhandled-rejections=strict`.  Doing so will produce the correct behavior, but presumably for incorrect reasons:  it seems that the nested worker `c` is incorrectly using `a`'s `process.execArgv` when not explicitly parameterized with `b`'s.

This contradicts the [documented behavior](https://nodejs.org/docs/latest-v14.x/api/worker_threads.html#worker_threads_new_worker_filename_options), which states:
> By default, options will be inherited from the parent thread.

<!--
Tell us anything else you think we should know.
-->