On Monday, December 31, 2012 4:09:47 PM UTC+1, Jean-Pierre Flori wrote: > > > > On Monday, December 31, 2012 12:12:52 AM UTC+1, Nils Bruin wrote: >> >> OK, caught redhanded. Indeed, the freelist of this pool ends up being >> circular, due to a double free happening. The first free is >> indeed coming from a TripleDictEraser callback. The second one doesn't >> seem to be. Indeed, the second one doesn't seem to be >> triggered by a GC, but simply by a refcount hitting zero. Either that >> or someone holding a pointer to an object on which it blindly >> calls a release. I imagine that could happen in an extension class >> where object pointers are stored in c variables. Objects that get >> cleaned up as circular garbage can't trust that everything they're >> used to pointing at is still alive during a dealloc. Perhaps >> __pyx_tp_dealloc_4sage_9structure_15category_object_CategoryObject >> needs to be examined for how it clears its substructures. Once >> circular references are involved (or hidden ones as with weakrefs) the >> rug can really be pulled from under you. >> >> tracebacks below >> >> (here 0x7fffbeb3e008 == &(pool->freeblock) ) >> >> (gdb) p *(block **) 0x7fffbeb3e008 >> (gdb) p *(block **) 0x7fffbeb3e008 >> $9 = (block *) 0x7fffbeb3e330 "0\u4cfe\377\177" >> (gdb) p *(block **) 0x7fffbeb3e330 >> $10 = (block *) 0x7fffbeb3e430 "" >> (gdb) p *(block **) 0x7fffbeb3e430 >> >> traceback is: >> >> #0 PyObject_Free (p=0x7fffbeb3e330) at Objects/obmalloc.c:981 >> #1 0x00007ffff7cc7b76 in subtype_dealloc (self=0x7fffbeb3e350) at >> Objects/typeobject.c:1014 >> #2 0x00007ffff7d4b7ca in delete_garbage (old=0x7ffff7fe19e0, >> collectable=0x7fffffffafb0) at Modules/gcmodule.c:770 >> #3 collect (generation=1) at Modules/gcmodule.c:930 >> #4 0x00007ffff7d4c1a8 in collect_generations () at Modules/gcmodule.c: >> 996 >> #5 _PyObject_GC_Malloc (basicsize=<optimized out>) at Modules/ >> gcmodule.c:1457 >> #6 _PyObject_GC_Malloc (basicsize=<optimized out>) at Modules/ >> gcmodule.c:1439 >> #7 0x00007ffff7d4c1cd in _PyObject_GC_New (tp=0x7ffff7fb7d00) at >> Modules/gcmodule.c:1467 >> #8 0x00007ffff7c86cb8 in PyWrapper_New (d=0x7ffff7bce230, >> self=0xb2eca0) at Objects/descrobject.c:1068 >> #9 0x00007ffff7cafcda in _PyObject_GenericGetAttrWithDict >> (obj=0xb2eca0, name=0x7ffff7bbc180, dict=0x0) at Objects/object.c:1434 >> #10 0x00007fffe99685b9 in >> __pyx_pf_4sage_9structure_11coerce_dict_16TripleDictEraser_2__call__ >> (__pyx_v_r=<optimized out>, >> __pyx_v_self=<optimized out>) at sage/structure/coerce_dict.c:1225 >> #11 >> __pyx_pw_4sage_9structure_11coerce_dict_16TripleDictEraser_3__call__ >> (__pyx_v_self=0x7fffea8659b8, >> __pyx_args=<optimized out>, __pyx_kwds=<optimized out>) at sage/ >> structure/coerce_dict.c:966 >> #12 0x00007ffff7c6f403 in PyObject_Call (func=0x7fffea8659b8, >> arg=<optimized out>, kw=<optimized out>) at Objects/abstract.c:2529 >> #13 0x00007ffff7c6fcf0 in PyObject_CallFunctionObjArgs >> (callable=0x7fffea8659b8) at Objects/abstract.c:2760 >> #14 0x00007ffff7cd7b0e in handle_callback (callback=0x7fffea8659b8, >> ref=0x7fffbeb520b0) at Objects/weakrefobject.c:881 >> #15 PyObject_ClearWeakRefs (object=<optimized out>) at Objects/ >> weakrefobject.c:928 >> #16 0x00007fffe9f9f0d0 in >> __pyx_tp_dealloc_4sage_9structure_15category_object_CategoryObject >> (o=0x7fffbeb3e350) >> at sage/structure/category_object.c:8989 >> #17 0x00007ffff7cc7b76 in subtype_dealloc (self=0x7fffbeb3e350) at >> Objects/typeobject.c:1014 >> >> A little later on: >> >> (gdb) p *(block **) 0x7fffbeb3e008 >> $24 = (block *) 0x7fffbeb3e330 "0\u3cfe\377\177" >> (gdb) p *(block **) 0x7fffbeb3e330 >> $25 = (block *) 0x7fffbeb3e330 "0\u3cfe\377\177" >> >> ///THIS IS BAD! This is a circular freelist. >> >> traceback: >> >> #0 PyObject_Free (p=0x7fffbeb3e330) at Objects/obmalloc.c:980 >> #1 0x00007ffff7cc7b76 in subtype_dealloc (self=0x7fffbeb3e350) at >> Objects/typeobject.c:1014 >> #2 0x00007ffff7ca7c97 in insertdict (mp=0x621180, key=0x7ffff7bc0b70, >> hash=12160036574, value=0x7ffff7fc6840) >> at Objects/dictobject.c:530 >> #3 0x00007ffff7caa3ce in PyDict_SetItem (op=0x621180, key=<optimized >> out>, value=0x7ffff7fc6840) at Objects/dictobject.c:775 >> #4 0x00007ffff7caffcb in _PyObject_GenericSetAttrWithDict >> (obj=<optimized out>, name=0x7ffff7bc0b70, value=0x7ffff7fc6840, >> dict=0x621180) at Objects/object.c:1524 >> #5 0x00007ffff7caf9b7 in PyObject_SetAttr (v=0x7ffff7bbbad0, >> name=0x7ffff7bc0b70, value=0x7ffff7fc6840) at Objects/object.c:1247 >> #6 0x00007ffff7d0f3d1 in PyEval_EvalFrameEx (f=<optimized out>, >> throwflag=<optimized out>) at Python/ceval.c:2004 >> #7 0x00007ffff7d14275 in PyEval_EvalCodeEx (co=<optimized out>, >> globals=<optimized out>, locals=<optimized out>, >> args=<optimized out>, argcount=1, kws=0x0, kwcount=0, defs=0x0, >> defcount=0, closure=0x0) at Python/ceval.c:3253 >> #8 0x00007ffff7c9717c in function_call (func=0x7fffc14af1b8, >> arg=0x7fffbeb01190, kw=0x0) at Objects/funcobject.c:526 >> #9 0x00007ffff7c6f403 in PyObject_Call (func=0x7fffc14af1b8, >> arg=<optimized out>, kw=<optimized out>) at Objects/abstract.c:2529 >> #10 0x00007ffff7d0cc97 in PyEval_CallObjectWithKeywords >> (func=0x7fffc14af1b8, arg=0x7fffbeb01190, kw=<optimized out>) >> at Python/ceval.c:3890 >> #11 0x00007ffff7d11d12 in PyEval_EvalFrameEx (f=<optimized out>, >> throwflag=<optimized out>) at Python/ceval.c:1739 >> #12 0x00007ffff7d14275 in PyEval_EvalCodeEx (co=<optimized out>, >> globals=<optimized out>, locals=<optimized out>, >> args=<optimized out>, argcount=0, kws=0x0, kwcount=0, defs=0x0, >> defcount=0, closure=0x0) at Python/ceval.c:3253 >> #13 0x00007ffff7d143b2 in PyEval_EvalCode (co=<optimized out>, >> globals=<optimized out>, locals=<optimized out>) >> at Python/ceval.c:667 >> #14 0x00007ffff7d123df in exec_statement (locals=0x2b65b60, >> globals=0x2b65b60, prog=<optimized out>, f=0x2809550) >> at Python/ceval.c:4718 >> #15 PyEval_EvalFrameEx (f=<optimized out>, throwflag=<optimized out>) >> at Python/ceval.c:1880 >> #16 0x00007ffff7d14275 in PyEval_EvalCodeEx (co=<optimized out>, >> globals=<optimized out>, locals=<optimized out>, >> args=<optimized out>, argcount=5, kws=0x0, kwcount=0, defs=0x0, >> defcount=0, closure=0x0) at Python/ceval.c:3253 >> > Not really sure but we might be interested in the Py_Clear macro to deal > with such intricated cases. > In particular, http://docs.python.org/2/c-api/refcounting.html states: "It is a good idea to use this macro whenever decrementing the value of a variable that might be traversed during garbage collection." Not sure if this is required though.
-- You received this message because you are subscribed to the Google Groups "sage-devel" group. To post to this group, send email to sage-devel@googlegroups.com. To unsubscribe from this group, send email to sage-devel+unsubscr...@googlegroups.com. Visit this group at http://groups.google.com/group/sage-devel?hl=en.