Control-C on Unix misbehaviour?
flight at mathi.uni-heidelberg.de
flight at mathi.uni-heidelberg.de
Mon Oct 18 09:47:52 EDT 1999
This is a thing I noticed some time ago and was about to enter into the
Python Bug Database. It's been recorded in the Debian Bug Tracking system
since some time:
- Debian Bug#24605: python-base: signal handling problems
(http://www.debian.org/Bugs/db/24/24605.html)
- Debian Bug#45929: python: ^C acts as ^D instead of raising a
KeyboardInterrupt exception while working within the interactive interpreter.
(http://www.debian.org/Bugs/db/45/45929.html)
I'll add a few more data points here for different Linux flavors, all of
them running on i386 machines:
(A) Debian GNU/Linux 2.1: python 1.5.1-7, libreadlineg2 2.1-12,
libc6 2.0.7.19981211
(B) Debian GNU/Linux 2.1 like above, but running python 1.5.2-5slink-1.
(C) Debian potato: python 1.5.2-6, libreadlineg2 2.1-13.6,
libc6 2.1.2-5
(D) SuSE Linux 6.1: python-1.5.1-44, libc-99.4.4-0, no readline module
(Like Debian 2.1, SuSE 6.1 is running libc6 2.0.7)
(E) SuSE Linux 6.1: like above, but running Debian's python 1.5.2-6 package.
First test: "python" and pressing Control-C twice
-------------------------------------------------
On (C), python will be aborted after the first Control-C.
On (A), (B) and (D), "KeyboardInterrupt" after the first Control-C, no reaction
at all after the second Control-C (Control-C won't work in this session
after the first).
On (E), nothing happens after the first Control-C, but if I press enter,
I get
Traceback (innermost last):
File "<stdin>", line 0, in ?
KeyboardInterrupt
On the second and any subsequent Control-C, I get an "KeyboardInterrupt"
immediately.
Second test: like first, but after installing an empty, dummy readline.so
-------------------------------------------------------------------------
On (A), (D), I get a message
Traceback (innermost last):
File "<stdin>", line 0, in ?
KeyboardInterrupt
after each Control-C, but only after pressing enter.
On (E), the same reaction as with the first test.
(B) and (C) now behave like (E), too.
python -c "raw_input()", ff, Control-C twice
--------------------------------------------
(A), (D): Back in shell after first Control-C, but only after I press enter:
ff
Traceback (innermost last):
File "<string>", line 1, in ?
KeyboardInterrupt
(B), (C), (E): back in shell after second Control-C:
ffTraceback (innermost last):
File "<string>", line 1, in ?
KeyboardInterrupt
python -c "import readline; raw_input()", ff, Control-C twice
-------------------------------------------------------------
(A), (B), (C): back in shell
[not applicable for (D) and (E)]
>
> > If Ctrl-C does kill the interpreter, it's a platform-specific bug. Start
> > your exciting search by trying:
> >
> > >>> import signal
> > >>> signal.default_int_handler()
> >
> > Hoping for something like:
> >
> > Traceback (innermost last):
> > File "<stdin>", line 1, in ?
> > KeyboardInterrupt
> > >>>
> >
> > and still in the interpreter shell.
Works like expected on all five configurations.
>
> No, that all works. The execution is never getting to the handler. I
> can do this:
>
> >>> import signal
> >>> def f():
> ... print "hello"
> ...
> >>> signal.signal(signal.SIGINT,f)
> <built-in function default_int_handler>
> >>> ^C - and back we go to bash
>
> I get the same behaviour if I use `kill' from another xterm, so it
> looks as if the signal's getting deleivered correctly.
>
> possibly relavent info:
>
> python 1.5.2 (both from redhat 6.1 & a fairly recent cvs)
> readline-2.2.1-5 (according rpm -q readline)
>
> running under gdb yields different behaviour (oh good!) - hitting
> control-C drops you into __libc_read where the stack looks a bit like
> this:
gdb python, run and Control-C
-----------------------------
(A) and (B): Program received signal SIGINT, Interrupt.
#0 0x400a2a44 in ()
#1 0x40037810 in ()
#2 0x400ff72a in rl_getc ()
#3 0x400ff6b5 in rl_read_key ()
#4 0x400ea760 in readline_internal_char ()
#5 0x400ea8a5 in readline_internal_char ()
#6 0x400ea8ed in readline_internal_char ()
#7 0x400ea4a0 in readline ()
#8 0x4000d2c9 in ()
...
#17 0x804f31a in ()
#18 0x804ed40 in main ()
(C): Program received signal SIGINT, Interrupt.
#0 0x401471a4 in read () from /lib/libc.so.6
#1 0x40097ffc in __libc_internal_tsd_get () from /lib/libpthread.so.0
#2 0x401b51a7 in rl_getc () from /lib/libreadline.so.2
#3 0x401b5152 in rl_read_key () from /lib/libreadline.so.2
#4 0x401a1e1b in readline_internal_char () from /lib/libreadline.so.2
#5 0x401a1f35 in readline_internal_char () from /lib/libreadline.so.2
#6 0x401a1f69 in readline_internal_char () from /lib/libreadline.so.2
#7 0x401a1b76 in readline () from /lib/libreadline.so.2
#8 0x40014554 in _init () from /usr/lib/python1.5/lib-dynload/readline.so
#9 0x4004eb71 in PyOS_Readline () from /usr/lib/libpython1.5.so.0.0
#10 0x40065c4a in PyTokenizer_Free () from /usr/lib/libpython1.5.so.0.0
#11 0x4006652a in PyTokenizer_Get () from /usr/lib/libpython1.5.so.0.0
#12 0x400503fb in PyParser_ParseFile () from /usr/lib/libpython1.5.so.0.0
#13 0x400502a5 in PyParser_ParseFile () from /usr/lib/libpython1.5.so.0.0
#14 0x4005a843 in PyRun_InteractiveOne () from /usr/lib/libpython1.5.so.0.0
#15 0x4005a743 in PyRun_InteractiveLoop () from /usr/lib/libpython1.5.so.0.0
#16 0x4005a67a in PyRun_AnyFile () from /usr/lib/libpython1.5.so.0.0
#17 0x4004b444 in Py_Main () from /usr/lib/libpython1.5.so.0.0
#18 0x8048724 in main ()
#19 0x400ce78a in __libc_start_main () from /lib/libc.so.6
[gdb not available on (D) and (E)]
> #0 0x40113db4 in __libc_read () from /lib/libc.so.6
> #1 0x40052a7c in __DTOR_END__ () from /lib/libpthread.so.0
> #2 0x4002f422 in rl_getc () from /usr/lib/libreadline.so.3
> #3 0x4002f3e2 in rl_read_key () from /usr/lib/libreadline.so.3
> #4 0x40021aa5 in readline_internal_char () from /usr/lib/libreadline.so.3
> #5 0x40021b7b in readline_internal_charloop () from /usr/lib/libreadline.so.3
> #6 0x40021baa in readline_internal () from /usr/lib/libreadline.so.3
> #7 0x40021888 in readline () from /usr/lib/libreadline.so.3
> #8 0x8085d85 in call_readline (prompt=0x811be9c ">>> ") at ./readline.c:288
> #9 0x8052689 in PyOS_Readline (prompt=0x811be9c ">>> ") at myreadline.c:148
> #10 0x805184b in tok_nextc (tok=0x8140e70) at tokenizer.c:216
> ...
>
> single stepping a few times through source-absent libc files leaves me
> back at the Python interpreter's prompt.
Same behavior here.
No need to say that with the readline module loaded behavior for Control-C
(SIGINT) is different depending if you're on the Python command line or if
you're running a Python statement.
The problem is indeed related to the readline module, but then, it seems to
depend on libc6 as well! At least I get different effects with the same
Python version running on systems with a roughly identical libreadline, but
different libc6 versions.
Gregor
More information about the Python-list
mailing list