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
cmd/go: copy/delete instead of rename existing binaries on windows #21997
Comments
I sent an e-mail to an MS employee about this. Considering backup files, I note that running Emacs' eshell to overwrite a text file (on Windows) creates a backup. |
I don't actually understand what the problem is. In this scenario, the go tool has been asked to create an executable. It is possible that that executable is running which the go tool is also running. This typically happens when using
Your proposal for what we should do instead will not work. We have already tried and failed to remove the executable. It won't help to copy the file first. We could say that using |
I primarily use UNIX based systems, but a quick peer survey returned the conclusion that this behavior was confusing on Windows. From the perspective of a UNIX user, there is no problem because this approximates the behavior of a UNIX system. But Windows is not a UNIX system and doesn't normally allows files associated with a running process to be altered.
It should be the user's responsibility to satisfy the conditions of altering a file on their system. Windows users expect files associated with running processes to be immutable, therefore The community can decide whether this is a compelling issue or not. The goal was to get the data on the issue tracker for those who search for it later. |
OK. But the suggestion of copy/delete does not make sense. It sounds like you are suggesting that if This would essentially reverse https://golang.org/cl/5502054 . CC @alexbrainman . It's worth noting that this change would almost certainly break the special case of |
Yes, that would be the idealistic behavior on a Windows system. Reading the cl gave me some perspective on how long this behavior has been in place, and it does indeed suggest that a change would break things. Perhaps there is a way to inform the user that a file associated with a running process is being moved, at least then the element of surprise is gone. Another odd behavior occurs when the backup file
|
I am not sure I agree that this is ideal. At this moment "go build" and "go install" just silently replaces executable file whether it is running or not - the user does not need to worry if executable is running or not. What you are proposing will make "go build" and "go install" fail occasionally with "executable file is used by another process". People will come here and complain about "go build" is broken sometimes, and we would have to explain the details. I can see that it confuses knowledgeable users like yourself. But I think this is small price to pay - you could always look at the code or ask here.
How do you propose to do that? We don't want warnings that user should not act upon. And these will only happens occasionally - because there is no reliable way to determine if process is exited or not. I also wouldn't be surprised if we would get many triggers from anti-virus software opening executable file during or after its run.
Yes that happens when you are trying to actually run new copy of main.exe while previous main.exe process is still running, and we tried our trick of renaming main.exe into main.exe~ and that failed (so we are out of all options). I think the error message is clear about what has happened. So the user has to terminate previous process before trying to build new executable. I think what we have now is as good as it can be. But if you think you can improve the situation, go ahead and propose you changes. Do not forget, you need to address Ian's comment of:
I suggest you find solution to that problem first. Alex |
Given that the behavior existed for 5+ years and this seems to be the only issue logged against it, I don't think the improvement is worth pursuing. Nobody else seems to have an opinion on it except @forskning either, so it's probably best we just leave things as they are in a working state. |
@as I will close this as "working as expected". But feel free to reopen if you have some new suggestions. Alex |
A surprising behavior on Windows allows executable on disk associated with running processes to be renamed without error. This behavior only occurs for the rename or 'move' operation, and not 'delete' or 'write'.
Currently, go build will move an old binary like
main.exe
out of the way by renaming it tomain.exe~
. However,main.exe
may still be associated with a running process. Windows thinks this is OK, so it allows the rename operation to happen without error.This raises two issues:
1.) It is confusing when I terminate the original process (long after a build is finished), run the associated program again on disk, only to see the program is different in some way, because it has been replaced between executions.
2.) The call to
os.Executable
is wrong after a rename or move operation on Windows. This might be a separate issue, but its worth mentioning, because it may be unfixable. The userspace process environment block is not updated to reflect the change of the rename operation.My request is that
go build
instead copiesmain.exe
->main.exe~
and then attempts to delete the originalmain.exe
. If that operation fails it can then deletemain.exe~
. To my knowledge this is compatible with the current behavior ofgo build
on Windows systems.What version of Go are you using (
go version
)?go version go1.9 windows/amd64
Does this issue reproduce with the latest release?
Yes
What did you do?
One line reproduction for Windows
What did you expect to see?
Copy main.exe -> ~main.exe
Delete main.exe
Resume build
What did you see instead?
Move main.exe -> ~main.exe
Resume build
What operating system and processor architecture are you using (
go env
)?set GOARCH=amd64
set GOBIN=C:\gotools
set GOEXE=.exe
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOOS=windows
set GOPATH=C:\g
set GORACE=
set GOROOT=C:\Go
set GOTOOLDIR=C:\Go\pkg\tool\windows_amd64
set GCCGO=gccgo
set CC=gcc
set GOGCCFLAGS=-m64 -mthreads -fmessage-length=0
set CXX=g++
set CGO_ENABLED=1
set CGO_CFLAGS=-g -O2
set CGO_CPPFLAGS=
set CGO_CXXFLAGS=-g -O2
set CGO_FFLAGS=-g -O2
set CGO_LDFLAGS=-g -O2
set PKG_CONFIG=pkg-config
The text was updated successfully, but these errors were encountered: