classification
Title: Ctrl-C will exit out of Python interpreter in Windows
Type: behavior Stage: resolved
Components: Interpreter Core, Macintosh, Windows Versions: Python 3.3, Python 3.2, Python 2.7
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: tim.golden Nosy List: Devin Jeanpierre, Dude-X, amaury.forgeotdarc, brian.curtin, christian.heimes, jcea, kristjan.jonsson, loewis, mhammond, pitrou, python-dev, r.david.murray, ronaldoussoren, santoso.wijaya, tim.golden
Priority: normal Keywords: patch

Created on 2007-12-21 06:16 by Dude-X, last changed 2012-07-03 11:21 by jcea. This issue is now closed.

Files
File name Uploaded Description Edit
issue1677-python27.patch tim.golden, 2012-06-28 09:31 Patch of myreadline.c against 2.7 branch review
issue1677-python3x.patch tim.golden, 2012-06-28 17:10 Patch of myreadline.c against default branch review
issue1677-python32.patch tim.golden, 2012-06-29 15:15 Patch of myreadline.c against 3.2 branch review
Messages (34)
msg58933 - (view) Author: Isaul Vargas (Dude-X) Date: 2007-12-21 06:16
When running Python 2.5.1 stable in Windows, you can press Ctrl-C as 
many times as you want and it will always output Keyboard Interrupt in 
the interpreter.
Python 3.0a+ will quit if you press ctrl-c too many times. The last 
release of 3.0a2 can handle many interrupts before quitting, but the 
latest snapshot (Dec 20th) can not.

Steps to reproduce:
Run python.exe
hold down ctrl-c, or press it many times. It will quit the interpreter 
eventually.
msg58939 - (view) Author: Christian Heimes (christian.heimes) * (Python committer) Date: 2007-12-21 09:44
I don't think it's a critical bug but it may be worth to debug it.
msg58940 - (view) Author: Amaury Forgeot d'Arc (amaury.forgeotdarc) * (Python committer) Date: 2007-12-21 09:57
I get the same behaviour with python 2.5.1, and even 2.4.4 (on Windows
2000): I hold down Ctrl-C, and after ~30 "KeyboardInterrupt", the
interpreter stops.

So this is not 3.0 specific. What is new in python3.0 is that file
objects are implemented in python, and are much slower.
It is possible that when the key buffer is full, the next Ctrl-C kills
the program. And this is more likely to happen with python3.0.
msg58975 - (view) Author: Isaul Vargas (Dude-X) Date: 2007-12-23 21:03
I wanted to add that this issue also affects python 2.5.1 on the Mac.
Sometimes I may be writing something in the interpreter and I decide to 
invalidate my input by pressing Ctrl-C. This will exit the interpreter 
occasionally. I think it would be a good idea to see if there's a way 
to make the interpreter bullet proof from Ctrl-C, or at least good 
enough so that a single Ctrl-c won't cause the interpreter to exit.
msg89651 - (view) Author: Amaury Forgeot d'Arc (amaury.forgeotdarc) * (Python committer) Date: 2009-06-23 23:33
Removing the Windows part: on my machine, repeated Ctrl-C's don't exit the 
3.1 interpreter, probably because the io module is now written in C.
msg89655 - (view) Author: Ronald Oussoren (ronaldoussoren) * (Python committer) Date: 2009-06-24 05:41
I cannot reproduce this on my machine (running OSX) using 2.5, 2.6 and 3.1  
(latest rc).
msg104643 - (view) Author: Ronald Oussoren (ronaldoussoren) * (Python committer) Date: 2010-04-30 15:03
Unassigning this issue from myself as I cannot reproduce the issue on OSX.
msg115133 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2010-08-27 21:39
I can't reproduce this on windows (in a KVM) with 2.6 or 2.7.
msg115139 - (view) Author: Isaul Vargas (Dude-X) Date: 2010-08-27 22:58
I tested this on a real Windows 7 machine (64 bit, Ultimate)
I open the command prompt, and I have the latest Pythons installed,
Python 2.6.6, Python 2.7 final, and Python 3.1.2
If I hold down Ctrl-C, it will eventually exit the interpreter.
Though it's not normal to hold down Ctrl-C, in practice that means pressing Ctrl-C
to cancel a currently running script may just exit the interpreter.
Python 3.1 seems really terrible in this regard where sometimes a single Ctrl-C will exit the interpreter.

I have seen this issue fixed in Python 2.5.2 on Windows. It would never exit the interpreter no matter how long I pressed Ctrl-C. I don't see this issue in Linux. I don't have a Mac to test, but I'd like Mac users to test the signal handling in their terminals.
msg115155 - (view) Author: Brian Curtin (brian.curtin) * (Python committer) Date: 2010-08-28 14:38
I'm not able to reproduce this. Do you have anything installed like pyreadline?
msg131632 - (view) Author: Devin Jeanpierre (Devin Jeanpierre) Date: 2011-03-21 11:07
Windows 7 64-bit (on the metal, not in a VM), can confirm. Holding down Ctrl+C will (eventually) halt Python on all the versions I have installed: 2.3, 2.7, 3.0, 3.1, 3.2. (All of these are 32-bit Pythons). Haven't done anything silly like try to install readline on Windows.

I also tried it on cygwin Python (2.6), held down for maybe 20 seconds, didn't crash.
msg164064 - (view) Author: Devin Jeanpierre (Devin Jeanpierre) Date: 2012-06-26 11:17
For extra clarification, this issue can crop up with even a single press of ctrl-c. It's not really related to multiple presses, except that pressing it more increases the odds of it happening.
msg164065 - (view) Author: Christian Heimes (christian.heimes) * (Python committer) Date: 2012-06-26 11:26
Could add a printf() to PC/launcher.c:ctrl_c_handler() to test if the handler is called in the error case?
msg164133 - (view) Author: Tim Golden (tim.golden) * (Python committer) Date: 2012-06-27 09:33
Just to confirm: I can reproduce this more or less consistently on all versions of Python 2.2 -> 3.2 on Windows 7. Those are distribution builds -- ie not debug builds I've made myself. But it certainly does occur on a debug build of 2.7.

I'm trying to narrow it down through some instrumentation (read: printf) on the 2.7 branch. The MSDN page for signal warns that a separate thread will be created for the signal handler which will muddy the waters.
msg164150 - (view) Author: Tim Golden (tim.golden) * (Python committer) Date: 2012-06-27 13:04
OK, I've run out of time to look, but the culprit looks like it's an odd interaction between my_fgets in myreadline.c and the interrupt handler in signal. There's a section of code which is conditional on ERROR_OPERATION_ABORTED being returned from fgets in the CRT. 

That then tries to play ball with a the interrupt handler having fired already (in a separate thread) by sleeping for one second and checking that the handler was tripped. If it has then the function returns one and stuff happens elsewhere; it it hasn't then the function behaves as if EOF (ie Ctrl-Z) was pressed and Python exits.

That's as far as I've got; it looks like a race condition of some sort but I can't see where. I'm not 100% sure that the SIGINT handler is tripping.
msg164152 - (view) Author: Amaury Forgeot d'Arc (amaury.forgeotdarc) * (Python committer) Date: 2012-06-27 13:30
Great analysis!

> ... by sleeping for one second ...
Note that Sleep(1) only sleeps for 1 millisecond.
Does the issue go away if you replace with Sleep(10)?
msg164154 - (view) Author: Tim Golden (tim.golden) * (Python committer) Date: 2012-06-27 13:31
That'll be my next move when I get some more time.
I've got someone coming over to see me (about real work!)
msg164187 - (view) Author: Tim Golden (tim.golden) * (Python committer) Date: 2012-06-27 18:47
OK, it is a race condition between the code in myreadline.c and the 
signal_handler in signalmodule.c. It can take between 0 and 3 sleeps for 
the myreadline code to see the signal tripped. Patch on its way for 2.7; 
VS 2010 downloading so that 3.x patch can be tested.
msg164233 - (view) Author: Tim Golden (tim.golden) * (Python committer) Date: 2012-06-28 09:31
Attached is a patch against Python 2.7. It checks in a loop for SIGINT and, if it still hasn't fired, assumed Ctrl-Z was pressed which generates the same error.
msg164243 - (view) Author: Kristján Valur Jónsson (kristjan.jonsson) * (Python committer) Date: 2012-06-28 11:10
Shouldn't we be using a proper synchronization primitive?  What about waiting for an event?
msg164244 - (view) Author: Kristján Valur Jónsson (kristjan.jonsson) * (Python committer) Date: 2012-06-28 11:15
In fact, there is _PyOS_SigintEvent at the end of signalmodule.c
msg164246 - (view) Author: Amaury Forgeot d'Arc (amaury.forgeotdarc) * (Python committer) Date: 2012-06-28 11:33
Is the ERROR_OPERATION_ABORTED set when Ctrl-Z is hit?
msg164250 - (view) Author: Tim Golden (tim.golden) * (Python committer) Date: 2012-06-28 12:31
Yep.
msg164252 - (view) Author: Tim Golden (tim.golden) * (Python committer) Date: 2012-06-28 12:35
To be clear: ERROR_OPERATION_ABORTED is set when Ctrl-Z is hit as the
only thing on a line. If it's just an extra character then it operates
like any other keypress.
msg164261 - (view) Author: Tim Golden (tim.golden) * (Python committer) Date: 2012-06-28 14:49
This patch is for 2.7 and does enough to solve the issue without a major
rework. The signal module onthe default branch has had a lot of love
recently and I'll definitely make use of that for a 3.x patch.
msg164264 - (view) Author: Kristján Valur Jónsson (kristjan.jonsson) * (Python committer) Date: 2012-06-28 15:34
Hm, I wonder if the test for the SIGINT event is required at all.
Could it be sufficient to simply check for the EOF state?  EOF would indicate ctrl z and distinguish it thus from ctrl-c.
msg164275 - (view) Author: Tim Golden (tim.golden) * (Python committer) Date: 2012-06-28 16:46
Nope. Ctrl-C also sets EOF
msg164279 - (view) Author: Tim Golden (tim.golden) * (Python committer) Date: 2012-06-28 17:10
And here's a patch for the default branch, using the new sigint event as Kristan suggested.
msg164331 - (view) Author: Tim Golden (tim.golden) * (Python committer) Date: 2012-06-29 14:55
And here's the patch against 3.2 (essentially the 2.7 patch but allowing for the removal of RISCOS support)
msg164335 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2012-06-29 17:20
Tim, you've got tabs in your 3.3 patch.
Other than that, I wonder why you wait for 100 ms in 3.3 but 10 ms in the other versions?
msg164336 - (view) Author: Tim Golden (tim.golden) * (Python committer) Date: 2012-06-29 17:23
> Tim, you've got tabs in your 3.3 patch.

Thanks, Antoine. I'll sort that out. (Goodness know how;
none of my editors use tabs).

> Other than that, I wonder why you wait for 100 ms in 3.3 but 10 ms in the other versions?

Ummm. Because they were written separately and I didn't
check carefully enough? I'll drop back to 10ms all round;
it never took more than 3 1-ms loops to fire in testing.
msg164353 - (view) Author: Roundup Robot (python-dev) Date: 2012-06-29 21:14
New changeset bb4b184e5b33 by Tim Golden in branch '2.7':
Issue #1677: Handle better a race condition between the interactive interpreter and
http://hg.python.org/cpython/rev/bb4b184e5b33

New changeset 52af10209976 by Tim Golden in branch '3.2':
Issue #1677: Handle better a race condition between the interactive interpreter and
http://hg.python.org/cpython/rev/52af10209976

New changeset 9523c122d6fc by Tim Golden in branch 'default':
Issue #1677: Handle better a race condition between the interactive interpreter and
http://hg.python.org/cpython/rev/9523c122d6fc
msg164592 - (view) Author: Roundup Robot (python-dev) Date: 2012-07-03 11:08
New changeset 2de5c9ced464 by Jesus Cea in branch '2.7':
Issue #1677: Unused variable warning in Non-Windows
http://hg.python.org/cpython/rev/2de5c9ced464
msg164593 - (view) Author: Roundup Robot (python-dev) Date: 2012-07-03 11:18
New changeset 4de541fbdd58 by Jesus Cea in branch '3.2':
Issue #1677: Unused variable warning in Non-Windows
http://hg.python.org/cpython/rev/4de541fbdd58

New changeset 7937aa6b7e92 by Jesus Cea in branch 'default':
NULL MERGE: Issue #1677: Unused variable warning in Non-Windows
http://hg.python.org/cpython/rev/7937aa6b7e92
History
Date User Action Args
2012-07-03 11:21:22jceasetversions: - Python 3.1
2012-07-03 11:20:59jceasetnosy: + jcea
2012-07-03 11:18:47python-devsetmessages: + msg164593
2012-07-03 11:08:48python-devsetmessages: + msg164592
2012-06-29 21:34:34tim.goldensetstatus: open -> closed
resolution: fixed
stage: test needed -> resolved
2012-06-29 21:14:48python-devsetnosy: + python-dev
messages: + msg164353
2012-06-29 17:23:16tim.goldensetmessages: + msg164336
2012-06-29 17:20:56pitrousetmessages: + msg164335
2012-06-29 15:15:22tim.goldensetfiles: + issue1677-python32.patch
2012-06-29 15:12:45tim.goldensetfiles: - issue1677-python32.patch
2012-06-29 14:55:47tim.goldensetfiles: + issue1677-python32.patch

messages: + msg164331
2012-06-28 17:10:51tim.goldensetfiles: + issue1677-python3x.patch

messages: + msg164279
2012-06-28 16:46:20tim.goldensetmessages: + msg164275
2012-06-28 15:34:56kristjan.jonssonsetmessages: + msg164264
2012-06-28 14:49:34tim.goldensetmessages: + msg164261
2012-06-28 12:35:02tim.goldensetmessages: + msg164252
2012-06-28 12:31:51tim.goldensetmessages: + msg164250
2012-06-28 11:33:04amaury.forgeotdarcsetmessages: + msg164246
2012-06-28 11:15:03kristjan.jonssonsetmessages: + msg164244
2012-06-28 11:10:37kristjan.jonssonsetnosy: + kristjan.jonsson
messages: + msg164243
2012-06-28 09:32:01tim.goldensetfiles: + issue1677-python27.patch
assignee: tim.golden
messages: + msg164233

keywords: + patch
2012-06-27 18:47:47tim.goldensetmessages: + msg164187
2012-06-27 13:31:39tim.goldensetmessages: + msg164154
2012-06-27 13:30:35amaury.forgeotdarcsetmessages: + msg164152
2012-06-27 13:04:05tim.goldensetmessages: + msg164150
2012-06-27 09:33:46tim.goldensetnosy: + tim.golden
messages: + msg164133
2012-06-26 12:45:48mhammondsetnosy: + mhammond
2012-06-26 11:26:15christian.heimessetmessages: + msg164065
2012-06-26 11:17:37Devin Jeanpierresetnosy: + Devin Jeanpierre
messages: + msg164064
2012-06-26 07:11:18georg.brandlsetnosy: + loewis
2012-06-26 07:10:57georg.brandlsetnosy: + pitrou
2011-03-22 18:27:28santoso.wijayasetnosy: + santoso.wijaya, - Devin Jeanpierre
versions: + Python 3.2, Python 3.3
2011-03-21 11:07:31Devin Jeanpierresetnosy: + Devin Jeanpierre
messages: + msg131632
2010-08-28 14:38:50brian.curtinsetversions: - Python 2.6
nosy: + brian.curtin

messages: + msg115155

assignee: ronaldoussoren -> (no value)
2010-08-27 22:58:30Dude-Xsetversions: + Python 2.7
nosy: ronaldoussoren, amaury.forgeotdarc, christian.heimes, Dude-X, r.david.murray
messages: + msg115139

assignee: ronaldoussoren
components: + Interpreter Core, Windows
2010-08-27 21:39:55r.david.murraysetnosy: + r.david.murray
messages: + msg115133
2010-04-30 15:03:39ronaldoussorensetassignee: ronaldoussoren -> (no value)

messages: + msg104643
nosy: + ronaldoussoren
2009-09-06 14:31:21ronaldoussorensetnosy: - ronaldoussoren
2009-06-24 05:41:10ronaldoussorensetmessages: + msg89655
2009-06-23 23:33:14amaury.forgeotdarcsetnosy: + ronaldoussoren
messages: + msg89651

assignee: ronaldoussoren
components: + Macintosh, - Interpreter Core, Windows
2009-04-27 23:37:03ajaksu2setstage: test needed
versions: + Python 3.1, - Python 2.5, Python 2.4, Python 3.0
2008-01-06 22:29:44adminsetkeywords: - py3k
versions: Python 2.6, Python 2.5, Python 2.4, Python 3.0
2008-01-05 18:31:51christian.heimeslinkissue964949 superseder
2008-01-03 20:25:14JosephArmbrustersetcomponents: + Windows
2007-12-23 21:03:11Dude-Xsetmessages: + msg58975
versions: + Python 2.6, Python 2.5, Python 2.4
2007-12-21 09:57:40amaury.forgeotdarcsetnosy: + amaury.forgeotdarc
messages: + msg58940
2007-12-21 09:44:11christian.heimessetpriority: normal
keywords: + py3k
messages: + msg58939
nosy: + christian.heimes
2007-12-21 06:16:12Dude-Xcreate