Open Bug 839489 Opened 12 years ago Updated 2 years ago

Add memory leak detection tools at least to Nightlies so that we could catch earlier chrome code leaks

Categories

(Firefox :: General, defect)

defect

Tracking

()

People

(Reporter: smaug, Unassigned)

References

(Blocks 1 open bug)

Details

(Whiteboard: [MemShrink:P2])

Attachments

(1 file)

There are occasionally leaks found in chrome code (lately devtools and addon SDK). I've found those by running CC and looking at the graph size and what the graph contains. For that about:cc from bug 726346 works ok, but about:cc is super-ugly, and it has the features I need, not - I guess - what chrome js hackers might need. Should we perhaps add something simple which just notifies if some DOM Element or Document stays in CC graphs for a while, or if CC graph size increases or some such? Or what would be the most useful for UI/chrome js developers?
Whiteboard: [MemShrink]
Ok so when I investigated bug 833783, I wrote a very dirty but super usefull "tool" (more a bunch of code than a real tool), that allowed me to very quickly identify the two SDK leaks. I used the nsICycleCollectorListener API in order to list all GC nodes. GC, not CC, it is really important because the faulty edges only appear in GC. Then I used various JSAPI functions in order to be able to segregate objects for each compartment/global and highlighted edges between compartments. Then it was really easy to identify JS objects that were keeping references to the closed chrome window. But as I said, it is more a bunch of code than a tool, there is no UI, it just dump JSON values and I was doing various different queries by just modifying the code. I plan to blog about that crazy[1] experiment and release code when it becomes usable by someone else than me. [1] the crazy detail is that it is full JS code, using jsctypes to call the jsapi... It is fabulous for prototyping something extremelly quickly but I won't say it is by far the best option ;)
FYI, nsICycleCollectorListener tells only about CC stuff. CC may contain GCed stuff too (CC traces through JS code). I don't recall if we get GC log (which is separate from what nsICycleCollectorListener gives you) only in debug builds and/or only to a file. But what you did was about debugging the leak. I was hoping to have some notification to indicate that there might be some leak which could be then debugged. Right now it happens often that I keep about:cc open and run CC occasionally and see leaks and file a bug. Would be good to get other people to do similar leak hunting. But I don't think we have right tools for that atm. (and it would be super-great if you could document how you debugged the leak. You have the perspective of a chrome js hacker, not a cycle collector hacker :) )
It wouldn't be super hard to expose the GC heap dumping stuff to JS but it isn't something that is supported now.
FYI, after :ochameau told me of his experiments, I made an API to inspect a subset of the JS heap. https://github.com/nbp/mozilla-central/tree/t/logical-leak The JS API works as follow: watchForLeak(object) Add an object into the watch list, and return the same object. liveWatchedObjects() Returns an array of tuples (array), where the left-hand-side of each tuple is one of the watched object, and the right-hand-side is one of the object which hold a reference on it. If the rhs is null, then the value is kept alive by a rooted cell. If the value is undefined, then the object would be free in one of the following GCs, otherwise the value would be another object which refer to the watched object through potential intermediate non-object cells. stopWatchingLeaks() Free the weakmap used internally, unwatch all objects previously registered. I haven't made any xpcom bindings for it yet, and I only tested the API manually in the JS Shell. The API is not well designed yet. But the main idea is that you should have some hints on where to look for leaks. One simple reason for that is that full graph of live objects is generally too big to be digest. There is still a SEGV that I hope to solve soonish, I'll push it to github when I find it.
(In reply to Olli Pettay [:smaug] from comment #2) > FYI, nsICycleCollectorListener tells only about CC stuff. CC may contain > GCed stuff too > (CC traces through JS code). > I don't recall if we get GC log (which is separate from what > nsICycleCollectorListener gives you) > only in debug builds and/or only to a file. I thought that the WantAllTraces/allTraces() were enabling this listener to fetch all GC objects, as I was able to identify what seems to be all JS objects for each documents. I made this assumption when coming accros this usage: http://mxr.mozilla.org/mozilla-central/source/js/xpconnect/src/nsXPConnect.cpp#2737 In anycase, no matter what precise set of objects this API exposes, it looks like leaky JS objects are exposed. So I'd say there is no need for anything new on that side. > But what you did was about debugging the leak. I was hoping to have some > notification to indicate > that there might be some leak which could be then debugged. Right now it > happens often that > I keep about:cc open and run CC occasionally and see leaks and file a bug. > Would be good to > get other people to do similar leak hunting. But I don't think we have right > tools for that atm. > > (and it would be super-great if you could document how you debugged the > leak. You have the perspective of > a chrome js hacker, not a cycle collector hacker :) ) So my plan is to find time to make my piece of code usable by someone else than me in order to be able to expose how I identified the SDK leak. Then iterate on this in order to figure out what are the best presentation of the objects we can draw. There is multiple kind of leaks, these ones were easier as they are related to cross compartment leaks. So I tried to first identify the compartment/global related to the closed window we were leaking and then I searched for CCW that were refering to objects from this compartment and immediatly found two attributes: _tab and _window from objects hosted in SDK module sandboxes. The key here was: filtering per global/compartment and have access to JS metadata: object attributes. Atul Varma already wrote a really usefull piece of code that was unfortunately abandonned. He was spawning a new jsruntime that exposes an HTTP API (way before devtools came with the debugger api). This component was freezing the firefox instance while another one connects to this HTTP protocol in order to do any query on GC objects. It was really exciting as you were able to see Javascript objects with their attributes and not just a list of C++ object addresses with extremely limited metadata. Here is a presentation of his tool: http://www.toolness.com/wp/2009/10/web-application-memory-profiling-take-two/ And the platform source code: https://bitbucket.org/dalmaer/spidermonkey-playground/src/293eaba319ac/memory_profiler.cpp I hacked on top of his work in order to be able to segregate objects per global and also identify where each objects were initialized from the JS source code: http://blog.techno-barje.fr//post/2009/11/26/Mozilla-memory-profiling-part-2/ I still dream to have similar tooling released and maintained, where you can see objects counter directly from your source code. Then you can just execute various scenarios and identify which lines of code only grows and never gets down.
WantAllTraces will make the trace include all JS reachable from XPConnect roots, but not all JS.
This sounds great... but handwave-y. More concrete ideas on how it would work would be good...
Whiteboard: [MemShrink] → [MemShrink:P2]
We could analyze cycle collector logs occasionally and if it has increased since the previous time and has some suspicious objects (Documents, Windows or FragmentOrElement objects) a warning could be shown. I just don't know where exactly. What would be noticeable yet not annoying?
OS: Linux → All
Hardware: x86_64 → All
Attached patch WIP (deleted) — Splinter Review
Assignee: nobody → ttaubert
Status: NEW → ASSIGNED
Tim, what's the status here?
Sorry, no progress here. Too much other stuff to do :(
Assignee: ttaubert → nobody
Status: ASSIGNED → NEW
Severity: normal → S3
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: