[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

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: