Bug report
Bug description:
PyObject*dumps=state->pickle.dumps;
if (dumps!=NULL) {
returndumps;
}
dumps=PyImport_ImportModuleAttrString("pickle", "dumps");
if (dumps==NULL) returnNULL;
state->pickle.dumps=dumps;
returndumps;This is a check-then-act race. Two threads in the same interpreter can both run this code:
- Thread A reads state->pickle.dumps → NULL
- Thread B reads state->pickle.dumps → NULL
- Thread A imports pickle.dumps, holds a strong reference R_A
- Thread B imports pickle.dumps, holds a strong reference R_B
- Thread A stores R_A into the slot
- Thread B stores R_B into the slot, overwriting R_A
Now the slot owns R_B, and R_A is leaked forever.
CPython versions tested on:
CPython main branch
Operating systems tested on:
macOS
Linked PRs
Bug report
Bug description:
This is a check-then-act race. Two threads in the same interpreter can both run this code:
Now the slot owns R_B, and R_A is leaked forever.
CPython versions tested on:
CPython main branch
Operating systems tested on:
macOS
Linked PRs