Package: emacs;
Reported by: David Caldwell <david <at> porkrind.org>
Date: Thu, 7 Aug 2025 19:14:01 UTC
Severity: normal
Found in version 30.1
To reply to this bug, email your comments to 79195 AT debbugs.gnu.org.
Toggle the display of automated, internal messages from the tracker.
View this report as an mbox folder, status mbox, maintainer mbox
bug-gnu-emacs <at> gnu.org:bug#79195; Package emacs.
(Thu, 07 Aug 2025 19:14:02 GMT) Full text and rfc822 format available.David Caldwell <david <at> porkrind.org>:bug-gnu-emacs <at> gnu.org.
(Thu, 07 Aug 2025 19:14:02 GMT) Full text and rfc822 format available.Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):
From: David Caldwell <david <at> porkrind.org> To: bug-gnu-emacs <at> gnu.org Subject: 30.1; eglot + rust-analyzer on Debian pauses for minutes with large directories Date: Thu, 07 Aug 2025 11:42:31 -0700
I'm seeing an issue when using eglot with rust-analyzer and a very large
directory in the project directory on a Debian machine.
Here's a recipe to reproduce it. (It assumes you have rust-analyzer
available):
mkdir -p /tmp/test
cd /tmp/test
cargo init --bin --name temp
# create 40,000 files inside 40,000 directories
mkdir bigdir
for d in $(seq -w 0 39); do
mkdir bigdir/$d
for f in $(seq -w 0 999); do
mkdir bigdir/$d/$f
echo "$d $f" > "bigdir/$d/$f/$f"
done
done
emacs -Q src/main.rs
M-x eglot RET rust-analyzer RET
At this point, if I strace the emacs process I see a bunch of
inotify_add_watch calls. Using `strace -p $(pidof emacs) -e inotify_add_watch,inotify_rm_watch` I see:
inotify_add_watch(6, "/tmp/test1", IN_MODIFY|IN_MOVED_FROM|IN_MOVED_TO|IN_CREATE|IN_DELETE|IN_DELETE_SELF|IN_MOVE_SELF|IN_UNMOUNT|IN_IGNORED|IN_DONT_FOLLOW|IN_EXCL_UNLINK|IN_MASK_ADD) = 1
inotify_add_watch(6, "/tmp/test1/bigdir/00/000", IN_MODIFY|IN_MOVED_FROM|IN_MOVED_TO|IN_CREATE|IN_DELETE|IN_DELETE_SELF|IN_MOVE_SELF|IN_UNMOUNT|IN_IGNORED|IN_DONT_FOLLOW|IN_EXCL_UNLINK|IN_MASK_ADD) = 2
inotify_add_watch(6, "/tmp/test1/bigdir/00/001", IN_MODIFY|IN_MOVED_FROM|IN_MOVED_TO|IN_CREATE|IN_DELETE|IN_DELETE_SELF|IN_MOVE_SELF|IN_UNMOUNT|IN_IGNORED|IN_DONT_FOLLOW|IN_EXCL_UNLINK|IN_MASK_ADD) = 3
inotify_add_watch(6, "/tmp/test1/bigdir/00/002", IN_MODIFY|IN_MOVED_FROM|IN_MOVED_TO|IN_CREATE|IN_DELETE|IN_DELETE_SELF|IN_MOVE_SELF|IN_UNMOUNT|IN_IGNORED|IN_DONT_FOLLOW|IN_EXCL_UNLINK|IN_MASK_ADD) = 4
inotify_add_watch(6, "/tmp/test1/bigdir/00/003", IN_MODIFY|IN_MOVED_FROM|IN_MOVED_TO|IN_CREATE|IN_DELETE|IN_DELETE_SELF|IN_MOVE_SELF|IN_UNMOUNT|IN_IGNORED|IN_DONT_FOLLOW|IN_EXCL_UNLINK|IN_MASK_ADD) = 5
inotify_add_watch(6, "/tmp/test1/bigdir/00/004", IN_MODIFY|IN_MOVED_FROM|IN_MOVED_TO|IN_CREATE|IN_DELETE|IN_DELETE_SELF|IN_MOVE_SELF|IN_UNMOUNT|IN_IGNORED|IN_DONT_FOLLOW|IN_EXCL_UNLINK|IN_MASK_ADD) = 6
inotify_add_watch(6, "/tmp/test1/bigdir/00/005", IN_MODIFY|IN_MOVED_FROM|IN_MOVED_TO|IN_CREATE|IN_DELETE|IN_DELETE_SELF|IN_MOVE_SELF|IN_UNMOUNT|IN_IGNORED|IN_DONT_FOLLOW|IN_EXCL_UNLINK|IN_MASK_ADD) = 7
inotify_add_watch(6, "/tmp/test1/bigdir/00/006", IN_MODIFY|IN_MOVED_FROM|IN_MOVED_TO|IN_CREATE|IN_DELETE|IN_DELETE_SELF|IN_MOVE_SELF|IN_UNMOUNT|IN_IGNORED|IN_DONT_FOLLOW|IN_EXCL_UNLINK|IN_MASK_ADD) = 8
inotify_add_watch(6, "/tmp/test1/bigdir/00/007", IN_MODIFY|IN_MOVED_FROM|IN_MOVED_TO|IN_CREATE|IN_DELETE|IN_DELETE_SELF|IN_MOVE_SELF|IN_UNMOUNT|IN_IGNORED|IN_DONT_FOLLOW|IN_EXCL_UNLINK|IN_MASK_ADD) = 9
inotify_add_watch(6, "/tmp/test1/bigdir/00/008", IN_MODIFY|IN_MOVED_FROM|IN_MOVED_TO|IN_CREATE|IN_DELETE|IN_DELETE_SELF|IN_MOVE_SELF|IN_UNMOUNT|IN_IGNORED|IN_DONT_FOLLOW|IN_EXCL_UNLINK|IN_MASK_ADD) = 10
inotify_add_watch(6, "/tmp/test1/bigdir/00/009", IN_MODIFY|IN_MOVED_FROM|IN_MOVED_TO|IN_CREATE|IN_DELETE|IN_DELETE_SELF|IN_MOVE_SELF|IN_UNMOUNT|IN_IGNORED|IN_DONT_FOLLOW|IN_EXCL_UNLINK|IN_MASK_ADD) = 11
inotify_add_watch(6, "/tmp/test1/bigdir/00/010", IN_MODIFY|IN_MOVED_FROM|IN_MOVED_TO|IN_CREATE|IN_DELETE|IN_DELETE_SELF|IN_MOVE_SELF|IN_UNMOUNT|IN_IGNORED|IN_DONT_FOLLOW|IN_EXCL_UNLINK|IN_MASK_ADD) = 12
...and so on
This will go on for minutes on my machine. In that time, emacs is
completely unresponsive.
I do see the rust-analyzer process go through the same directories soon
after it launches:
[pid 2414105] openat(AT_FDCWD, "/tmp/test/bigdir/0/0", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_DIRECTORY) = 4
[pid 2414105] fstat(4, {st_mode=S_IFDIR|0775, st_size=60, ...}) = 0
[pid 2414105] readlink("/tmp/test/bigdir/0/0", 0x7fe6e00fb650, 256) = -1 EINVAL (Invalid argument)
[pid 2414105] getdents64(4, 0x7fe6e00b4250 /* 3 entries */, 32768) = 72
[pid 2414105] getdents64(4, 0x7fe6e00b4250 /* 0 entries */, 32768) = 0
[pid 2414105] close(4)
But while emacs is calling inotify_add_watch(), the rust-analyzer
process isn't doing anything similar. It also doesn't add any watches
itself:
$ ls -l $(printf "/proc/%d/fd " $(pidof rust-analyzer)) | grep inotify
$
This happens to me because a project I'm working on creates a file tree
based database and after a few months of testing, my dev db in the
project root had grown large. In that particular case there are more
than 65535 total directories and so after several minutes the kernel
returns ENOSPC to one of the inotify_add_watch() calls and emacs closes
the inotify fd.
The directories have no rust source and are not referenced by cargo or
git, so I don't think eglot should be looking in there.
However, I don't know how it all works so perhaps eglot is just
responding to something rust-analyzer is telling it to do?
It would be nice to be able to disable these extra watches somehow. Or
perhaps there's way to do it asynchronously so emacs can remain
responsive? Because having emacs take multiple minutes after `M-x eglot`
is... grating. :-)
Any help would be appreciated.
Thanks,
David
In GNU Emacs 30.1 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.24.49,
cairo version 1.18.4) of 2025-07-18, modified by Debian built on sbuild
System Description: Debian GNU/Linux 13 (trixie)
Configured using:
'configure --build x86_64-linux-gnu --prefix=/usr
--sharedstatedir=/var/lib --libexecdir=/usr/libexec
--localstatedir=/var/lib --infodir=/usr/share/info
--mandir=/usr/share/man --with-libsystemd --with-pop=yes
--enable-locallisppath=/etc/emacs:/usr/local/share/emacs/30.1/site-lisp:/usr/local/share/emacs/site-lisp:/usr/share/emacs/30.1/site-lisp:/usr/share/emacs/site-lisp
--with-sound=alsa --without-gconf --with-mailutils --build
x86_64-linux-gnu --prefix=/usr --sharedstatedir=/var/lib
--libexecdir=/usr/libexec --localstatedir=/var/lib
--infodir=/usr/share/info --mandir=/usr/share/man --with-libsystemd
--with-pop=yes
--enable-locallisppath=/etc/emacs:/usr/local/share/emacs/30.1/site-lisp:/usr/local/share/emacs/site-lisp:/usr/share/emacs/30.1/site-lisp:/usr/share/emacs/site-lisp
--with-sound=alsa --without-gconf --with-mailutils --with-cairo
--with-x=yes --with-x-toolkit=gtk3 --with-toolkit-scroll-bars
'CFLAGS=-g -O2 -Werror=implicit-function-declaration
-ffile-prefix-map=/build/reproducible-path/emacs-30.1+1=. -fstack-protector-strong
-fstack-clash-protection -Wformat -Werror=format-security
-fcf-protection -Wall' 'CPPFLAGS=-Wdate-time -D_FORTIFY_SOURCE=2'
LDFLAGS=-Wl,-z,relro'
Configured features:
ACL CAIRO DBUS FREETYPE GIF GLIB GMP GNUTLS GPM GSETTINGS HARFBUZZ JPEG
LCMS2 LIBOTF LIBSELINUX LIBSYSTEMD LIBXML2 M17N_FLT MODULES NATIVE_COMP
NOTIFY INOTIFY PDUMPER PNG RSVG SECCOMP SOUND SQLITE3 THREADS TIFF
TOOLKIT_SCROLL_BARS TREE_SITTER WEBP X11 XDBE XIM XINPUT2 XPM GTK3 ZLIB
Important settings:
value of $LANG: en_US.UTF-8
locale-coding-system: utf-8-unix
Major mode: Fundamental
Minor modes in effect:
tooltip-mode: t
global-eldoc-mode: t
show-paren-mode: t
electric-indent-mode: t
mouse-wheel-mode: t
tool-bar-mode: t
menu-bar-mode: t
file-name-shadow-mode: t
global-font-lock-mode: t
font-lock-mode: t
blink-cursor-mode: t
minibuffer-regexp-mode: t
line-number-mode: t
indent-tabs-mode: t
transient-mark-mode: t
auto-composition-mode: t
auto-encryption-mode: t
auto-compression-mode: t
Load-path shadows:
None found.
Features:
(shadow sort mail-extr comp-run comp-common rx emacsbug message mailcap
yank-media puny dired dired-loaddefs rfc822 mml mml-sec epa derived epg
rfc6068 epg-config gnus-util time-date mm-decode mm-bodies mm-encode
mail-parse rfc2231 mailabbrev gmm-utils mailheader sendmail rfc2047
rfc2045 ietf-drums mm-util mail-prsvr mail-utils shell pcomplete
cl-extra eglot external-completion jsonrpc xref flymake thingatpt
project compat diff ert pp ewoc debug backtrace help-mode find-func
filenotify warnings compile text-property-search comint ansi-osc
ansi-color ring pcase url-util url-parse auth-source cl-seq eieio
eieio-core cl-macs icons password-cache json subr-x map url-vars imenu
vc-git diff-mode track-changes easy-mmode vc-dispatcher cl-loaddefs
cl-lib term/tmux term/xterm xterm byte-opt gv bytecomp byte-compile rmc
iso-transl tooltip cconv eldoc paren electric uniquify ediff-hook
vc-hooks lisp-float-type elisp-mode mwheel term/x-win x-win
term/common-win x-dnd touch-screen tool-bar dnd fontset image regexp-opt
fringe tabulated-list replace newcomment text-mode lisp-mode prog-mode
register page tab-bar menu-bar rfn-eshadow isearch easymenu timer select
scroll-bar mouse jit-lock font-lock syntax font-core term/tty-colors
frame minibuffer nadvice seq simple cl-generic indonesian philippine
cham georgian utf-8-lang misc-lang vietnamese tibetan thai tai-viet lao
korean japanese eucjp-ms cp51932 hebrew greek romanian slovak czech
european ethiopic indian cyrillic chinese composite emoji-zwj charscript
charprop case-table epa-hook jka-cmpr-hook help abbrev obarray oclosure
cl-preloaded button loaddefs theme-loaddefs faces cus-face macroexp
files window text-properties overlay sha1 md5 base64 format env
code-pages mule custom widget keymap hashtable-print-readable backquote
threads dbusbind inotify lcms2 dynamic-setting system-font-setting
font-render-setting cairo gtk x-toolkit xinput2 x multi-tty move-toolbar
make-network-process native-compile emacs)
Memory information:
((conses 16 538484 30409) (symbols 48 11378 0)
(strings 32 155267 8041) (string-bytes 1 3857814) (vectors 16 57740)
(vector-slots 8 395983 19842) (floats 8 53 13788)
(intervals 56 311 59) (buffers 992 15))
bug-gnu-emacs <at> gnu.org:bug#79195; Package emacs.
(Fri, 08 Aug 2025 00:52:02 GMT) Full text and rfc822 format available.Message #8 received at 79195 <at> debbugs.gnu.org (full text, mbox):
From: Dmitry Gutov <dmitry <at> gutov.dev> To: David Caldwell <david <at> porkrind.org>, 79195 <at> debbugs.gnu.org Subject: Re: bug#79195: 30.1; eglot + rust-analyzer on Debian pauses for minutes with large directories Date: Fri, 8 Aug 2025 03:51:00 +0300
Hi! On 07/08/2025 21:42, David Caldwell wrote: > It would be nice to be able to disable these extra watches somehow. Or > perhaps there's way to do it asynchronously so emacs can remain > responsive? Because having emacs take multiple minutes after `M-x eglot` > is... grating. 🙂 Can you add the directory that contains them to the "ignored" part of the project? Then the corresponding part of eglot-register-capability shouldn't set watches in there. See project-vc-ignores, if you're using the default project.el backend.
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.