What happened?
When I save my monolithic todo.org file (257k) or use undo-tree to undo a change, Emacs often freezes. With other (smaller) Org files, this doesn’t usually happen. I am mentioning both the “save” and the “undo” because the backtraces that I’ve managed to get are identical; the error happens in the undo-list-transfer-to-tree
function. Spamming C-g
during the hang does nothing, but after adding (toggle-debug-on-quit)
to my config, I was able to generate these backtraces (spamming C-g
, pressing it once didn’t immediately trigger the debugger):
Hang on save and undo generate an identical backtrace:
Debugger entered--Lisp error: (quit)
#<subr undo-list-transfer-to-tree>()
apply(#<subr undo-list-transfer-to-tree> nil)
undo-list-transfer-to-tree()
#<subr undo-tree-save-history>(nil overwrite)
apply(#<subr undo-tree-save-history> (nil overwrite))
(prog1 (apply fn args) (message ""))
(let ((inhibit-message t) (save-silently t)) (prog1 (apply fn args) (message "")))
(if init-file-debug (progn (apply fn args)) (let ((inhibit-message t) (save-silently t)) (prog1 (apply fn args) (message ""))))
doom-shut-up-a(#<subr undo-tree-save-history> nil overwrite)
apply(doom-shut-up-a #<subr undo-tree-save-history> (nil overwrite))
undo-tree-save-history(nil overwrite)
undo-tree-save-history-from-hook()
run-hook-with-args-until-success(undo-tree-save-history-from-hook)
basic-save-buffer(nil)
#<subr save-buffer>()
funcall(#<subr save-buffer>)
(let ((apheleia-mode (and apheleia-mode (memq arg '(nil 1))))) (funcall orig-fn))
+format--inhibit-reformat-on-prefix-arg-a(#<subr save-buffer>)
apply(+format--inhibit-reformat-on-prefix-arg-a #<subr save-buffer> nil)
save-buffer()
evil-write(nil nil nil nil nil)
funcall-interactively(evil-write nil nil nil nil nil)
evil-ex-call-command(nil "w" nil)
evil-ex(nil)
funcall-interactively(evil-ex nil)
command-execute(evil-ex)
It’s possible the freeze on undo is related to garbage collection, because I also got this backtrace once:
;; Debugger entered--entering a function:
* undo-tree-post-gc()
garbage-collect()
gcmh-idle-garbage-collect()
apply(gcmh-idle-garbage-collect nil)
timer-event-handler([t 26059 39268 866324 nil gcmh-idle-garbage-collect nil nil 840999 nil])
Values of:
-
gcmh-mode
:t
-
gcmh-low-cons-threshold
:800000
-
gcmh-high-cons-threshold
:33554432
I was able to get a CPU and memory profile during the undo-list-transfer-to-tree
error (starting the profiler right before I tried to reproduce the error, and ending it right after the hang finished).
CPU:
Loading data dump...
Memory:
Loading data dump...
What did you expect to happen?
Org file should save almost instantly. Undo should work almost instantly, or at least not hang.
Steps to reproduce
Saving:
- Start Emacs (new instance)
- Open
todo.org
- Make a change
- Save
:w
Undoing:
- Make change to org file
- Undo the change (
u
)
System information
Loading data dump...