4

Sometimes emacsclient fails with an error like:

$ emacsclient .gitlab-ci.yml
Waiting for Emacs...
*ERROR*: Args out of range: 63695, 1, 1173

How can I debug this? emacsclient has no debug option, no backtrace is shown, and nothing is logged in the *Messages* buffer. Running the daemon with --debug-init does not help.

strace shows what the client sends the server over the socket, so if there is a bug, it is probably on the server side:

$ strace --trace=sendto,recvfrom -s 100 emacsclient ../.gitlab-ci.yml
sendto(3, "-dir /home/sam/Downloads/emacs/lisp/ -current-frame -file ../.gitlab-ci.yml \n", 77, 0, NULL, 0) = 77
Waiting for Emacs...
recvfrom(3, "-emacs-pid 33810\n-error Args&_out&_of&_range:&_116433,&_1,&_1173", 8192, 0, NULL, NULL) = 64

*ERROR*: Args out of range: 116433, 1, 1173
+++ exited with 1 +++

I ran the daemon in GDB with breakpoints on xsignal0, xsignal1, xsignal2, and xsignal3. Then when I invoke the emacsclient, I get:

(gdb) bt
#0  0x00000000004248da in xsignal3 ()
#1  0x0000000000423bc4 in args_out_of_range_3 ()
#2  0x0000000000597ade in Fline_number_at_pos ()
#3  0x0000000000590b6b in Ffuncall ()
#4  0x00000000005cc740 in exec_byte_code ()
#5  0x0000000000593480 in funcall_lambda ()
#6  0x0000000000590a97 in Ffuncall ()
#7  0x00000000005cc740 in exec_byte_code ()
#8  0x0000000000593480 in funcall_lambda ()
#9  0x0000000000590a97 in Ffuncall ()
#10 0x0000000000590b79 in funcall_nil ()
#11 0x000000000059026d in run_hook_with_args ()
#12 0x0000000000590378 in run_hook ()
...snip...
#40 0x0000000000429f56 in main ()

see full stack

The problem is that I am invoking emacsclient from inside *ansi-term* inside emacs. For some reason, the emacs server tries to use the position in the *ansi-term* buffer (63695) in the input file (only 1173 bytes).

This can be fixed by running:

$ emacsclient --eval '(find-file ".gitlab-ci.yml")'

but find-file doesn't wait for the file to be closed, so I still want to find out the root of the problem.

It appears (from the stacktrace) some hook, perhaps 'server-after-make-frame-hook, is causing the faulty behavior. But Emacs in my distro is not compiled with debug symbols, so I can't poke around in that frame easily. Is there an elisp way of seeing what functions are bound to a hook?

The problem seems to go away when I disable (indent-guide-global-mode), but I'm not sure why.

7
  • I can't tell from the backtrace who calls line-number-at-pos and with what arguments. Is there some more info that you haven't shown? Also, have you tried starting your emacs with -Q and seeing if the problem is still there?
    – NickD
    Dec 2, 2022 at 19:59
  • I updated the question to show more of the backtrace and say that -Q makes the buggy behavior go away. Dec 2, 2022 at 20:32
  • Thanks! The backtrace is not very useful as it stands: you might want to compile an unoptimized emacs with symbols and also use the uncompiled versions of the lisp files (although there is always the possibility that that alone will hide the problem). But if -Q gets rid of the bug, then probably the best thing you can do is bisect your init file to find out what exactly is causing the problem.
    – NickD
    Dec 2, 2022 at 20:47
  • The reported position (63695) in the error message of emacsclient is different from the number in the strace output (116433), presumably because these came from two different runs - correct?
    – NickD
    Dec 2, 2022 at 21:13
  • Yes, the cursor in *ansi-term* changed since then, but the file is still 1173 bytes long. Dec 2, 2022 at 21:23

1 Answer 1

3

Sadly that could be a lot of things.

I think you will need to run the emacs inside of gdb

  1. Run gdb --args emacs -nw, then start the server in that emacs.

    a. Alternatively, start the server normally, pgrep emacs | xargs ps fp | grep "emacs ". Note the space in the last grep command identifies the emacs server as opposed to the emacsclient. Then run sudo gdb -ex 'attach $PID' where $PID is the server's process ID.

  2. Set a breakpoint on the xsignal-functions: type break xsignal0, break xsignal1, break xsignal2, break xsignal3.

  3. Type c or continue

  4. Do whatever invocation causes you to hit an error.

  5. Switch back to gdb and type bt or backtrace. This shows the place in C code where the emacs server broke.

The emacs server/client protocol is implemented in emacs/lisp/server.el and emacs/lib-src/emacsclient.c. When emacsclient asks the emacs server to open $FILE, it will send -file $FILE. You can view the protocol trace by running:

$ strace -s 500 --trace=sendto,recvfrom emacsclient $FILE

The backtrace explains what went wrong, while the protocol trace explains how the server got there. With these in hand, you can begin to debug emacsclient.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.