[Python-bugs-list] [ python-Bugs-793822 ] gc.get_referrers() is inherently dangerous

SourceForge.net noreply at sourceforge.net
Sat Sep 6 16:51:03 EDT 2003


Bugs item #793822, was opened at 2003-08-23 10:17
Message generated for change (Comment added) made by bcannon
You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=793822&group_id=5470

Category: Python Interpreter Core
Group: Python 2.3
Status: Open
Resolution: None
Priority: 5
Submitted By: Armin Rigo (arigo)
Assigned to: Nobody/Anonymous (nobody)
Summary: gc.get_referrers() is inherently dangerous

Initial Comment:
gc.get_referrers() can be used to crash any Python

interpreter because it allows the user to obtain

objects which are still under construction.



Here is an example where an iterator can use it to

obtain a tuple while it is still being populated by the

'tuple' built-in function. The following example

triggers a SystemError, but as the tuple 't' is at the

moment still full of null values it can easily generate

segfaults instead.



from gc import get_referrers



def iter():

    tag = object()

    yield tag   # 'tag' gets stored in the result tuple

    lst = [x for x in get_referrers(tag)

           if isinstance(x, tuple)]

    t = lst[0]  # this *is* the result tuple

    print t     # full of nulls !



tuple(iter())



Unless someone has more ideas than me as to how to

prevent this problem, I'd suggest that

gc.get_referrers() should be deemed 'officially

dangerous' in the docs.



----------------------------------------------------------------------

>Comment By: Brett Cannon (bcannon)
Date: 2003-09-06 15:51

Message:
Logged In: YES 
user_id=357491

The wording Armin proposes in his patch makes sense to me.

----------------------------------------------------------------------

Comment By: Armin Rigo (arigo)
Date: 2003-09-02 11:11

Message:
Logged In: YES 
user_id=4771

Here is the doc patch (attached).



A clean solution to this problem would involve delaying GC

registration, which I think would imply changes in the C

API. It is probably not worth it. I don't think it would be

a problem for the GC not to be able to browse through

objects still under constructions because such objects are

never part of a dead cycle anyway, and probably not part of

a cycle at all until later mutated.

----------------------------------------------------------------------

Comment By: Tim Peters (tim_one)
Date: 2003-08-31 16:36

Message:
Logged In: YES 
user_id=31435

Martin, it's easy to transform the example into one that 

crashes.  For example, adding "print t[3]" as the last line of 

the iter() function causes it to die with a segfault on my box.  

Virtually anything that fetches a NULL from the tuple will try 

to Py_INCREF it (that's all "t[3]" does), and that's an instant 

NULL-pointer dereferencing death.



That said, it would be more helpful <wink> if Armin submitted 

a doc patch.  The introspective features of the gc module are 

intended to be used by consenting adults facing hard 

debugging problems, and I don't care if they can be tricked 

into blowing up.  I agree the docs should point out the 

possibility, though.

----------------------------------------------------------------------

Comment By: Martin v. Löwis (loewis)
Date: 2003-08-31 10:18

Message:
Logged In: YES 
user_id=21627

I see no harm in your example. Even though the tuple has

NULLs in it, is in a stable state. The lesson learned is

that an object should become gc-tracked only if it is in a

stable state, as gc-tracking means to expose references to

the object. This is true independent of get_referrers, as

gc-tracking means that tp_traverse might be called for the

object, so it *has* to be in a stable state.



I fail to see how the example "crashes" the Python

interpreter. I causes a SystemError when the tuple is

resized, that's all. There are many ways to cause a

SystemError, including



raise SystemError



I recommend not to declare a function as "dangerous" in the

docs. Instead, the actual problem should be explained, both

in the GC part of the C API, and in gc module docs (for both

get_referrers, and get_objects).

----------------------------------------------------------------------

Comment By: Armin Rigo (arigo)
Date: 2003-08-28 06:23

Message:
Logged In: YES 
user_id=4771

But it would be very difficult to fix the code base to avoid

the problem. The 'tuple' constructor was only an example; it

is actually a quite common pattern everywhere in the C code

base of both the core and extension modules. Expecting an

object not to be seen before you first hand it out is

extremely common, and get_referrers() breaks that

assumption. Hence the claim that the problem really lies in

get_referrers().

----------------------------------------------------------------------

Comment By: Denis S. Otkidach (ods)
Date: 2003-08-28 00:35

Message:
Logged In: YES 
user_id=63454

I guess it's dangerous to make object that is not properly 

initialized reachable from other code. Even if it's reachable 

with get_referrers() only. There is no danger in 

get_referrers() itself.

----------------------------------------------------------------------

You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=793822&group_id=5470



More information about the Python-bugs-list mailing list