diff --git a/lib/internal/debugger/inspect_repl.js b/lib/internal/debugger/inspect_repl.js index a93a8dfecf2720..401887cbda5c74 100644 --- a/lib/internal/debugger/inspect_repl.js +++ b/lib/internal/debugger/inspect_repl.js @@ -325,6 +325,7 @@ function createRepl(inspector) { const history = { control: [], debug: [] }; const watchedExpressions = []; const knownBreakpoints = []; + let heapSnapshotPromise = null; let pauseOnExceptionState = 'none'; let lastCommand; @@ -961,7 +962,13 @@ function createRepl(inspector) { }, takeHeapSnapshot(filename = 'node.heapsnapshot') { - return new Promise((resolve, reject) => { + if (heapSnapshotPromise) { + print( + 'Cannot take heap snapshot because another snapshot is in progress.' + ); + return heapSnapshotPromise; + } + heapSnapshotPromise = new Promise((resolve, reject) => { const absoluteFile = Path.resolve(filename); const writer = FS.createWriteStream(absoluteFile); let sizeWritten = 0; @@ -983,6 +990,7 @@ function createRepl(inspector) { writer.end(() => { teardown(); print(`Wrote snapshot: ${absoluteFile}`); + heapSnapshotPromise = null; resolve(); }); } @@ -1006,6 +1014,7 @@ function createRepl(inspector) { HeapProfiler.takeHeapSnapshot({ reportProgress: true }), onResolve, onReject); }); + return heapSnapshotPromise; }, get watchers() { diff --git a/test/sequential/test-debugger-heap-profiler.js b/test/sequential/test-debugger-heap-profiler.js index 6ba55e8078348f..69be07a6f9c517 100644 --- a/test/sequential/test-debugger-heap-profiler.js +++ b/test/sequential/test-debugger-heap-profiler.js @@ -32,6 +32,10 @@ const filename = 'node.heapsnapshot'; .then(() => cli.waitForPrompt()) .then(() => cli.command('takeHeapSnapshot()')) .then(() => JSON.parse(readFileSync(filename, 'utf8'))) + // Check that two simultaneous snapshots don't step all over each other. + // Refs: https://github.com/nodejs/node/issues/39555 + .then(() => cli.command('takeHeapSnapshot(); takeHeapSnapshot()')) + .then(() => JSON.parse(readFileSync(filename, 'utf8'))) .then(() => cli.quit()) .then(null, onFatal); }