Repository navigation
Conversation
…ges.mjs is released The fixture counted the server cells that a collection leaves, with a limit of 2000 turns. A server that nothing refers to any more can still be in the heap: the collector scans the machine stack conservatively. The last server stays that way through a closed socket of the host, whose handlers close over the scope that has the server. - The host's sockets no longer close over the server. - The count is compared with what the class itself has, not with a reading that can include the first server. - A server that stays is looked up in a heap snapshot. It is kept only if a root reaches it. The fixture then prints the path from that root. - The wait has no limit in turns. A server whose builds are not done is reached by a root, so the fixture waits on.
Not for merging. Runs the fixture as it is on main on the macOS lanes, next to the two tests that use it. When that fixture would print "kept", the diagnostic prints the path from a root to each server, or, for a server that no root reaches, the cells that reach it and the words of the stack that point at them. The report is adapted from #45816. Co-authored-by: Dylan Conway <dylan.conway567@gmail.com>
Collaborator
Author
Collaborator
Author
|
Status: draft, waiting for the macOS x64 job of #46490 How the failure was reproduced:
The temporary diagnostic is out of this PR. #46490 (not for merging) prints the heap snapshot and the stack words on the macOS and Windows lanes. I add the output of its macOS x64 job to the notes here and close it. The second failure of this file on those lanes ( |
… x64" This reverts commit c7d42a7.
…le-graph-pages-server-released
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
module-graph-isolation.test.tsfails on x64 lanes: macOS 14 from bake: options own their strings, in one set of types #44496 to Hardening: fix crashes across the runtime, bundler, dev server, shell and CLI #46021, Windows 2019 since. "a server whose HTML routes were still being built is released with it" printskept 1, notcollected.server.Fix
Background
Bun.serve()wrapper is a GC root until its server has no listener, connection or pending request. A building HTML route holds one.dispose()does not cancel a build.generateHeapSnapshotForDebugging()lists cells, edges and roots, not stack words.realmsARootReaches()in this file judges realms the same way.Notes
What keeps the server (Linux x64, release build of 9b4284f)
The fixture of main, with a heap snapshot taken in turn 16 of its last loop. All builds are done by then.
gdb on the same process, stopped in
JSC::MachineThreads::gatherConservativeRootsof the next collection. One word of the stack holds the address of that socket:The word is in the outgoing argument area of
runInternalMicrotask. An earlier microtask passed the socket there. The turns of the last loop runAsyncFunctionResumemicrotasks in a frame at the same address, and that path does not write the slot. The word changes in turn 20 or 21, and the count drops in that turn.Why the test passes or fails with the same word in place
The fixture reads its baseline after the first
use(), when two readings are equal. The first server is usually still being built then, so the baseline is 2 (the prototype and that server). With a baseline of 2 the fixture accepts one server that stays. With a baseline of 1 it does not.The same tolerance hides a real leak. With the last server assigned to a global, the fixture of main prints
collectedin 3 of 3 runs. The new fixture printskept 1: {root: ProtectedValues} GlobalObject -> .last HTTPServer.The macOS x64 lane (build 129752, darwin-x64-14.8.9, 12 cores)
The first push of this PR ran copies of the main fixture on that lane, with counters.
dispose()every build is done and every socket is closed within 27 ms (3 runs).kept.dispose()comes earlier than on Linux: 1 to 6 of the six requests have started a build, and some of the six connects are refused.No run on that lane reached 2000 turns, so there is no heap snapshot of the failure itself. Build 129752 has #46021, and builds with #46021 do not fail on that lane (next section). #46490 runs the report in turn 50 on the macOS and Windows lanes.
The macOS arm64 lane (build 130840 of #46490, 9634520)
#46490 runs the main fixture, made to wait for a count of 1, and prints the report in turn 50 when a server is still there. In 19 of 22 runs on this lane the last server goes in turn 21. In one run it is still there in turn 50:
The fixture reads the word from its own stack with
bun:ffi. The count drops in the turn in which the word changes. This run has a baseline of 1: with a word that stays past 2000 turns it is the failure.The two function names come from the canary
bun-profileof that commit. The test binary has no symbols, and its layout is close to the canary's but not the same (other frames of the chain resolve a few kilobytes beside the microtask drain functions). So read the names as the neighbourhood: a native frame of the microtask dispatch, as on Linux.On the two Windows lanes of that build every run reaches a count of 1 within 11 turns. The macOS x64 jobs of that build have not run yet.
Which builds have it
I read the annotations of the builds of all branches in two windows, and took the merge base of each build with main. A build counts when a test job of the lane ran (in the first window: after 10-16 08:00).
keptis alwayskept 1.keptkept(In the first window the Windows lanes still failed in another way, which #45821 fixed.)
developmentservers. It changes the layout of the binary.Runs of the new fixture (Linux x64)
releasedin 360 of 360 runs (median 0.4 to 0.6 s). With the serve plugin: 216 of 216.kept 1with the path, after 16 s.The other failure of this file on the same lane
dials-after-it-was-disposed.mjsprints{"arrivedFromTheGraph":-1}. That is another fixture and another cause. #45930 covers it.no test proof · iteration 1 · platform-specific test(s) that do not run on this machine, deferring to CI, which covers all platforms: test/js/bun/module-graph/module-graph-isolation.test.ts