Bug 510183 - [Webkit2] Internal browser hangs in WebKitGTK._swtWebkitEvaluateJavascript()
Summary: [Webkit2] Internal browser hangs in WebKitGTK._swtWebkitEvaluateJavascript()
Status: RESOLVED FIXED
Alias: None
Product: Platform
Classification: Eclipse Project
Component: SWT (show other bugs)
Version: 4.6   Edit
Hardware: PC Linux
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: Leo Ufimtsev CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on: 510694
Blocks: Webkit2Port4.7
  Show dependency tree
 
Reported: 2017-01-10 07:49 EST by Stephan Herrmann CLA
Modified: 2017-05-17 14:46 EDT (History)
5 users (show)

See Also:


Attachments
snippet that hangs on webkit2 (1.86 KB, text/plain)
2017-01-26 10:37 EST, Leo Ufimtsev CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Stephan Herrmann CLA 2017-01-10 07:49:23 EST
Have a java class with the following link in javadoc:

/**
 * <a href="http://help.eclipse.org/kepler/topic/org.eclipse.jdt.doc.isv/reference/api/org/eclipse/jdt/annotation/NonNull.html"><code>@NonNull</code> in 1.1.0</a>.
 */

Use JDT's javadoc hover to show the javadoc, then click the link.

Result: thread "main" hangs, even exiting eclipse will not shutdown.

Manually opening the internal browser and entering the URL into the location bar does not have this problem, the page is correctly shown.

Platform: Kubuntu 16.04.1 LTS

Configuration:
eclipse.buildId=4.7.0.I20170102-2000
org.eclipse.swt.internal.deviceZoom=100
org.eclipse.swt.internal.gtk.theme=Breeze
org.eclipse.swt.internal.gtk.version=3.18.9
org.eclipse.swt.internal.webkitgtk.version=2.12.5
Preferences select "Internal Browser"

Stacktrace:
"main" #1 prio=6 os_prio=0 tid=0xb6507c00 nid=0xf45 runnable [0xb66e5000]
   java.lang.Thread.State: RUNNABLE
        at org.eclipse.swt.internal.webkit.WebKitGTK._swtWebkitEvaluateJavascript(Native Method)
        at org.eclipse.swt.internal.webkit.WebKitGTK.swtWebkitEvaluateJavascript(WebKitGTK.java:1699)
        at org.eclipse.swt.browser.WebKit.evaluate(WebKit.java:951)
        at org.eclipse.swt.browser.WebKit.execute(WebKit.java:911)
        at org.eclipse.swt.browser.WebBrowser.createFunction(WebBrowser.java:375)
        at org.eclipse.swt.browser.BrowserFunction.<init>(BrowserFunction.java:147)
        at org.eclipse.swt.browser.BrowserFunction.<init>(BrowserFunction.java:84)
        at org.eclipse.swt.browser.WebKit$1.<init>(WebKit.java:748)
        at org.eclipse.swt.browser.WebKit.create(WebKit.java:748)
        at org.eclipse.swt.browser.Browser.<init>(Browser.java:99)
        at org.eclipse.ui.internal.browser.WebBrowserUtil.canUseInternalWebBrowser(WebBrowserUtil.java:136)
        at org.eclipse.ui.internal.browser.WebBrowserPreference.getBrowserChoice(WebBrowserPreference.java:132)
        at org.eclipse.ui.internal.browser.DefaultBrowserSupport.createBrowser(DefaultBrowserSupport.java:96)
        at org.eclipse.ui.internal.browser.DefaultBrowserSupport.createBrowser(DefaultBrowserSupport.java:146)
        at org.eclipse.ui.internal.browser.WorkbenchBrowserSupport.createBrowser(WorkbenchBrowserSupport.java:96)
        at org.eclipse.jdt.internal.ui.actions.OpenBrowserUtil$3.run(OpenBrowserUtil.java:74)
        at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:70)
        at org.eclipse.jdt.internal.ui.actions.OpenBrowserUtil.internalOpen(OpenBrowserUtil.java:61)
        at org.eclipse.jdt.internal.ui.actions.OpenBrowserUtil.access$0(OpenBrowserUtil.java:60)
        at org.eclipse.jdt.internal.ui.actions.OpenBrowserUtil$1.run(OpenBrowserUtil.java:39)
        at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233)
        at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144)
        at org.eclipse.swt.widgets.Display.syncExec(Display.java:5410)
        at org.eclipse.jdt.internal.ui.actions.OpenBrowserUtil.open(OpenBrowserUtil.java:36)
        at org.eclipse.jdt.internal.ui.text.java.hover.JavadocHover$1.handleExternalLink(JavadocHover.java:603)
        at org.eclipse.jdt.internal.ui.viewsupport.JavaElementLinks$1.changing(JavaElementLinks.java:302)
        at org.eclipse.swt.browser.WebKit.webkit_decide_policy(WebKit.java:2007)
        at org.eclipse.swt.browser.WebKit.webViewProc(WebKit.java:529)
        at org.eclipse.swt.browser.WebKit.Proc(WebKit.java:401)
        at org.eclipse.swt.internal.gtk.OS._g_main_context_iteration(Native Method)
        at org.eclipse.swt.internal.gtk.OS.g_main_context_iteration(OS.java:2081)
        at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:4076)
Comment 1 Alexander Kurtakov CLA 2017-01-11 06:18:16 EST
Hi Stephan. 
I see you use webkit2 (SWT fallbacks to it if webkit1 is not available to at least have some browser functionality) but it's not fully supported yet (see bug 441568 for details). Installing webkit 1.x (ibwebkitgtk-3.0 or similar) should bring you a good workaround while this is being worked on.
Leo, please investigate this.
Comment 2 Leo Ufimtsev CLA 2017-01-17 16:19:56 EST
I'm working on this functionality.

This could potentially occur if there is an infinite loop on the javascript side itself. I.e, if javascript doesn't return, then SWT will wait/hang. Or maybe there is a bug in my logic somewhere :-).

I would like to debug this hang to find out the cause.

@Stephan, I tried to reproduce:
- Snippet303
- #58: browser.setText("<body> Hello <a href=\"http://help.eclipse.org/kepler/topic/org.eclipse.jdt.doc.isv/reference/api/org/eclipse/jdt/annotation/NonNull.html\"> <code>@NonNull</code> </a></body>");

However, hang did not occur for me. When clicking the link, the help guide loads for me.

@Stephan, to investigate further, can you explain to me how I could reproduce this hang on my machine?
(I can pull in the relevant eclipse/projects from sources, platform.ui etc..).
Comment 3 Stephan Herrmann CLA 2017-01-17 17:58:37 EST
When it occurred, I simply had a dependency to org.eclipse.jdt.annotation_2.1.0.jar, used @NonNull from that bundle in my code. From the reference @NonNull I opened the javadoc hover, saw inside the javadoc the mentioned link (at the bottom), clicked it and - hang.

Sorry I know nothing about Snippet303. Is that showing a browser in a hover? Maybe JDT adds some styling / js which contributes to the hang?


Trying this today, it no longer hands, probably due to

$ sudo apt-get install libwebkitgtk-3.0

:)

Configuration now says:
org.eclipse.swt.internal.webkitgtk.version=2.4.11

Mhhh, I can't seem to make much sense from those version numbers. Installing 3.0 gives 2.4.11 which is webkit1? Oh, yea:
  2.4.11 is actually version 3.0 of webkit (==webkit1 I assume), and
  2.14.2 is version 4.0 of webkit2. Wow!
Comment 4 Leo Ufimtsev CLA 2017-01-17 18:06:39 EST
(In reply to Stephan Herrmann from comment #3)
> When it occurred, I simply had a dependency to
> org.eclipse.jdt.annotation_2.1.0.jar, used @NonNull from that bundle in my
> code. From the reference @NonNull I opened the javadoc hover, saw inside the
> javadoc the mentioned link (at the bottom), clicked it and - hang.
> 
> Sorry I know nothing about Snippet303. Is that showing a browser in a hover?
> Maybe JDT adds some styling / js which contributes to the hang?
> 
> 
> Trying this today, it no longer hands, probably due to
> 
> $ sudo apt-get install libwebkitgtk-3.0
> 
> :)
> 
> Configuration now says:
> org.eclipse.swt.internal.webkitgtk.version=2.4.11
> 
> Mhhh, I can't seem to make much sense from those version numbers. Installing
> 3.0 gives 2.4.11 which is webkit1? Oh, yea:
>   2.4.11 is actually version 3.0 of webkit (==webkit1 I assume), and
>   2.14.2 is version 4.0 of webkit2. Wow!

Yea, version numbering is confusing.
Note: There is Webkit and there is WebkitGTK. Their version numbers are not in sync.
In general, Webkitgtk 2.5 and onwards uses webkit2.

You could force webkit2 via:
export SWT_WEBKIT2=1
eclipse


From the above I can't figure out how to reproduce. Can you explain steps in more granularity?
(I know a little bit about plugin/platform development, but most of the time I chill in the SWT cave).
Comment 5 Alexander Kurtakov CLA 2017-01-18 00:46:55 EST
(In reply to Stephan Herrmann from comment #3)
> When it occurred, I simply had a dependency to
> org.eclipse.jdt.annotation_2.1.0.jar, used @NonNull from that bundle in my
> code. From the reference @NonNull I opened the javadoc hover, saw inside the
> javadoc the mentioned link (at the bottom), clicked it and - hang.
> 
> Sorry I know nothing about Snippet303. Is that showing a browser in a hover?
> Maybe JDT adds some styling / js which contributes to the hang?
> 
> 
> Trying this today, it no longer hands, probably due to
> 
> $ sudo apt-get install libwebkitgtk-3.0
> 
> :)
> 
> Configuration now says:
> org.eclipse.swt.internal.webkitgtk.version=2.4.11
> 
> Mhhh, I can't seem to make much sense from those version numbers. Installing
> 3.0 gives 2.4.11 which is webkit1? Oh, yea:
>   2.4.11 is actually version 3.0 of webkit (==webkit1 I assume), and
>   2.14.2 is version 4.0 of webkit2. Wow!

Stephan, think of webkit version as interface and webkitgtk as implementation (there are qt, win32, cocoa, android... implementations too). So when we speak of webkit1 or webkit2 it's a matter of the version of the interface implemented. When we speak of the webkitgtk version we speak of the actual version of the implementation. The whole confusion came due to support for both GTK2 and GTK3 for some time (that's never a good idea) so we had:
* webkitgtk 1.x - webkit 1 implementation on gtk2
* webkitgtk 2.0-2.4 - webkit1 implementation on gtk3
* webkitgtk 2.5-... - webkit2 implementation on gtk3
At the time when webkitgtk bumped to 2.0 for the gtk3 move I don't think webkit2 was a think and after that webkitgtk maintainers decided to not bump it to webkitgtk 3.x for webkit2 implementaion in order to keep the confusion here and not push it forward in the future with next webkit versions.
Comment 6 Alexander Kurtakov CLA 2017-01-18 00:54:39 EST
Leo, here are the instructions to reproduce:
1. Run eclipse with SWT_WEBKIT2=1
2. Create new java project with 1 class in it.
3. Put the followin as comment for a method:
/**
 * <a href="http://help.eclipse.org/kepler/topic/org.eclipse.jdt.doc.isv/reference/api/org/eclipse/jdt/annotation/NonNull.html"><code>@NonNull</code> in 1.1.0</a>.
 */

4. Hover over the method to see the javadoc hover, click on the "@NonNull in 1.1.0" link in the hover.
5. Experience the deadlock.
Comment 7 Leo Ufimtsev CLA 2017-01-18 17:12:24 EST
(In reply to Alexander Kurtakov from comment #6)
> Leo, here are the instructions to reproduce:
> 1. Run eclipse with SWT_WEBKIT2=1
> 2. Create new java project with 1 class in it.
> 3. Put the followin as comment for a method:
> /**
>  * <a
> href="http://help.eclipse.org/kepler/topic/org.eclipse.jdt.doc.isv/reference/
> api/org/eclipse/jdt/annotation/NonNull.html"><code>@NonNull</code> in
> 1.1.0</a>.
>  */
> 
> 4. Hover over the method to see the javadoc hover, click on the "@NonNull in
> 1.1.0" link in the hover.
> 5. Experience the deadlock.

Ah, I see. Thank you for posting steps to reproduce. I can reproduce on my system. Let me investigate.
Comment 8 Leo Ufimtsev CLA 2017-01-19 12:32:41 EST
I found the cause.

The issue is that webkit1-javascript is being called in Webkit2 in browser.close(), causing an infinite loop. I.e fault in internal Webkit.java code.

This is because browser.function and browser.close hasn't been ported over to webkit2 yet. (I linked dependents).

In:
Bug 510694 - [Webkit2] Implement 'close' for webkit2
I submitted a patch that turns off function/close for webkit2 (as they're not implemented yet anyway). It prevents the hang from occuring. Once merged, the next nightly should not hang in javadoc. I will post a comment here once it's available for download.

I'll keep this bug open until function and close are implemented, and I'll verify that the hanging no longer occurs once these are implemented.
Comment 9 Leo Ufimtsev CLA 2017-01-26 10:37:15 EST
After further investigation I found that the cause is an issue with my implementation of browser.execute(..).

If you add a locationChange listener, and if you dispose the browser while navigating to a new link, then a hang occurs.

The reason is that execute(..) waits for the javascript to complete, but if you dispose a browser instance in the middle of a javascript execution, then execute(..) will loop for ever. (snippet to reproduce attached). 

I'll look for a way to add a check to see if browser is still a valid instance during in the exec() loop. <in progress>
Comment 10 Leo Ufimtsev CLA 2017-01-26 10:37:55 EST
Created attachment 266470 [details]
snippet that hangs on webkit2
Comment 11 Eclipse Genie CLA 2017-01-30 11:04:22 EST
New Gerrit change created: https://git.eclipse.org/r/89875
Comment 12 Leo Ufimtsev CLA 2017-01-30 11:14:04 EST
(In reply to Eclipse Genie from comment #11)
> New Gerrit change created: https://git.eclipse.org/r/89875

After further research, I found the issue to be more abstract:

If a webkit2 signal LocationListener.changing or from OpenWindoListener calls browser.execute() or browser.evaluate(), then there is a deadlock. Evaluate is waiting for signal to be handled and signal is waiting for evaluate.

The above hang occurred because javadoc, when clicking on the link runs browser.close(), which in turn runs browser.execute().

I found a fix. The solution is to postpone SWT listener's via display.asyncExec(), so that the webkit2 signal is finished before execute/evaluate is called.

~awaiting path reviews.
Comment 13 Leo Ufimtsev CLA 2017-02-15 15:30:43 EST
This bug is resolved via:
Bug 512001 - [Webkit2] Move evaluate() logic to java
(big 500+ lines patch)

Tomorrow's build should have the latest webkit2. Please report if you find any deadlocks.
Comment 14 Leo Ufimtsev CLA 2017-02-15 15:31:05 EST
Thank you for bug submission btw.