Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

regression: ArArchiveBuilder can no longer handle output to temporary files managed by Python #131896

Open
amyspark opened this issue Oct 18, 2024 · 8 comments
Labels
C-discussion Category: Discussion or questions that doesn't represent real issues.

Comments

@amyspark
Copy link
Contributor

amyspark commented Oct 18, 2024

Code

I tried this code:

x = ['rustc.EXE', '--print=native-static-libs', '--target', 'x86_64-pc-windows-msvc', '--crate-type', 'staticlib', 'nul', '-o']                                                                    
from tempfile import TemporaryFile()
y = TemporaryFile()  
x += [y.name]
import subprocess 
subprocess.run(x, check=True, text=True)

I expected to see this happen:

note: Link against the following native artifacts when linking against this static library. The order and any duplication can be significant on some platforms.

note: native-static-libs: kernel32.lib advapi32.lib ntdll.lib userenv.lib ws2_32.lib dbghelp.lib /defaultlib:msvcrt

Instead, this happened:

error: failed to build archive at `C:\Users\Amalia\AppData\Local\Temp\tmpk51p4sru`: failed to rename archive file: Acceso denegado. (os error 5)

error: aborting due to 1 previous error

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Program Files\Python310\lib\subprocess.py", line 524, in run
    raise CalledProcessError(retcode, process.args,
subprocess.CalledProcessError: Command '['rustc.EXE', '--print=native-static-libs', '--target', 'x86_64-pc-windows-msvc', '--crate-type', 'staticlib', 'nul', '-o', 'C:\\Users\\Amalia\\AppData\\Local\\Temp\\tmpk51p4sru']' returned non-zero exit status 1.

This breaks librsvg building on MSVC, because I use this technique to query the native-static-libs for the Meson dependency setup.

I traced the issue to the following pull request: #122723

Version it worked on

It most recently worked on: 1.77.2

Version with regression

rustc --version --verbose:

rustc 1.82.0 (f6e511eec 2024-10-15)
binary: rustc
commit-hash: f6e511eec7342f59a25f7c0534f1dbea00d01b14
commit-date: 2024-10-15
host: x86_64-pc-windows-msvc
release: 1.82.0
LLVM version: 19.1.1

Backtrace

N/A

@rustbot modify labels: +regression-from-stable-to-stable -regression-untriaged
cc @sdroege @nirbheek @federicomenaquintero

@amyspark amyspark added C-bug Category: This is a bug. regression-untriaged Untriaged performance or correctness regression. labels Oct 18, 2024
@rustbot rustbot added I-prioritize Issue: Indicates that prioritization has been requested for this issue. needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. regression-from-stable-to-stable Performance or correctness regression from one stable version to another. and removed regression-untriaged Untriaged performance or correctness regression. labels Oct 18, 2024
@workingjubilee
Copy link
Member

@amyspark #12272 was opened in 2014, are you sure?

@ChrisDenton
Copy link
Member

Might have meant #122723

@amyspark
Copy link
Contributor Author

My bad, copy-pasted monched one character. #122723 is the one.

@ChrisDenton
Copy link
Member

ChrisDenton commented Oct 18, 2024

My suggestion would be to essentially revert it for Windows only (i.e. use archive_tmpfile.persist). The reasoning for that PR is UNIX specific. We could duplicate some of the tempfile Windows-specific code instead but that seems redundant.

cc @bjorn3

@bjorn3
Copy link
Member

bjorn3 commented Oct 18, 2024

Why is the temporary directory created in %LocalAppData%\Temp in the first place? We are specifying the output directory as the directory to place the temporary directory in, precisely to avoid cross-filesystem renames. It needs to be a rename rather than a copy either way to prevent another rustc instance from observing a partially written file.

@amyspark
Copy link
Contributor Author

@bjorn3 did you mean my snippet? Python's tempfile uses whatever folder has been specified in the TEMP environment variable. For instance, had I run it in our (GStreamer's) Cerbero repository, because we use the MSYS2 shell, it'd have been created in <install folder of MSYS2>\tmp.

The issue here is that you can rename open files in Linux (I think it's because you can always keep references to a deleted inode), whereas this is not possible on Windows, at least with Python's way of opening the handle. This did not happen previously because the file can still be written to.

@the8472
Copy link
Member

the8472 commented Oct 19, 2024

Python's tempfile uses whatever folder has been specified in the TEMP environment variable.

It has an optional Dir argument: https://docs.python.org/3/library/tempfile.html#tempfile.TemporaryFile

@bjorn3
Copy link
Member

bjorn3 commented Oct 19, 2024

I missed your python snippet. I assumed what happened was: You tell rustc to output somewhere on a filesystem other than C:. Rustc decides to create a temporary directory in C: and then fails to do a cross-filesystem rename, in which case the step where rustc decides to create a temporary directory in C: shouldn't happen. I now see that the issue is with the output file you specified currently being open by another process, which on Windows would require either renaming the existing file before renaming the temp file to the specified output path or overwriting the existing output file. Before my PR the latter was presumably done. This is not correct behavior however as it would make it possible for other rustc invocations to accidentally see partially written output, which can cause corruption of their output or crashes. As such renaming the old file on windows or declaring that the python snippet you wrote should not work (and you need to either close the temp file first without deleting it before calling rustc or open it with the flag that allows deletion while it is still open) are the only acceptable options I think.

gnomesysadmins pushed a commit to GNOME/librsvg that referenced this issue Oct 19, 2024
Starting with rust 1.82 the internal rustc call fails with:

failed to rename archive file: Access is denied. (os error 5)

For some reason rust doesn't like Python having the file open while
it tries to write to it (or replace it). See upstream issue:
rust-lang/rust#131896

Work around by creating a temporary file and closing the handle before
calling into rust, and deleting the file at the end.

This could also be done with NamedTemporaryFile() by passing
delete_on_close=False to it and using it as a context manager,
but that only works since Python 3.12.

Fixes #1134
gnomesysadmins pushed a commit to GNOME/librsvg that referenced this issue Oct 19, 2024
It's failing due to rust-lang/rust#131896 -
we can either pin a rustc version or wait until this issue is fixed; I
hope upstream will give it a high priority.

Part-of: <https://gitlab.gnome.org/GNOME/librsvg/-/merge_requests/1039>
gnomesysadmins pushed a commit to GNOME/librsvg that referenced this issue Oct 20, 2024
Starting with rust 1.82 the internal rustc call fails with:

failed to rename archive file: Access is denied. (os error 5)

For some reason rust doesn't like Python having the file open while
it tries to write to it (or replace it). See upstream issue:
rust-lang/rust#131896

Work around by creating a temporary file and closing the handle before
calling into rust, and deleting the file at the end.

This could also be done with NamedTemporaryFile() by passing
delete_on_close=False to it and using it as a context manager,
but that only works since Python 3.12.

Fixes #1134

Part-of: <https://gitlab.gnome.org/GNOME/librsvg/-/merge_requests/1040>
@jieyouxu jieyouxu added C-discussion Category: Discussion or questions that doesn't represent real issues. and removed regression-from-stable-to-stable Performance or correctness regression from one stable version to another. C-bug Category: This is a bug. I-prioritize Issue: Indicates that prioritization has been requested for this issue. needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels Nov 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-discussion Category: Discussion or questions that doesn't represent real issues.
Projects
None yet
Development

No branches or pull requests

7 participants