Skip to content
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

help crash leaves terminal in echo off mode #67980

Closed
RusiMody mannequin opened this issue Mar 27, 2015 · 20 comments
Closed

help crash leaves terminal in echo off mode #67980

RusiMody mannequin opened this issue Mar 27, 2015 · 20 comments
Labels
topic-IDLE type-bug An unexpected behavior, bug, or error

Comments

@RusiMody
Copy link
Mannequin

RusiMody mannequin commented Mar 27, 2015

BPO 23792
Nosy @ezio-melotti, @bitdancer, @berkerpeksag, @vadmium
Files
  • keyboardinterrupt_in_pydoc_pager.patch
  • keyboardinterrupt_in_pydoc_pager.patch
  • interrupt.patch
  • catch_additional_interrupt.patch
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields:

    assignee = None
    closed_at = <Date 2015-03-29.19:21:10.748>
    created_at = <Date 2015-03-27.17:09:23.856>
    labels = ['expert-IDLE', 'type-bug']
    title = 'help crash leaves terminal in echo off mode'
    updated_at = <Date 2015-07-17.14:03:39.565>
    user = 'https://bugs.python.org/RusiMody'

    bugs.python.org fields:

    activity = <Date 2015-07-17.14:03:39.565>
    actor = 'r.david.murray'
    assignee = 'none'
    closed = True
    closed_date = <Date 2015-03-29.19:21:10.748>
    closer = 'r.david.murray'
    components = ['IDLE']
    creation = <Date 2015-03-27.17:09:23.856>
    creator = 'RusiMody'
    dependencies = []
    files = ['38714', '38715', '38730', '38731']
    hgrepos = []
    issue_num = 23792
    keywords = ['patch']
    message_count = 20.0
    messages = ['239417', '239420', '239422', '239423', '239426', '239427', '239428', '239429', '239431', '239446', '239460', '239511', '239512', '239535', '239537', '239541', '239612', '239614', '246845', '246853']
    nosy_count = 7.0
    nosy_names = ['ezio.melotti', 'r.david.murray', 'RusiMody', 'python-dev', 'berker.peksag', 'martin.panter', 'swanson']
    pr_nums = []
    priority = 'normal'
    resolution = 'fixed'
    stage = 'resolved'
    status = 'closed'
    superseder = None
    type = 'behavior'
    url = 'https://bugs.python.org/issue23792'
    versions = ['Python 3.4', 'Python 3.5']

    @RusiMody
    Copy link
    Mannequin Author

    RusiMody mannequin commented Mar 27, 2015

    Start python3.4
    Do help(something) which invokes the pager
    Ctrl-C
    A backtrace results and after that the terminal is in raw mode even after exiting python

    [python 3.4 under debian testing with xfce4]

    @RusiMody RusiMody mannequin added type-crash A hard crash of the interpreter, possibly with a core dump topic-IDLE labels Mar 27, 2015
    @bitdancer
    Copy link
    Member

    I can't reproduce this. Maybe it is a debian bug?

    @berkerpeksag
    Copy link
    Member

    This looks like a duplicate of bpo-21398. I can reproduce it with Python 3.4.1 (compiled myself) on Ubuntu 12.04.

    >> help(str)

    Ctrl-C

    :Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/usr/local/lib/python3.4/_sitebuiltins.py", line 103, in __call__
        return pydoc.help(*args, **kwds)
      File "/usr/local/lib/python3.4/pydoc.py", line 1817, in __call__
        self.help(request)
      File "/usr/local/lib/python3.4/pydoc.py", line 1867, in help
        else: doc(request, 'Help on %s:', output=self._output)
      File "/usr/local/lib/python3.4/pydoc.py", line 1603, in doc
        pager(render_doc(thing, title, forceload))
      File "/usr/local/lib/python3.4/pydoc.py", line 1411, in pager
        pager(text)
      File "/usr/local/lib/python3.4/pydoc.py", line 1431, in <lambda>
        return lambda text: pipepager(text, 'less')
      File "/usr/local/lib/python3.4/pydoc.py", line 1453, in pipepager
        pipe.close()
      File "/usr/local/lib/python3.4/os.py", line 957, in close
        returncode = self._proc.wait()
      File "/usr/local/lib/python3.4/subprocess.py", line 1565, in wait
        (pid, sts) = self._try_wait(0)
      File "/usr/local/lib/python3.4/subprocess.py", line 1513, in _try_wait
        (pid, sts) = _eintr_retry_call(os.waitpid, self.pid, wait_flags)
      File "/usr/local/lib/python3.4/subprocess.py", line 491, in _eintr_retry_call
        return func(*args)
    KeyboardInterrupt

    @ezio-melotti
    Copy link
    Member

    I can reproduce on Python 3 on Ubuntu 14.10.
    When I hit Ctrl+C I get:
    >>> help(range)
    ...
     |  __hash__(self, /)
     |      Return hash(self).
     |  
    :Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/home/wolf/dev/py/py3k/Lib/_sitebuiltins.py", line 103, in __call__
        return pydoc.help(*args, **kwds)
      File "/home/wolf/dev/py/py3k/Lib/pydoc.py", line 1833, in __call__
        self.help(request)
      File "/home/wolf/dev/py/py3k/Lib/pydoc.py", line 1886, in help
        else: doc(request, 'Help on %s:', output=self._output)
      File "/home/wolf/dev/py/py3k/Lib/pydoc.py", line 1619, in doc
        pager(render_doc(thing, title, forceload))
      File "/home/wolf/dev/py/py3k/Lib/pydoc.py", line 1409, in pager
        pager(text)
      File "/home/wolf/dev/py/py3k/Lib/pydoc.py", line 1431, in <lambda>
        return lambda text: pipepager(text, 'less')
      File "/home/wolf/dev/py/py3k/Lib/pydoc.py", line 1455, in pipepager
        pipe.write(text)
      File "/home/wolf/dev/py/py3k/Lib/subprocess.py", line 900, in __exit__
        self.wait()
      File "/home/wolf/dev/py/py3k/Lib/subprocess.py", line 1552, in wait
        (pid, sts) = self._try_wait(0)
      File "/home/wolf/dev/py/py3k/Lib/subprocess.py", line 1502, in _try_wait
        (pid, sts) = os.waitpid(self.pid, wait_flags)
    KeyboardInterrupt
    >>>

    If I keep pressing Enter the rest of the help gets printed. Once the pager is done, pressing enter doesn't go on a new line and the prompts (>>>) are printed one after the other on the same line. The same happens on my shell prompt once I exit from the interpreter. reset fixes it.

    On Python 2 Ctrl+C does nothing.

    @ezio-melotti ezio-melotti added type-bug An unexpected behavior, bug, or error and removed type-crash A hard crash of the interpreter, possibly with a core dump labels Mar 27, 2015
    @bitdancer
    Copy link
    Member

    I do see the anomalous behavior inside python, but on my gentoo system when I exit python the terminal is fine.

    @bitdancer
    Copy link
    Member

    The attached patch fixes the issue for me.

    @ezio-melotti
    Copy link
    Member

    Patch WFM too.

    @bitdancer
    Copy link
    Member

    The print of KeyboardInterrupt whould be dropped. less itself does nothing if you press ctl-c, and the pager is used when pydoc is called from the shell command line, and printing KeyboardInterrupt there just looks wrong.

    @bitdancer
    Copy link
    Member

    Updated patch.

    @vadmium
    Copy link
    Member

    vadmium commented Mar 28, 2015

    I suspect you also need ignore signals while piping data to the child process. Similar to how the POSIX system() call ignores SIGINT and SIGQUIT soon after spawning the child, until after the child has exited.

    Try with a large help text on Linux, like

    import _pyio
    help(_pyio)

    Also, Python 2 still gets interrupted for me, it is just that it doesn’t seem to happen immediately if it is up to the pipe.close() call.

    @bitdancer
    Copy link
    Member

    SIGINT *is* keyboard interrupt. Since less at least seems to ignore SIGQUIT I suppose also ignoring that would be reasonable, since the user (should) by analogy expect that behavior while the pager is active. Note, however, that the signals we are ignoring are in the parent process, not the child as is the case for system. So one can argue that letting the python process die when SIGQUIT is received would also be reasonable, and arguably is the less surprising option.

    @python-dev
    Copy link
    Mannequin

    python-dev mannequin commented Mar 29, 2015

    New changeset 77c04e949b4b by R David Murray in branch '3.4':
    bpo-23792: Ignore KeyboardInterrupt when the pydoc pager is active.
    https://hg.python.org/cpython/rev/77c04e949b4b

    New changeset fe0c830b43bb by R David Murray in branch 'default':
    Merge: bpo-23792: Ignore KeyboardInterrupt when the pydoc pager is active.
    https://hg.python.org/cpython/rev/fe0c830b43bb

    @bitdancer
    Copy link
    Member

    I've committed the fix. If someone wants to argue in favor of also handling SIGQUIT, they can open a new issue.

    @vadmium
    Copy link
    Member

    vadmium commented Mar 29, 2015

    I don’t think SIGQUIT handling is a big problem. But even with the new change, it is still easy to screw up the terminal in many cases, so I wouldn’t say this is fixed yet. Steps for Python 3 in a small 80 × 25 terminal on Linux:

    • import _pyio; help(_pyio)
    • Hit Ctrl-C

    Steps for Python 2:

    • import _pyio; help(_pyio)
    • Hit Ctrl-C
    • Hit Space ten times to scroll down. Alternatively, hit Ctrl-C a second time.

    I am posting a quick patch which I think should fix this in Python 3 by deferring the traceback until after the child has finished. Another method is using the signal module like <https://github.com/vadmium/pacman-tools/blob/9ffdd88/roopwn#L976\>, but that’s probably too platform-specific for the pydoc module.

    @bitdancer
    Copy link
    Member

    Here is a version that keeps things clean by not diplaying the traceback. The ctl-c does have an effect, but not a visible one unless one pays careful attention :)

    @vadmium
    Copy link
    Member

    vadmium commented Mar 30, 2015

    I think your patch should be fine for all practical cases I can think of.

    @python-dev
    Copy link
    Mannequin

    python-dev mannequin commented Mar 30, 2015

    New changeset 7a5f30babc72 by R David Murray in branch '3.4':
    bpo-23792: also catch interrupt around pipe.write.
    https://hg.python.org/cpython/rev/7a5f30babc72

    New changeset 536c4f4acae1 by R David Murray in branch 'default':
    Merge: bpo-23792: also catch interrupt around pipe.write.
    https://hg.python.org/cpython/rev/536c4f4acae1

    @bitdancer
    Copy link
    Member

    Yeah, someone could theoretically manage to hit ctl-c between the time the process is started and the call to pipe.write, or between it and the call to wait, but I don't think those very-low-probability events are worth worrying about.

    @swanson
    Copy link
    Mannequin

    swanson mannequin commented Jul 17, 2015

    Changing the title in case anyone else is looking for this bug.

    This is not raw mode. It's just that echo is turned off.

    It is sufficient to type (invisibly, of course):
    stty echo
    to resume normal use of the terminal.

    @swanson swanson mannequin changed the title help crash leaves terminal in raw mode help crash leaves terminal in echo off mode Jul 17, 2015
    @bitdancer
    Copy link
    Member

    Well, not exactly. While the title was inaccurate, the real problem was the management of the subprocess, not what mode the terminal was in.

    @ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    topic-IDLE type-bug An unexpected behavior, bug, or error
    Projects
    None yet
    Development

    No branches or pull requests

    4 participants