-
-
Notifications
You must be signed in to change notification settings - Fork 34.2k
Closed
Labels
inspectorIssues and PRs related to the V8 inspector protocolIssues and PRs related to the V8 inspector protocol
Description
Version
20.10.0
Platform
All
Subsystem
inspector
What steps will reproduce the bug?
The following code leaks memory at about 10MB per second on my machine:
import { Session } from "node:inspector/promises";
const session = new Session();
session.connect();
session.on("Debugger.paused", async (event) => {
for (const frame of event.params.callFrames) {
const localScope = frame.scopeChain.find((scope) => scope.type === "local");
if (localScope?.object?.objectId) {
const props = await session.post("Runtime.getProperties", {
objectId: localScope.object.objectId,
ownProperties: true,
});
}
}
});
await session.post("Debugger.enable");
await session.post("Debugger.setPauseOnExceptions", { state: "all" });
setInterval(() => {
console.log(`${Math.floor(process.memoryUsage().rss / 1024 / 1024)} MB`);
}, 1000);
setInterval(() => {
try {
throw new Error("Hello");
} catch {}
}, 1);How often does it reproduce? Is there a required condition?
Every time
What is the expected behavior? Why is that the expected behavior?
No memory leaked
What do you see instead?
I see ~10MB leaked every second which is around 10kB per debugger pause event.
Additional information
I found that that the following code:
import { Session } from "node:inspector/promises";
const session = new Session();
session.connect();
session.on("Debugger.resumed", () => {
console.log("Debugger resumed");
});
session.on("Debugger.paused", async (event) => {
console.log("Debugger paused start");
for (const frame of event.params.callFrames) {
const localScope = frame.scopeChain.find((scope) => scope.type === "local");
if (localScope?.object?.objectId) {
console.log("Runtime.getProperties");
const props = await session.post("Runtime.getProperties", {
objectId: localScope.object.objectId,
});
console.log("Runtime.getProperties returned");
}
}
console.log("Debugger.paused end");
});
await session.post("Debugger.enable");
await session.post("Debugger.setPauseOnExceptions", { state: "all" });
setTimeout(() => {
try {
throw new Error("Hello");
} catch {}
}, 1000);Outputs:
Debugger paused start
Runtime.getProperties
Debugger resumed
Runtime.getProperties returned
Runtime.getProperties
Runtime.getProperties returned
Runtime.getProperties
Runtime.getProperties returned
Debugger.paused end
The debugger does not wait for Debugger.resume. Instead it resumes automatically as soon as we call await session.post and I guess calling Runtime.getProperties after the resume causes something to be leaked?
tonivj5
Metadata
Metadata
Assignees
Labels
inspectorIssues and PRs related to the V8 inspector protocolIssues and PRs related to the V8 inspector protocol