Closed Bug 228233 Opened 16 years ago Closed 4 years ago

Mozilla freezes leaks memory setting image source (src) via JS due to nsHttpChannel never calling OnStopRequest

Categories

(Core :: Networking: Cache, defect, critical)

defect
Not set
critical

Tracking

()

RESOLVED FIXED

People

(Reporter: vhaarr+bmo, Unassigned)

References

()

Details

(Keywords: memory-leak, testcase, Whiteboard: [necko-active])

Attachments

(3 files, 1 obsolete file)

User-Agent:       Mozilla/5.0 (Windows; U; Windows NT 5.1; rv:1.6b) Gecko/20031206
Build Identifier: Mozilla/5.0 (Windows; U; Windows NT 5.1; rv:1.6b) Gecko/2003120608

This page causes my Mozilla to freeze for more than 8 minutes, and consume more
than ~300 megabytes of memory, before suddenly dropping to ~30-50 megabytes,
staying like that for a while, and then dropping to ~5-10 megabytes and crash.
This happens every time. It also freezes on my Linux RH9 Mozilla 1.5 installation.

The person who reported it to me on IRC said that it worked in his version of
Internet Explorer 6, although IE froze on my computer, just like Mozilla (didn't
use as much memory, though).

It works on Opera v7.23.

The page doesn't validate, but my belief is that it's a JS error of some sort.

Reproducible: Always

Steps to Reproduce:
1. Open the page in Mozilla.
2. Wait for more than 10 minutes.
Actual Results:  
During the loading, it freezed, and after about 10 minutes it crashed.

Expected Results:  
Probably show the page.. although I believe that it has severe errors.
This is the guy who reported it: aditsu@yahoo.com.
He doesn't have a bugzilla account, so I'll mail him and ask him to create one.

I should also specify that Mozilla didn't really crash, I got a "the memory
could not be 'read'" error. So I didn't get that WinXP crash report dialog.
Keywords: qawanted
Same symptoms on my Firebird installation.

Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.6b) Gecko/20031213
Firebird/0.7+
Attached file javascript testcase
i don't think this is an evangelism bug.
i think it's a javascript bug.
*** Bug 233235 has been marked as a duplicate of this bug. ***
brew: very good work - thanks!
This is a known issue, I think - I wonder if it should be fixed by bug 13350 ? I
didn't read through it. In any case, I can't seem to find another bug - perhaps
someone else has more luck.

-> Browser/DOM 0
Assignee: chinese-traditional → general
Component: Chinese-Traditional → DOM: Level 0
Keywords: hang, testcase
Product: Tech Evangelism → Browser
QA Contact: chinese-traditional → ian
Version: unspecified → Trunk
Loading the testcase now hits the 5 second maximum script limit, but chews up a
good chunk of memory during that time.  Letting the script continue continues
eating memory and it doesn't get reclaimed.

I'll attach a leak log from valgrind

==> HTTP
Assignee: general → darin
Component: DOM: Level 0 → Networking: HTTP
Keywords: hang, qawantedmlk
QA Contact: ian → networking.http
Attached file testcase
var myImage=new Image();
while (1) {
  myImage.src="http://mozilla.org/images/mlogo.gif";
}
Attached file valgrind leak log
I ran the testcase I attached under valgrind with current trunk and got this.
I dumped this in HTTP because of the leak log, but that doesn't seem very
logical.  I retested with FTP and it behaves the same

==> imagelib
Assignee: darin → pavlov
Component: Networking: HTTP → ImageLib
QA Contact: networking.http
Summary: Mozilla freezes first, and then crashes on this site. → Mozilla freezes leaks memory setting image source via JS
So I think the right fix for this would be to add some checks in to
nsImageLoadingContent that when the URL changes if its the same don't do
anythinkg.  I'm not sure what this breaks though.  Its also not clear why we
wouldn't be bumping off each previous request as we kick off a new one.

I'll poke at this further, but sending it to layout: images hoping bz can shed
some light.
Assignee: pavlov → bzbarsky
Component: ImageLib → Layout: Images
> add some checks in to nsImageLoadingContent that when the URL changes if its the 
> same don't do anythinkg.

that won't help this, which leaks just as badly:

      var myImage=new Image();
      var i = 1;
      while (1) {
         myImage.src="http://mozilla.org/images/mlogo"+(i++)+".gif";
      }
> So I think the right fix for this would be to add some checks

We have such checks in all the cases where they're possible.

> I'm not sure what this breaks though.

It breaks various pages that have no-cache images they want to animate (client
pull animations).

I can try to take a look at this when I get back using the refcount logger; if
someone gets a chance to do that before then, that would rock.
OK, so the testcase is totally an HTTP bug.  The FTP memory leak is a separate
issue, and I'll file a separate bug for it.

With HTTP, here's what's going on:  We call AsyncOpen on the HTTP channel, then
immediately call Cancel().  The URL points to a redirect, so once it's been
cached AsyncOpen will get into ReadFromCache() and that will |return
AsyncCall(&nsHttpChannel::HandleAsyncRedirect);|.

Now before HandleAsyncRedirect is called, we get canceled.  In Cancel(), all of
mProxyRequest, mTransaction, and mCachePump are null, since we're waiting on the
HandleAsyncRedirect call to actually do anything.  So we just set mStatus and
mCanceled and return.

Now when HandleAsyncRedirect is called, mStatus is an error status, so we just
close the cache entry, remove ourselves from the loadgroup and return.  At no
point is nsHttpChannel::OnStopRequest called.  So we never drop the mListener
ref.  The mListener is a ProxyRequest, which holds a strong ref to the
imgRequest, which holds a strong ref to the nsHttpChannel.  So we have a
reference cycle that never gets broken, and we leak.

We could probably fix this easily in the imagelib code by dropping the mChannel
ref when we cancel the channel, but that would still leave this http bug (eg the
fact that we're never calling OnStartRequest/OnStopRequest on the listener
passed to AsyncOpen in this case).

Darin, any idea what we can do here?  I suspect the other HandleAsync* methods
might have similar issues, btw...
Assignee: bzbarsky → darin
Component: Layout: Images → Networking: HTTP
QA Contact: networking.http
maybe Cancel should call AsyncAbort in an else {}, i.e. if it has nothing else
to call cancel on. However, I note that AsyncAbort clears much fewer references
than OnStopRequest, and I see no way that AsyncAbort calls OnStopRequest so that
can drop the refs... it just sets up the request proxy for its mListener and
calls onstartrequest/onstoprequest on that...
So I managed to reproduce the ftp leak exactly once; I haven't been able to
reproduce it since... I'm going to hold off on filing a bug on it until I (or
someone else) has a way to reliably reproduce it.
Summary: Mozilla freezes leaks memory setting image source via JS → Mozilla freezes leaks memory setting image source (src) via JS
-> default owner
Assignee: darin → nobody
Component: Networking: HTTP → Networking
QA Contact: networking.http → networking
*** Bug 353644 has been marked as a duplicate of this bug. ***
Flags: blocking1.9?
Not going to block, but we'll look for an appropriate owner.
Flags: blocking1.9? → blocking1.9-
Whiteboard: [wanted-1.9]
Attached file test case (obsolete) —
Hi,
I think this bug has nothing to do with network code unless the network code is somehow involved in also reading local files!
Here is a simple test case that demonstrates the bug.

Steps to Reproduce:
1. Put 18 reasonbly large jpegs (I use 1365x768) in a folder along with the attached html file.
2. Load file into firefox 2.0 on windowsXP

Expected Result:
IE 6 on winXP just happily shows the images 1 by 1 with no noticable change in mem usage.
FF 1.5.0.8 on windows2k just happily shows the images 1 by 1 with no noticable change in mem usage.

Actual:
Watch the firefox 2.0.0.1 on winXP memory usage climb indefinitely until your machine starts to crawl to a halt due to swapping and you need to close the tab!

Reproducible: Always!

I'll also see if I can reproduce this on my linux box at home.
Comment on attachment 254396 [details]
test case

s the network code is somehow involved in also reading local files!

It is.  All URL accesses in Gecko go through the networking library.  That includes file:// URLs.

That said, the leak described in comment 14 is HTTP-specific.  If you're seeing a problem with file://, please file a new bug, attach this testcase to it, and cc me, ok?
Attachment #254396 - Attachment is obsolete: true
Duplicate of this bug: 395025
Bug #401159 might be a dup of this one.
Depends on: 401159
Duplicate of this bug: 408344
Duplicate of this bug: 410752
Flags: wanted1.9+
Whiteboard: [wanted-1.9]
Patrick, Honza, would one of you have time to look into this?  It's still an issue as far as I can tell....
Summary: Mozilla freezes leaks memory setting image source (src) via JS → Mozilla freezes leaks memory setting image source (src) via JS due to nsHttpChannel never calling OnStopRequest
Looking into this now.
Not sure what exactly was happening before we made opening cache entries asynchronous, but now it hangs/loops/leaks because the cache IO thread is posting an event that calls httpChannel->OnCacheEntryAvailable on the main thread but that event never gets fired, because the main thread is blocked by the JS execution.  So, the first nsHttpChannel hangs waiting for the cache entry, canceling it does not have any affect.
so now the "testcase" attachment causes what looks like infinite stack depth. I think we ought to fix this.

For some reason its easier to see if you turn off e10s.

41 0x00007fffe8267b07 in mozilla::net::CacheEntry::OnHandleClosed(mozilla::net::CacheEntryHandle const*) () from /home/mcmanus/src/mozilla2/wd/channels/firefox/nightly/firefox/libxul.so
#24642 0x00007fffe8267d4c in mozilla::net::CacheEntryHandle::~CacheEntryHandle() () from /home/mcmanus/src/mozilla2/wd/channels/firefox/nightly/firefox/libxul.so
#24643 0x00007fffe8267d6e in mozilla::net::CacheEntryHandle::~CacheEntryHandle() () from /home/mcmanus/src/mozilla2/wd/channels/firefox/nightly/firefox/libxul.so
#24644 0x00007fffe8267dce in mozilla::net::CacheEntryHandle::Release() () from /home/mcmanus/src/mozilla2/wd/channels/firefox/nightly/firefox/libxul.so
#24645 0x00007fffe82680bf in mozilla::net::CacheEntry::InvokeAvailableCallback(mozilla::net::CacheEntry::Callback const&) () from /home/mcmanus/src/mozilla2/wd/channels/firefox/nightly/firefox/libxul.so
#24646 0x00007fffe826840b in mozilla::net::CacheEntry::InvokeCallback(mozilla::net::CacheEntry::Callback&) () from /home/mcmanus/src/mozilla2/wd/channels/firefox/nightly/firefox/libxul.so
#24647 0x00007fffe826657e in mozilla::net::CacheEntry::InvokeCallbacks(bool) () from /home/mcmanus/src/mozilla2/wd/channels/firefox/nightly/firefox/libxul.so
#24648 0x00007fffe82668c1 in mozilla::net::CacheEntry::InvokeCallbacks() () from /home/mcmanus/src/mozilla2/wd/channels/firefox/nightly/firefox/libxul.so
#24649 0x00007fffe8267b07 in mozilla::net::CacheEntry::OnHandleClosed(mozilla::net::CacheEntryHandle const*) () from /home/mcmanus/src/mozilla2/wd/channels/firefox/nightly/firefox/libxul.so
#24650 0x00007fffe8267d4c in mozilla::net::CacheEntryHandle::~CacheEntryHandle() () from /home/mcmanus/src/mozilla2/wd/channels/firefox/nightly/firefox/libxul.so
#24651 0x00007fffe8267d6e in mozilla::net::CacheEntryHandle::~CacheEntryHandle() () from /home/mcmanus/src/mozilla2/wd/channels/firefox/nightly/firefox/libxul.so
#24652 0x00007fffe8267dce in mozilla::net::CacheEntryHandle::Release() () from /home/mcmanus/src/mozilla2/wd/channels/firefox/nightly/firefox/libxul.so
#24653 0x00007fffe82680bf in mozilla::net::CacheEntry::InvokeAvailableCallback(mozilla::net::CacheEntry::Callback const&) () from /home/mcmanus/src/mozilla2/wd/channels/firefox/nightly/firefox/libxul.so
#24654 0x00007fffe826840b in mozilla::net::CacheEntry::InvokeCallback(mozilla::net::CacheEntry::Callback&) () from /home/mcmanus/src/mozilla2/wd/channels/firefox/nightly/firefox/libxul.so
#24655 0x00007fffe826657e in mozilla::net::CacheEntry::InvokeCallbacks(bool) () from /home/mcmanus/src/mozilla2/wd/channels/firefox/nightly/firefox/libxul.so
#24656 0x00007fffe82668c1 in mozilla::net::CacheEntry::InvokeCallbacks() () from /home/mcmanus/src/mozilla2/wd/channels/firefox/nightly/firefox/libxul.so
#24657 0x00007fffe8267b07 in mozilla::net::CacheEntry::OnHandleClosed(mozilla::net::CacheEntryHandle const*) () from /home/mcmanus/src/mozilla2/wd/channels/firefox/nightly/firefox/libxul.so
#24658 0x00007fffe8267d4c in mozilla::net::CacheEntryHandle::~CacheEntryHandle() () from /home/mcmanus/src/mozilla2/wd/channels/firefox/nightly/firefox/libxul.so
#24659 0x00007fffe8267d6e in mozilla::net::CacheEntryHandle::~CacheEntryHandle() () from /home/mcmanus/src/mozilla2/wd/channels/firefox/nightly/firefox/libxul.so
#24660 0x00007fffe8267dce in mozilla::net::CacheEntryHandle::Release() () from /home/mcmanus/src/mozilla2/wd/channels/firefox/nightly/firefox/libxul.so
#24661 0x00007fffe82680bf in mozilla::net::CacheEntry::InvokeAvailableCallback(mozilla::net::CacheEntry::Callback const&) () from /home/mcmanus/src/mozilla2/wd/channels/firefox/nightly/firefox/libxul.so
#24662 0x00007fffe826840b in mozilla::net::CacheEntry::InvokeCallback(mozilla::net::CacheEntry::Callback&) () from /home/mcmanus/src/mozilla2/wd/channels/firefox/nightly/firefox/libxul.so
#24663 0x00007fffe826657e in mozilla::net::CacheEntry::InvokeCallbacks(bool) () from /home/mcmanus/src/mozilla2/wd/channels/firefox/nightly/firefox/libxul.so
#24664 0x00007fffe82668c1 in mozilla::net::CacheEntry::InvokeCallbacks() () from /home/mcmanus/src/mozilla2/wd/channels/firefox/nightly/firefox/libxul.so
#24665 0x00007fffe8267b07 in mozilla::net::CacheEntry::OnHandleClosed(mozilla::net::CacheEntryHandle const*) () from /home/mcmanus/src/mozilla2/wd/channels/firefox/nightly/firefox/libxul.so
#24666 0x00007fffe8267d4c in mozilla::net::CacheEntryHandle::~CacheEntryHandle() () from /home/mcmanus/src/mozilla2/wd/channels/firefox/nightly/firefox/libxul.so
#24667 0x00007fffe8267d6e in mozilla::net::CacheEntryHandle::~CacheEntryHandle() () from /home/mcmanus/src/mozilla2/wd/channels/firefox/nightly/firefox/libxul.so
#24668 0x00007fffe8267dce in mozilla::net::CacheEntryHandle::Release() () from /home/mcmanus/src/mozilla2/wd/channels/firefox/nightly/firefox/libxul.so
#24669 0x00007fffe82680bf in mozilla::net::CacheEntry::InvokeAvailableCallback(mozilla::net::CacheEntry::Callback const&) () from /home/mcmanus/src/mozilla2/wd/channels/firefox/nightly/firefox/libxul.so
#24670 0x00007fffe826840b in mozilla::net::CacheEntry::InvokeCallback(mozilla::net::CacheEntry::Callback&) () from /home/mcmanus/src/mozilla2/wd/channels/firefox/nightly/firefox/libxul.so
#24671 0x00007fffe826657e in mozilla::net::CacheEntry::InvokeCallbacks(bool) () from /home/mcmanus/src/mozilla2/wd/channels/firefox/nightly/firefox/libxul.so
#24672 0x00007fffe82668c1 in mozilla::net::CacheEntry::InvokeCallbacks() () from /home/mcmanus/src/mozilla2/wd/channels/firefox/nightly/firefox/libxul.so
#24673 0x00007fffe8267b07 in mozilla::net::CacheEntry::OnHandleClosed(mozilla::net::CacheEntryHandle const*) () from /home/mcmanus/src/mozilla2/wd/channels/firefox/nightly/firefox/libxul.so
#24674 0x00007fffe8267d4c in mozilla::net::CacheEntryHandle::~CacheEntryHandle() () from /home/mcmanus/src/mozilla2/wd/channels/firefox/nightly/firefox/libxul.so
#24675 0x00007fffe8267d6e in mozilla::net::CacheEntryHandle::~CacheEntryHandle() () from /home/mcmanus/src/mozilla2/wd/channels/firefox/nightly/firefox/libxul.so
#24676 0x00007fffe8267dce in mozilla::net::CacheEntryHandle::Release() () from /home/mcmanus/src/mozilla2/wd/channels/firefox/nightly/firefox/libxul.so
#24677 0x00007fffe82680bf in mozilla::net::CacheEntry::InvokeAvailableCallback(mozilla::net::CacheEntry::Callback const&) () from /home/mcmanus/src/mozilla2/wd/channels/firefox/nightly/firefox/libxul.so
#24678 0x00007fffe826840b in mozilla::net::CacheEntry::InvokeCallback(mozilla::net::CacheEntry::Callback&) () from /home/mcmanus/src/mozilla2/wd/channels/firefox/nightly/firefox/libxul.so
#24679 0x00007fffe826657e in mozilla::net::CacheEntry::InvokeCallbacks(bool) () from /home/mcmanus/src/mozilla2/wd/channels/firefox/nightly/firefox/libxul.so
#24680 0x00007fffe82668c1 in mozilla::net::CacheEntry::InvokeCallbacks() () from /home/mcmanus/src/mozilla2/wd/channels/firefox/nightly/firefox/libxul.so
#24681 0x00007fffe8267b07 in mozilla::net::CacheEntry::OnHandleClosed(mozilla::net::CacheEntryHandle const*) () from /home/mcmanus/src/mozilla2/wd/channels/firefox/nightly/firefox/libxul.so
#24682 0x00007fffe8267d4c in mozilla::net::CacheEntryHandle::~CacheEntryHandle() () from /home/mcmanus/src/mozilla2/wd/channels/firefox/nightly/firefox/libxul.so
#24683 0x00007fffe8267d6e in mozilla::net::CacheEntryHandle::~CacheEntryHandle() () from /home/mcmanus/src/mozilla2/wd/channels/firefox/nightly/firefox/libxul.so
#24684 0x00007fffe8267dce in mozilla::net::CacheEntryHandle::Release() () from /home/mcmanus/src/mozilla2/wd/channels/firefox/nightly/firefox/libxul.so
#24685 0x00007fffe82680bf in mozilla::net::CacheEntry::InvokeAvailableCallback(mozilla::net::CacheEntry::Callback const&) () from /home/mcmanus/src/mozilla2/wd/channels/firefox/nightly/firefox/libxul.so
#24686 0x00007fffe826840b in mozilla::net::CacheEntry::InvokeCallback(mozilla::net::CacheEntry::Callback&) () from /home/mcmanus/src/mozilla2/wd/channels/firefox/nightly/firefox/libxul.so
#24687 0x00007fffe826657e in mozilla::net::CacheEntry::InvokeCallbacks(bool) () from /home/mcmanus/src/mozilla2/wd/channels/firefox/nightly/firefox/libxul.so
#24688 0x00007fffe82668c1 in mozilla::net::CacheEntry::InvokeCallbacks() () from /home/mcmanus/src/mozilla2/wd/channels/firefox/nightly/firefox/libxul.so
#24689 0x00007fffe8267b07 in mozilla::net::CacheEntry::OnHandleClosed(mozilla::net::CacheEntryHandle const*) () from /home/mcmanus/src/mozilla2/wd/channels/firefox/nightly/firefox/libxul.so
#24690 0x00007fffe8267d4c in mozilla::net::CacheEntryHandle::~CacheEntryHandle() () from /home/mcmanus/src/mozilla2/wd/channels/firefox/nightly/firefox/libxul.so
#24691 0x00007fffe8267d6e in mozilla::net::CacheEntryHandle::~CacheEntryHandle() () from /home/mcmanus/src/mozilla2/wd/channels/firefox/nightly/firefox/libxul.so
Component: Networking → Networking: Cache
Flags: needinfo?(honzab.moz)
Whiteboard: [necko-active]
This is definitely fixed in bug 1154124.  Are you up to date?
Flags: needinfo?(honzab.moz)
1154124 was merged to central the same day I did the test.. so could go either way. I'll retest.
confirmed we're good now.
Status: NEW → RESOLVED
Closed: 4 years ago
Resolution: --- → FIXED
You need to log in before you can comment on or make changes to this bug.