python / python/cpython

make marshal output not dependent on reference count

Offen
#98,819 4 Kommentare 1 Reaktion 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

interpreter-core type-bug
Vorherrschende Sprache
Python
Sterne
77.2k
Forks
36k
Ø Merge
1 T. 9 Std.
Gemergte PRs (30 T.)
558

Beschreibung

Bug report

Currently the marshal module will emit a previously-unseen object flagged as a potential reference from later objects, unless the object has a reference count of 1. See https://github.com/python/cpython/blob/b27b57c6e44a276c8a9843fd37d4cf65b2827d5c/Python/marshal.c#L305

This is an overly-conservative heuristic -- it's easy to construct cases where an object has a reference count >1 but is not actually referenced by any other object about to be marshaled, so FLAG_REF is set when it does not need to be.

This makes marshal output unstable depending on accidents of reference counting behavior in the code calling marshal.dumps.

I ran into this because the Cinder JIT is able to reduce unnecessary increfs, and that resulted in some importlib tests failing on comparison of marshal output at https://github.com/python/cpython/blob/b27b57c6e44a276c8a9843fd37d4cf65b2827d5c/Lib/test/test_importlib/test_abc.py#L870-L871 because under Cinder JIT the reference count of code_object in that method is 1.

This previously caused issues in distutils reproducibility, resulting in a partial fix that applies only to interned strings: https://github.com/python/cpython/pull/8226

It would be better if marshal would actually determine which objects have multiple parents in the DAG and deterministically use FLAG_REF or not based on that.

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Rechercherichtung

Beginne mit Python/marshal.c bei der referenzierten Referenzzählungsheuristik und untersuche die betroffenen Assertions in Lib/test/test_importlib/test_abc.py in den Zeilen 870-871. Verfolge, wie marshal.dumps FLAG_REF bestimmt, erstelle dann Tests, die zeigen, dass die Ausgabe unabhängig von den Referenzzählerständen des Aufrufers ist, und bestätige, dass die importlib-Tests erfolgreich durchlaufen.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
c, python
Bereich
backend
Issue-Typ
Bug
Schwierigkeit
5/5
Geschätzter Aufwand
Über eine Woche
Aktivitätsstatus
Veraltet
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
35/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.