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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions