python / python/cpython

make marshal output not dependent on reference count

Aperta
#98,819 4 commenti 1 reazione 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

interpreter-core type-bug
Lingua principale
Python
Stelle
77.2k
Fork
36k
Merge medio
1g 9h
PR unite (30g)
558

Descrizione

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.

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Direzione di ricerca

Inizia da Python/marshal.c in corrispondenza dell’euristica sul conteggio dei riferimenti indicata e ispeziona le asserzioni interessate in Lib/test/test_importlib/test_abc.py alle righe 870-871. Traccia il modo in cui marshal.dumps decide FLAG_REF, quindi crea test che dimostrino che l’output è indipendente dai conteggi dei riferimenti del chiamante e conferma che i test di importlib passano.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
c, python
Ambito
backend
Tipo di issue
Bug
Difficoltà
5/5
Tempo stimato
Più di una settimana
Stato di attività
Ferma
Chiarezza
Abbastanza chiara
Idoneità per principianti
35/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.