Skip to content

Commit ad043ba

Browse files
MrJithilruyadorno
authored andcommitted
process: add custom dir support for heapsnapshot-signal
PR-URL: #47854 Refs: #47842 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Benjamin Gruenbaum <[email protected]> Reviewed-By: Joyee Cheung <[email protected]> Reviewed-By: Erick Wendel <[email protected]>
1 parent b4d42a8 commit ad043ba

File tree

2 files changed

+87
-2
lines changed

2 files changed

+87
-2
lines changed

lib/internal/process/pre_execution.js

+37-2
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,23 @@
22

33
const {
44
ArrayPrototypeForEach,
5+
Date,
6+
DatePrototypeGetDate,
7+
DatePrototypeGetFullYear,
8+
DatePrototypeGetHours,
9+
DatePrototypeGetMinutes,
10+
DatePrototypeGetMonth,
11+
DatePrototypeGetSeconds,
512
NumberParseInt,
613
ObjectDefineProperties,
714
ObjectDefineProperty,
815
ObjectGetOwnPropertyDescriptor,
916
SafeMap,
17+
String,
1018
StringPrototypeStartsWith,
1119
Symbol,
12-
SymbolDispose,
1320
SymbolAsyncDispose,
21+
SymbolDispose,
1422
globalThis,
1523
} = primordials;
1624

@@ -400,6 +408,7 @@ function initializeReportSignalHandlers() {
400408

401409
function initializeHeapSnapshotSignalHandlers() {
402410
const signal = getOptionValue('--heapsnapshot-signal');
411+
const diagnosticDir = getOptionValue('--diagnostic-dir');
403412

404413
if (!signal)
405414
return;
@@ -408,7 +417,8 @@ function initializeHeapSnapshotSignalHandlers() {
408417
const { writeHeapSnapshot } = require('v8');
409418

410419
function doWriteHeapSnapshot() {
411-
writeHeapSnapshot();
420+
const heapSnapshotFilename = getHeapSnapshotFilename(diagnosticDir);
421+
writeHeapSnapshot(heapSnapshotFilename);
412422
}
413423
process.on(signal, doWriteHeapSnapshot);
414424

@@ -700,6 +710,31 @@ function markBootstrapComplete() {
700710
internalBinding('performance').markBootstrapComplete();
701711
}
702712

713+
// Sequence number for diagnostic filenames
714+
let sequenceNumOfheapSnapshot = 0;
715+
716+
// To generate the HeapSnapshotFilename while using custom diagnosticDir
717+
function getHeapSnapshotFilename(diagnosticDir) {
718+
if (!diagnosticDir) return undefined;
719+
720+
const date = new Date();
721+
722+
const year = DatePrototypeGetFullYear(date);
723+
const month = String(DatePrototypeGetMonth(date) + 1).padStart(2, '0');
724+
const day = String(DatePrototypeGetDate(date)).padStart(2, '0');
725+
const hours = String(DatePrototypeGetHours(date)).padStart(2, '0');
726+
const minutes = String(DatePrototypeGetMinutes(date)).padStart(2, '0');
727+
const seconds = String(DatePrototypeGetSeconds(date)).padStart(2, '0');
728+
729+
const dateString = `${year}${month}${day}`;
730+
const timeString = `${hours}${minutes}${seconds}`;
731+
const pid = process.pid;
732+
const threadId = internalBinding('worker').threadId;
733+
const fileSequence = (++sequenceNumOfheapSnapshot).toString().padStart(3, '0');
734+
735+
return `${diagnosticDir}/Heap.${dateString}.${timeString}.${pid}.${threadId}.${fileSequence}.heapsnapshot`;
736+
}
737+
703738
module.exports = {
704739
setupUserModules,
705740
prepareMainThreadExecution,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
'use strict';
2+
const common = require('../common');
3+
4+
5+
if (common.isWindows)
6+
common.skip('test not supported on Windows');
7+
8+
const assert = require('assert');
9+
10+
const validateHeapSnapshotFile = () => {
11+
const fs = require('fs');
12+
13+
assert.strictEqual(process.listenerCount('SIGUSR2'), 1);
14+
process.kill(process.pid, 'SIGUSR2');
15+
process.kill(process.pid, 'SIGUSR2');
16+
17+
// Asynchronously wait for the snapshot. Use an async loop to be a bit more
18+
// robust in case platform or machine differences throw off the timing.
19+
(function validate() {
20+
const files = fs.readdirSync(process.cwd());
21+
22+
if (files.length === 0)
23+
return setImmediate(validate);
24+
25+
assert.strictEqual(files.length, 2);
26+
27+
for (let i = 0; i < files.length; i++) {
28+
assert.match(files[i], /^Heap\..+\.heapsnapshot$/);
29+
30+
// Check the file is parsable as JSON
31+
JSON.parse(fs.readFileSync(files[i]));
32+
}
33+
})();
34+
};
35+
36+
if (process.argv[2] === 'child') {
37+
validateHeapSnapshotFile();
38+
} else {
39+
// Modify the timezone. So we can check the file date string still returning correctly.
40+
process.env.TZ = 'America/New_York';
41+
const { spawnSync } = require('child_process');
42+
const tmpdir = require('../common/tmpdir');
43+
44+
tmpdir.refresh();
45+
const args = ['--heapsnapshot-signal', 'SIGUSR2', '--diagnostic-dir', tmpdir.path, __filename, 'child'];
46+
const child = spawnSync(process.execPath, args, { cwd: tmpdir.path });
47+
48+
assert.strictEqual(child.status, 0);
49+
assert.strictEqual(child.signal, null);
50+
}

0 commit comments

Comments
 (0)