Skip to content

Commit e1e2f66

Browse files
author
bcoe
committed
process: add source-map support to stack traces
PR-URL: nodejs#29564 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
1 parent 739f113 commit e1e2f66

33 files changed

+732
-26
lines changed

doc/api/cli.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,15 @@ added: v6.0.0
135135
Enable FIPS-compliant crypto at startup. (Requires Node.js to be built with
136136
`./configure --openssl-fips`.)
137137

138+
### `--enable-source-maps`
139+
<!-- YAML
140+
added: REPLACEME
141+
-->
142+
143+
> Stability: 1 - Experimental
144+
145+
Enable experimental Source Map V3 support for stack traces.
146+
138147
### `--es-module-specifier-resolution=mode`
139148
<!-- YAML
140149
added: v12.0.0
@@ -980,6 +989,7 @@ node --require "./a.js" --require "./b.js"
980989
Node.js options that are allowed are:
981990
<!-- node-options-node start -->
982991
* `--enable-fips`
992+
* `--enable-source-maps`
983993
* `--es-module-specifier-resolution`
984994
* `--experimental-exports`
985995
* `--experimental-loader`

lib/internal/bootstrap/pre_execution.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,15 @@ function prepareMainThreadExecution(expandArgv1 = false) {
2121
setupCoverageHooks(process.env.NODE_V8_COVERAGE);
2222
}
2323

24+
// If source-map support has been enabled, we substitute in a new
25+
// prepareStackTrace method, replacing the default in errors.js.
26+
if (getOptionValue('--enable-source-maps')) {
27+
const { prepareStackTrace } =
28+
require('internal/source_map/source_map_cache');
29+
const { setPrepareStackTraceCallback } = internalBinding('errors');
30+
setPrepareStackTraceCallback(prepareStackTrace);
31+
}
32+
2433
setupDebugEnv();
2534

2635
// Only main thread receives signals.
@@ -119,7 +128,8 @@ function setupCoverageHooks(dir) {
119128
const cwd = require('internal/process/execution').tryGetCwd();
120129
const { resolve } = require('path');
121130
const coverageDirectory = resolve(cwd, dir);
122-
const { sourceMapCacheToObject } = require('internal/source_map');
131+
const { sourceMapCacheToObject } =
132+
require('internal/source_map/source_map_cache');
123133

124134
if (process.features.inspector) {
125135
internalBinding('profiler').setCoverageDirectory(coverageDirectory);

lib/internal/modules/cjs/loader.js

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,10 @@ const {
3131
} = primordials;
3232

3333
const { NativeModule } = require('internal/bootstrap/loaders');
34-
const { maybeCacheSourceMap } = require('internal/source_map');
34+
const {
35+
maybeCacheSourceMap,
36+
rekeySourceMap
37+
} = require('internal/source_map/source_map_cache');
3538
const { pathToFileURL, fileURLToPath, URL } = require('internal/url');
3639
const { deprecate } = require('internal/util');
3740
const vm = require('vm');
@@ -51,6 +54,7 @@ const {
5154
loadNativeModule
5255
} = require('internal/modules/cjs/helpers');
5356
const { getOptionValue } = require('internal/options');
57+
const enableSourceMaps = getOptionValue('--enable-source-maps');
5458
const preserveSymlinks = getOptionValue('--preserve-symlinks');
5559
const preserveSymlinksMain = getOptionValue('--preserve-symlinks-main');
5660
const experimentalModules = getOptionValue('--experimental-modules');
@@ -707,7 +711,19 @@ Module._load = function(request, parent, isMain) {
707711

708712
let threw = true;
709713
try {
710-
module.load(filename);
714+
// Intercept exceptions that occur during the first tick and rekey them
715+
// on error instance rather than module instance (which will immediately be
716+
// garbage collected).
717+
if (enableSourceMaps) {
718+
try {
719+
module.load(filename);
720+
} catch (err) {
721+
rekeySourceMap(Module._cache[filename], err);
722+
throw err; /* node-do-not-add-exception-line */
723+
}
724+
} else {
725+
module.load(filename);
726+
}
711727
threw = false;
712728
} finally {
713729
if (threw) {
@@ -846,9 +862,7 @@ Module.prototype.require = function(id) {
846862
var resolvedArgv;
847863
let hasPausedEntry = false;
848864

849-
function wrapSafe(filename, content, cjsModuleInstance) {
850-
maybeCacheSourceMap(filename, content, cjsModuleInstance);
851-
865+
function wrapSafe(filename, content) {
852866
if (patched) {
853867
const wrapper = Module.wrap(content);
854868
return vm.runInThisContext(wrapper, {
@@ -913,7 +927,8 @@ Module.prototype._compile = function(content, filename) {
913927
manifest.assertIntegrity(moduleURL, content);
914928
}
915929

916-
const compiledWrapper = wrapSafe(filename, content, this);
930+
maybeCacheSourceMap(filename, content, this);
931+
const compiledWrapper = wrapSafe(filename, content);
917932

918933
var inspectorWrapper = null;
919934
if (getOptionValue('--inspect-brk') && process._eval == null) {

lib/internal/modules/esm/translators.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ const {
3131
} = require('internal/errors').codes;
3232
const readFileAsync = promisify(fs.readFile);
3333
const JsonParse = JSON.parse;
34-
const { maybeCacheSourceMap } = require('internal/source_map');
34+
const { maybeCacheSourceMap } = require('internal/source_map/source_map_cache');
3535

3636
const debug = debuglog('esm');
3737

0 commit comments

Comments
 (0)