lib: add trace-sigint APIs

PR-URL: https://github.com/nodejs/node/pull/59040
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
This commit is contained in:
theanarkh 2025-08-11 17:14:44 +08:00 committed by RafaelGSS
parent fb0a6fb57f
commit e055539604
No known key found for this signature in database
GPG key ID: 8BEAB4DFCF555EF4
9 changed files with 141 additions and 4 deletions

View file

@ -739,6 +739,16 @@ fs.access('file/that/does/not/exist', (err) => {
});
```
## `util.setTraceSigInt(enable)`
<!-- YAML
added: REPLACEME
-->
* `enable` {boolean}
Enable or disable printing a stack trace on `SIGINT`. The API is only available on the main thread.
## `util.inherits(constructor, superConstructor)`
<!-- YAML

View file

@ -393,10 +393,7 @@ function setupStacktracePrinterOnSigint() {
if (!getOptionValue('--trace-sigint')) {
return;
}
const { SigintWatchdog } = require('internal/watchdog');
const watchdog = new SigintWatchdog();
watchdog.start();
require('internal/util/trace_sigint').setTraceSigInt(true);
}
function initializeReport() {

View file

@ -0,0 +1,29 @@
'use strict';
const { isMainThread } = require('worker_threads');
const {
ERR_WORKER_UNSUPPORTED_OPERATION,
} = require('internal/errors').codes;
let sigintWatchdog;
function getSigintWatchdog() {
if (!sigintWatchdog) {
const { SigintWatchdog } = require('internal/watchdog');
sigintWatchdog = new SigintWatchdog();
}
return sigintWatchdog;
}
function setTraceSigInt(enable) {
if (!isMainThread)
throw new ERR_WORKER_UNSUPPORTED_OPERATION('Calling util.setTraceSigInt');
if (enable) {
getSigintWatchdog().start();
} else {
getSigintWatchdog().stop();
}
};
module.exports = {
setTraceSigInt,
};

View file

@ -535,3 +535,9 @@ defineLazyProperties(
'internal/util/diff',
['diff'],
);
defineLazyProperties(
module.exports,
'internal/util/trace_sigint',
['setTraceSigInt'],
);

View file

@ -0,0 +1,20 @@
'use strict';
const common = require('../common');
const assert = require('assert');
const util = require('util');
const { Worker, workerData } = require('worker_threads');
if (workerData?.isWorker) {
assert.throws(() => {
util.setTraceSigInt(true);
}, {
code: 'ERR_WORKER_UNSUPPORTED_OPERATION',
});
} else {
const w = new Worker(__filename, { workerData: { isWorker: true } });
w.on('exit', common.mustCall((code) => {
assert.strictEqual(code, 0);
}));
}

View file

@ -0,0 +1,32 @@
'use strict';
const { mustCall } = require('../common');
const childProcess = require('child_process');
const assert = require('assert');
const util = require('util');
if (process.env.CHILD === 'true') {
main();
} else {
// Use inherited stdio child process to prevent test tools from determining
// the case as crashed from SIGINT
const cp = childProcess.spawn(
process.execPath,
[__filename],
{
env: { ...process.env, CHILD: 'true' },
stdio: 'inherit',
});
cp.on('exit', mustCall((code, signal) => {
assert.strictEqual(signal, 'SIGINT');
assert.strictEqual(code, null);
}));
}
function main() {
util.setTraceSigInt(true);
// Deactivate colors even if the tty does support colors.
process.env.NODE_DISABLE_COLORS = '1';
process.kill(process.pid, 'SIGINT');
while (true);
}

View file

@ -0,0 +1,11 @@
KEYBOARD_INTERRUPT: Script execution was interrupted by `SIGINT`
at main (*/test-start-trace-sigint.js:*)
at */test-start-trace-sigint.js:*
at *
at *
at *
at *
at *
at *
at *
at *

View file

@ -0,0 +1,32 @@
'use strict';
const { mustCall } = require('../common');
const childProcess = require('child_process');
const assert = require('assert');
const util = require('util');
if (process.env.CHILD === 'true') {
main();
} else {
// Use inherited stdio child process to prevent test tools from determining
// the case as crashed from SIGINT
const cp = childProcess.spawn(
process.execPath,
['--trace-sigint', __filename],
{
env: { ...process.env, CHILD: 'true' },
stdio: 'inherit',
});
cp.on('exit', mustCall((code, signal) => {
assert.strictEqual(signal, 'SIGINT');
assert.strictEqual(code, null);
}));
}
function main() {
util.setTraceSigInt(false);
// Deactivate colors even if the tty does support colors.
process.env.NODE_DISABLE_COLORS = '1';
process.kill(process.pid, 'SIGINT');
while (true);
}