-
Notifications
You must be signed in to change notification settings - Fork 39
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
Handle Ctrl+C interupts for Mingw Executables #31
Conversation
Could you squash the last commit into the one wit the incorrect merge conflict resolution? Also, could you download https://github.com/msys2/msys2-runtime/suites/2262965199/artifacts/47141681 and verify that it does, indeed, fix the Ctrl+C problem? |
84e3564
to
f867abc
Compare
Could you help me on how to install it? |
I think I have to cherry-pick from git-for-windows/msys2-runtime@25c4c01 also |
f867abc
to
1fd1ca2
Compare
Yes. You could simply extract this over an existing MSYS2 installation, but all you really want is to replace the
Yes, this is crucial to be able to interrupt processes running in a different CPU architecture than the MSYS2 runtime itself. BTW I think 2153eb0 is not needed: it tries to export a function that is no longer an exported function, but an inline function instead. About 42f68af... I dropped it from Git for Windows. The rationale is that the processes that are getting interrupted need to make sure themselves that their child processes are reaped, too. |
It looks like it is working for me. I did a new install from tar archive and pasted the contents of the zip file on that and opened the $ python -c "import time;time.sleep(40)"
Traceback (most recent call last):
File "<string>", line 1, in <module>
KeyboardInterrupt I will look into your comments and change things soon. |
|
1fd1ca2
to
002db58
Compare
Also, it works. But randomly triggers AntiVirus saying it does something malicious and deletes |
Well, the code does inject a remote thread... So I can see why anti-malware would be triggered, even if it is wrong. And I have no idea why Git for Windows does not trigger this... I have no insight into how these anti-malware programs work. |
That shouldn't be a problem for me because I have excluded it from scanning the Msys2 directory. |
Hey, but here's an idea: we already use those What do you think, @naveen521kk? |
Should be better. |
I think that is just a bug if anti-malware quarantines But with the injected remote thread, I think anti-malware is "less wrong"... So in my mind, if we do it right, and if anti-malware is not overly overzealous, it should be enough to exclude those two helpers (or alternatively, hope that anti-malware developers will analyze the helpers, verify that they are mostly harmless, and add patterns that match those use cases specifically to avoid triggering on them). |
Don't know, it was just once after that it didn't do anything there.
Right. If they analyze |
I will try to work on that tomorrow. |
Looks like my knowledge with C and win32 API is so poor to do this. I think I won't be able to do it, sorry. |
e3eb220
to
92f5113
Compare
I was able to confirm by compiling the source of test CtrlRoutine 0 2440 where Traceback (most recent call last):
File "<string>", line 1, in <module>
KeyboardInterrupt which shows that it works. |
92f5113
to
7ae17f7
Compare
Here I pushed again, I think it should work? |
935ecea
to
336d4c7
Compare
Yes finally, this works 🎉 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks pretty good already!
Eventually, I would love to break this change apart and fold it into the earlier commits (feel free to mark yourself as co-author via the Co-authored-by:
footer) because that will make it easier to maintain the MSYS2-specific patches on top of Cygwin.
The idea is that we handle Ctrl+C not by terminating the processes (which would reflect `kill -KILL`, not `kill -INT`) but by imitating what Windows does in a CMD window: we inject a remote thread that runs the `CtrlRoutine` function. This lets the `atexit()` handlers and the ConsoleCtrlEvent handlers do their job. This commit brings the goodness from msys2/msys2-runtime#31 over into MSYS2-packages, which cherry-picked and edited the patches from Git for Windows. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
@naveen521kk congratulations, and let me say this: I am very impressed how you kept working on this for three months, with a really nice end result. Thank you! |
Thank you for reviewing. This helped me to learn C and about Win32 APIs; without you, this will not be possible :). |
on arm, running mintty, running clangarm64 python, hitting ctrl-c kills python (after a significant delay). from windows terminal ctrl-c shows KeyboardInterrupt as expected. this seems to be expected behavior for lack of arm binaries for the libexec binaries |
question: doesn't cygwin provide |
Does this work on win7? I could only get python to get a keyboard interrupt if run through winpty. Otherwise, sometimes python would die, but leave things in a very broken state that never got back to bash. It appears getprocaddress32 (or 64) hangs around in taskmgr for many seconds, and then both it and python die. The only reason I tried win7 was to make sure my proposed change to detect arm processes wouldn't blow up there, but I'm seeing the same behavior with that as with the version currently in staging On Windows 10 I get keyboard interrupt AND python exits when attempting to interrupt EDIT: I'm sometimes seeing the 'broken' behavior on Win10 too... It appears the 'forked' bash process that supposedly 'execed' python is hanging around. Killing it returns to the shell. |
Hmm, I tried to install this version from Pacman(staging repo) today, and I found it wasn't working, there was a long hang and nothing worked, I had to close the Window. I tried the same It was working previously and also works on a fresh installation but not on my old one, and that looked weird. So, to debug I downloaded Process Monitor and started to check whether
When starting Next up, this one
Again, a large PID but different from the previous one. As expected I wondering why this happens that too only in the main installation. |
Hmm, the same number comes up
Next, I tried placing the build from this PR on the tree and now it still hangs but the numbers changed and I think something is going wrong
Even on second time it was same number. |
That is really strange. I thought maybe the |
| PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, | ||
FALSE, pids[i]); | ||
if (!process) | ||
process = OpenProcess (PROCESS_TERMINATE, FALSE, pids[i]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should probably have PROCESS_QUERY_LIMITED_INFORMATION
here too, to be able to query PID and exit code. Assuming nobody here cares about anything older than Vista, on XP you need PROCESS_QUERY_INFORMATION
.
Seems related, I was also testing on win7. Though in my case |
Hmm, I just downloaded https://github.com/msys2/msys2-installer/releases/download/nightly-x86_64/msys2-base-x86_64-latest.tar.xz extracted it added the Pacman staging repo and updated runtime. There it is worked perfectly $ /h/mingw/test_programs/likefinal/pip.exe
start
Traceback (most recent call last):
File "H:\mingw\test_programs\likefinal\pip-script.py", line 34, in <module>
time.sleep(4000)
KeyboardInterrupt So, I think it isn't a problem with code here. |
That doesn't make any sense, msys2-runtime is/should be self-contained |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Going through this code looking for something that could be causing issues...
size_t len = wcslen (wbuf) + wcslen (function_name) + 3 /* exit code */ | ||
+ 1 /* space */ + 10 /* process ID, i.e. DWORD */ + 1 /* NUL */; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is missing 2 spaces (space between wbuf
and function_name
, and space between function_name
and exit_code
. Also, is it safe to assume exit_code
will always only be 3 digits? It seems so because the callers use exit_code & 0x7f
, or else CTRL_C_EVENT
/CTRL_BREAK_EVENT
which are 0 or 1 resp.
PROCESSENTRY32 entry; | ||
DWORD pids[16384]; | ||
int max_len = sizeof (pids) / sizeof (*pids), i, len, ret = 0; | ||
pid_t pid = GetProcessId (main_process); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this pid_t
and not DWORD
? This is a Windows PID, not a cygwin PID.
pid_t pid = GetProcessId (main_process); | ||
int signo = exit_code & 0x7f; | ||
|
||
pids[0] = (DWORD)pid; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then this cast would be unnecessary
if (orig_len == len || len >= max_len) | ||
break; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CloseHandle(snapshot);
?
I guess now that this is merged I should make my own pull request instead of review comments suggesting code 😁 |
From my post-merge review at msys2#31 (review)
kill_via_console_helper: use %u instead of %ld for DWORD. It appears that cygwin's swprintf is acting like LP64 instead of Windows LLP64, and expecting a 64-bit long. DWORDs are 32-bit unsigned. Minor fixes for Ctrl-C handling code. From my post-merge review at msys2#31 (review)
kill_via_console_helper: use %u instead of %ld for DWORD. It appears that cygwin's swprintf is acting like LP64 instead of Windows LLP64, and expecting a 64-bit long. DWORDs are 32-bit unsigned. Add check to avoid closing the handle from the input paramter. It may well be that the caller still intends to use it. Minor fixes for Ctrl-C handling code. From my post-merge review at msys2#31 (review)
kill_via_console_helper: use %u instead of %ld for DWORD. It appears that cygwin's swprintf is acting like LP64 instead of Windows LLP64, and expecting a 64-bit long. DWORDs are 32-bit unsigned. Add check to avoid closing the handle from the input paramter. It may well be that the caller still intends to use it. Minor fixes for Ctrl-C handling code. From my post-merge review at #31 (review)
kill_via_console_helper: use %u instead of %ld for DWORD. It appears that cygwin's swprintf is acting like LP64 instead of Windows LLP64, and expecting a 64-bit long. DWORDs are 32-bit unsigned. Add check to avoid closing the handle from the input paramter. It may well be that the caller still intends to use it. Minor fixes for Ctrl-C handling code. From my post-merge review at #31 (review)
kill_via_console_helper: use %u instead of %ld for DWORD. It appears that cygwin's swprintf is acting like LP64 instead of Windows LLP64, and expecting a 64-bit long. DWORDs are 32-bit unsigned. Add check to avoid closing the handle from the input paramter. It may well be that the caller still intends to use it. Minor fixes for Ctrl-C handling code. From my post-merge review at #31 (review)
kill_via_console_helper: use %u instead of %ld for DWORD. It appears that cygwin's swprintf is acting like LP64 instead of Windows LLP64, and expecting a 64-bit long. DWORDs are 32-bit unsigned. Add check to avoid closing the handle from the input paramter. It may well be that the caller still intends to use it. Minor fixes for Ctrl-C handling code. From my post-merge review at #31 (review)
kill_via_console_helper: use %u instead of %ld for DWORD. It appears that cygwin's swprintf is acting like LP64 instead of Windows LLP64, and expecting a 64-bit long. DWORDs are 32-bit unsigned. Add check to avoid closing the handle from the input paramter. It may well be that the caller still intends to use it. Minor fixes for Ctrl-C handling code. From my post-merge review at #31 (review)
cherry-picked from
cc @dscho
there were conflicts while picking tried my best to fix them say if they were wrong 😉
Fixes #29