python / python/cpython

Builtin input does not always correctly handle errors from `PyOS_Readline`

未关闭
#134,644 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

3.13 3.14 3.15 interpreter-core type-crash
主要语言
Python
星标
77.2k
派生
35.9k
PR 合并指标
PR 指标待抓取

描述

Assertion failure sending SIGINT while calling input
import os, signal, threading

send = threading.Event()

def interrupter():
    while True:
        send.wait()
        os.kill(os.getpid(), signal.SIGINT)

threading.Thread(target=interrupter).start()

send.set()
while True:
    try:
        input(">")
    except KeyboardInterrupt:
        pass

Note, this is a modified version of the example code in #112585.

Python (tested v3.12.10, v3.13.3, v3.14.0b1, and current HEAD), built with assertions enabled:

~/src/cpython/ $ ./python crash.py
>>>>>>>>>>>python: Objects/call.c:342: _PyObject_Call: Assertion `!_PyErr_Occurred(tstate)' failed.
Aborted (core dumped)

IIUC the issue is builtin_input_impl in Python/bltinmodule.c calls PyOS_Readline but assumes it cannot set an exception:

    s = PyOS_Readline(stdin, stdout, promptstr);
    if (s == NULL) {
        PyErr_CheckSignals();
        if (!PyErr_Occurred())
            PyErr_SetNone(PyExc_KeyboardInterrupt);

If PyOS_Readline sets an exception (e.g. as in this case by running an interrupt signal handler itself), as opposed to being interrupted by a signal and returning NULL without setting the exception, and another signal with a handler is pending when PyErr_CheckSignals() is called, the handler will be called with the prior exception already set, and hence the assertion fails.

CPython versions tested on:

CPython main branch

Operating systems tested on:

Linux

Output from running 'python -VV' on the command line:

No response

Linked PRs
  • gh-134645

贡献指南

打开贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

调研方向

从 Python/bltinmodule.c 中的 builtin_input_impl 开始,使用提供的信号和输入示例重现该断言。跟踪 PyOS_Readline 和 PyErr_CheckSignals 如何处理已有的异常;完成的标准是重现过程不再因 _PyObject_Call 断言而中止,并保留预期的中断行为。

由索引模型根据 Issue 内容生成。

评估

技术栈
python
领域
operating-systems
Issue 类型
缺陷
难度
3/5
预计耗时
1-2 天
活跃度
停滞
描述清晰度
描述清楚
新手友好度
35/100

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。