[issue13616] Never ending loop in in update_refs Modules/gcmodule.c

Jesús Cea Avión report at bugs.python.org
Tue Dec 20 03:27:48 CET 2011


Jesús Cea Avión <jcea at jcea.es> added the comment:

Instrumentalize: check for this pathological case (an object with a GC pointer back to itself) in the code that modify the GC pointers. Lets say, everytime code change the pointers, you test for this. Luckily you can learn the codepath creating this situation. Change and recompile python code for checking this.

Read Include/object.h. You will see that ANY python object has, at least, two components: a reference counter and a pointer to its type. Follow that pointer to type and get its name.

Let me try an example...

"""
gdb python
GNU gdb (GDB) 7.3.1
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i386-pc-solaris2.10".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /usr/local/bin/python...done.
(gdb) br PyTuple_New
Function "PyTuple_New" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 1 (PyTuple_New) pending.
(gdb) r
Starting program: /usr/local/bin/python 
[Thread debugging using libthread_db enabled]
[New Thread 1 (LWP 1)]
[Switching to Thread 1 (LWP 1)]

Breakpoint 1, PyTuple_New (size=0) at Objects/tupleobject.c:50
50      Objects/tupleobject.c: No such file or directory.
        in Objects/tupleobject.c
(gdb) fin
Run till exit from #0  PyTuple_New (size=0) at Objects/tupleobject.c:50
0xfee650e4 in PyType_Ready (type=0xfef5cd00) at Objects/typeobject.c:4077
4077    Objects/typeobject.c: No such file or directory.
        in Objects/typeobject.c
Value returned is $1 = (PyObject *) 0x806202c
(gdb) print $1->ob_type
$2 = (struct _typeobject *) 0xfef5cb40
(gdb) print *($1->ob_type)
$3 = {ob_refcnt = 1, ob_type = 0xfef5cde0, ob_size = 0, tp_name = 0xfef07542 "tuple", tp_basicsize = 12, tp_itemsize = 4, 
  tp_dealloc = 0xfee568f0 <tupledealloc>, tp_print = 0xfee56c80 <tupleprint>, tp_getattr = 0, tp_setattr = 0, tp_compare = 0, 
  tp_repr = 0xfee57380 <tuplerepr>, tp_as_number = 0x0, tp_as_sequence = 0xfef52500, tp_as_mapping = 0xfef52528, 
  tp_hash = 0xfee56850 <tuplehash>, tp_call = 0, tp_str = 0, tp_getattro = 0xfee416d0 <PyObject_GenericGetAttr>, tp_setattro = 0, 
  tp_as_buffer = 0x0, tp_flags = 67519979, 
  tp_doc = 0xfef3b580 "tuple() -> empty tuple\ntuple(iterable) -> tuple initialized from iterable's items\n\nIf the argument is a tuple, the return value is the same object.", tp_traverse = 0xfee56440 <tupletraverse>, tp_clear = 0, 
  tp_richcompare = 0xfee56b10 <tuplerichcompare>, tp_weaklistoffset = 0, tp_iter = 0xfee56a60 <tuple_iter>, tp_iternext = 0, 
  tp_methods = 0xfef52540, tp_members = 0x0, tp_getset = 0x0, tp_base = 0x0, tp_dict = 0x0, tp_descr_get = 0, tp_descr_set = 0, 
  tp_dictoffset = 0, tp_init = 0, tp_alloc = 0, tp_new = 0xfee57680 <tuple_new>, tp_free = 0xfeede6a0 <PyObject_GC_Del>, 
  tp_is_gc = 0, tp_bases = 0x0, tp_mro = 0x0, tp_cache = 0x0, tp_subclasses = 0x0, tp_weaklist = 0x0, tp_del = 0, 
  tp_version_tag = 0}
"""

I break in the tuple creation routine. Then I let it finish. It is going to return a PyObject, a generic python object. I follow the type pointer and get the name of the type: 'tp_name = 0xfef07542 "tuple"'. I already knew the result was going to be a tuple, but it is nice to cross-check :)

Sometimes it is more complicated, and you have to cast pointers. Use the source code as your map.

Sorry, it is difficult to teach how to do such a low level debug remotely :).

PS: Remember to add "gc.collect()" in your mainloop. In this way you will hit the problem faster, because you don't have to wait for Python to invoke the collector implicitly. If you have tons of objects this can be actually slower. Try.

----------

_______________________________________
Python tracker <report at bugs.python.org>
<http://bugs.python.org/issue13616>
_______________________________________


More information about the Python-bugs-list mailing list