You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
ctypes pointer not always keeping target alive #46376
It's hard to tell for sure, given the lack of precise definition, but I
believe that the attached piece of code "should" work. What it does is
make p1 point to c_long(20). So ctypes should probably keep the
c_long(20) alive as long as p1 is alive (and not further modified).
This test shows that the c_long(20) gets freed instead, making the
p1.contents reference garbage.
Assigning to .contents changes 'where the pointer points to'.
__setitem__ changes the pointed to memory location; __getitem__
retrieves the pointed to memory location.
Having said that, it is no longer clear to me what reading the
.contents attribute should mean. Would making the .contents attribute
write-only help - is it impossible to construct this 'bug' without
assigning to .contents?
We're finding such bugs because we are trying to reimplement ctypes in PyPy.
I guess your last question was "is it impossible to construct this 'bug'
without *reading* .contents?". The answer is that it doesn't change
much; you can replace all the reads from .contents with reads from [0],
and still see the issue. See attached y.py, where I've put the
equivalent C code in comments.
Activity
arigo commentedon Feb 15, 2008
It's hard to tell for sure, given the lack of precise definition, but I
believe that the attached piece of code "should" work. What it does is
make p1 point to c_long(20). So ctypes should probably keep the
c_long(20) alive as long as p1 is alive (and not further modified).
This test shows that the c_long(20) gets freed instead, making the
p1.contents reference garbage.
theller commentedon Feb 15, 2008
May I ask: do you have a real use case for this, or is it a carefully
constructed example?
Of course I take all the blame for not defining/documenting this
stuff. My current view is this:
Python code C code
======================= ================
Assigning to .contents changes 'where the pointer points to'.
__setitem__ changes the pointed to memory location; __getitem__
retrieves the pointed to memory location.
Having said that, it is no longer clear to me what reading the
.contents attribute should mean. Would making the .contents attribute
write-only help - is it impossible to construct this 'bug' without
assigning to .contents?
arigo commentedon Feb 16, 2008
We're finding such bugs because we are trying to reimplement ctypes in PyPy.
I guess your last question was "is it impossible to construct this 'bug'
without *reading* .contents?". The answer is that it doesn't change
much; you can replace all the reads from .contents with reads from [0],
and still see the issue. See attached y.py, where I've put the
equivalent C code in comments.
bitdancer commentedon Mar 24, 2009
Thomas, do you accept this as a bug or should the issue be closed as
invalid?
theller commentedon Mar 26, 2009
I accept this as a bug; however I don't have time now to work on it.
ambv commentedon Jul 22, 2023
This looks like it works as expected at least as of Python 3.7 where c_long(20) is indeed preserved and p1.contents removes 20 as expected.
code-of-kpp commentedon Jul 22, 2023
Original examples would pass, but only because of gc delay.
Here's fun way to demonstrate that the problem still exists (and can be converted to a test):
24 remaining items
pythongh-46376: add (failing) tests for ctypes/pointer/cast/set_contents
pythongh-46376: add (failing) tests for ctypes/pointer/cast/set_contents
vstinner commentedon Aug 30, 2023
Right, see issue #107940 which is a Python 3.12 regression.
In the 3.12 branch, I confirm that the commit 54aaaad introduced the regression: issue #46376 of PR #107487 (backport of PR #107131).
Revert "pythongh-46376: Return existing pointer when possible in ctyp…
code-of-kpp commentedon Aug 31, 2023
Please, take a look at
#108519
Revert "gh-46376: Return existing pointer when possible in ctypes (#1… (
Revert "[3.12] pythongh-46376: Return existing pointer when possible …
Revert "pythongh-46376: Return existing pointer when possible in ctyp…
[3.12] gh-46376: Revert "Return existing pointer when possible in cty…
pythongh-46376: add (failing) tests for ctypes/pointer/cast/set_contents
pythongh-46376: add (failing) tests for ctypes/pointer/cast/set_contents
pythongh-46376: add (failing) tests for ctypes/pointer/cast/set_contents
pythongh-46376: minimal fix for setting pointers via pointers in ctypes