Generally, the MacPorts version of Emacs works great on my Mac Mini. But every so often, I'd hit a Too many open files error.
The *Messages* buffer was little help as it just repeated what I already knew:
insert-directory: Opening process input file: Too many open files, /dev/null [2 times]
I'd attempt to close buffers or shut down projectile projects, but there was nothing I could reliably do to recover from this error. Ultimately, I had to do the unthinkable and restart emacs.
I tried the obvious fix: telling my Mac to allow processes to open more files. I followed this recipe:
$ sudo cat /Library/LaunchDaemons/limit.maxfiles.plist <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Label</key> <string>limit.maxfiles</string> <key>ProgramArguments</key> <array> <string>launchctl</string> <string>limit</string> <string>maxfiles</string> <string>64000</string> <string>20480</string> </array> <key>RunAtLoad</key> <true/> <key>ServiceIPC</key> <false/> </dict> </plist> $ sysctl kern.maxfiles kern.maxfiles: 20480 $ sysctl kern.maxfilesperproc kern.maxfilesperproc: 64000
It didn't help. Perhaps I was setting the limit incorrectly for my particular version of the OS. Or maybe I was setting the value too high, and the system was reverting it to something smaller. Or maybe all was good at the OS level, and it was a bash ulimit problem.
I considered all of these scenarios, but no matter how I set the file limit or what I set the file limit too, emacs kept hitting a 1024 open files limit. I could easily confirm this with lsof:
$ ps auxww|grep Emacs ben 15944 0.0 0.7 412688032 111280 ?? S Mon06AM 71:07.20 /Applications/MacPorts/Emacs.app/Contents/MacOS/Emacs $ lsof -p 15944 | wc -l 1618
After much frustration and searching, I finally stumbled on this reddit thread where a fellow emacs user complained about the 1024 max file limit:
Been trying to figure out a way to get out of this trap… I got a new Mac as a work laptop and I can’t seem to update the file descriptors. I updated it for the system but whenever eMacs is opened, ulimit is still at 1024.
Thankfully, there was a helpful reply:
I hit this all the time, as I work on a large monorepo with lsp-mode (and sometimes treemacs, which also watches stuff).
Whenever it happens I run M-x file-notify-rm-all-watches and things go back to normal for a while.
Last time I looked into this, you could not work around it by adjusting ulimits or literally anything. It's a core limitation of a low-level API used internally and is not configurable. I will try to find the previous discussion.
Aha! This made sense, as I've added lsp-mode to my workflow recently.
I was delighted to find I wasn't the only one having this problem, and more importantly, there was an easy work around.
Alas, when I tried to execute M-x file-notify-rm-all-watches I found that my version of emacs didn't have this function.
A quick Google search turned up this source file for filenotify.el. It does have file-notify-rm-all-watches defined as follows:
(defun file-notify-rm-all-watches () "Remove all existing file notification watches from Emacs." (interactive) (maphash (lambda (key _value) (file-notify-rm-watch key)) file-notify-descriptors))
I copied the code, untouched, into my emacs configuration. Next time I got the dreaded Too many open files error, I ran M-x file-notify-rm-all-watches and just like that, emacs was happy again. And so was I.
No comments:
Post a Comment