A Trick to Troubleshoot Emacs Subprocess Creating

There are many packages of Emacs that leverage subprocesses to do their jobs, Magit, eglot, elpy, to name a few. And there are times that a subprocess doesn't work as expected, for example, Magit is slow, and you're sure that it's ok when running git commands on shell. So how to spot these problems effectively and quickly?

The problem is that we don't know what's going on exactly, so here I want to share a few Elisp advices to make the subprocess creating visible, and print the exact program and its arguments to the *Message* buffer. Visibility is the key.

(defvar trace-subprocess-p nil
  "Whether to trace subprocess creating or not.")

(defun my-toggle-trace-subprocess ()
  "Toggle whether to trace subprocess creating."
  (setq trace-subprocess-p (not trace-subprocess-p))
  (when trace-subprocess-p
    (message "Trace subprocess creating.")))

(defun my-quote-argument (arg)
  "Double quote ARG."
  (concat "\"" arg "\""))

(define-advice start-process (:before (name buffer program &rest program-args) trace)
  (when trace-subprocess-p
    (message "Trace start-process: name: %s, buffer: %s, program and args: %s %s"
             name buffer program
             (mapconcat #'my-quote-argument program-args " "))))

(define-advice shell-command-to-string (:before (command) trace)
  (when trace-subprocess-p
    (message "Trace shell-command-to-string: %s" command)))

(define-advice call-process (:before (program &optional infile destination display &rest args) trace)
  (when trace-subprocess-p
    (message "Trace call-process: %s %s"
             (mapconcat #'my-quote-argument args " "))))

Add these to your .emacs.d and type M-x my-toggle-trace-subprocess RET when you want to see what is going on under the neath. The following is how it looks like when I run M-x elpy-mode on a Python buffer:

Trace start-process: name:  *elpy-rpc [project:~/python/qtile/ environment:/home/whatacold/virtualenv/elpy]*, buffer:  *elpy-rpc [project:~/python/qtile/ environment:/home/whatacold/virtualenv/elpy]*, program and args: /home/whatacold/.emacs.d/elpy/rpc-venv/bin/python "-W" "ignore" "-m" "elpy.__main__"

With the help of these advice, I successfully resolved a performance issue of Magit with a particular repo the other day, which was caused by magit-svn hooks.

See also

comments powered by Disqus