Subject: bug#36648: emacs signals under gdb - [Re: connecting to a lost server process

From: Madhu <[email-masked]>
Date: Thu, 18 Jul 2019 20:28:21 +0530 (IST)

*  Eli Zaretskii <[email-masked]> <[email-masked]>
Wrote on Thu, 18 Jul 2019 08:35:04 +0300

>> From: Madhu <[email-masked]>
>> Date: Sun, 14 Jul 2019 17:30:52 +0530
>>
>> #5  report_file_errno (string=<optimized out>, name=name@entry=XIL(0xdd55f3),
>>     errorno=<optimized out>)
>>     at /var/tmp/portage/app-editors/emacs-27.0.50-r3/work/emacs-27.0.50/src/fileio.c:222
>> #6  0x000000000041a663 in connect_network_socket (proc=XIL(0xd7f415),
>>     addrinfos=<optimized out>, use_external_socket_p=<optimized out>)
>>     at /var/tmp/portage/app-editors/emacs-27.0.50-r3/work/emacs-27.0.50/src/process.c:3633
>> #7  0x00000000005a2cc6 in Fmake_network_process (nargs=<optimized out>,
>>     args=<optimized out>)
>>     at /var/tmp/portage/app-editors/emacs-27.0.50-r3/work/emacs-27.0.50/src/process.c:4246
>
> See the call to report_file_errno in frame #5?  Signaling an error
> while waiting for input is fatal in Emacs, so it aborts.
>
>> Lisp Backtrace:
>> "make-network-process" (0xffffc2a0)
>> "server-running-p" (0xffffc690)
>> "server-start" (0xffffcbc0)
>>
>> (gdb) up 5
>> #5  report_file_errno (string=<optimized out>, name=name@entry=XIL(0xdd55f3),
>>     errorno=<optimized out>)
>>     at /var/tmp/portage/app-editors/emacs-27.0.50-r3/work/emacs-27.0.50/src/fileio.c:222
>> 222	  xsignal (Fcar (data), Fcdr (data));
>>
>> (gdb) pp data
>> (file-missing "make client process failed" "No such file or directory" :name "server-client-test" :family local :server nil :noquery t :service "/dev/shm/madhu/emacs/emacs-test")
>
> So here's the reason for the problem: the way you try to restart the
> server fails because the socket no longer exists.
>
>> Additional notes:
>> - make-network-process signals a (file-missing "make client process failed" "No such file or directory" :name "server-client-test" :family local :server nil :noquery t :service "/dev/shm/madhu/emacs/emacs-test")
>>   which is not supposed to happen since the file would be created by the
>>   system call to socket.  I suspect a wrong error is being reported
>>   because of some problem with pselect (which is interrupted when we
>>   enter gdb)
>
> I don't think the error is wrong.  Look at the function
> server-running-p: it attempts to determine whether the server is
> already running by creating a client process of the server.  This
> happens _before_ restarting the server.  IOW, Emacs attempts to clean
> up if the server is already running.  In your case, the socket
> doesn't exist, so this method of restarting the server can no longer
> be used safely, because when you attach GDB to Emacs, Emacs will
> almost always be waiting for input, where every error is fatal.

server-running-p tries to start a server, and if it fails with a file
error, then the condition-case is expected to catch it and the
function is supposed to return nil.  If I modify this function (see
patch [1]) to test for the file instead of trying to catch an error
from make-network-process, then this particular example (of restarting
the server from gdb) works.

>From the point of view of elisp, no error should be signalled - it
should be caught by the condition-case.

If I'm running an emacs compiled without X, when I suspend emacs and
enter gdb on the same terminal, then no error is signalled (presumably
because emacs is not waiting for input).

> Instead, I suggest to restart the server by binding a function to the
> sigusr1 or sigusr2 event.  These events can be triggered by the
> corresponding signals.

Thank you, I will take up this suggestion. The default SIGUSR is
very useful to unwedge emacs.

However there seems to be room for improvement around the "abort when
awaiting for input behaviour" - as there are other situations within
gdb which are not "really" error situations which unnecessarily abort
emacs.

>> - another unrelated emacs-bug. M-x gud-gdb -- emacs .. with the above
>>   arg line fails to pass the quoted arguments to gdb.
>
> Sorry, I don't think I understand what exactly do you mean by "with
> the above arg line".  Can you please show a full sequence of commands
> that produce this problem?

M-x gud-gdb RET
gdb --args emacs --arg -Q --eval '(progn (load-library "custom") (load-library "server") (setq server-name "emacs-test"))' RET

=>

|Reading symbols from emacs...
(gdb) show args
Argument list to give program being debugged when it is started is "--arg -Q --eval \'\(progn \(load-library custom \) \(load-library server \) \(setq server-name emacs-test \)\)\'".
(gdb)

i.e. the arguments are not correctly quoted when passed to gdb.

[1]

diff --git a/lisp/server.el b/lisp/server.el
index 436a44a7e9..2bd512f52c 100644
--- a/lisp/server.el
+++ b/lisp/server.el
@@ -763,6 +763,9 @@ server-running-p
 Emacs process.  To check from a Lisp program whether a server was started
 by the current Emacs process, use the `server-process' variable."
   (unless name (setq name server-name))
+  (if (and (not server-use-tcp)
+	   (not (file-exists-p (expand-file-name name server-socket-dir))))
+      nil
   (condition-case nil
       (if server-use-tcp
 	  (with-temp-buffer
@@ -778,7 +781,7 @@ server-running-p
 	  :name "server-client-test" :family 'local :server nil :noquery t
 	  :service (expand-file-name name server-socket-dir)))
 	t)
-    (file-error nil)))
+    (file-error nil))))
 
 ;;;###autoload
 (define-minor-mode server-mode