Skip to content

Commit 264a838

Browse files
theanarkhaduh95
authored andcommitted
lib: add trace-sigint APIs
PR-URL: #59040 Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
1 parent d22d2fa commit 264a838

File tree

9 files changed

+141
-4
lines changed

9 files changed

+141
-4
lines changed

doc/api/util.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -729,6 +729,16 @@ fs.access('file/that/does/not/exist', (err) => {
729729
});
730730
```
731731

732+
## `util.setTraceSigInt(enable)`
733+
734+
<!-- YAML
735+
added: REPLACEME
736+
-->
737+
738+
* `enable` {boolean}
739+
740+
Enable or disable printing a stack trace on `SIGINT`. The API is only available on the main thread.
741+
732742
## `util.inherits(constructor, superConstructor)`
733743

734744
<!-- YAML

lib/internal/process/pre_execution.js

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -440,10 +440,7 @@ function setupStacktracePrinterOnSigint() {
440440
if (!getOptionValue('--trace-sigint')) {
441441
return;
442442
}
443-
const { SigintWatchdog } = require('internal/watchdog');
444-
445-
const watchdog = new SigintWatchdog();
446-
watchdog.start();
443+
require('internal/util/trace_sigint').setTraceSigInt(true);
447444
}
448445

449446
function initializeReport() {

lib/internal/util/trace_sigint.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
'use strict';
2+
3+
const { isMainThread } = require('worker_threads');
4+
const {
5+
ERR_WORKER_UNSUPPORTED_OPERATION,
6+
} = require('internal/errors').codes;
7+
8+
let sigintWatchdog;
9+
function getSigintWatchdog() {
10+
if (!sigintWatchdog) {
11+
const { SigintWatchdog } = require('internal/watchdog');
12+
sigintWatchdog = new SigintWatchdog();
13+
}
14+
return sigintWatchdog;
15+
}
16+
17+
function setTraceSigInt(enable) {
18+
if (!isMainThread)
19+
throw new ERR_WORKER_UNSUPPORTED_OPERATION('Calling util.setTraceSigInt');
20+
if (enable) {
21+
getSigintWatchdog().start();
22+
} else {
23+
getSigintWatchdog().stop();
24+
}
25+
};
26+
27+
module.exports = {
28+
setTraceSigInt,
29+
};

lib/util.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -734,3 +734,9 @@ defineLazyProperties(
734734
'internal/util/diff',
735735
['diff'],
736736
);
737+
738+
defineLazyProperties(
739+
module.exports,
740+
'internal/util/trace_sigint',
741+
['setTraceSigInt'],
742+
);
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
'use strict';
2+
3+
const common = require('../common');
4+
5+
const assert = require('assert');
6+
const util = require('util');
7+
const { Worker, workerData } = require('worker_threads');
8+
9+
if (workerData?.isWorker) {
10+
assert.throws(() => {
11+
util.setTraceSigInt(true);
12+
}, {
13+
code: 'ERR_WORKER_UNSUPPORTED_OPERATION',
14+
});
15+
} else {
16+
const w = new Worker(__filename, { workerData: { isWorker: true } });
17+
w.on('exit', common.mustCall((code) => {
18+
assert.strictEqual(code, 0);
19+
}));
20+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
'use strict';
2+
3+
const { mustCall } = require('../common');
4+
const childProcess = require('child_process');
5+
const assert = require('assert');
6+
const util = require('util');
7+
8+
if (process.env.CHILD === 'true') {
9+
main();
10+
} else {
11+
// Use inherited stdio child process to prevent test tools from determining
12+
// the case as crashed from SIGINT
13+
const cp = childProcess.spawn(
14+
process.execPath,
15+
[__filename],
16+
{
17+
env: { ...process.env, CHILD: 'true' },
18+
stdio: 'inherit',
19+
});
20+
cp.on('exit', mustCall((code, signal) => {
21+
assert.strictEqual(signal, 'SIGINT');
22+
assert.strictEqual(code, null);
23+
}));
24+
}
25+
26+
function main() {
27+
util.setTraceSigInt(true);
28+
// Deactivate colors even if the tty does support colors.
29+
process.env.NODE_DISABLE_COLORS = '1';
30+
process.kill(process.pid, 'SIGINT');
31+
while (true);
32+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
KEYBOARD_INTERRUPT: Script execution was interrupted by `SIGINT`
2+
at main (*/test-start-trace-sigint.js:*)
3+
at */test-start-trace-sigint.js:*
4+
at *
5+
at *
6+
at *
7+
at *
8+
at *
9+
at *
10+
at *
11+
at *
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
'use strict';
2+
3+
const { mustCall } = require('../common');
4+
const childProcess = require('child_process');
5+
const assert = require('assert');
6+
const util = require('util');
7+
8+
if (process.env.CHILD === 'true') {
9+
main();
10+
} else {
11+
// Use inherited stdio child process to prevent test tools from determining
12+
// the case as crashed from SIGINT
13+
const cp = childProcess.spawn(
14+
process.execPath,
15+
['--trace-sigint', __filename],
16+
{
17+
env: { ...process.env, CHILD: 'true' },
18+
stdio: 'inherit',
19+
});
20+
cp.on('exit', mustCall((code, signal) => {
21+
assert.strictEqual(signal, 'SIGINT');
22+
assert.strictEqual(code, null);
23+
}));
24+
}
25+
26+
function main() {
27+
util.setTraceSigInt(false);
28+
// Deactivate colors even if the tty does support colors.
29+
process.env.NODE_DISABLE_COLORS = '1';
30+
process.kill(process.pid, 'SIGINT');
31+
while (true);
32+
}

test/pseudo-tty/test-stop-trace-sigint.out

Whitespace-only changes.

0 commit comments

Comments
 (0)