This makes sure the init phase is properly detected throughout all
Node.js versions.
A couple of mechanisms work together to achieve that:
1) Get the stack trace while starting Node.js and remove all those
frames later on.
2) All native modules are detected while initializing and all frames
before that one including it will also be marked as bootstrapping
frames.
3) For Node.js 10 a few more stacks are detected by directly checking
for the `internal/bootstrap.js` file. It would not show up in the
other two mechanisms.
4) A check for `internalBinding` is in place since this code would
only execute during native module loading.
5) An explicit check for `NativeModule` is in place since that is the
name of the internal Node.js module loading to bootstrap core.
This makes sure that pretty much all loading is properly detected.
Besides this, this commit fixes another small bug when using the
`treeDebug` option in combination with the `mapFrames` option. Before
the arguments were not passed through properly.
So far the child process spawned to vizualize the data could be a
different one than the one used to run 0x. Now it's always the same
and there should be no mismatch left.
Fixes: #119
Handles folders that already exist and many more error cases than previously. 0x already has npm mkdirp as a dep-of-dep, but make-dir is actively maintained and appears much more robust.
The detection will now rely on the `anonymous` function that is used
by node to wrap modules. The very first of such entries is detected
and all other entries must be init frames. This is reliable in a way
that further changes to Node.js internals in the init phase will not
have any impact on the detection.
0x doesn't support it.
I used the 'fork' event because it's easier than intercepting `require`
and this way it allows requiring but not using `cluster`.
If the subprocess does `try { cluster.fork() }` this won't crash, but
that's probably fine? Same if the subprocess has an 'uncaughtException'
handler.
Ex:
```
➜ ./cmd.js cluster.js
🔥 Profiling/home/goto-bus-stop/Code/nearform/0x/lib/preload/no-cluster.js:4
throw new Error('0x does not support clustering.')
^
Error: 0x does not support clustering.
at EventEmitter.cluster.on (/home/goto-bus-stop/Code/nearform/0x/lib/preload/no-cluster.js:4:9)
at EventEmitter.emit (events.js:182:13)
at emitForkNT (internal/cluster/master.js:226:11)
at process._tickCallback (internal/process/next_tick.js:63:19)
at Function.Module.runMain (internal/modules/cjs/loader.js:745:11)
at startup (internal/bootstrap/node.js:266:19)
at bootstrapNodeJSCore (internal/bootstrap/node.js:596:3)
🚫 Target subprocess error, code: 1
```
Problem:
If the file with trace stacks is larger than the maximum string length,
then traceStacksToTicks chokes on a call to toString.
Solution:
Split buffer on newlines via repeated indexOf rather than via
buf.toString.split('\n')
Test:
I ran assert.deepEqual to compare the stacks generated by the
old and new approaches. It said they were equivalent.
Fixes: #120