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. 

-- 
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.


Reply via email to