diff options
Diffstat (limited to 'tests/org.eclipse.swt.tests.win32/ManualTests/org/eclipse/swt/tests/win32/snippets/Bug543747_JvmCrash_Msctf.java')
-rw-r--r-- | tests/org.eclipse.swt.tests.win32/ManualTests/org/eclipse/swt/tests/win32/snippets/Bug543747_JvmCrash_Msctf.java | 202 |
1 files changed, 202 insertions, 0 deletions
diff --git a/tests/org.eclipse.swt.tests.win32/ManualTests/org/eclipse/swt/tests/win32/snippets/Bug543747_JvmCrash_Msctf.java b/tests/org.eclipse.swt.tests.win32/ManualTests/org/eclipse/swt/tests/win32/snippets/Bug543747_JvmCrash_Msctf.java new file mode 100644 index 0000000000..b157caa3ad --- /dev/null +++ b/tests/org.eclipse.swt.tests.win32/ManualTests/org/eclipse/swt/tests/win32/snippets/Bug543747_JvmCrash_Msctf.java @@ -0,0 +1,202 @@ +/******************************************************************************* + * Copyright (c) 2019 Syntevo and others. All rights reserved. + * The contents of this file are made available under the terms + * of the GNU Lesser General Public License (LGPL) Version 2.1 that + * accompanies this distribution (lgpl-v21.txt). The LGPL is also + * available at http://www.gnu.org/licenses/lgpl.html. If the version + * of the LGPL at http://www.gnu.org is different to the version of + * the LGPL accompanying this distribution and there is any conflict + * between the two license versions, the terms of the LGPL accompanying + * this distribution shall govern. + * + * Contributors: + * Syntevo - initial API and implementation + *******************************************************************************/ +package org.eclipse.swt.tests.win32.snippets; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.*; +import org.eclipse.swt.widgets.*; + +public class Bug543747_JvmCrash_Msctf { + /** + * This test demonstrates a crash where destroying a Shell + * accesses context already freed by 'ImmDestroyContext'. + */ + public static void reproduceCrash1(Shell parentShell) { + Shell tempShell = new Shell(parentShell); + + // Create something to catch initial focus, so that + // text.setFocus() does something. This is only to + // show that .setFocus() is important. + new Button(tempShell, SWT.PUSH); + + // This Text will cause crash. + Text text = new Text(tempShell, 0); + + // Shell must be visible to prevent early return in .setFocus() + tempShell.setSize(10, 10); + tempShell.open(); + + // ImmAssociateContext() itself is lazy. + // .setFocus() causes it to start up. + text.setFocus(); + + // Destroying the shell triggers the bug. + tempShell.dispose(); + + // JVM still alive? + MessageBox msgbox = new MessageBox(parentShell); + msgbox.setMessage("Crash didn't reproduce"); + msgbox.open(); + } + + /** + * This test demonstrates a crash where destroying a Shell + * accesses context already freed by 'ImmDestroyContext' + * if IME-capable Control has an intermediate parent. + */ + public static void reproduceCrash23(Shell parentShell, boolean focusEditOnClose) { + Shell tempShell = new Shell(parentShell); + + // Create something to catch initial focus, so that + // text.setFocus() does something. This is only to + // show that .setFocus() is important. + Button button = new Button(tempShell, SWT.PUSH); + + // This Text will cause crash. + // Text needs to have an intermediate parent for this bug. + Composite composite = new Composite(tempShell, 0); + Text text = new Text(composite, 0); + + // Shell must be visible to prevent early return in .setFocus() + tempShell.setSize(10, 10); + tempShell.open(); + + // ImmAssociateContext() itself is lazy. + // .setFocus() causes it to start up. + text.setFocus(); + + // There are two slightly different crashes depending on focus + if (!focusEditOnClose) + button.setFocus(); + + // Destroying the shell triggers the bug. + tempShell.dispose(); + + // Give additional instructions + MessageBox msgbox = new MessageBox(parentShell); + msgbox.setMessage( + "Now please do one of:\n" + + "a) Open Task Manager, go to Users, right-click your user, select Disconnect, log in again\n" + + "b) Connect Remote Desktop to this machine\n" + + "\n" + + "The snippet is expected to crash just after that." + ); + msgbox.open(); + } + + /** + * This test demonstrates a crash where destroying a Composite + * with Text inside it crashes, even if 'ImmDestroyContext' wasn't + * called yet. + */ + public static void reproduceCrash4(Shell parentShell) { + Shell tempShell = new Shell(parentShell); + + // Create something to catch initial focus, so that + // text.setFocus() does something. This is only to + // show that .setFocus() is important. + // new Button(tempShell, SWT.PUSH); + + // This Text will cause crash. + // Text needs to have an intermediate parent for this bug. + Composite composite = new Composite(tempShell, 0); + Text text = new Text(composite, 0); + + // Shell must be visible to prevent early return in .setFocus() + tempShell.setSize(10, 10); + tempShell.open(); + + // ImmAssociateContext() itself is lazy. + // .setFocus() causes it to start up. + text.setFocus(); + + // Destroying the composite triggers the bug. + composite.dispose(); + + // Cleanup + tempShell.dispose(); + + // JVM still alive? + MessageBox msgbox = new MessageBox(parentShell); + msgbox.setMessage("Crash didn't reproduce"); + msgbox.open(); + } + + public static void main (String [] args) { + Display display = new Display (); + + Shell shell = new Shell (display); + RowLayout layout = new RowLayout(SWT.VERTICAL); + layout.marginHeight = 10; + layout.marginWidth = 10; + layout.spacing = 10; + shell.setLayout(layout); + + final Text labelInfo = new Text(shell, SWT.READ_ONLY | SWT.MULTI); + labelInfo.setText( + "Both of these crashes are only seen on Win10 1809+\n" + + "\n" + + "To reproduce reliably, use Application Verifier:\n" + + "1) Install Application Verifier:\n" + + "a) Download Windows SDK:\n" + + " https://go.microsoft.com/fwlink/p/?LinkID=2033908\n" + + "b) Install it, selecting Application Verifier. Other components are not required.\n" + + "\n" + + "2) Configure Application Verifier\n" + + "a) Run 'Application Verifier (X64)' from Start menu.\n" + + "b) Use File | Add application... to add java.exe\n" + + "c) IMPORTANT: On the right pane, make sure that only 'Basics/Heaps' is selected.\n" + + " JVM always crashes with 'Basics/Exceptions' and 'Basics/Memory'\n" + + "d) Click 'Save'. You can close Application Verifier now\n" + + " It will be active until you explicitly disable it.\n" + + "e) Restart application once.\n" + + "f) Note: applications run slower and consume more RAM under Application Verifier.\n" + + "\n" + + "3) Reproduce the problem\n" + + "\n" + + "4) Disable Application Verifier if you want\n" + + "a) Keep it enabled it if you're ready to tolerate the slowness, but find more bugs\n" + + "b) Go to Application Verifier again\n" + + "c) Delete java.exe from the list.\n" + + "d) Click Save.\n" + + "e) There's no need to uninstall Application Verifier, but you can do that if you like." + ); + + final Button buttonCrash1 = new Button(shell, SWT.PUSH); + buttonCrash1.setText("Reproduce crash #1 - Bug 526758"); + buttonCrash1.addListener(SWT.Selection, event -> {reproduceCrash1(shell);}); + + final Button buttonCrash2 = new Button(shell, SWT.PUSH); + buttonCrash2.setText("Reproduce crash #2 - Bug 543747 (A)"); + buttonCrash2.addListener(SWT.Selection, event -> {reproduceCrash23(shell, true);}); + + final Button buttonCrash3 = new Button(shell, SWT.PUSH); + buttonCrash3.setText("Reproduce crash #3 - Bug 543747 (B)"); + buttonCrash3.addListener(SWT.Selection, event -> {reproduceCrash23(shell, false);}); + + final Button buttonCrash4 = new Button(shell, SWT.PUSH); + buttonCrash4.setText("Reproduce crash #4 - Bug 543747 (C)"); + buttonCrash4.addListener(SWT.Selection, event -> {reproduceCrash4(shell);}); + + shell.pack(); + shell.open(); + + while (!shell.isDisposed()) { + if (!display.readAndDispatch ()) display.sleep (); + } + + display.dispose (); + } +} |