macvim-dev / macvim

Vim - the text editor - for macOS
https://macvim.org
Vim License
7.51k stars 683 forks source link

Fix Vim crashing when querying serverlist when quitting #1427

Closed ychin closed 1 year ago

ychin commented 1 year ago

Currently, when quitting MacVim using Cmd-Q, if an autocmd queries serverlist() during shutdown (e.g. VimLeavePre), there's a potential that Vim will crash and then stuck in a spinloop and never gets killed by the parent process.

The reason is somehwat complicated. MMAppController tells Vim to quit but has a hard-coded timer before terminating the connection. If Vim takes too long to respond somehow, it will see a "connectionDidDie" message where it will be forced to quit. The serverlist() IPC API call isn't properly guarding against an invalid connection and if an autocmd triggers that call during this time, it will throw an exception and crash.

Usually if Vim crashes, it should terminate cleanly, but couple things cause this to not work properly:

MacVim also doesn't have a solid mechanism to shut down zombie processes right now (it depends on Vim cleaning up after itself), so after MacVim quits, the now-orphaned Vim process stuck consuming 100% CPU.

The fix is to simply guard against this and make sure we clean up the connection properly when we detected it died, and to be more defensive and make sure the serverlist call properly guard against invalid states and exceptions.

Not tackling the other issues for now. There are some unfortunate interactions here with an unwound exception causing invoke_all_defer() to not work, but we just need to make sure to guard potential places with try/catch blocks, as invoke_all_defer() is still useful. Also, proper zombie process killing will be done at a later time, as we will soon tackle removing Distributed Objects/NSConnection and revamp the entire IPC stack anyway.

Fix #1423