Subject: bug#71073: Emacs segfaults if corfu is asked to autocomplete something while the LSP server providing completions is still starting/indexing

From: alexis purslane <[email-masked]>
Date: Sun, 19 May 2024 19:58:23 +0000

## Description

If corfu is prompted to start autocompletion (by typing the first 3
letters of a word in my case) while an eglot LSP server is still
starting up, but after eglot has connected to that server, you get a
segmentation fault.

## Steps to reproduce

1. Open a file with a mode associated with it that has a language server
2. {M-x eglot}
3. Before the server has finished indexing and can provide completions,
   but after it has connected, prompt corfu to do an autocompletion
4. Enjoy your segfault salad

## Debug information

Here's the backtrace from the core dump:

```
Fatal error 11: Segmentation fault
Backtrace:
emacs(emacs_backtrace+0x5a)[0x595c1a]
emacs(terminate_due_to_signal+0x9f)[0x467885]
emacs[0x468623]
emacs[0x70bae4]
/lib64/libc.so.6(+0x40750)[0x7f153d9e3750]
emacs(parse_modifiers+0x12c)[0x57a06c]
emacs[0x590ad8]
emacs(read_char+0x212a)[0x57f7ea]
emacs[0x648f3a]
/usr/bin/../lib64/emacs/29.3/native-lisp/29.3-f9fbfec9/preloaded/subr-13adf6a6-bfb9f448.eln(F7369742d666f72_sit_for_0+0x19f)[0x7f1536c1b2ff]
emacs(Ffuncall+0xfd)[0x62148d]
/usr/lib64/emacs/29.3/native-lisp/29.3-f9fbfec9/jsonrpc-e62a9c36-62ae7160.eln(F6a736f6e7270632d72657175657374_jsonrpc_request_0+0xa14)[0x7f152409e2c4]
emacs(Ffuncall+0xfd)[0x62148d]
emacs(Fapply+0x1b0)[0x621b90]
emacs(exec_byte_code+0x54c)[0x66b8bc]
emacs(Ffuncall+0xfd)[0x62148d]
emacs(Fall_completions+0x372)[0x5b6122]
/usr/bin/../lib64/emacs/29.3/native-lisp/29.3-f9fbfec9/preloaded/minibuffer-1b0f548b-25462d74.eln(F636f6d706c6574696f6e2d70636d2d2d616c6c2d636f6d706c6574696f6e73_completion_pcm__all_completions_0+0x1a7)[0x7f1536bbda67]
emacs(Ffuncall+0xfd)[0x62148d]
/usr/bin/../lib64/emacs/29.3/native-lisp/29.3-f9fbfec9/preloaded/minibuffer-1b0f548b-25462d74.eln(F636f6d706c6574696f6e2d737562737472696e672d2d616c6c2d636f6d706c6574696f6e73_completion_substring__all_completions_0+0x1d6)[0x7f1536bc0f86]
emacs(Ffuncall+0xfd)[0x62148d]
/usr/bin/../lib64/emacs/29.3/native-lisp/29.3-f9fbfec9/preloaded/minibuffer-1b0f548b-25462d74.eln(F636f6d706c6574696f6e2d666c65782d616c6c2d636f6d706c6574696f6e73_completion_flex_all_completions_0+0xb6)[0x7f1536bc1a16]
emacs(Ffuncall+0xfd)[0x62148d]
emacs(Fapply+0x1b0)[0x621b90]
emacs(exec_byte_code+0x54c)[0x66b8bc]
emacs(Ffuncall+0xfd)[0x62148d]
/usr/bin/../lib64/emacs/29.3/native-lisp/29.3-f9fbfec9/preloaded/minibuffer-1b0f548b-25462d74.eln(F636f6d706c6574696f6e2d2d736f6d65_completion__some_0+0x1e2)[0x7f1536baa852]
emacs(Ffuncall+0xfd)[0x62148d]
/usr/bin/../lib64/emacs/29.3/native-lisp/29.3-f9fbfec9/preloaded/minibuffer-1b0f548b-25462d74.eln(F636f6d706c6574696f6e2d2d6e74682d636f6d706c6574696f6e_completion__nth_completion_0+0x2d4)[0x7f1536baf914]
emacs(Ffuncall+0xfd)[0x62148d]
/usr/bin/../lib64/emacs/29.3/native-lisp/29.3-f9fbfec9/preloaded/minibuffer-1b0f548b-25462d74.eln(F636f6d706c6574696f6e2d616c6c2d636f6d706c6574696f6e73_completion_all_completions_0+0x50)[0x7f1536bafcd0]
emacs(Ffuncall+0xfd)[0x62148d]
emacs(Fapply+0x1b0)[0x621b90]
emacs(exec_byte_code+0x54c)[0x66b8bc]
emacs(Ffuncall+0xfd)[0x62148d]
emacs(Fapply+0x1b0)[0x621b90]
/var/home/alexispurslane/.emacs.d/eln-cache/29.3-f9fbfec9/corfu-4ecf6dfc-d30fc894.eln(F636f7266752d2d66696c7465722d636f6d706c6574696f6e73_corfu__filter_completions_0+0x199)[0x7f1524616be9]
emacs(Ffuncall+0xfd)[0x62148d]
/var/home/alexispurslane/.emacs.d/eln-cache/29.3-f9fbfec9/corfu-4ecf6dfc-d30fc894.eln(F636f7266752d2d7265636f6d70757465_corfu__recompute_0+0x29e)[0x7f1524617b9e]
emacs(Ffuncall+0xfd)[0x62148d]
/var/home/alexispurslane/.emacs.d/eln-cache/29.3-f9fbfec9/corfu-4ecf6dfc-d30fc894.eln(F636f7266752d2d757064617465_corfu__update_0+0x755)[0x7f1524618e25]
...
Segmentation fault: oops, process 'emacs' core dumped
```

## Recipe

I was able to repro this bug with just this in my config (running with
emacs --init-directory set to a separate dummy directory with this in my
init.el):

```lisp
(use-package corfu
    :ensure t
    ;; Optional customizations
    :custom
    (corfu-cycle t)                ;; Enable cycling for `corfu-next/previous'
    (corfu-auto t)                 ;; Enable auto completion
    (corfu-separator ?\s)          ;; Orderless field separator
    (corfu-quit-no-match 'separator)
    (corfu-auto-delay 0.12)
    (corfu-auto-prefix 3)
    (corfu-popupinfo-delay 0.22)
    (corfu-popupinfo-direction 'right)
    :config
    (global-corfu-mode)
    (defun corfu-enable-in-minibuffer ()
        "Enable Corfu in the minibuffer."
        (when (local-variable-p 'completion-at-point-functions)
            (setq-local corfu-echo-delay nil ;; Disable automatic echo and popup
                        corfu-popupinfo-delay nil)
            (corfu-mode 1)))
    (add-hook 'minibuffer-setup-hook #'corfu-enable-in-minibuffer)

    (defun corfu-popupinfo-start ()
        (require 'corfu-popupinfo)
        (set-face-attribute 'corfu-popupinfo nil :inherit 'variable-pitch)
        (corfu-popupinfo-mode))
    (add-hook 'corfu-mode-hook #'corfu-popupinfo-start))
```

## Config

Here's my full corfu and orderless configuration:

```lisp
;; Optionally use the `orderless' completion style for proper fuzzy searching
;; in vertico
(use-package orderless
    :after vertico
    :init
(setq completion-styles '(orderless basic)
      completion-category-defaults nil
          completion-category-overrides '((file (styles partial-completion)))))

(use-package corfu
    ;; Optional customizations
    :custom
    (corfu-cycle t)                ;; Enable cycling for `corfu-next/previous'
    (corfu-auto t)                 ;; Enable auto completion
    (corfu-separator ?\s)          ;; Orderless field separator
    (corfu-quit-no-match 'separator)
    (corfu-auto-delay 0.12)
    (corfu-auto-prefix 3)
    (corfu-popupinfo-delay 0.22)
    (corfu-popupinfo-direction 'right)
    :config
    (global-corfu-mode)
    (defun corfu-enable-in-minibuffer ()
        "Enable Corfu in the minibuffer."
        (when (local-variable-p 'completion-at-point-functions)
            (setq-local corfu-echo-delay nil ;; Disable automatic echo and popup
                        corfu-popupinfo-delay nil)
            (corfu-mode 1)))
    (add-hook 'minibuffer-setup-hook #'corfu-enable-in-minibuffer)

    (defun corfu-popupinfo-start ()
        (require 'corfu-popupinfo)
        (set-face-attribute 'corfu-popupinfo nil :inherit 'variable-pitch)
        (corfu-popupinfo-mode))
    (add-hook 'corfu-mode-hook #'corfu-popupinfo-start))

(use-package nerd-icons
    :if (display-graphic-p)
    :custom (nerd-icons-font-family "Symbols Nerd Font Mono"))

;; Integrate them with corfu
(use-package nerd-icons-corfu
    :after (corfu nerd-icons)
    :config (add-to-list 'corfu-margin-formatters #'nerd-icons-corfu-formatter))
```

In GNU Emacs 29.3 (build 1, x86_64-redhat-linux-gnu, GTK+ Version
 3.24.41, cairo version 1.18.0) of 2024-04-18 built on
 f79e87ffac024d38993f848c551f45fc
System Description: Fedora Linux 41 (Container Image Prerelease)

Configured using:
 'configure --build=x86_64-redhat-linux-gnu
 --host=x86_64-redhat-linux-gnu --program-prefix=
 --disable-dependency-tracking --prefix=/usr --exec-prefix=/usr
 --bindir=/usr/bin --sbindir=/usr/sbin --sysconfdir=/etc
 --datadir=/usr/share --includedir=/usr/include --libdir=/usr/lib64
 --libexecdir=/usr/libexec --localstatedir=/var --runstatedir=/run
 --sharedstatedir=/var/lib --mandir=/usr/share/man
 --infodir=/usr/share/info --with-cairo --with-dbus --with-gif
 --with-gpm=no --with-harfbuzz --with-jpeg --with-json --with-modules
 --with-native-compilation=aot --with-pgtk --with-png --with-rsvg
 --with-sqlite3 --with-tiff --with-tree-sitter --with-webp --with-xpm
 --with-xwidgets build_alias=x86_64-redhat-linux-gnu
 host_alias=x86_64-redhat-linux-gnu CC=gcc 'CFLAGS=-DMAIL_USE_LOCKF -O2
 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches
 -pipe -Wall -Werror=format-security
 -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS
 -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong
 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -march=x86-64
 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection
 -fcf-protection -mtls-dialect=gnu2 -fno-omit-frame-pointer
 -mno-omit-leaf-frame-pointer ' LDFLAGS=-Wl,-z,relro
 PKG_CONFIG_PATH=:/usr/lib64/pkgconfig:/usr/share/pkgconfig CXX=g++
 'CXXFLAGS=-O2 -flto=auto -ffat-lto-objects -fexceptions -g
 -grecord-gcc-switches -pipe -Wall -Werror=format-security
 -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS
 -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong
 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -march=x86-64
 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection
 -fcf-protection -mtls-dialect=gnu2 -fno-omit-frame-pointer
 -mno-omit-leaf-frame-pointer ''

Configured features:
ACL CAIRO DBUS FREETYPE GIF GLIB GMP GNUTLS GSETTINGS HARFBUZZ JPEG JSON
LIBOTF LIBSELINUX LIBSYSTEMD LIBXML2 MODULES NATIVE_COMP NOTIFY INOTIFY
PDUMPER PGTK PNG RSVG SECCOMP SOUND SQLITE3 THREADS TIFF
TOOLKIT_SCROLL_BARS TREE_SITTER WEBP XIM XWIDGETS GTK3 ZLIB

Important settings:
  value of $LANG: en_US.UTF-8
  value of $XMODIFIERS: @im=ibus
  locale-coding-system: utf-8-unix

Major mode: ELisp/l

Minor modes in effect:
  elisp-def-mode: t
  highlight-defined-mode: t
  electric-pair-mode: t
  hl-line-mode: t
  display-line-numbers-mode: t
  corfu-popupinfo-mode: t
  corfu-mode: t
  eldoc-box-hover-at-point-mode: t
  yas-minor-mode: t
  hl-todo-mode: t
  ligature-mode: t
  nerd-icons-completion-mode: t
  mood-line-mode: t
  spacious-padding-mode: t
  global-treesit-auto-mode: t
  global-evil-collection-unimpaired-mode: t
  evil-collection-unimpaired-mode: t
  marginalia-mode: t
  vertico-mode: t
  which-key-mode: t
  general-override-mode: t
  evil-mode: t
  evil-local-mode: t
  override-global-mode: t
  recentf-mode: t
  winner-mode: t
  pixel-scroll-precision-mode: t
  delete-selection-mode: t
  cua-mode: t
  apheleia-mode: t
  tooltip-mode: t
  global-eldoc-mode: t
  eldoc-mode: t
  show-paren-mode: t
  electric-indent-mode: t
  mouse-wheel-mode: t
  file-name-shadow-mode: t
  global-font-lock-mode: t
  font-lock-mode: t
  blink-cursor-mode: t
  column-number-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:
/var/home/alexispurslane/.emacs.d/elpa/transient-20240509.1849/transient hides /usr/share/emacs/29.3/lisp/transient

Features:
(shadow sort mail-extr emacsbug message yank-media puny
evil-collection-dired dired dired-loaddefs rfc822 mml mml-sec
evil-collection-epa epa derived epg rfc6068 epg-config gnus-util
mm-decode mm-bodies mm-encode mail-parse rfc2231 mailabbrev gmm-utils
mailheader sendmail rfc2047 rfc2045 ietf-drums mm-util mail-prsvr
mail-utils vertico-directory mule-util time-date evil-collection-vc-git
vc-git evil-collection-diff-mode diff-mode vc-dispatcher
mood-line-segment-vc elisp-def evil-collection-ert ert ewoc
evil-collection-debug debug backtrace evil-collection-xref xref
find-func f s dash highlight-defined elec-pair hl-line
display-line-numbers corfu-popupinfo yasnippet-capf nerd-icons-corfu
evil-collection-corfu corfu mood-line-segment-modal yasnippet eldoc-box
hl-todo ligature time evil-collection-flymake flymake-proc flymake
project evil-collection-compile compile evil-collection-comint comint
ansi-osc ansi-color nerd-icons-completion evil-collection-dashboard
dashboard dashboard-widgets nerd-icons nerd-icons-faces nerd-icons-data
nerd-icons-data-mdicon nerd-icons-data-flicon nerd-icons-data-codicon
nerd-icons-data-devicon nerd-icons-data-sucicon nerd-icons-data-wicon
nerd-icons-data-faicon nerd-icons-data-powerline nerd-icons-data-octicon
nerd-icons-data-pomicon nerd-icons-data-ipsicon ffap mood-line
spacious-padding doom-gruvbox-theme doom-themes doom-themes-base
treesit-auto evil-textobj-tree-sitter
evil-textobj-tree-sitter-thing-at-point evil-collection-unimpaired
evil-collection-which-key evil-collection-vertico
evil-collection-tabulated-list evil-collection-tab-bar
evil-collection-simple evil-collection-replace
evil-collection-process-menu evil-collection-package-menu
evil-collection-info evil-collection-indent evil-collection-help
evil-collection-elisp-mode evil-collection-eldoc evil-collection-custom
evil-collection-consult evil-collection-buff-menu
evil-collection-bookmark evil-collection annalist consult bookmark
text-property-search orderless marginalia vertico compat which-key
general evil-textobj-tree-sitter-core evil evil-keybindings
evil-integration evil-maps evil-commands reveal evil-jumps
evil-command-window evil-types evil-search evil-ex evil-macros
evil-repeat evil-states evil-core comp comp-cstr warnings rx advice
evil-common thingatpt rect evil-vars treesit edmacro kmacro
use-package-bind-key bind-key use-package-diminish recentf tree-widget
winner pixel-scroll ring delsel cua-base cus-edit pp cus-load icons
wid-edit cl-extra help-mode use-package-ensure use-package-core
clang-rename clang-include-fixer let-alist clang-format xml
apheleia-autoloads easy-mmode breadcrumb-autoloads
centaur-tabs-autoloads consult-notes-autoloads consult-autoloads
corfu-autoloads darkroom-autoloads dashboard-autoloads denote-autoloads
doom-themes-autoloads eldoc-box-autoloads elisp-def-autoloads
elisp-demos-autoloads emojify-autoloads evil-collection-autoloads
annalist-autoloads evil-textobj-tree-sitter-autoloads general-autoloads
helpful-autoloads elisp-refs-autoloads f-autoloads
highlight-defined-autoloads hl-todo-autoloads hyperbole-autoloads
kotl-autoloads hact set hhist latex-preview-pane-autoloads
ligature-autoloads magit-autoloads pcase git-commit-autoloads
magit-section-autoloads marginalia-autoloads markdown-mode-autoloads
markdown-ts-mode-autoloads mood-line-autoloads
nerd-icons-completion-autoloads nerd-icons-corfu-autoloads
nerd-icons-dired-autoloads nerd-icons-autoloads orderless-autoloads
powerline-autoloads rainbow-delimiters-autoloads
spacious-padding-autoloads transient-autoloads treemacs-evil-autoloads
treemacs-autoloads cfrs-autoloads posframe-autoloads ht-autoloads
hydra-autoloads lv-autoloads pfuture-autoloads ace-window-autoloads
avy-autoloads s-autoloads dash-autoloads evil-autoloads
goto-chg-autoloads treesit-auto-autoloads vertico-autoloads
visual-fill-column-autoloads which-key-autoloads with-editor-autoloads
info compat-autoloads yasnippet-capf-autoloads yasnippet-autoloads
package browse-url url url-proxy url-privacy url-expand url-methods
url-history url-cookie generate-lisp-file url-domsuf url-util mailcap
url-handlers url-parse auth-source cl-seq eieio eieio-core cl-macs
password-cache json subr-x map byte-opt gv bytecomp byte-compile
url-vars cl-loaddefs cl-lib rmc iso-transl tooltip cconv eldoc paren
electric uniquify ediff-hook vc-hooks lisp-float-type elisp-mode mwheel
term/pgtk-win pgtk-win term/common-win pgtk-dnd 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 xwidget-internal dbusbind
inotify dynamic-setting system-font-setting font-render-setting cairo
gtk pgtk multi-tty make-network-process native-compile emacs)

Memory information:
((conses 16 398743 161667)
 (symbols 48 23840 0)
 (strings 32 98289 5189)
 (string-bytes 1 3584246)
 (vectors 16 46773)
 (vector-slots 8 943753 143975)
 (floats 8 528 347)
 (intervals 56 1561 0)
 (buffers 984 20))