[Python-Dev] Problem with _PyTrash_destroy_chain ?

Manu cupcicm at gmail.com
Thu Aug 30 22:22:17 CEST 2012


On Thu, Aug 30, 2012 at 8:49 PM, "Martin v. Löwis" <martin at v.loewis.de>wrote:

> Am 30.08.12 14:39, schrieb Manu:
>
>  After spending quite a bit of time trying to understand what could go
>> wrong in the C extensions I use, and not finding anything interesting, I
>> decided to try to find the problem with gdb. The stacktrace I have seems
>> to mean that we are trying to double free something in the frame_dealloc
>> method. See
>>
>> (gdb) bt
>> #0  0x000000000046479f in _Py_ForgetReference (op=0x4dc7bc0) at
>> Objects/object.c:2222
>> #1  0x0000000000464810 in _Py_Dealloc (op=0x4dc7bc0) at
>> Objects/object.c:2242
>> #2  0x0000000000559a68 in frame_dealloc (f=0x4997ab0) at
>> Objects/frameobject.c:458
>> #3  0x000000000046481d in _Py_Dealloc (op=0x4997ab0) at
>> Objects/object.c:2243
>>
>
> Why do you think that this stacktrace "seems to mean that we are trying
> to double free something"? I can't infer that from the stacktrace.
>

That's right, sorry. The reason why I think this is a double free is that
the op seems to point to an object that has been deallocated by python.

(gdb) select-frame 0
(gdb) print *op
$6 = {_ob_next = 0x0, _ob_prev = 0x0, ob_refcnt = 0, ob_type = 0x2364020}



>
> You seem to suggest that the crash happens on object.c:2222. If so,
> it's indeed likely a double-free; my suspicion is that the object memory
> shows the regular "deallocated block" memory pattern (display *op at
> the point of crash).
>
> It would then be interesting to find out what object used to be there.
> Unfortunately, there is no easy way to find out (unless the crash
> always involves 0x4dc7bc0).


Not sure why you know this address by heart ;) but the op pointer points
exactly there in the stacktrace I posted in the bug report. I'd bet it's
like this every time. What does it mean ?

(gdb) p op
$12 = (PyObject *) 0x4dc7bc0

I'll reproduce tomorrow and tell you if I get this again.


> So I suggest the following tracing:
>
> - in _Py_NewReference, printf("allocate %p\n", op);
> - in _Py_ForgetReference,
>   printf("free %p %s\n", op, op->ob_type->tp_name);
>   fflush(stdout);
>
> This may get large, so you may open a file (e.g. in /tmp/fixedname)
> to collect the trace. When it crashes, find the last prior free
> of the address - there shouldn't be any subsequent alloc.
>
> If the type doesn't give a clue, but it's always the same type,
> you can restrict tracing to that type, and then print values
> of the object for further diagnosis.
>

OK I'll do that.

It's always the same type. It's one of our mapped SqlAlchemy types. The
code I am using uses sqlalchemy heavily in a multithreaded environment, and
is using mostly instances of exactly this mapped type.


>
> Other useful debug information would be to find out what specific
> frame object is being deallocated - this can still be diagnosed
> at the point of crash (try _PyObject_Dump(f->f_code)), and then
> which specific variable (not sure what exact Python version you
> are using - it seems it's in localsplus, so it likely is a local
> variable of that frame).
>

I used the macro to get the python stacktrace. It always crashes on the
same line, in a sqlalchemy file. It looked innocuous to me, but I can post
it tomorrow when I get back to work.


>
> HTH,
> Martin
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-dev/attachments/20120830/8a1a9431/attachment.html>


More information about the Python-Dev mailing list