Here is a change I made when investigating `ScriptSource`s outliving their `JSRuntime` because of `ScriptSourceObject`s being considered reachable after the final DESTROY_RUNTIME collection, and therefore not having their finalizer run, which would have freed the leaking `ScriptSource`s. I am iterating all cells in all zones to find `ScriptSourceObject`s and dump their retaining paths.
@@ -366,16 +368,29 @@ JSRuntime::init(uint32_t maxbytes, uint32_t maxNurseryBytes) JSRuntime::~JSRuntime() { MOZ_ASSERT(!isHeapBusy()); MOZ_ASSERT(childRuntimeCount == 0); fx.destroyInstance(); if (gcInitialized) { + fprintf(stderr, "FITZGEN: Check for leaking ScriptSourceObject *BEFORE* final GC on runtime\n"); + for (ZonesIter zone(this, WithAtoms); !zone.done(); zone.next()) { + for (auto kind : ObjectAllocKinds()) { + for (ZoneCellIter i(zone, kind); !i.done(); i.next()) { + if (i.get<JSObject>()->is<ScriptSourceObject>()) { + fprintf(stderr, "FITZGEN: FOUND MAYBE LEAKING ScriptSourceObject VIA CELL ITER!!!\n"); + JS::ubi::Node node(i.get<JSObject>()); + JS::ubi::dumpPaths(this, node); + } + } + } + } + /* Free source hook early, as its destructor may want to delete roots. */ sourceHook = nullptr; /* * Cancel any pending, in progress or completed Ion compilations and * parse tasks. Waiting for AsmJS and compression tasks is done * synchronously (on the main thread or during parse tasks), so no * explicit canceling is needed for these. On Mon, Apr 25, 2016 at 10:26 AM, Jim Blandy <jbla...@mozilla.com> wrote: > Could you show a sample patch that uses this? > > On Mon, Apr 25, 2016 at 10:19 AM, Nick Fitzgerald <nfitzger...@mozilla.com > > wrote: > >> Hi everyone! >> >> Friendly PSA: sometimes you're debugging a "leak" where the GC considers >> something reachable and therefore won't collect it, and this happens at an >> inopportune time for using the devtools memory panel (eg right before a >> DESTROY_RUNTIME collection), so you can't use the nice GUI for visualizing >> the GC's retaining paths. >> >> Fear not! You can use `JS::ubi::dumpPaths` to log retaining paths of any >> GC >> thing from within GDB, or you can compile it in as you might do with a >> tactically placed printf. >> >> The signature is `void JS::ubi::dumpPaths(JSRuntime* rt, JS::ubi::Node >> node, maxRetainingPaths = 10)`. The `rt` should be the runtime that the >> thing belongs to, `node` is the thing (JS::ubi::Node constructs from raw >> GC >> pointers as well as Rooted and Handle), and `maxRetainingPaths` is the >> number of retaining paths to dump. >> >> Include the "js/UbiNodeShortestPaths.h" header to get >> `JS::ubi::dumpPaths`. >> >> Happy bug hunting! >> >> Example output: >> >> Path 0: >> 0x7fff5fbfec10 JS::ubi::RootList >> | >> | >> '<no edge name>' >> | >> V >> 0x115c49d80 JSObject >> | >> | >> 'shape' >> | >> V >> 0x12ac4db50 js::Shape >> | >> | >> 'base' >> | >> V >> 0x116244e70 js::BaseShape >> | >> | >> 'ShapeTable shape' >> | >> V >> 0x116289120 js::Shape >> | >> | >> 'getter' >> | >> V >> 0x11627b3a0 JSObject >> | >> | >> 'private' >> | >> V >> 0x11855d940 JSObject >> | >> | >> 'script' >> | >> V >> 0x113290bf0 JSScript >> | >> | >> 'sourceObject' >> | >> V >> 0x1132763c0 JSObject >> >> Full output: https://pastebin.mozilla.org/8868795 >> _______________________________________________ >> dev-developer-tools mailing list >> dev-developer-to...@lists.mozilla.org >> https://lists.mozilla.org/listinfo/dev-developer-tools >> > > _______________________________________________ dev-platform mailing list dev-platform@lists.mozilla.org https://lists.mozilla.org/listinfo/dev-platform