| Summary: | Eclipse crashes in ieframe.dll when repeatedly opening the same link in an external browser | ||||||
|---|---|---|---|---|---|---|---|
| Product: | [Eclipse Project] Platform | Reporter: | Helmut J. Haigermoser <helmut.haigermoser> | ||||
| Component: | User Assistance | Assignee: | platform-ua-inbox <platform-ua-inbox> | ||||
| Status: | RESOLVED FIXED | QA Contact: | |||||
| Severity: | normal | ||||||
| Priority: | P3 | CC: | ChrisAustin, grant_gayed, remy.suen | ||||
| Version: | 3.7 | ||||||
| Target Milestone: | 3.8 M4 | ||||||
| Hardware: | PC | ||||||
| OS: | Windows 7 | ||||||
| Whiteboard: | |||||||
| Attachments: |
|
||||||
|
Description
Helmut J. Haigermoser
CQ:WIND00310454 *setting Eclipse Version of 3.7* Created attachment 205304 [details]
Oracle crash report file showing the problematic frame as ieframe.dll
snippet:
public static void main(String[] args) {
final Display display = new Display();
Shell shell = new Shell(display);
shell.setLayout(new GridLayout());
final Browser external = new Browser(shell, SWT.NONE);
external.setLayoutData(new GridData(0,0));
Browser browser = new Browser(shell, SWT.NONE);
browser.setLayoutData(new GridData(200,200));
browser.setText("<html><body><a href=\"http://ximbiot.com/cvs/\" target=\"_blank\">click</a></body></html>");
browser.addOpenWindowListener(new OpenWindowListener() {
public void open(WindowEvent event) {
event.browser = external;
}
});
external.addLocationListener(new LocationAdapter() {
public void changing(LocationEvent event) {
event.doit = false;
}
});
shell.pack();
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) display.sleep();
}
display.dispose();
}
(In reply to comment #3) > snippet: Thanks Grant for providing the snippet! :) All, can we get this one addressed in 3.8, do you need any more input? Thanks in advance, Helmut Haigermoser The problem is that o.e.help.ui.internal.browser.embedded.EmbeddedBrowser.displayURLExternal() is creating a singleton Browser and reusing it for all OpenWindowListener.open() events. However it is expected that the Browser instance that is returned via this event is unique (new). Native IE depends on this to be the case (see http://msdn.microsoft.com/en-us/library/aa768337%28v=vs.85%29.aspx ), and if it is not then it can cause the native browser's refcount to be decremented by a net amount of 1. This is why the crash happens after ~16 repetitions; it is able to get way with a few premature releases without its refcount ever hitting 0, but eventually it does reach 0 and native resources are released that were still needed. The fix is for the EmbeddedBrowser to not re-use the singleton "externalBrowser". I've confirmed that this change fixes the crash, and th extra Browser creations do not affect the memory footprint, because embedded IE's do not consume any real memory until they are displaying content. The changes to be made appear below in the // commented lines. Moving report to UA. private void displayURLExternal(WindowEvent e) { // if (externalBrowser == null) { final Shell externalShell = new Shell(shell, SWT.NONE); externalBrowser = new Browser(externalShell, SWT.NONE); externalBrowser.addLocationListener(new LocationAdapter() { public void changing(final LocationEvent e) { e.doit = false; try { BaseHelpSystem.getHelpBrowser(true).displayURL(e.location); } catch (Throwable t) { String msg = "Error opening external Web browser"; //$NON-NLS-1$ HelpUIPlugin.logError(msg, t); } } }); // } // also, remove the "EmbeddedBrowser.externalBrowser" field e.browser = externalBrowser; } (In reply to comment #5) > The problem is that > o.e.help.ui.internal.browser.embedded.EmbeddedBrowser.displayURLExternal() Thanks Grant for tracking this one down! :) The fix looks isolated and save to me, UA, can this be picked up for 3.8? TIA, Ciao, hh One additional comment on comment 7, the fix is improved by adding the following within the "changing()" block, to dispose the created Shell and Browser once they are no longer needed. externalShell.getDisplay().asyncExec(new Runnable() { public void run() { externalShell.dispose(); } }); Fix looks good. Committed to master, integration. http://git.eclipse.org/c/platform/eclipse.platform.ua.git/commit/?id=6e608e3f86e13b043ba22affc3a41b369ffb5cab Chris I notice in the patch that the additional lines in comment 7 are not added. These lines should be safe to add, and will clean up the extra Shell and Browser instances that are now being created. (In reply to comment #9) > Chris I notice in the patch that the additional lines in comment 7 are not > added. These lines should be safe to add, and will clean up the extra Shell > and Browser instances that are now being created. Sorry - forgot about that. So something like this? public void changing(final LocationEvent e) { e.doit = false; try { BaseHelpSystem.getHelpBrowser(true).displayURL(e.location); } catch (Throwable t) { String msg = "Error opening external Web browser"; //$NON-NLS-1$ HelpUIPlugin.logError(msg, t); } externalShell.getDisplay().asyncExec(new Runnable() { public void run() { externalShell.dispose(); } }); } > Sorry - forgot about that. So something like this?
yes
Additional lines committed to master, integration. http://git.eclipse.org/c/platform/eclipse.platform.ua.git/commit/?id=b39926c0ab2dd7974b66869b9cd310679d4fc926 (In reply to comment #12) > Additional lines committed to master, integration. > > http://git.eclipse.org/c/platform/eclipse.platform.ua.git/commit/?id=b39926c0ab2dd7974b66869b9cd310679d4fc926 Thanks Chris, good work! :) |