Closed Bug 1142678 Opened 5 years ago Closed 5 years ago

Loading a message sending frame script into a private about:home tab causes leaks

Categories

(Core :: Storage: IndexedDB, defect)

defect
Not set

Tracking

()

RESOLVED FIXED

People

(Reporter: smacleod, Unassigned)

References

Details

(Whiteboard: [MemShrink:P2])

I wasn't sure which component this should go in, since I'm not actually sure what's causing the issue here, just what pieces are involved. The leak appears to come from things related to IndexedDB so I stuck it here for now.

I first hit a leak when attempting to access content in a private about:home tab using ContentTask.spawn(). Narrowing things down a bit the like appears to happen when:
 - about:home is loaded into a private browser.
 - A frame script is loaded into the browser, which then sends a message.

It appears that the frame script needs to actually send a message for the leak to appear. I've included a basic code snippet which is able to cause the leak:

> add_task(function* test_abouthome_leak() {
>   // The browser must be private.
>   let win = yield BrowserTestUtils.openNewBrowserWindow({private: true});
> 
>   // Must load about:home.
>   let browser = win.gBrowser.addTab("about:home").linkedBrowser;
>   yield BrowserTestUtils.browserLoaded(browser);
> 
>   let mm = browser.messageManager;
> 
>   let promiseContent = new Promise(resolve => {
>     mm.addMessageListener('MSG:CameBackFromContent', function listener(msg) {
>       mm.removeMessageListener('MSG:CameBackFromContent', listener);
>       resolve(msg);
>     });
>   });
> 
>   // Loading a framescript itself does not cause the leakage - the script
>   // must send a message back.
>   mm.loadFrameScript(`data:,
>     sendAsyncMessage("MSG:CameBackFromContent", {});
>   `, true);
> 
>   // Wait until we receieve the message.
>   yield promiseContent;
> 
>   // Single always passing test so there are no complaints about 0 tests.
>   ok(true);
>   win.close();
> });

And here is the output from running the test:
> TEST-INFO | leakcheck | default process: leak threshold set at 0 bytes
> TEST-INFO | leakcheck | plugin process: leak threshold set at 0 bytes
> TEST-INFO | leakcheck | tab process: leak threshold set at 100000 bytes
> TEST-INFO | leakcheck | geckomediaplugin process: leak threshold set at 20000 bytes
> 
> == BloatView: ALL (cumulative) LEAK AND BLOAT STATISTICS, default process 28883
> 
>      |<----------------Class--------------->|<-----Bytes------>|<----Objects---->|
>                                               Per-Inst   Leaked    Total      Rem
>    0 TOTAL                                          32      664  1241946       10
>  277 Mutex                                          32       32      857        1
>  363 ReentrantMonitor                               40       80      789        2
>  446 TransactionThreadPool                          96       96        1        1
>  447 TransactionThreadPoolListener                  24       24        1        1
> 1030 nsTArray_base                                   8       24   280487        3
> 1038 nsThread                                      240      240       44        1
> 1040 nsThreadPool                                  168      168        4        1
> 
> nsTraceRefcnt::DumpStatistics: 1146 entries
> TEST-INFO | leakcheck | default process: leaked 1 Mutex (32 bytes)
> TEST-INFO | leakcheck | default process: leaked 2 ReentrantMonitor (80 bytes)
> TEST-INFO | leakcheck | default process: leaked 1 TransactionThreadPool (96 bytes)
> TEST-INFO | leakcheck | default process: leaked 1 TransactionThreadPoolListener (24 bytes)
> TEST-INFO | leakcheck | default process: leaked 3 nsTArray_base (24 bytes)
> TEST-INFO | leakcheck | default process: leaked 1 nsThread (240 bytes)
> TEST-INFO | leakcheck | default process: leaked 1 nsThreadPool (168 bytes)
> TEST-UNEXPECTED-FAIL | leakcheck | default process: 664 bytes leaked (Mutex, ReentrantMonitor, TransactionThreadPool, TransactionThreadPoolListener, nsTArray_base, ...)

There is a try push with the leak[1] caused by the private browsing test in a commit[2] from Bug 1132566

[1] https://treeherder.mozilla.org/#/jobs?repo=try&revision=5fa23e72ce19
[2] https://hg.mozilla.org/try/rev/3181dee9585a
Whiteboard: [MemShrink]
indexedDB.open() checks for private browsing and deliberately fails because we don't support that (bug 781982). Removing this check here ...

http://hg.mozilla.org/mozilla-central/annotate/9dbb2d41bb2c/dom/indexedDB/ActorsParent.cpp#l10758

... fixes the leak. I assume that cleanup somehow fails in this case and we leak some indexedDB objects?
Blocks: 1144253
Flags: needinfo?(bent.mozilla)
Whiteboard: [MemShrink] → [MemShrink:P2]
I won't be able to get to this for a while... But it sounds like kind of an edge case? Anyway if someone else wants to dig in here feel free.
I bet this is the same as bug 1155634.
Flags: needinfo?(bent.mozilla)
It looks like bug 1155634 has been fixed.  Could you retest if you get a chance, Steven?  Thanks.
Flags: needinfo?(smacleod)
Pushed bug 1144253 to try and that seems fine. Thanks!
Status: NEW → RESOLVED
Closed: 5 years ago
Flags: needinfo?(smacleod)
Resolution: --- → FIXED
You need to log in before you can comment on or make changes to this bug.