Bug 175855

Summary: [GTK] Segfault on WebView run_javascript() function from Python thread
Product: WebKit Reporter: luke
Component: WebKitGTKAssignee: Nobody <webkit-unassigned>
Status: RESOLVED INVALID    
Severity: Normal CC: bugs-noreply, davidmohammed, jbicha, mcatanzaro
Priority: P2    
Version: Other   
Hardware: PC   
OS: Linux   
Attachments:
Description Flags
Test case to reproduce the issue none

Description luke 2017-08-22 15:27:45 PDT
Created attachment 318810 [details]
Test case to reproduce the issue

Hi there. In a recent library update, a Python WebKitGTK application now runs into a segfault when invoking the run_javascript() function from a Python thread (via the threading module). This is a regression as this didn't occur in previous versions and crashes web applications for the desktop, such as ubuntu-mate-welcome.

Confirmed a problem
==========================
WebKit2GTK Version: 2.17.91-1ubuntu1
Python version: 3.6.2
Ubuntu version: 17.10 Alpha 2

Last known good version
==========================
WebKit2GTK Version: 2.16.6-0ubuntu0.16.04.1
Python version: 3.5.2
Ubuntu version: 16.04.3 LTS

A test case has been attached to reproduce this issue. It creates a simple GTK window with WebView, and invokes run_javascript() to run "window.alert" but will be invoked from a new thread. In Ubuntu 16.04, this executes the JavaScript "window.alert()" successfully, but in Ubuntu 17.10, this will produce a segfault and crash the application.

The segfault as follows:

------------------------------------------------------
1   0x7fed43b7f287 /usr/lib/x86_64-linux-gnu/libjavascriptcoregtk-4.0.so.18(WTFCrash+0x17) [0x7fed43b7f287]
2   0x7fed4cb90cca /usr/lib/x86_64-linux-gnu/libwebkit2gtk-4.0.so.37(+0x63dcca) [0x7fed4cb90cca]
3   0x7fed4cb8582c /usr/lib/x86_64-linux-gnu/libwebkit2gtk-4.0.so.37(+0x63282c) [0x7fed4cb8582c]
4   0x7fed4cd5d463 /usr/lib/x86_64-linux-gnu/libwebkit2gtk-4.0.so.37(webkit_web_view_run_javascript+0xc3) [0x7fed4cd5d463]
5   0x7fed607e0e18 /usr/lib/x86_64-linux-gnu/libffi.so.6(ffi_call_unix64+0x4c) [0x7fed607e0e18]
6   0x7fed607e087a /usr/lib/x86_64-linux-gnu/libffi.so.6(ffi_call+0x32a) [0x7fed607e087a]
7   0x7fed611ce9cc /usr/lib/python3/dist-packages/gi/_gi.cpython-36m-x86_64-linux-gnu.so(+0x2b9cc) [0x7fed611ce9cc]
8   0x7fed611d04b8 /usr/lib/python3/dist-packages/gi/_gi.cpython-36m-x86_64-linux-gnu.so(+0x2d4b8) [0x7fed611d04b8]
9   0x7fed611c4209 /usr/lib/python3/dist-packages/gi/_gi.cpython-36m-x86_64-linux-gnu.so(+0x21209) [0x7fed611c4209]
10  0x4591b3 /usr/bin/python3(_PyObject_FastCallDict+0xa3) [0x4591b3]
11  0x54e607 /usr/bin/python3() [0x54e607]
12  0x552f9b /usr/bin/python3(_PyEval_EvalFrameDefault+0x36ab) [0x552f9b]
13  0x54e4b1 /usr/bin/python3() [0x54e4b1]
14  0x54f45f /usr/bin/python3(PyEval_EvalCodeEx+0x2f) [0x54f45f]
15  0x48b41d /usr/bin/python3() [0x48b41d]
16  0x458fbe /usr/bin/python3(PyObject_Call+0x3e) [0x458fbe]
17  0x551497 /usr/bin/python3(_PyEval_EvalFrameDefault+0x1ba7) [0x551497]
18  0x54da88 /usr/bin/python3() [0x54da88]
19  0x54e9e6 /usr/bin/python3() [0x54e9e6]
20  0x552f9b /usr/bin/python3(_PyEval_EvalFrameDefault+0x36ab) [0x552f9b]
21  0x54da88 /usr/bin/python3() [0x54da88]
22  0x54e9e6 /usr/bin/python3() [0x54e9e6]
23  0x552f9b /usr/bin/python3(_PyEval_EvalFrameDefault+0x36ab) [0x552f9b]
24  0x54da88 /usr/bin/python3() [0x54da88]
25  0x55772e /usr/bin/python3(_PyFunction_FastCallDict+0x2be) [0x55772e]
26  0x459531 /usr/bin/python3(_PyObject_Call_Prepend+0x231) [0x459531]
27  0x458fbe /usr/bin/python3(PyObject_Call+0x3e) [0x458fbe]
28  0x58db52 /usr/bin/python3() [0x58db52]
29  0x7fed62d7a74a /lib/x86_64-linux-gnu/libpthread.so.0(+0x774a) [0x7fed62d7a74a]
30  0x7fed61f43caf /lib/x86_64-linux-gnu/libc.so.6(clone+0x3f) [0x7fed61f43caf]
Segmentation fault
------------------------------------------------------
Comment 1 davidmohammed 2017-08-23 10:27:33 PDT
phew - thanks for filing this Luke.  I thought I was going mad!  Can confirm this with budgie-welcome - Ubuntu Budgie 17.10
Comment 2 Michael Catanzaro 2017-08-28 07:34:41 PDT
In the future please use the WebKitGTK+ component or we won't notice your bugs. Someone pinged me about this one on IRC!
Comment 3 Michael Catanzaro 2017-08-28 07:49:17 PDT
I can reproduce. It works fine with Fedora's 2.16.6 but fails with trunk built in JHBuild. It's interesting that the behavior changed from one WebKit version to the next, but your code is illegal and it's just luck that it ever worked. You can't use GTK+ except on the thread you initialized it on (usually the main thread), because it's not threadsafe. Same goes for WebKit and most GNOME-related libraries. It might work on your computer, but users could be getting crashes or weird problems. The fix is to post actions you want to take to the main thread, e.g. using GLib.idle_add. For example:

def run_js(i):
    webkit.run_javascript("window.alert('It works!')")
    print("Successfully ran Javascript!")
    return GLib.SOURCE_REMOVE

# Now create a thread
def threaded_function():
    print("Sleeping on thread for 2 seconds")
    sleep(2)
    print("Going to run Javascript...")
    GLib.idle_add(run_js, None)

That works without crashing for me. Hope that helps.
Comment 4 Michael Catanzaro 2017-08-28 07:51:19 PDT
(In reply to Michael Catanzaro from comment #3)
> def run_js(i):

Should be def run_js():. I was messing around. ;)
Comment 6 luke 2017-08-28 08:14:15 PDT
Makes sense, thanks for the info Michael :)