Skip to content

Immutability: Incorrect unfreeze of non-completed SCC #100

@kulisak12

Description

@kulisak12

Setup

Running on latest immutable-main:

from immutable import freeze

class A:
    pass

class Restart:
    def __pre_freeze__(self):
        freeze(self)

a = A()
a.l = [a, Restart()]
l = a.l  # create another reference

freeze(A)
print("All good")
freeze(a)

Output

All good
./Include/refcount.h:673: _Py_NegativeRefcount: Assertion failed: object has negative ref count
<object at 0x73d90168be40 is freed>
Fatal Python error: _PyObject_AssertFailed: _PyObject_AssertFailed
Python runtime state: initialized

Current thread 0x000073d902611740 [python] (most recent call first):
  File "/home/david/coding/cpython/personal/debug.py", line 8 in __pre_freeze__
  File "/home/david/coding/cpython/personal/debug.py", line 15 in <module>
Aborted (core dumped)

What happens

When the freezing algorithms encounters a again, it creates an SCC but does not complete it yet, meaning that reference counts stay mostly intact.
The pre-freeze hook causes a restart, which unfreezes a, calling scc_reset_root_refcount.
However, that function assumes that the SCC already uses a single reference count in its representative.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions