Bug#748922: python-apt: TagFile doesnt close file
On Thu, May 22, 2014 at 11:57:12AM +0200, Johannes Schauer wrote:
> Package: python-apt
> Version: 0.9.3.5
> Severity: normal
Thanks for your bugreport.
> Consider the following snippet:
>
> --%<---------------------------------------------------
> import gc
> import os
> import sys
> import apt_pkg
>
> print os.listdir("/proc/self/fd/")
> f = apt_pkg.TagFile(sys.argv[1])
> print os.listdir("/proc/self/fd/")
> del f
> print os.listdir("/proc/self/fd/")
> gc.collect
> print os.listdir("/proc/self/fd/")
> -->%---------------------------------------------------
There is a small typo in the above script. gc.collect should be
gc.collect().
I verified that the following works and does not leak fds:
"""
class LeakTestCase(unittest.TestCase):
def test_leak(self):
# clenaup gc first
import gc
gc.collect()
# see what fds we have
fds = os.listdir("/proc/self/fd")
testfile = __file__
tagf = apt_pkg.TagFile(testfile)
tagf.step()
del tagf
import gc
gc.collect()
# ensure fd is closed
self.assertEqual(fds, os.listdir("/proc/self/fd"))
"""
Unfortunately just doing a "del tagf" is not enough, the gc call is
needed afterwards. The reason that the del is not enough is that there
is there is a cyclic reference from the tagf to tagf.section. The
garbage collector breaks it, but a simple del sees a refcount >
0. This particular case could maybe fixed by copying the data from the
pkgTagFile to a pkgTagSection instead of letting it operator on the
Buffer of pkgTagFile. But that requires somework (plus additional
memory for the copied data).
Cheers,
Michael
Reply to: