Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork32k
GH-99293: Fix stale method caches and assertion errors in SWIG-generated modules#99294
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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
base:main
Are you sure you want to change the base?
Conversation
modules.Extension modules generated by SWIG up to version 4.1.0 clear thePy_TPFLAGS_VALID_VERSION_TAG bit from tp_flags when modifying the type, asthey should, but do not update tp_version_tag as typeobject.c expects. (Forexample, merely one of many instances I've found:https://github.com/OSGeo/gdal/blob/6bd07b20b3e55c2fc94da611244a615a4fd2991f/swig/python/extensions/osr_wrap.cpp#L2296)In release builds this means a potentially stale cached entry is used, andin debug builds (or release builds that happen to enable assertions, whichas it turns out is actually a good idea) it triggers an assertion error.SWIG 4.1.0 avoids this problem by using PyType_Modified(), but there are alot of older versions of SWIG and of checked-in generated extension modulesaround.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
LGTM. However, let's wait a bit for others to review.
#if MCACHE_STATS | ||
cache->hits++; | ||
#endif | ||
assert(_PyType_HasFeature(type, Py_TPFLAGS_VALID_VERSION_TAG)); | ||
return entry->value; | ||
} | ||
Fidget-SpinnerNov 9, 2022 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
For other reviewers wondering what happens down this code path ifPy_TPFLAGS_VALID_VERSION_TAG
is not set:
- A normal lookup happens where we walk the MRO.
- We assign a new version tag to the type. This sets
Py_TPFLAGS_VALID_VERSION_TAG
.
So this should be safe.
@@ -0,0 +1 @@ | |||
Fix an issue where extension modules could inadvertently trigger an assertion error in typeobject.c by clearing the Py_TPFLAGS_VALID_VERSION_TAG tp_flag without clearing the tp_version_tag field. (Extension modules should use PyType_Modified() instead, however.) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
I just noticedPy_TPFLAGS_VALID_VERSION_TAG
isn't actually documented.
Fix an issue where extension modules could inadvertently trigger an assertion error in typeobject.c by clearing the Py_TPFLAGS_VALID_VERSION_TAG tp_flag without clearing the tp_version_tag field. (Extension modules should use PyType_Modified() instead, however.) | |
Fix an issue where extension modules could inadvertently trigger an assertion error in``typeobject.c`` by clearing the``Py_TPFLAGS_VALID_VERSION_TAG``:c:member:`~PyTypeObject.tp_flags` without clearing the:c:member:`~PyTypeObject.tp_version_tag` field. (Extension modules should use:c:func:`PyType_Modified` instead, however.) |
Fidget-Spinner commentedNov 9, 2022 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
Copying a comment I made elsewhere: The code will One fix is to add a guard to all specialised |
Uh oh!
There was an error while loading.Please reload this page.
Extension modules generated by SWIG up to version 4.1.0 clear the Py_TPFLAGS_VALID_VERSION_TAG bit from tp_flags when modifying the type, as they should, but do not update tp_version_tag as typeobject.c expects. (For example, merely one of many instances I've found:https://github.com/OSGeo/gdal/blob/6bd07b20b3e55c2fc94da611244a615a4fd2991f/swig/python/extensions/osr_wrap.cpp#L2296)
In release builds this means a potentially stale cached entry is used, and in debug builds (or release builds that happen to enable assertions, which as it turns out is actually a good idea) it triggers an assertion error.
SWIG 4.1.0 avoids this problem by using PyType_Modified(), but there are a lot of older versions of SWIG and of checked-in generated extension modules around.