Jesús Cea Avión <j...@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 <rep...@bugs.python.org>
<http://bugs.python.org/issue13616>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to