Skip to content

Commit 3f01bc9

Browse files
committed
process: add custom dir support for heapsnapshot-signal
1 parent 19fa9f1 commit 3f01bc9

File tree

2 files changed

+86
-1
lines changed

2 files changed

+86
-1
lines changed

lib/internal/process/pre_execution.js

+36-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,14 @@ const {
88
ObjectGetOwnPropertyDescriptor,
99
SafeMap,
1010
StringPrototypeStartsWith,
11+
Date,
12+
DatePrototypeGetFullYear,
13+
DatePrototypeGetMonth,
14+
DatePrototypeGetDate,
15+
DatePrototypeGetHours,
16+
DatePrototypeGetMinutes,
17+
DatePrototypeGetSeconds,
18+
String,
1119
globalThis,
1220
} = primordials;
1321

@@ -365,6 +373,7 @@ function initializeReportSignalHandlers() {
365373

366374
function initializeHeapSnapshotSignalHandlers() {
367375
const signal = getOptionValue('--heapsnapshot-signal');
376+
const diagnosticDir = getOptionValue('--diagnostic-dir');
368377

369378
if (!signal)
370379
return;
@@ -373,7 +382,8 @@ function initializeHeapSnapshotSignalHandlers() {
373382
const { writeHeapSnapshot } = require('v8');
374383

375384
function doWriteHeapSnapshot() {
376-
writeHeapSnapshot();
385+
const heapSnapshotFilename = getHeapSnapshotFilename(diagnosticDir);
386+
writeHeapSnapshot(heapSnapshotFilename);
377387
}
378388
process.on(signal, doWriteHeapSnapshot);
379389

@@ -650,6 +660,31 @@ function markBootstrapComplete() {
650660
internalBinding('performance').markBootstrapComplete();
651661
}
652662

663+
// Sequence number for diagnostic filenames
664+
let sequenceNumOfheapSnapshot = 0;
665+
666+
// To generate the HeapSnapshotFilename while using custom diagnosticDir
667+
function getHeapSnapshotFilename(diagnosticDir) {
668+
if (!diagnosticDir) return undefined;
669+
670+
const date = new Date();
671+
672+
const year = DatePrototypeGetFullYear(date);
673+
const month = String(DatePrototypeGetMonth(date) + 1).padStart(2, '0');
674+
const day = String(DatePrototypeGetDate(date)).padStart(2, '0');
675+
const hours = String(DatePrototypeGetHours(date)).padStart(2, '0');
676+
const minutes = String(DatePrototypeGetMinutes(date)).padStart(2, '0');
677+
const seconds = String(DatePrototypeGetSeconds(date)).padStart(2, '0');
678+
679+
const dateString = `${year}${month}${day}`;
680+
const timeString = `${hours}${minutes}${seconds}`;
681+
const pid = process.pid;
682+
const threadId = internalBinding('worker').threadId;
683+
const fileSequence = (++sequenceNumOfheapSnapshot).toString().padStart(3, '0');
684+
685+
return `${diagnosticDir}/Heap.${dateString}.${timeString}.${pid}.${threadId}.${fileSequence}.heapsnapshot`;
686+
}
687+
653688
module.exports = {
654689
setupUserModules,
655690
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)