Skip to content

[3.12] getattr_static can result in reference leaks #118013

Closed
@williamwen42

Description

@williamwen42

Bug report

Bug description:

I discovered this bug while working on pytorch/pytorch#124302.

It looks like calling getattr_static is causing an object to be reference leaked:

import gc
from inspect import getattr_static
import weakref

class C1:
    pass

def main():
    obj = C1()
    weakref.finalize(obj, lambda: print("obj deleted!"))
    class C2:
        def __init__(self):
            self.obj = obj
    c2 = C2()
    getattr_static(c2, "bad", None)
    print("done main!")

main()
gc.collect()
print("done!")

Output:

done main!
done!
obj deleted!

If I comment out the getattr_static line, the output is as expected:

done main!
obj deleted!
done!

It looks like this PR #104267 indirectly cached calls to getattr_static, which is resulting in reference leaks. Perhaps this cache needs to use weak references?

Original PyTorch code for reference (torch.compile calls getattr_static on mod at some point):

import torch

import gc
import sys
import weakref

from inspect import getattr_static

def dbg(o):
    refs = gc.get_referrers(o)
    print(len(refs), sys.getrefcount(o))
    return refs

gm_list = []
def backend(gm, _):
    gm_list.append(weakref.ref(gm, lambda _: print("gm deleted")))
    # breakpoint()
    return gm

def main():
    param = torch.nn.Parameter(torch.randn(5, 5))

    class Mod(torch.nn.Module):
        def __init__(self):
            super().__init__()
            self.param = param

        def forward(self, x):
            return self.param * x

    mod = Mod()
    ref = weakref.ref(param, lambda _: print("obj deleted"))
    opt_mod = torch.compile(mod, backend=backend)
    print(opt_mod(torch.randn(5, 5)))
    return ref

ref = main()

gc.collect()
print("done!")
print(ref)

CPython versions tested on:

3.12

Operating systems tested on:

Linux

Linked PRs

Metadata

Metadata

Assignees

Labels

3.12only security fixes3.13bugs and security fixesstdlibPython modules in the Lib dirtype-bugAn unexpected behavior, bug, or error

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions