Skip to content

Commit c8bf432

Browse files
joyeecheungtargos
authored andcommitted
process: move process mutation into bootstrap/node.js
This patch moves the part in the report initialization that mutates the process object into bootstrap/node.js so it's easier to tell the side effect of the initialization on the global state during bootstrap. PR-URL: #25821 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Gus Caplan <[email protected]> Reviewed-By: Richard Lau <[email protected]> Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: Michaël Zasso <[email protected]>
1 parent 1d76ba1 commit c8bf432

File tree

2 files changed

+149
-140
lines changed

2 files changed

+149
-140
lines changed

lib/internal/bootstrap/node.js

+12-1
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,18 @@ if (process.env.NODE_V8_COVERAGE) {
333333
}
334334

335335
if (getOptionValue('--experimental-report')) {
336-
NativeModule.require('internal/process/report').setup();
336+
const {
337+
config,
338+
handleSignal,
339+
report,
340+
syncConfig
341+
} = NativeModule.require('internal/process/report');
342+
process.report = report;
343+
// Download the CLI / ENV config into JS land.
344+
syncConfig(config, false);
345+
if (config.events.includes('signal')) {
346+
process.on(config.signal, handleSignal);
347+
}
337348
}
338349

339350
function setupTraceCategoryState() {

lib/internal/process/report.js

+137-139
Original file line numberDiff line numberDiff line change
@@ -3,158 +3,156 @@
33
const { emitExperimentalWarning } = require('internal/util');
44
const {
55
ERR_INVALID_ARG_TYPE,
6-
ERR_SYNTHETIC } = require('internal/errors').codes;
6+
ERR_SYNTHETIC
7+
} = require('internal/errors').codes;
78

8-
exports.setup = function() {
9-
const REPORTEVENTS = 1;
10-
const REPORTSIGNAL = 2;
11-
const REPORTFILENAME = 3;
12-
const REPORTPATH = 4;
13-
const REPORTVERBOSE = 5;
9+
const REPORTEVENTS = 1;
10+
const REPORTSIGNAL = 2;
11+
const REPORTFILENAME = 3;
12+
const REPORTPATH = 4;
13+
const REPORTVERBOSE = 5;
1414

15-
// If report is enabled, extract the binding and
16-
// wrap the APIs with thin layers, with some error checks.
17-
// user options can come in from CLI / ENV / API.
18-
// CLI and ENV is intercepted in C++ and the API call here (JS).
19-
// So sync up with both sides as appropriate - initially from
20-
// C++ to JS and from JS to C++ whenever the API is called.
21-
// Some events are controlled purely from JS (signal | exception)
22-
// and some from C++ (fatalerror) so this sync-up is essential for
23-
// correct behavior and alignment with the supplied tunables.
24-
const nr = internalBinding('report');
15+
// If report is enabled, extract the binding and
16+
// wrap the APIs with thin layers, with some error checks.
17+
// user options can come in from CLI / ENV / API.
18+
// CLI and ENV is intercepted in C++ and the API call here (JS).
19+
// So sync up with both sides as appropriate - initially from
20+
// C++ to JS and from JS to C++ whenever the API is called.
21+
// Some events are controlled purely from JS (signal | exception)
22+
// and some from C++ (fatalerror) so this sync-up is essential for
23+
// correct behavior and alignment with the supplied tunables.
24+
const nr = internalBinding('report');
2525

26-
// Keep it un-exposed; lest programs play with it
27-
// leaving us with a lot of unwanted sanity checks.
28-
let config = {
29-
events: [],
30-
signal: 'SIGUSR2',
31-
filename: '',
32-
path: '',
33-
verbose: false
34-
};
35-
const report = {
36-
setDiagnosticReportOptions(options) {
37-
emitExperimentalWarning('report');
38-
// Reuse the null and undefined checks. Save
39-
// space when dealing with large number of arguments.
40-
const list = parseOptions(options);
26+
// Keep it un-exposed; lest programs play with it
27+
// leaving us with a lot of unwanted sanity checks.
28+
let config = {
29+
events: [],
30+
signal: 'SIGUSR2',
31+
filename: '',
32+
path: '',
33+
verbose: false
34+
};
35+
const report = {
36+
setDiagnosticReportOptions(options) {
37+
emitExperimentalWarning('report');
38+
// Reuse the null and undefined checks. Save
39+
// space when dealing with large number of arguments.
40+
const list = parseOptions(options);
4141

42-
// Flush the stale entries from report, as
43-
// we are refreshing it, items that the users did not
44-
// touch may be hanging around stale otherwise.
45-
config = {};
42+
// Flush the stale entries from report, as
43+
// we are refreshing it, items that the users did not
44+
// touch may be hanging around stale otherwise.
45+
config = {};
4646

47-
// The parseOption method returns an array that include
48-
// the indices at which valid params are present.
49-
list.forEach((i) => {
50-
switch (i) {
51-
case REPORTEVENTS:
52-
if (Array.isArray(options.events))
53-
config.events = options.events;
54-
else
55-
throw new ERR_INVALID_ARG_TYPE('events',
56-
'Array',
57-
options.events);
58-
break;
59-
case REPORTSIGNAL:
60-
if (typeof options.signal !== 'string') {
61-
throw new ERR_INVALID_ARG_TYPE('signal',
62-
'String',
63-
options.signal);
64-
}
65-
process.removeListener(config.signal, handleSignal);
66-
if (config.events.includes('signal'))
67-
process.on(options.signal, handleSignal);
68-
config.signal = options.signal;
69-
break;
70-
case REPORTFILENAME:
71-
if (typeof options.filename !== 'string') {
72-
throw new ERR_INVALID_ARG_TYPE('filename',
73-
'String',
74-
options.filename);
75-
}
76-
config.filename = options.filename;
77-
break;
78-
case REPORTPATH:
79-
if (typeof options.path !== 'string')
80-
throw new ERR_INVALID_ARG_TYPE('path', 'String', options.path);
81-
config.path = options.path;
82-
break;
83-
case REPORTVERBOSE:
84-
if (typeof options.verbose !== 'string' &&
85-
typeof options.verbose !== 'boolean') {
86-
throw new ERR_INVALID_ARG_TYPE('verbose',
87-
'Booelan | String' +
88-
' (true|false|yes|no)',
89-
options.verbose);
90-
}
91-
config.verbose = options.verbose;
92-
break;
93-
}
94-
});
95-
// Upload this new config to C++ land
96-
nr.syncConfig(config, true);
97-
},
47+
// The parseOption method returns an array that include
48+
// the indices at which valid params are present.
49+
list.forEach((i) => {
50+
switch (i) {
51+
case REPORTEVENTS:
52+
if (Array.isArray(options.events))
53+
config.events = options.events;
54+
else
55+
throw new ERR_INVALID_ARG_TYPE('events',
56+
'Array',
57+
options.events);
58+
break;
59+
case REPORTSIGNAL:
60+
if (typeof options.signal !== 'string') {
61+
throw new ERR_INVALID_ARG_TYPE('signal',
62+
'String',
63+
options.signal);
64+
}
65+
process.removeListener(config.signal, handleSignal);
66+
if (config.events.includes('signal'))
67+
process.on(options.signal, handleSignal);
68+
config.signal = options.signal;
69+
break;
70+
case REPORTFILENAME:
71+
if (typeof options.filename !== 'string') {
72+
throw new ERR_INVALID_ARG_TYPE('filename',
73+
'String',
74+
options.filename);
75+
}
76+
config.filename = options.filename;
77+
break;
78+
case REPORTPATH:
79+
if (typeof options.path !== 'string')
80+
throw new ERR_INVALID_ARG_TYPE('path', 'String', options.path);
81+
config.path = options.path;
82+
break;
83+
case REPORTVERBOSE:
84+
if (typeof options.verbose !== 'string' &&
85+
typeof options.verbose !== 'boolean') {
86+
throw new ERR_INVALID_ARG_TYPE('verbose',
87+
'Booelan | String' +
88+
' (true|false|yes|no)',
89+
options.verbose);
90+
}
91+
config.verbose = options.verbose;
92+
break;
93+
}
94+
});
95+
// Upload this new config to C++ land
96+
nr.syncConfig(config, true);
97+
},
9898

9999

100-
triggerReport(file, err) {
101-
emitExperimentalWarning('report');
102-
if (err == null) {
103-
if (file == null) {
104-
return nr.triggerReport(new ERR_SYNTHETIC().stack);
105-
}
106-
if (typeof file !== 'string')
107-
throw new ERR_INVALID_ARG_TYPE('file', 'String', file);
108-
return nr.triggerReport(file, new ERR_SYNTHETIC().stack);
100+
triggerReport(file, err) {
101+
emitExperimentalWarning('report');
102+
if (err == null) {
103+
if (file == null) {
104+
return nr.triggerReport(new ERR_SYNTHETIC().stack);
109105
}
110-
if (typeof err !== 'object')
111-
throw new ERR_INVALID_ARG_TYPE('err', 'Object', err);
112-
if (file == null)
113-
return nr.triggerReport(err.stack);
114106
if (typeof file !== 'string')
115107
throw new ERR_INVALID_ARG_TYPE('file', 'String', file);
116-
return nr.triggerReport(file, err.stack);
117-
},
118-
getReport(err) {
119-
emitExperimentalWarning('report');
120-
if (err == null) {
121-
return nr.getReport(new ERR_SYNTHETIC().stack);
122-
} else if (typeof err !== 'object') {
123-
throw new ERR_INVALID_ARG_TYPE('err', 'Object', err);
124-
} else {
125-
return nr.getReport(err.stack);
126-
}
108+
return nr.triggerReport(file, new ERR_SYNTHETIC().stack);
109+
}
110+
if (typeof err !== 'object')
111+
throw new ERR_INVALID_ARG_TYPE('err', 'Object', err);
112+
if (file == null)
113+
return nr.triggerReport(err.stack);
114+
if (typeof file !== 'string')
115+
throw new ERR_INVALID_ARG_TYPE('file', 'String', file);
116+
return nr.triggerReport(file, err.stack);
117+
},
118+
getReport(err) {
119+
emitExperimentalWarning('report');
120+
if (err == null) {
121+
return nr.getReport(new ERR_SYNTHETIC().stack);
122+
} else if (typeof err !== 'object') {
123+
throw new ERR_INVALID_ARG_TYPE('err', 'Object', err);
124+
} else {
125+
return nr.getReport(err.stack);
127126
}
128-
};
129-
130-
// Download the CLI / ENV config into JS land.
131-
nr.syncConfig(config, false);
132-
133-
function handleSignal(signo) {
134-
if (typeof signo !== 'string')
135-
signo = config.signal;
136-
nr.onUserSignal(signo);
137127
}
128+
};
138129

139-
if (config.events.includes('signal')) {
140-
process.on(config.signal, handleSignal);
141-
}
130+
function handleSignal(signo) {
131+
if (typeof signo !== 'string')
132+
signo = config.signal;
133+
nr.onUserSignal(signo);
134+
}
142135

143-
function parseOptions(obj) {
144-
const list = [];
145-
if (obj == null)
146-
return list;
147-
if (obj.events != null)
148-
list.push(REPORTEVENTS);
149-
if (obj.signal != null)
150-
list.push(REPORTSIGNAL);
151-
if (obj.filename != null)
152-
list.push(REPORTFILENAME);
153-
if (obj.path != null)
154-
list.push(REPORTPATH);
155-
if (obj.verbose != null)
156-
list.push(REPORTVERBOSE);
136+
function parseOptions(obj) {
137+
const list = [];
138+
if (obj == null)
157139
return list;
158-
}
159-
process.report = report;
140+
if (obj.events != null)
141+
list.push(REPORTEVENTS);
142+
if (obj.signal != null)
143+
list.push(REPORTSIGNAL);
144+
if (obj.filename != null)
145+
list.push(REPORTFILENAME);
146+
if (obj.path != null)
147+
list.push(REPORTPATH);
148+
if (obj.verbose != null)
149+
list.push(REPORTVERBOSE);
150+
return list;
151+
}
152+
153+
module.exports = {
154+
config,
155+
handleSignal,
156+
report,
157+
syncConfig: nr.syncConfig
160158
};

0 commit comments

Comments
 (0)