Electron segmentation fault after window.close() (windows, linux)

I’m updating an electron app to use the latest version (from 4.x) and since then, the Electron binary has been crashing when I close a window in response to an IPC message.

ipcMain.on('close-options', (event) => {
  logger.info('IPC: close-options')
  // setImmediate(() => {
    if (main.optionsWindow) {
      main.optionsWindow.close()
    }
  // })
})

On the renderer side, my window has a keydown handler that runs:

ipcRenderer.send('close-options')

when I press the esc key.

This has been working in Electron 4.x for years. But with electron 11, every time I press esc, it closes the window then produces a segfault with no further information. I added the setImmediate() wrapper, and at first it seemed like that fixed it, but it only masked the problem…it only crashes sometimes, which is almost worse…

I’m not sure exactly where it’s crashing, either… the window’s close and closed event handlers do both run before crashing.

I tried electron@10 and got the same problem…I’ll probably keep trying all the versions between 4 and 10, but it’s not completely straightforward because of API changes.

Meanwhile, any advice? I suspect it has something to do with the IPC, since setImmediate changed the behavior. Am I doing something egregiously wrong?

A couple other things I forgot to mention: It only seems to happen on Windows or Linux platforms. My dev platform is MacOS, and it never happens there. Also never happens if I close the window by clicking the close button.

My closed handler, if that helps…this is why I test if (main.optionsWindow) {...} before operating on it:

main.optionsWindow.on('closed', function () {
  logger.debug('optionsWindow closed')
  main.optionsWindow = undefined
})

I was just looking through the code to verify that I am always testing the existence of main.optionsWindow and it looks like I am, excluding the function that actually creates it with new BrowserWindow().

I did notice that in another place in the code (http handler) I’m closing the window using

main.optionsWindow && main.optionsWindow.destroy()

I don’t think that should be a problem though… should still emit the closed event.

Update:
I got my app running under Electron 9.4.0 after modifying my protocol registration API code to match, and it doesn’t crash anymore.

So the problem seems to be limited to Electron 10.x and up, and only on Windows and Linux platforms.