Subject: bug#60996: 29.0.60; Native compile fails to remove temp file for trampoline

From: Andy Moreton <[email-masked]>
Date: Tue, 24 Jan 2023 01:18:01 +0000

On Mon 23 Jan 2023, Eli Zaretskii wrote:

>> From: Andy Moreton <[email-masked]>
>> Date: Mon, 23 Jan 2023 02:30:43 +0000
>> 
>> >From more expermenting with a debug build in gdb, it seem to be related
>> to this code in native-elisp-load:
>> 
>>       /* If in this session there was ever a file loaded with this
>> 	 name, rename it before loading, to make sure we always get a
>> 	 new handle!  */
>>       Lisp_Object tmp_filename =
>> 	Fmake_temp_file_internal (filename, Qnil, build_string (".eln.tmp"),
>> 				  Qnil);
>>       if (NILP (Ffile_writable_p (tmp_filename)))
>> 	comp_u->handle = dynlib_open_for_eln (SSDATA (encoded_filename));
>>       else
>> 	{
>> 	  Frename_file (filename, tmp_filename, Qt);
>> 	  comp_u->handle = dynlib_open_for_eln (SSDATA (ENCODE_FILE (tmp_filename)));
>> 	  Frename_file (tmp_filename, filename, Qnil);
>> 	}
>> 
>> The renaming results in the ".eln.tmp" suffixed name having an open
>> handle. That handle is still open when other code tries to delete
>> the renamed ".eln" file, which fails.
>
> The question is: why is that .eln.tmp file still open when we are
> trying to delete it?  I hoped we'd be able to establish that, so that
> we could decide what to do about it.  But I don't yet see the
> information which would explain why the file is still open.

The file handle is returned from dynlib_open_for_eln (which came from a
LoadLibrary call in dylib_open). More below.

> Do these *.eln.tmp file remain in %TEMP% after Emacs startup?  If they
> remain there, then what happens if you exit Emacs and restart it? do
> these files remain there or are they deleted?  IOW, if we just ignore
> these errors (e.g., by ignore-error), would the problem be fixed, or
> will there be left-overs?

The ".eln.tmp" suffixed files are only renamed temporarily, and the files
only fleetingly have that name. The ".eln" suffixed file names persist
after the failed delete, so will accumulate unless removed manually.

>> The attached .csv file shows filesystem activity captured by Process
>> Monitor for the relevant "...\comp-lambda-*" temp files during emacs
>> startup. (It may be easier to read if imported into a spreadsheet).
>
> Maybe I don't understand how to read this, but I cannot find any
> traces for the failed deletion of a .eln.tmp file.  The only failure
> to delete is this:
>
>> "14:15:24.8773402","emacs.exe","6452","SetDispositionInformationEx","C:\Users\ajm\AppData\Local\Temp\comp-lambda-SGvFx7.eln","CANNOT
>> DELETE","Flags: FILE_DISPOSITION_DELETE, FILE_DISPOSITION_POSIX_SEMANTICS,
>> FILE_DISPOSITION_FORCE_IMAGE_SECTION_CHECK"

That line is the failed delete-file (for "comp-lambda-SGvFx7.eln") at the
end of comp--native-compile.

>From the Microsoft kernel docs at:
https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntddk/ns-ntddk-_file_disposition_information_ex

  "A return value of STATUS_CANNOT_DELETE indicates that either the file
  is read-only, or there is an existing mapped view to the file."

The earlier lines in the trace with CreateFileMapping and Load Image for
"comp-lambda-SGvFx7.eln" to suggest that existing mapping created from
dynlib_open (by LoadLibrary) may be the problem.

>> Any idea when those changes were committed, and which changesets ? IT
>> doesn't apper obvios from the commit history.
>
> See commit 1a8015b837.  Maybe also commit 5fec9182db.

Thanks for the additional details.

   AndyM