WebView: Change how scheme handlers are registered
evolution is registering the evo-file
scheme in two different places under the same WebKitWebContext - in src/modules/webkit-editor/e-webkit-editor.c
and src/e-util/e-web-view.c
. However an assert enabled webkit-gtk build will hit assertion on a scheme being added multiple times (to the same context) and aborts the application. Asserts are disabled in release builds (CMAKE_BUILD_TYPE=Release or RelWithDebugInfo), but not in Debug builds or in Gentoo what we do as similar to meson -Dbuildtype=plain with cmake too. However that's not important - things should work without triggering asserts.
In details this happens like this:
On startup it is registered via the e-web-view.c one:
Thread 1 "evolution" hit Breakpoint 1, webkit_web_context_register_uri_scheme (context=context@entry=0x555555ccf8a0 [WebKitWebContext], scheme=scheme@entry=0x7ffff165015c "evo-file",
callback=callback@entry=0x7ffff15fc2f0 <web_view_process_uri_request_cb>, userData=0x555555fdde50, destroyNotify=0x7ffff71ca5d0 <g_object_unref>)
at /usr/src/debug/net-libs/webkit-gtk-2.30.4/webkitgtk-2.30.4/Source/WebKit/UIProcess/API/glib/WebKitWebContext.cpp:1279
1279 {
(gdb) bt
#0 webkit_web_context_register_uri_scheme(WebKitWebContext*, char const*, WebKitURISchemeRequestCallback, gpointer, GDestroyNotify)
(context=context@entry=0x555555ccf8a0 [WebKitWebContext], scheme=scheme@entry=0x7ffff165015c "evo-file", callback=callback@entry=0x7ffff15fc2f0 <web_view_process_uri_request_cb>, userData=0x555555fdde50, destroyNotify=0x7ffff71ca5d0 <g_object_unref>) at /usr/src/debug/net-libs/webkit-gtk-2.30.4/webkitgtk-2.30.4/Source/WebKit/UIProcess/API/glib/WebKitWebContext.cpp:1279
#1 0x00007ffff15fc638 in e_web_view_register_content_request_for_scheme
(web_view=0x555555fbcdf0 [EMailDisplay], scheme=scheme@entry=0x7ffff165015c "evo-file", content_request=content_request@entry=0x555555fdde50)
at /usr/src/debug/mail-client/evolution-3.38.2/evolution-3.38.2/src/e-util/e-web-view.c:1274
#2 0x00007ffff15ffe78 in web_view_initialize (web_view=0x555555fbcdf0 [EMailDisplay]) at /usr/src/debug/mail-client/evolution-3.38.2/evolution-3.38.2/src/e-util/e-web-view.c:1291
#3 web_view_constructed (object=0x555555fbcdf0 [EMailDisplay]) at /usr/src/debug/mail-client/evolution-3.38.2/evolution-3.38.2/src/e-util/e-web-view.c:1543
#4 0x00007fff9c73442a in mail_display_constructed (object=0x555555fbcdf0 [EMailDisplay]) at /usr/src/debug/mail-client/evolution-3.38.2/evolution-3.38.2/src/mail/e-mail-display.c:1620
#5 0x00007ffff71caf55 in g_object_new_with_custom_constructor (n_params=2, params=0x7fffffffc000, class=0x555555fcaba0) at ../glib-2.66.4/gobject/gobject.c:1911
#6 g_object_new_internal (class=class@entry=0x555555fcaba0, params=params@entry=0x7fffffffc000, n_params=n_params@entry=2) at ../glib-2.66.4/gobject/gobject.c:1937
#7 0x00007ffff71cc9ee in g_object_new_valist (object_type=<optimized out>, first_property_name=first_property_name@entry=0x7fff9c7bceb1 "headers-collapsable", var_args=var_args@entry=0x7fffffffc150)
at ../glib-2.66.4/gobject/gobject.c:2264
(gdb) print context
$1 = 0x555555ccf8a0 [WebKitWebContext]
(gdb) frame 2
#2 0x00007ffff15ffe78 in web_view_initialize (web_view=0x555555fbcdf0 [EMailDisplay]) at /usr/src/debug/mail-client/evolution-3.38.2/evolution-3.38.2/src/e-util/e-web-view.c:1291
1291 e_web_view_register_content_request_for_scheme (E_WEB_VIEW (web_view), "evo-file", content_request);
(gdb) print web_view
$2 = 0x555555fbcdf0 [EMailDisplay]
The app works fine, until the component is changed (e.g. from mail to contacts):
Thread 1 "evolution" hit Breakpoint 1, webkit_web_context_register_uri_scheme (context=context@entry=0x555555ccf8a0 [WebKitWebContext], scheme=scheme@entry=0x7ffff165015c "evo-file",
callback=callback@entry=0x7ffff15fc2f0 <web_view_process_uri_request_cb>, userData=0x5555566ae640, destroyNotify=0x7ffff71ca5d0 <g_object_unref>)
at /usr/src/debug/net-libs/webkit-gtk-2.30.4/webkitgtk-2.30.4/Source/WebKit/UIProcess/API/glib/WebKitWebContext.cpp:1279
1279 {
(gdb) bt
#0 webkit_web_context_register_uri_scheme(WebKitWebContext*, char const*, WebKitURISchemeRequestCallback, gpointer, GDestroyNotify)
(context=context@entry=0x555555ccf8a0 [WebKitWebContext], scheme=scheme@entry=0x7ffff165015c "evo-file", callback=callback@entry=0x7ffff15fc2f0 <web_view_process_uri_request_cb>, userData=0x5555566ae640, destroyNotify=0x7ffff71ca5d0 <g_object_unref>) at /usr/src/debug/net-libs/webkit-gtk-2.30.4/webkitgtk-2.30.4/Source/WebKit/UIProcess/API/glib/WebKitWebContext.cpp:1279
#1 0x00007ffff15fc638 in e_web_view_register_content_request_for_scheme
(web_view=0x5555565d13a0 [EABContactDisplay], scheme=scheme@entry=0x7ffff165015c "evo-file", content_request=content_request@entry=0x5555566ae640)
at /usr/src/debug/mail-client/evolution-3.38.2/evolution-3.38.2/src/e-util/e-web-view.c:1274
#2 0x00007ffff15ffe78 in web_view_initialize (web_view=0x5555565d13a0 [EABContactDisplay]) at /usr/src/debug/mail-client/evolution-3.38.2/evolution-3.38.2/src/e-util/e-web-view.c:1291
#3 web_view_constructed (object=0x5555565d13a0 [EABContactDisplay]) at /usr/src/debug/mail-client/evolution-3.38.2/evolution-3.38.2/src/e-util/e-web-view.c:1543
#4 0x00007ffff71caf55 in g_object_new_with_custom_constructor (n_params=0, params=0x0, class=0x5555565f6000) at ../glib-2.66.4/gobject/gobject.c:1911
#5 g_object_new_internal (class=class@entry=0x5555565f6000, params=params@entry=0x0, n_params=n_params@entry=0) at ../glib-2.66.4/gobject/gobject.c:1937
#6 0x00007ffff71cc28d in g_object_new_with_properties
(gdb) print context
$3 = 0x555555ccf8a0 [WebKitWebContext]
(gdb) frame 2
#2 0x00007ffff15ffe78 in web_view_initialize (web_view=0x5555565d13a0 [EABContactDisplay]) at /usr/src/debug/mail-client/evolution-3.38.2/evolution-3.38.2/src/e-util/e-web-view.c:1291
1291 e_web_view_register_content_request_for_scheme (E_WEB_VIEW (web_view), "evo-file", content_request);
(gdb) frame 1
#1 0x00007ffff15fc638 in e_web_view_register_content_request_for_scheme (web_view=0x5555565d13a0 [EABContactDisplay], scheme=scheme@entry=0x7ffff165015c "evo-file",
content_request=content_request@entry=0x5555566ae640) at /usr/src/debug/mail-client/evolution-3.38.2/evolution-3.38.2/src/e-util/e-web-view.c:1274
1274 webkit_web_context_register_uri_scheme (web_context, scheme, web_view_process_uri_request_cb,
(gdb) print web_view
$4 = 0x5555565d13a0 [EABContactDisplay]
My downstream users are also triggering this on opening the settings.
The assertion message is as follows:
ASSERTION FAILED: schemeResult.isNewEntry
/tmp/portage/net-libs/webkit-gtk-2.30.4/work/webkitgtk-2.30.4/Source/WebKit/UIProcess/WebPageProxy.cpp(9431) : void WebKit::WebPageProxy::setURLSchemeHandlerForScheme(WTF::Ref<WebKit::WebURLSchemeHandler>&&, const WTF::String&)
Aborted (core dumped)
This is in a webkit-gtk code in Source/WebKit/UIProcess/WebPageProxy.cpp
that does this:
auto schemeResult = m_urlSchemeHandlersByScheme.add(canonicalizedScheme.value(), handler.get());
ASSERT_UNUSED(schemeResult, schemeResult.isNewEntry);
So if the scheme was already registered (I think surrounding code and caller limits this to per-context), it'll assert, and non-NDEBUG builds will call the CRASH macro and abort. This feels like it makes some sense, because how can it be sure which handler for the scheme is supposed to be called, when multiple get registered.
Downstream I will at least temporarily change back our webkit-gtk builds to build with -DNDEBUG, but hopefully this can be solved in evolution to be free of asserts.