lericson/pylibmc — Issue #68: Bad decref causes python panic.
Author: bukzor
Created: 2011-12-20 19:22:13+00:00
State: open

The decref on this line is improper:
https://github.com/lericson/pylibmc/blob/master/_pylibmcmodule.c#L1439

Timeline:
1. There is a pickled value in memcached which cannot be unpickled
2. pylibmc attempts to fetch and unpickle the value
3. pylibmc fails to unpickle the value
4. pylibmc decrements the refcount on its empty result dict
5. pylibmc returns the result dict
6. user's python code releases reference on the dictionary
7. python gc caches empty dictionary for later use
8. user's code allocates a dictionary, in completely unrelated code
9. python gc uses the pylibmc result dict (from #4) to fulfil the allocation
10. refcount check fails. Python stops with fatal error "[GC object already tracked](http://hg.python.org/cpython/file/99af4b44e7e4/Include/objimpl.h#l267)"

This is the value which caused this problem for us, after unzipping:

"\200\002}q\001(U\006ratingq\002G@\002;:\222\031\001\370U\vis_inactiveq\003\211U\022is_bogus_for_eventq\004\211U\004dealq\005NU\006mapURLq\006UPhttp://maps.google.com/maps?q=1%20World%20Way%2C%20Los%20Angeles%2C%20CA%2090045q\aU\nhours_rowsq\b]q\t(}q\n(U\topen_timeq\v\212"

Here is the binary, unzipped value, in python-repr form:
https://gist.github.com/1502632