-
Notifications
You must be signed in to change notification settings - Fork 17.9k
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/cgo: no console output after invoking a go c-shared dll via Windows Powershell #44876
Comments
@gopherbot add OS-Windows |
/cc @ianlancetaylor |
@nwoodmsft Can you try to reproduce this issue on Go 1.16? |
Investigation results (hi! I own the Windows Console 😄) The go runtime disables handle inheritance for stdin/stdout/stderr on Windows. go/src/syscall/syscall_windows.go Line 468 in 4662029
go/src/syscall/syscall_windows.go Lines 472 to 476 in 4662029
go/src/syscall/exec_windows.go Lines 141 to 143 in 4662029
When the runtime is loaded in a DLL, it immediately disables the inheritance of stdin/stdout/stderr. 😊 |
Thank you so much for taking a look @DHowett ! @alexbrainman It looks like a fix is needed in golang to address this. I did try on 1.16 and the issue was the same. @DHowett Until a fix can be made, is there any workaround we can do after the p/invoke to "repair" a console which is in this state? My current workaround is to execute the PS cmdlet in a new session (i.e. "$result = Powershell.exe -command { Hello-World }" or to execute it as a PS job potentially. |
A harmless workaround would be to P/Invoke SetHandleInformation to restore inheritance to those three handles. 😄 |
Previously we likely twiddled with inheritance because our invocations of CreateProcess were unsafe. I've fixed that for 1.16 already. That means we can safely stop changing stdio handle inheritance. I'll send a CL. |
Thank you for creating this issue. I can reproduce your problem here. I am trying to add new syscall test that fails because of this issue. Unfortunately I don't know much about Powershell. If I put this
into a file, like a.ps1. And then run this command
I get correct output
Unfortunately I had to run this powershell command
I plan to run this test on other people computers. So I won't be able to run Is there any way to run your Powershell script on command line or something? For example, I can run multiple commands there delimited by Alternatively, do you know of a way to reproduce your program with a C program built with Mingw GCC? That would be even better, because this way we don't need to rely on Powershell. Thank you. Alex |
Change https://golang.org/cl/316269 mentions this issue: |
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
Uncertain.
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
I cross-compiled a very simple c-shared dll for Windows with one exported function (HelloWorld). I then invoked the dll from Powershell.
The go code was:
The build command (from linux) used was:
I then copied the resultant .dll to Windows and invoked the HelloWorld() function using the following Powershell script:
What did you expect to see?
I expected the dll's HelloWorld() function to be invoked successfully (causing the text "Hello World" to be written to the console) and then I expected to be able to use my powershell prompt to execute further console commands such as "hostname" or "ipconfig" etc.
What did you see instead?
This is really odd. The HelloWorld() function is indeed executed successfully and I see the text "Hello World" on the console. However, after the function has been invoked, I am no longer able to see any console output from cmd.exe commands in my powershell window. For example, calling "hostname" just returns with no output and the same happens with "ipconfig".
e.g. initially hostname.exe works and provides output, but after executing the cshared dll I am unable to see any further output from hostname..exe on the console:
If I pipe the output of hostname.exe to a file (e.g. "hostname > out.txt") then I can confirm that the output is present and the command is succeeding....so it seems like executing the c-shared dll somehow causes stdout to be redirected or not shown properly?
I tried removing the fmt.Println from the go code to see if that helps, but the issues is still the same. I am also only seeing this with Powershell (if I do the same experiment but invoke the helloworld.dll from python on Windows, I do not see any issue afterwards).
Any ideas?
The text was updated successfully, but these errors were encountered: