Bug 175855 - [GTK] Segfault on WebView run_javascript() function from Python thread
Summary: [GTK] Segfault on WebView run_javascript() function from Python thread
Alias: None
Product: WebKit
Classification: Unclassified
Component: WebKitGTK (show other bugs)
Version: Other
Hardware: PC Linux
: P2 Normal
Assignee: Nobody
Depends on:
Reported: 2017-08-22 15:27 PDT by luke
Modified: 2017-08-28 08:14 PDT (History)
4 users (show)

See Also:

Test case to reproduce the issue (975 bytes, text/x-python)
2017-08-22 15:27 PDT, luke
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
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")
    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 :)