Closed Bug 753274 Opened 13 years ago Closed 12 years ago

Television app crashes runtime

Categories

(Firefox Graveyard :: Webapp Runtime, defect, P2)

x86_64
Windows 7
defect

Tracking

(Not tracked)

VERIFIED FIXED
Firefox 15

People

(Reporter: eviljeff, Assigned: TimAbraldes)

References

()

Details

(Keywords: crash, Whiteboard: [appreview-blocker], [qa!])

Attachments

(1 file, 1 obsolete file)

I can consistently crash the Television app. Steps to reproduce: 1) Install & run Television app 2) load a live stream (e.g. RT America) 3) wait for it to start 4) click one of the VOD links on the right Windows reports Nightly has crashed. As the crash reporter isn't in the runtime yet (bug 745980) I don't have the normal Mozilla crash reports. I uploaded the windows crash logs here though: http://www.2shared.com/file/NytoRsNQ/TV_app_crash_logs.html If I go to the url (http://internet-tv.appspot.com/) in Nightly and try the same STR the live flash stream doesn't play, but I can then switch to a vodcast without Nightly crashing. I don't have any plugins disabled in Nightly (I just have Flash and an MS Office one).
Severity: normal → critical
Myk - Is there enough information here to determine what happened? If not, what else should Andrew get to figure out the root cause of the crash?
From my POV, we really need the crash reporter in the runtime to diagnose such things nicely. That said, you can probably try running the runtime/app in a debugger and try getting a stack that way.
Blocks: 737571
Priority: -- → P2
No longer blocks: 737571
Target Milestone: --- → M1
Flagging for stackwanted - we need a stack trace for this bug.
Keywords: crash, stackwanted
Component: Desktop Runtime → Webapp Runtime
Product: Web Apps → Firefox
Target Milestone: M1 → Firefox 15
KERNELBASE!DebugBreak+0x2 xul!RealBreak(void)+0xa xul!Break(char * aMsg = 0x00000000`0032d4e0 "###!!! ASSERTION: Invalid window handle: 'Error', file c:/src/central/obj/widget/windows/../../../widget/windows/nsWindow.cpp, line 904")+0x255 xul!NS_DebugBreak_P(unsigned int aSeverity = 1, char * aStr = 0x000007fe`e42fd5f0 "Invalid window handle", char * aExpr = 0x000007fe`e42fc5a4 "Error", char * aFile = 0x000007fe`e42fd590 "c:/src/central/obj/widget/windows/../../../widget/windows/nsWindow.cpp", int aLine = 904)+0x35a xul!nsWindow::SubclassWindow(int bState = 0)+0x5d xul!nsWindow::OnDestroy(void)+0x65 xul!nsWindow::Destroy(void)+0x129 xul!nsPluginInstanceOwner::Destroy(void)+0xf0b xul!nsObjectLoadingContent::DoStopPlugin(class nsPluginInstanceOwner * aInstanceOwner = 0x00000000`09359ef0, bool aDelayedStop = false)+0x11a xul!nsObjectLoadingContent::StopPluginInstance(void)+0x148 xul!InDocCheckEvent::Run(void)+0x82 xul!nsBaseAppShell::RunSyncSectionsInternal(bool aStable = true, unsigned int aThreadRecursionLevel = 0)+0x14d xul!nsBaseAppShell::RunSyncSections(bool stable = true, unsigned int threadRecursionLevel = 0)+0x3e xul!nsBaseAppShell::OnProcessNextEvent(class nsIThreadInternal * thr = 0x00000000`02281b70, bool mayWait = true, unsigned int recursionDepth = 0)+0x252 xul!nsThread::ProcessNextEvent(bool mayWait = true, bool * result = 0x00000000`0032e110)+0x293 xul!NS_ProcessNextEvent_P(class nsIThread * thread = 0x00000000`02281b70, bool mayWait = true)+0x6b xul!mozilla::ipc::MessagePump::Run(class base::MessagePump::Delegate * aDelegate = 0x00000000`02271bc0)+0x2db xul!MessageLoop::RunInternal(void)+0x68 xul!MessageLoop::RunHandler(void)+0x3b xul!MessageLoop::Run(void)+0x22 xul!nsBaseAppShell::Run(void)+0x63 xul!nsAppStartup::Run(void)+0x8a xul!XREMain::XRE_mainRun(void)+0xf31 xul!XREMain::XRE_main(int argc = 1, char ** argv = 0x00000000`004c7a80, struct nsXREAppData * aAppData = 0x00000000`004c1950)+0x34b xul!XRE_main(int argc = 1, char ** argv = 0x00000000`004c7a80, struct nsXREAppData * aAppData = 0x00000000`004c1950)+0x52 TV!`anonymous namespace'::AttemptGRELoadAndLaunch(char * greDir = 0x00000000`0032f1f0 "C:\src\central\obj\dist\bin")+0x635 TV!`anonymous namespace'::AttemptLoadFromDir(char * firefoxDir = 0x00000000`0032f1f0 "C:\src\central\obj\dist\bin")+0x19f TV!NS_internal_main(int argc = 1, char ** argv = 0x00000000`004c7a80)+0x320 TV!wmain(int argc = 1, wchar_t ** argv = 0x00000000`004d28f0)+0x196 TV!__tmainCRTStartup(void)+0xd2 TV!wmainCRTStartup(void)+0xe kernel32!BaseThreadInitThunk+0xd ntdll!RtlUserThreadStart+0x21 Not sure if this is the appropriate place to paste it (maybe pastebin is better?), but here's a stack trace of this error.
Keywords: stackwanted
Thanks Tim. Looking at the stack, do you have any ideas of what the root cause of the problem is? I see mention of the plugins & windows in the above stack.
From what I can tell, a window related to the flash plugin is being destroyed. By the time we get to the `SubclassWindow()` call in `nsWindow::OnDestroy`, `mWnd` is no longer a valid window handle. I'm not sure what causes the `mWnd` handle to become invalid; I'd probably have to set some breakpoints and run through the STR in the debugger a few times to get a better understanding of what's going on here. I'll try to take another look at this soon but I'll be out of town May 24th-29th and may not get to this until afterward.
Whiteboard: [appreview-blocker]
This bug appears to be timing related. See https://mxr.mozilla.org/mozilla-central/source/widget/windows/nsWindow.cpp?rev=bea5301cf21f#636 When the bug does NOT express itself: `nsWindow::Destroy()` is called `nsWindow::Destroy()` calls `::DestroyWindow()` `nsWindow`s wndProc handles the `WM_DESTROY` message by calling `nsWindow::OnDestroy()` `nsWindow::OnDestroy()` validates `mWnd` by calling `::IsWindow()` `nsWindow::OnDestroy()` successfully destroys the window `nsWindow::Destroy()` returns successfully When the bug DOES express itself: `nsWindow::Destroy()` is called `nsWindow::Destroy()` calls `::DestroyWindow()` `nsWindow::Destroy()` calls `nsWindow::OnDestroy()` `nsWindow::OnDestroy()` attempts to validate `mWnd` by calling `::IsWindow()` Assertion fires My guess is that something along the following lines is happening: `::DestroyWindow()` invalidates the `HWND` that `mWnd` points to `::DestroyWindow()` posts a `WM_DESTROY` message to the window's message queue In the crash case, `nsWindow::Destroy()` continues executing before the `WM_DESTROY` has been processed
The attached patch seems to resolve this issue. It works by modifying `nsWindow::SubclassWindow()` to be more lenient about an invalid `mWnd` if we are removing a subclass rather than adding one. The attached patch modifies `nsWindow` which is slightly terrifying. Jimm: Do you see any obvious issues with this approach?
Assignee: nobody → tabraldes
Status: NEW → ASSIGNED
Attachment #628947 - Flags: review?(jmathies)
Comment on attachment 628947 [details] [diff] [review] Patch v1 - Make `nsWindow::SubclassWindow` deal more gracefully with windows that have already been destroyed Review of attachment 628947 [details] [diff] [review]: ----------------------------------------------------------------- ::: widget/windows/nsWindow.cpp @@ +850,5 @@ > // Subclass (or remove the subclass from) this component's nsWindow > void nsWindow::SubclassWindow(BOOL bState) > { > + if (bState) { > + if (NULL == mWnd || !::IsWindow(mWnd)) { lets clean this up while we're here - (!mWnd || !IsWindow(mWnd)) @@ +856,5 @@ > } > > + if (mUnicodeWidget) > + mPrevWndProc = (WNDPROC)::SetWindowLongPtrW(mWnd, GWLP_WNDPROC, > + (LONG_PTR)nsWindow::WindowProc); nix the '::' throughout and line things up right. Also bracket this if statement. @@ +864,5 @@ > + NS_ASSERTION(mPrevWndProc, "Null standard window procedure"); > + // connect the this pointer to the nsWindow handle > + WinUtils::SetNSWindowPtr(mWnd, this); > + } else { > + if (::IsWindow(mWnd)) { This appears to be the only real change here right? This should be ok. Please run this through try.
(In reply to Tim Abraldes from comment #7) > When the bug DOES express itself: > `nsWindow::Destroy()` is called > `nsWindow::Destroy()` calls `::DestroyWindow()` > `nsWindow::Destroy()` calls `nsWindow::OnDestroy()` > `nsWindow::OnDestroy()` attempts to validate `mWnd` by calling > `::IsWindow()` > Assertion fires > > My guess is that something along the following lines is happening: > `::DestroyWindow()` invalidates the `HWND` that `mWnd` points to > `::DestroyWindow()` posts a `WM_DESTROY` message to the window's message > queue > In the crash case, `nsWindow::Destroy()` continues executing before the > `WM_DESTROY` has been processed I don't see how this is possible, according the MSDN this is a synchronous call. Is it possible something in the window has subclassed our window and is stealing the WM_DESTROY message?
(In reply to Jim Mathies [:jimm] from comment #10) > (In reply to Tim Abraldes from comment #7) > > When the bug DOES express itself: > > `nsWindow::Destroy()` is called > > `nsWindow::Destroy()` calls `::DestroyWindow()` > > `nsWindow::Destroy()` calls `nsWindow::OnDestroy()` > > `nsWindow::OnDestroy()` attempts to validate `mWnd` by calling > > `::IsWindow()` > > Assertion fires > > > > My guess is that something along the following lines is happening: > > `::DestroyWindow()` invalidates the `HWND` that `mWnd` points to > > `::DestroyWindow()` posts a `WM_DESTROY` message to the window's message > > queue > > In the crash case, `nsWindow::Destroy()` continues executing before the > > `WM_DESTROY` has been processed > > I don't see how this is possible, according the MSDN this is a synchronous > call. I couldn't find anything on the MSDN pages for `DestroyWindow`[1] or `WM_DESTROY`[2] saying that the message would be processed synchronously. I planned to set breakpoints in `DestroyWindow` to see if it calls `SendMessage` or `PostMessage` but I'd have to mess with my symbol settings to get export symbols for user32.dll. > Is it possible something in the window has subclassed our window and > is stealing the WM_DESTROY message? Yes, I believe that this is possible, though it would have to be happening non-deterministically (sometimes the window gets subclassed, sometimes it doesn't). I think the attached patch would still be appropriate if this is the case: In [3], the window will be destroyed by `DestroyWindow()` `mOnDestroyCalled` will be false, so `OnDestroy` will be called from [3] `OnDestroy` will call `SubclassWindow(FALSE)` which will now run without asserting [1] http://msdn.microsoft.com/en-us/library/windows/desktop/ms632682%28v=vs.85%29.aspx [2] http://msdn.microsoft.com/en-us/library/windows/desktop/ms632620%28v=vs.85%29.aspx [3] https://mxr.mozilla.org/mozilla-central/source/widget/windows/nsWindow.cpp?rev=bea5301cf21f#636
(In reply to Jim Mathies [:jimm] from comment #9) > Comment on attachment 628947 [details] [diff] [review] > Patch v1 - Make `nsWindow::SubclassWindow` deal more gracefully with windows > that have already been destroyed > > Review of attachment 628947 [details] [diff] [review]: > ----------------------------------------------------------------- > > ::: widget/windows/nsWindow.cpp > @@ +850,5 @@ > > // Subclass (or remove the subclass from) this component's nsWindow > > void nsWindow::SubclassWindow(BOOL bState) > > { > > + if (bState) { > > + if (NULL == mWnd || !::IsWindow(mWnd)) { > > lets clean this up while we're here - > > (!mWnd || !IsWindow(mWnd)) Done. > @@ +856,5 @@ > > } > > > > + if (mUnicodeWidget) > > + mPrevWndProc = (WNDPROC)::SetWindowLongPtrW(mWnd, GWLP_WNDPROC, > > + (LONG_PTR)nsWindow::WindowProc); > > nix the '::' throughout and line things up right. Also bracket this if > statement. Done. Removed '::' in front of system calls and bracketed all if statements. > @@ +864,5 @@ > > + NS_ASSERTION(mPrevWndProc, "Null standard window procedure"); > > + // connect the this pointer to the nsWindow handle > > + WinUtils::SetNSWindowPtr(mWnd, this); > > + } else { > > + if (::IsWindow(mWnd)) { > > This appears to be the only real change here right? This should be ok. > Please run this through try. Running this through try: https://tbpl.mozilla.org/?tree=Try&rev=978a52a598d9 I had actually run the previous patch through try but it's taking forEVER: https://tbpl.mozilla.org/?tree=Try&rev=1e4aa67b9db5 Also I changed the C-style casts to reinterpret_casts.
Attachment #628947 - Attachment is obsolete: true
Attachment #628947 - Flags: review?(jmathies)
Attachment #629308 - Flags: review?(jmathies)
Attachment #629308 - Flags: review?(jmathies) → review+
Status: ASSIGNED → RESOLVED
Closed: 12 years ago
Resolution: --- → FIXED
Whiteboard: [appreview-blocker] → [appreview-blocker], [qa+]
Andrew - Could you do a re-review of the Television app and see if this bug is fixed?
Whiteboard: [appreview-blocker], [qa+] → [appreview-blocker], [qa+:jsmith]
(In reply to Jason Smith [:jsmith] from comment #15) > Andrew - Could you do a re-review of the Television app and see if this bug > is fixed? Its fixed for me on my laptop, but I won't be able to test on my desktop machine (that originally exhibited the bug) for a few weeks. Its Win7, 64 bit also so its probably okay.
Status: RESOLVED → VERIFIED
Whiteboard: [appreview-blocker], [qa+:jsmith] → [appreview-blocker], [qa!]
Flags: in-moztrap-
QA Contact: desktop-runtime → jsmith
Product: Firefox → Firefox Graveyard
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: