Subject: bug#46972: 28.0.50; [feature/native-comp] Emacs locks itself during native compilation because of permission denied

From: Eli Zaretskii <[email-masked]>
Date: Sun, 14 Mar 2021 12:51:06 +0200

> From: Matt M <[email-masked]>
> Date: Sat, 6 Mar 2021 17:23:34 +0000
> 
> I'm on windows using latest native compilation. I noticed that when doing
> doom sync (I use Doom emacs) it would hang on the native compilation
> step. I looked at the opened emacs processes in the task manager
> during this bug to try to find a file with which I could make the bug
> trigger again. In the task manager I see that about 10 emacs processes
> are stuck on 10 files.
> 
> Using this file: https://pastebin.com/z4wLheXa as
> emacs-async-comp-ox-ascii.el, I call the following command:
> 
> emacs -Q --batch -l c:/Users/Matt/emacs-async-comp-ox-ascii.el
> > Compiling c:/Users/Matt/.emacs.d/.local/straight/build-28.0.50/org-mode/ox-ascii.el...
> 
> It never finishes. If I interrupt the process I get the following
> backtrace:
> 
> Debugger entered--Lisp error: (file-error "Removing old name" "Permission denied" "c:/Users/Matt/.emacs.d/.local/cache/eln/28.0.50-4c...")
>   kill-emacs(t)
>   command-line()
>   normal-top-level()
> 
> Removing old name: Permission denied, c:/Users/Matt/.emacs.d/.local/cache/eln/28.0.50-4c6fa13f/ox-ascii-dcca1ba0-825ea35cp6iXUJ.eln.old
> Debugger entered--Lisp error: (file-error "Removing old name" "Permission denied" "c:/Users/Matt/.emacs.d/.local/cache/eln/28.0.50-4c...")
>   command-error-default-function((file-error "Removing old name" "Permission denied" "c:/Users/Matt/.emacs.d/.local/cache/eln/28.0.50-4c...") "" debug)
>   apply(command-error-default-function ((file-error "Removing old name" "Permission denied" "c:/Users/Matt/.emacs.d/.local/cache/eln/28.0.50-4c...") "" debug))
>   #f(advice-wrapper :after command-error-default-function help-command-error-confusable-suggestions)((file-error "Removing old name" "Permission denied" "c:/Users/Matt/.emacs.d/.local/cache/eln/28.0.50-4c...") "" debug)
> 
> It renamed a file from file.eln to file.eln.old, then tries to delete
> the file.eln.old but gets a Permission denied error.
> 
> If I start the same command again without interrupting, and try to
> delete the file.eln.old manually, I get the error:
> Can't remove file because the file is opened in emacs.exe
> 
> And the only emacs.exe process runnin on the computer is the one doing
> the native compilation, the one which created the file.eln.old.
> 
> So that seems to indicate that the emacs process that renames the file
> doesn't have the permission to remove the same file because of it being
> opened in itself.

I'm trying to understand what's going on in your case, and I'm quite
confused.  Can you help me understand what happens there?

The error message quoted above come from the delete-file call.
However, the only place where we call delete-file in
comp-delete-or-replace-file is here:

         (ignore-errors (delete-file oldfile))

and that ignores any errors.  So how come this still signals an error
in your case?  Likewise, I don't understand how replacing rename-file
with delete-file fixes this problem.

Moreover, I actually don't think these error messages are related to
what really happens during compilation, I think they are related to
the fact that you "interrupted the process" (how did you do that,
btw?).  Because the backtrace shows you invoked kill-emacs
interactively, and that triggered the error.  When Emacs exits, it
attempts to clean up *.eln.old files left behind.

Can you show the list of .eln.old files in the relevant directories
that are left when the compilation is stuck?  And also, can you try
figuring out whether any of those .eln.old files are open in any of
the running Emacs processes?  One way of finding this out is by using
the Process Explorer from SysInternals: it can show all the files that
a given process has open.

Andrea, it looks like the inner loop in eln_load_path_final_clean_up
isn't protected against errors?  IOW, if Fdelete_file signals an
error, it won't be caught, is that right?