wxpython

wxPython ‘RuntimeError: wrapped C/C++ object of type JLCPCBTools has been deleted’


I'm struggling to debug an issue users are reporting with the kicad JLCPCB tools plugin. I feel like this is due to a misusage of queues or objects but I'm stuck without any next step ideas.

The queue usage can been seen in the logging.StreamHandler here.

I've also reported it on the wxPython discussion group.

The argument is coming in as LogRecord, we are generating a local like:

msg = self.format(record)

Which looks like its calling logging.Handler.format

and then we build a local to pass it to the queue via wx.QueueEvent, formatting it with an f-string:

    def emit(self, record):
        """Marshal the event over to the main thread."""
        msg = self.format(record)
        wx.QueueEvent(self.event_destination, LogboxAppendEvent(
                msg=f"{msg}\n"
            )
        )

Solution

  • From the commit I made here to fix the issue

    Root cause is that the Python instance persists for the duration of Kicad's execution. Thus calls to addHandler() to the root logger are cumulative. Each time you re-open the mainwindow the logging handlers are added. The previous handlers, which now refer to deleted instances of the mainwindow (class JLCPCBTools, see the error message in the commit subject), persist. Each subsequent call to Python's logging functions results in all of these loggers being called.

    Previously the try/except in each of these loggers was discarding the wxPython/wxWidgets errors but removing the try/except meant they were now unhandled.

    Fix the crash by calling removeHandler() in quit_dialog() so there are no old logger handlers with references to now deleted dialogs.

    Note that due to the try/except it is likely that this issue was latent in the plugin for months or years, at least since the addHandler() was called without removeHandler().