[C-API] Weird sys.exc_info reference segfault

Antoine Pitrou solipsis at pitrou.net
Sun Oct 3 01:16:51 CEST 2010


On Sat, 02 Oct 2010 23:35:01 +0200
"Jonas H." <jonas at lophus.org> wrote:
> 
> This WSGI application:
> 
>    def app(env, start_response):
>        start_response('200 alright', [])
>        try:
>            a
>        except:
>            import sys
>            sys.exc_info()
>        return ['hello']
> 
>    import bjoern
>    bjoern.run(app, '0.0.0.0', 8080)
> 
> works perfect, however, if I make the 7th line an assignment:
> 
>    x = sys.exc_info()
> 
> I get a segmentation fault after a few requests, the stack trace being:
> 
>    #1  frame_clear ()
>    #2  collect ()
>    #3  _PyObject_GC_Malloc ()
[...]
> 
> Now that is weird. The only difference between the two functions is that 
> the second one (with the assignment) keeps a reference to the exc_info 
> tuple in the function frame.

Which creates a reference cycle, since you now have a local variable
which has a reference to the exception traceback which has a reference
to the current frame which has a reference to the local variable.

This explains that the cyclic garbage collector ("collect()") gets
called in the code above, and tries to clear the frame which is caught
in the reference cycle ("frame_clear()"). The important thing to notice
is that clearing the frame can happen long after the frame was last
executed (that's because the cyclic garbage collector is only run from
time to time, based on allocation statistics). Which explains that you
get a segmentation fault only after a few requests.

So the issue is to find out why clearing the frame crashes. You should
check that you aren't doing anything wrong with "env" and
"start_response" (like deallocate them forcefully).

> Do you have any tips how to debug this?

If the information above is not sufficient, you could use a debug build
of Python ("./configure --with-pydebug" when building from the source
tree). It will enable both C-level debugging information and additional
assertions in the Python interpreter.

Regards

Antoine.





More information about the Python-list mailing list