Segfault when destroying and recreating wx.html2.webview

Hello,

I made a test program to reproduce as simply as I could a bug I’m seeing in my app with webviews.

Here it is:

import wx
import wx.html2

import faulthandler
faulthandler.enable()


class SubFrame(wx.Frame):
   def __init__(self, parent, ID, x=0):
       wx.Frame.__init__(self, parent, ID, "Sub %i" % x, size=(820, 800))

       self.parent = parent
       self.x = x
       self.webview = wx.html2.WebView.New(self)

       self.Bind(wx.EVT_CLOSE, self.on_close)
       self.Show(True)

   def on_close(self, evt):
       SubFrame(self.parent, wx.ID_ANY, x=self.x+1)
       self.Destroy()


class MainFrame(wx.Frame):
   def __init__(self, parent, ID, title):
       wx.Frame.__init__(self, parent, ID, title, size=(820, 800))
       new_frame = SubFrame(self, wx.ID_ANY)


app = wx.App(False)
frame = MainFrame(None, wx.ID_ANY, "Test")
frame.Show(True)
app.MainLoop()

The idea is to create and destroy webviews a few times.
I create a new frame in the on_close handler only for the purposes of this test, as it seems that I need to wait a little time between creating the webview and destroying it for the bug to happen.

What happens with this code, is that if I close successive sub frames so that about 5 frames with webviews get created and destroyed, I get a segfault. Without the call to destroy, on the other hand, I can create tons of frames with webviews in them… so it seems there is something about destroying and recreating a webview (or at least the frame / panel that contains them) that fails. Maybe something gets reused that shouldn’t ?

The trace for the segfaults points to the webview.New() call.

Current thread 0x00007fa739c66740 (most recent call first):
  File "./test_wxhtml", line 17 in __init__
  File "./test_wxhtml", line 23 in on_close
  File "/home/arno/.local/share/virtualenvs/mw-qYOYF2Tf/lib/python3.8/site-packages/wx/core.py", line 2167 in MainLoop
  File "./test_wxhtml", line 36 in <module>
Segmentation fault (core dumped)

Is there something specific I should do when destroying frames with webviews in them ?

Even simpler version, that segfaults at the first key press.

import wx
import wx.html2

import faulthandler
faulthandler.enable()


class MainFrame(wx.Frame):
    def __init__(self, parent, ID, title):
        wx.Frame.__init__(self, parent, ID, title, size=(820, 800))
        self.Bind(wx.EVT_CHAR_HOOK, self.on_key_down)
        self.webview = wx.html2.WebView.New(self)

    def on_key_down(self, evt):
        self.webview.Destroy()
        self.webview = wx.html2.WebView.New(self)


app = wx.App(False)
frame = MainFrame(None, wx.ID_ANY, "Test")
frame.Show(True)
app.MainLoop()

I’m unable to replicate the problem with either example. What are your versions and platform?

One thing that I expected to be a problem in the 2nd example is that there can be crashes when destroying widgets while there are still events pending for them. Top-level windows will defer the actual destruction until there are no more pending events, but non top-level widgets do not do that. The workaround is to call the Destroy from a wx.CallAfter function, there is also a DestroyLater method in newer versions of wxPython.

But like I said, I didn’t have any crashes with your samples, so more info is needed.

Hello,

Thanks for looking into it.

The first example is closer to my actual situation since I am closing a top level window. Second example was an attempt to boil the code down to the issue.

I’m on Archlinux,
wxPython version is 4.0.7, and here are the C libs that get loaded :
wx/libwx_gtk3u_webview-3.0.so.0
wx/libwx_gtk3u_html-3.0.so.0
wx/_html.cpython-38-x86_64-linux-gnu.so
wx/libwx_baseu-3.0.so.0
wx/libwx_gtk3u_core-3.0.so.0
wx/_core.cpython-38-x86_64-linux-gnu.so
wx/_html2.cpython-38-x86_64-linux-gnu.so
wx/libwx_baseu_net-3.0.so.0