EVALUATION
http://hg.openjdk.java.net/hsx/hotspot-comp/jdk/rev/c66b34ec39c3
|
|
|
EVALUATION
With the suggested fix applied
http://sa.sfbay.sun.com/projects/awt_data/7/7024749.1/
there's a number of failed tests:
AWT_Focus/Automated/AWT/FocusableStateTest2/DialogTest1 execute_script
AWT_Focus/Automated/AWT/FocusableStateTest2/FrameTest1 execute_script
AWT_Modality/Automated/Focus/DocumentModal execute_script mustang
AWT_Modality/Automated/Focus/ModelessFocus execute_script mustang
AWT_Modality/Automated/Focus/NonModal execute_script mustang
The current fix is incomplete and it should be enhanced.
|
|
|
SUGGESTED FIX
$ hg diff src/windows/native/sun/windows/awt_Window.cpp
diff -r 0b7f41c14605 src/windows/native/sun/windows/awt_Window.cpp
--- a/src/windows/native/sun/windows/awt_Window.cpp Mon May 16 18:40:10 2011 +0400
+++ b/src/windows/native/sun/windows/awt_Window.cpp Mon May 23 18:04:46 2011 +0400
@@ -429,7 +429,8 @@ LRESULT CALLBACK AwtWindow::CBTFilter(in
AwtWindow* win = (AwtWindow*)comp;
if (!win->IsFocusableWindow() ||
- win->m_filterFocusAndActivation)
+ win->m_filterFocusAndActivation ||
+ win->IsSimpleWindow())
{
return 1; // Don't change focus/activation.
}
|
|
|
EVALUATION
A better fix - consume the unexpected activation. Suggested fix attached. It's a low-risk fix because any simple window already marked as WM_EX_NOACTIVATE so that such window cannot be activated.
|
|
|
EVALUATION
Here's a couple of observations regarding this issues.
the native stack attached to the bug report doesn't seem to be valid. it's more likely that valid stack is as follow (only top part mentioned)
C [COMCTL32.dll+0x345f1] DefSubclassProc+0x46
C [awt.dll+0xaef13] ComCtl32Util::DefWindowProcW+0x30
C [awt.dll+0x7062b] AwtComponent::CallProxyDefWindowProc+0x2d
C [awt.dll+0x722bb] AwtComponent::WindowProc+0x9cd
C [awt.dll+0x922c2] AwtWindow::WindowProc+0xa6
C [awt.dll+0x6f86a] AwtComponent::WndProc+0x48
here's a reduced test to reproduce the problem easily
final Frame f = new Frame("F");
f.setBounds(0,0,200,200);
f.setEnabled(false); // <- disable the top-level
f.setVisible(true);
Window w = new Window(f);
w.setBounds(300,300,300,300);
w.add(new TextField(20));
w.setVisible(true);
the important thing is that the test disable the top-level and as soon as the user clicks on the top-level, AWT crashes.
the crash happens here: AwtComponent::CallProxyDefWindowProc:
retVal = ComCtl32Util::GetInstance().DefWindowProc(NULL, proxy, message, wParam, lParam);
// the message is WM_IME_SETCONTEXT
and the crash is reproducible starting from the changes for 6826397.
after 6826397, the proxy (passed into DefWindowProc) contains the top-level window (not a separate child window).
so, during the test, the user clicks on the disabled top-level (the native focus owner) and i guess that the native system decides to transfer the focus from the *disabled* top-level to another window (an *enabled* window). The focus tries to go to the enabled window but AWT restores it to the disabled top-level. at the same time, there's a short period of time during which the enabled window is the native focus owner and any IME message (coming to the enabled window) will be dispatched to the proxy (the top-level) which isn't currently a native focus owner.
in this particular case, we should probably explicitly dispatch all WM_IME_* messages to DefWindowProc(..., MSG.hwnd, ...).
|
|
|
EVALUATION
The crash seem happens just after the activation which causes the WM_KILLFOCUS to be handled. Also the WM_IME_SETCONTEXT is seen in the Spy++ log. Don't think that the new body of the AwtFrame::ProxyWindowProc is the right reason for that as it only appears in 7b142 (see 7034291: Regression : Preedit String on active client is committed into unexpected component)
|
|
|
EVALUATION
I can reproduce the crash on Vista with a test from 7045054.
|
|
|
EVALUATION
The stack trace of the crashing thread is:
ntdll.dll!_KiFastSystemCallRet@0()
user32.dll!_NtUserMessageCall@28() + 0xc bytes
user32.dll!_SendMessageW@16() + 0x49 bytes
> awt.dll!AwtComponent::_SetFocus(void * param) Line 5802 + 0x15 bytes C++
awt.dll!AwtToolkit::SyncCall(void * (void *)* ftn, void * param) Line 1538 + 0x11 bytes C++
awt.dll!Java_sun_awt_windows_WComponentPeer_setFocus(JNIEnv_ * env, _jobject * self, unsigned char doSetFocus) Line 6610
It sounds like a thread race which results in that the pData value is invalid here in awt_Component.cpp thus we crash on
dereference in the next line:
void AwtComponent::_SetFocus(void *param) {
<skip>
c = (AwtComponent *)pData;
if (::IsWindow(c->GetHWnd())) {
c->SendMessage(WM_AWT_COMPONENT_SETFOCUS, (WPARAM)doSetFocus, 0);
}
But in reality the pData is valid but still we crash on any forthcoming sendMessage(args) native call.
The test structure is as:
Applet has start() and stop() methods:
start() spawns new thread which perform the doTest() routine.
In turn the stop() method makes that thread wait() on monitor which should have released after the doTest() has finished.
So far the start() and stop() run on AppletThread.
On clicking on a component we should transfer the focus and that happens on EventQueue-thread but seem should result on
AppletThread call which is blocked. So far we're crashing on every SendMessage() call after some moment in.
The strange thing is that it continues/repeats the test if even the crashed.
|
|
|
EVALUATION
The test\closed\java\awt\MenuBar\MenuBarStress1\ crashes intermittently (one of 5 attempts) and potentially has same root cause with this CR. Reopening for further investigation.
|
|
|
EVALUATION
It constantly reproducible (this is XP machine jdk7b132) with PopupMenuTest (see attach) but with some unusual interactions:
1) run test
2) press "hide/show menubar" several times
3) resize the main frame dragging by the right edge
|
|
|
EVALUATION
Not reproducible with jdk7b134 perhaps because of the 6826397 fix.
|
|
|