Subject: bug#79201: 30.1.90; set-process-thread can permanently break fd_callback_info slots

From: Spencer Baugh <[email-masked]>
Date: Fri, 08 Aug 2025 13:06:22 -0400

Using set-process-thread sets the fd_callback_info[fd].thread slot,
which is not cleared on process exit.  As a result
fd_callback_info[fd].thread can contain a dangling pointer to a dead
thread, which means that fd_callback_info[fd] will be permanently
broken, and any new process created which uses that slot will also be
broken.

Reproduction: the following code will hang forever when the
(delete-process proc1) line is present, but terminates just fine when
that line is deleted.

(setq my-thread (make-thread (lambda () (while t (sleep-for 60)))))
(setq proc1
      (make-process
       :name "proc1"
       :command '("sleep" "inf")))
; Set the process's thread to my-thread
(set-process-thread proc1 my-thread)
; Delete the process so fd_callback_info[fd].thread doesn't get cleared
; on thread exit.
(delete-process proc1)
; Kill my-thread, just for completeness.
(thread-signal my-thread 'error nil)
; Start up a seemingly completely unrelated process; Emacs will never be
; able to read from this process because it's reusing
; fd_callback_info[fd] and .thread is pointing to a dead thread.
(setq proc2
      (make-process
       :name "proc2"
       :command '("sh" "-c" "echo hi; sleep inf")))
(message "waiting on proc2")
(while (null (accept-process-output proc2)))

In fact, SIGINTing this process while it's hanging will cause Emacs to
segfault.  It looks like current_thread is NULL?  Not sure why that
happens, possibly an unrelated bug.

Anyway, probably we should be setting fd_callback_info[fd].thread to
NULL also when the process exits.  But, I suggest we should further also
set it to NULL (and also waiting_thread) when we start using a
fd_callback_info[fd] slot, e.g. in add_read_fd.  That avoids the
possibility of permanent contamination of fd_callback_info slots, which
I think is possible in some other ways, though I haven't been able to
reproduce it yet...

In GNU Emacs 30.1.90 (build 8, x86_64-pc-linux-gnu, X toolkit, cairo
 version 1.15.12, Xaw scroll bars) of 2025-08-06 built on
 igm-qws-u22796a
Repository revision: a7392a6cea9cb7d77fab044a8e8cbcb012b5d6c7
Repository branch: emacs-30
Windowing system distributor 'The X.Org Foundation', version 11.0.12011000
System Description: Rocky Linux 8.10 (Green Obsidian)

Configured using:
 'configure --with-x-toolkit=lucid --without-gpm --without-gconf
 --without-gsettings --without-selinux --without-imagemagick
 --with-modules --with-gif=no --with-cairo --with-rsvg
 --without-compress-install --with-tree-sitter
 --with-native-compilation=aot
 PKG_CONFIG_PATH=/usr/local/home/garnish/libtree-sitter/0.22.6-1/lib/pkgconfig/'

Configured features:
CAIRO DBUS FREETYPE GLIB GMP GNUTLS HARFBUZZ JPEG LIBSYSTEMD LIBXML2
MODULES NATIVE_COMP NOTIFY INOTIFY PDUMPER PNG RSVG SECCOMP SOUND
SQLITE3 THREADS TIFF TOOLKIT_SCROLL_BARS TREE_SITTER X11 XDBE XIM
XINPUT2 XPM LUCID ZLIB

Important settings:
  value of $LANG: en_US.UTF-8
  locale-coding-system: utf-8-unix