Skip to content

gc longlived relocation problem #1218

@notro

Description

@notro

I'm working on the tests for the logging module and I encountered a problem that can be expressed like this:

Adafruit CircuitPython patchbase-7-g216f0f952-dirty on 2018-09-25; Adafruit Metro M4 Express with samd51j19
>>> class Logger:
...     pass
...
>>> root = Logger()
>>> Logger.root = root
>>> Logger.root == root
False
>>> root
<Logger object at 20002a00>
>>> Logger.root
<Logger object at 2002d9a0>
>>>

If I disable gc_make_long_lived() it works as expected.

Is this a second reference case as mentioned in the code?

    // We copy everything over and let the garbage collection process delete the old copy. That way
    // we ensure we don't delete memory that has a second reference. (Though if there is we may
    // confuse things when its mutable.)

My workaround is:

root = RootLogger(WARNING)
Logger.root = root
root = Logger.root  ## Work around gc long lived relocation not fixing up refs

My next step was to turn the old object into a Zombie (patch) so it would be easy to detect when/if I accessed the dead object.

But what's going on here?

>>> class Logger: pass
...
>>> root = Logger()
>>> root
<Logger object at 20002a50>
>>> root
Zombie
>>>

It turns out that the _ variable assignment makes the object longlived...

>>> class Logger: pass
...
>>> root = Logger()
>>> _
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name '_' is not defined
>>> root
<Logger object at 20002a50>
>>> _
<Logger object at 2002e9c0>
>>> p = _
>>> root
Zombie
>>> p
<Logger object at 2002e9c0>
>>> p
<Logger object at 2002e9c0>
>>>

I really would like a way to know if I'm accessing the old discarded object. The current situation leads to bugs that are subtle an difficult to find.
Luckily the logging module had a test case that tripped over this.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions