forked from micropython/micropython
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Closed
Labels
Milestone
Description
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.