-
-
Notifications
You must be signed in to change notification settings - Fork 30.3k
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
[3.13] _PyObject_Init() assertion fails with the stable ABI on Python built with assertions (extension built with Python 3.11) #121528
Comments
The issue is confirmed, I have found the reason, but I'm not sure this is a bug, I prefer its undefined behavior. It's caused by the TL;DR; For the 3.11 version of the For the 3.13 version of the And the function is an inline function, which is means we will expand the function into the binary during the compile. So in 3.11 version, the We can compare the assemble code to prove it For 3.11 0000000000001120 <foo_bar>:
1120: 48 83 ec 08 sub $0x8,%rsp
1124: 48 8b 05 9d 2e 00 00 mov 0x2e9d(%rip),%rax # 3fc8 <PyExc_TypeError@Base>
112b: 48 8d 35 ce 0e 00 00 lea 0xece(%rip),%rsi # 2000 <_fini+0xe9c>
1132: 48 8b 38 mov (%rax),%rdi
1135: 48 83 07 01 addq $0x1,(%rdi)
1139: e8 f2 fe ff ff call 1030 <PyErr_SetString@plt>
113e: 31 c0 xor %eax,%eax
1140: 48 83 c4 08 add $0x8,%rsp
1144: c3 ret
1145: 66 66 2e 0f 1f 84 00 data16 cs nopw 0x0(%rax,%rax,1)
114c: 00 00 00 00 For 3.13 0000000000001120 <foo_bar>:
1120: 48 83 ec 08 sub $0x8,%rsp
1124: 48 8b 05 9d 2e 00 00 mov 0x2e9d(%rip),%rax # 3fc8 <PyExc_TypeError@Base>
112b: 48 8b 38 mov (%rax),%rdi
112e: 8b 07 mov (%rdi),%eax
1130: 83 c0 01 add $0x1,%eax
1133: 74 02 je 1137 <foo_bar+0x17>
1135: 89 07 mov %eax,(%rdi)
1137: 48 8d 35 c2 0e 00 00 lea 0xec2(%rip),%rsi # 2000 <_fini+0xe9c>
113e: e8 ed fe ff ff call 1030 <PyErr_SetString@plt>
1143: 31 c0 xor %eax,%eax
1145: 48 83 c4 08 add $0x8,%rsp
1149: c3 ret
114a: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1) The patch to fix this issue is simple ,we just the code back if (_PyType_HasFeature(typeobj, Py_TPFLAGS_HEAPTYPE) || _Py_IsImmortal(typeobj)) {
Py_INCREF(typeobj);
} I'm not sure this patch has side effect or not. I may need @markshannon help |
I setup a new disscussion here https://discuss.python.org/t/disable-the-inline-by-default-for-the-function-api-which-is-included-in-the-stable-abi/57832 |
After dive more deeper, I think maybe its the user code issue. I think you use If you use the |
The general impression I get from wjakob/nanobind#500 is that |
Yes, this is implemented as a Limit API/Stable ABI but actually it's not(can't guarantee the behavior and inlined). I'm not sure we should open a new discussion about this.
https://docs.python.org/3/c-api/stable.html#limited-api-scope-and-performance |
I think we might need a core to decide this issue should be fixed or not |
It seems like this will break a large number of existing extensions if it's not resolved. If the decision is not to fix this, then CPython needs to not load abi3 .sos that are impacted. |
In the limited C API version 3.12 and newer, Py_INCREF() is now implemented as a function call. You can build your C extension with Python 3.12 and the binary should work on Python 3.11 unless you use features specific to Python 3.12. Moreover, the binary (.abi3.so shared library) should work on Python 3.12 and newer. Example. setup.py from setuptools import setup, Extension
setup(name='foo',
version='0',
ext_modules=[
Extension('foo', ['foo.c'], py_limited_api='cp312'),
]) Build:
It works on Python 3.11, 3.12, 3.13:
It works even on Python 3.6:
|
My concern is primarily for the existing abi3 wheels on PyPI. The whole point is that maintainers could publish them and they'd continue to work. |
|
Yes, the problem is the code which is using I'm not sure we should fix this or not. |
PEP 683 promises to not break the backward compatibility for the stable ABI, but the implementation doesn't seem to be fully compatible. The problem is that _Py_IsImmortal() checks exactly if ref count is equal to _Py_IMMORTAL_REFCNT (refcnt == _Py_IMMORTAL_REFCNT). This problem remains me the commit 5f6ac2d of the PR gh-112174. |
Yes, I have mentioned this at here #121528 (comment) But I think here's another core problem we change the way that we treat the object which is not in the heap and is not immortal object(From |
Other interesting changes:
|
Py_INCREF(PyExc_TypeError)
in stable ABI causes python3.13: ./Include/internal/pycore_object.h:284: _PyObject_Init: Assertion '_PyType_HasFeature(typeobj, Py_TPFLAGS_HEAPTYPE) || _Py_IsImmortal(typeobj)' failed.
How did you install this |
it's not related debug build I guess. I can reproduce it in non-debug build Python 3.13(install by pyenv) |
To check if you're using a debug build, you can check:
I cannot reproduce the issue with a release build. |
The following code is a reference leak, you don't have to INCREF the TypeError exception: Py_INCREF(PyExc_TypeError);
PyErr_SetString(PyExc_TypeError, "foo");
return NULL; You should just: PyErr_SetString(PyExc_TypeError, "foo");
return NULL; |
Weird, I can't reproduce this in non-debug build now. Sorry for the previous reply, maybe I mix up something |
We're building The problem right now is that all current versions of PyO3 produce "broken" extensions, and it will take some time before packages update to the very newest version that fixes this, and every single package published on PyPI before that happens will remain broken. |
Add _Py_IsImmortalLoose() function for assertions.
I wrote PR gh-121725 to fix the assertion. I'm not sure if it's correct. It's an heuristic. |
Add _Py_IsImmortalLoose() function for assertions.
Add _Py_IsImmortalLoose() function for assertions.
…nGH-121725) Add _Py_IsImmortalLoose() function for assertions. (cherry picked from commit b826e45) Co-authored-by: Victor Stinner <vstinner@python.org>
Crash report
What happened?
Consider the following extension.
C code:
setup.py
:If I compile the extension using Python older than 3.12, and then run the method, Python 3.13.0b3 (built
--with-assertions
) crashes:I've been able to bisect it to c32dc47 (CC @markshannon). Originally hit it in extensions using PyO3, and reported to PyO3/pyo3#4311.
CPython versions tested on:
CPython main branch
Operating systems tested on:
Linux
Output from running 'python -VV' on the command line:
Python 3.13.0b3 (main, Jul 4 2024, 14:30:57) [GCC 14.1.1 20240622]
Linked PRs
The text was updated successfully, but these errors were encountered: