Skip to content

Message view shows empty tab — WebKit extension crashes due to null GTK display context #773

Description

@jfmoulin

Message view shows empty tab — WebKit extension crashes due to null GTK display context

Environment

  • OS: Ubuntu 24.04
  • Astroid: built from source, master branch, commit 89e88fc
  • webkit2gtk: 4.1
  • gtkmm: 3.24.9

Symptom

Clicking a message in the thread index opens an empty tab. No content is ever rendered. The external editor works fine; search works fine.

Diagnosis

Running astroid 2>&1 | tee /tmp/astroid.log and clicking a message showed the log ending abruptly after the database read — no pc: got extension connect line ever appeared, meaning the WebKit web extension was silently failing to load.

journalctl revealed a segfault in WebKitWebProcess every time a message was opened:

kernel: WebKitWebProces[PID]: segfault at 0 ip ... in libgtkmm-3.0.so.1

coredumpctl gdb <PID> + bt full identified three crash sites in tvextension.cc:

Crash 1 — AstroidExtension constructor (~line 134)

#0  Gtk::IconTheme::load_icon(...) from libgtkmm-3.0.so.1
#1  AstroidExtension::AstroidExtension() at tvextension.cc:134
    theme = {pCppObject_ = 0x0}   ← null!

Gtk::IconTheme::get_default() returns null in the WebKit subprocess because there is no GDK display context. Calling load_icon() on the null pointer crashes the process immediately.

Crash 2 — set_attachment_icon() (line ~1421)

After fixing crash 1, attachment_icon is null (was never loaded). attachment_icon->save_to_buffer() then crashes in libgdkmm-3.0.so.1.

Crash 3 — load_marked_icon() (line ~1458)

Same pattern: marked_icon->save_to_buffer() on a null pointer.

Root cause

The WebKit web extension runs in a sandboxed child process (WebKitWebProcess) without a proper GTK/GDK display connection. Any GTK call that implicitly requires a display — including Gtk::IconTheme::get_default() and Gdk::Pixbuf::save_to_buffer() — either returns null or crashes outright.

Workaround applied locally

Guard all three call sites with null checks:

Constructor (tvextension.cc ~line 132):

Glib::RefPtr<Gtk::IconTheme> theme = Gtk::IconTheme::get_default();
if (theme) {
  attachment_icon = theme->load_icon(
      "mail-attachment-symbolic",
      ATTACHMENT_ICON_WIDTH,
      Gtk::ICON_LOOKUP_USE_BUILTIN);
  marked_icon = theme->load_icon(
      "object-select-symbolic",
      ATTACHMENT_ICON_WIDTH,
      Gtk::ICON_LOOKUP_USE_BUILTIN);
}

set_attachment_icon():

if (attachment_icon) {
  attachment_icon->save_to_buffer(content, content_size, "png");
  // ... rest of icon setting code ...
}

load_marked_icon():

if (marked_icon) {
  marked_icon->save_to_buffer(content, content_size, "png");
  // ... rest of icon setting code ...
}

With this workaround the extension no longer crashes, messages render correctly, and the pc: got extension connect handshake completes successfully. The attachment and marked icons are not displayed (they remain blank), but this is a cosmetic limitation of the workaround.

Suggested proper fix

Load the icons in the main Astroid process (where a display context exists) and transmit them to the extension as PNG data over the existing IPC channel, the same way message content is already sent. This would restore icon display without requiring a GTK display in the WebKit subprocess.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions