python / python/cpython

Improve traceability of assertion errors in common functions

Đang mở
#130,454 24 bình luận 0 reaction 0 người được giao Xem trên GitHub

Chưa có ai nhận issue này.

interpreter-core type-feature
Ngôn ngữ chính
Python
Star
77.2k
Fork
35.9k
Chỉ số merge pull request
Chỉ số pull request đang chờ

Mô tả

Feature request

(By @picnizx)

While the C API docs explicitly state that functions should usually not be called with an exception set, else some assertion errors may occur and/or the thread state may be invalid, this means that assert(!PyErr_Occurred()) in common macros / functions such as _PyType_LookupRef would just crash. However, in a CI scenario, without a debugger, it's extremely hard to pinpoint the actual cause.

Related: https://github.com/python/cpython/pull/128159 would give the possibility to show the C stack trace with -X faulthandler.

A crude idea: add assert(!PyErr_Occurred()) inside public common C API functions to be sure that the assertion is checked as well, making debugging a bit easier.


Toy Scenario (original request):

I was working on freethread support for pygame-ce, and I finally need to use a python build with debug symbols, and our atexit-registered quit function was causing SIGABRT to be thrown. This took me a while to figure out. Here's all the code you need to run (or just run python -c "import pygame" since pygame.quit() is atexit-registered).

import pygame
pygame.quit()

Here's the guilty block of code in our codebase:

    funcobj = PyObject_GetAttrString(module, "_internal_mod_quit");

    /* If we could not load _internal_mod_quit, load quit function */
    if (!funcobj)
        funcobj = PyObject_GetAttrString(module, "quit");

    /* Silence errors */
    if (PyErr_Occurred())
        PyErr_Clear();

In the 3.12 docs for PyObject_GetAttrString and PyObject_GetAttr. there's no mention at all that there shouldn't be any exceptions set before calling this function, and it works on release versions of python, so nobody has ever questioned this structure. I'll be making a pull request on our end to clear any exceptions between the first call and second call if needed (or use PyObject_GetOptionalAttrString in 3.13+).

The reason for this issue is that I'm not sure throwing a SIGABRT is the best option here.

gdb backtrace on a debug python 3.13t
[gdb.txt](https://github.com/user-attachments/files/18922524/gdb.txt)
CPython versions tested on:

3.12, 3.13, 3.14

Operating systems tested on:

Linux

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Hướng nghiên cứu

Bắt đầu bằng việc xem xét hành vi của C API xung quanh PyObject_GetAttrString, PyObject_GetAttr, PyErr_Occurred và _PyType_LookupRef, cùng với pull request faulthandler liên quan. So sánh các điều kiện tiên quyết được ghi lại với các lỗi assertion được hiển thị trong kịch bản pygame. Được xem là hoàn tất khi một phương án đã được thống nhất để cải thiện khả năng truy vết assertion và hành vi dự kiến của phương án đó đã được xác lập.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Đánh giá

Công nghệ
c, python
Lĩnh vực
api
Loại issue
Tính năng
Độ khó
4/5
Thời gian dự kiến
3-5 ngày
Mức độ hoạt động
Đình trệ
Độ rõ ràng
Khá rõ ràng
Mức phù hợp với người mới
45/100

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.