Skip to content

Release pool unsoundness #756

@Alexander-N

Description

@Alexander-N

Follow up for #720 where NameErrors and SIGSEGVs were found. The error can be observed with two tests running in parallel (might need a few tries):

#[test]
fn test_release_race1() {
    let gil = Python::acquire_gil();
    let py = gil.python();
    println!("make ob1");
    let ob1 = py.eval("object()", None, None).unwrap();
    py.import("datetime").unwrap();
    py_run!(py, ob1, "print('ob1' + str(ob1))");
}

#[test]
fn test_release_race2() {
    let gil = Python::acquire_gil();
    let py = gil.python();
    println!("make ob2");
    let ob2 = py.eval("object()", None, None).unwrap();
    py.import("datetime").unwrap();
    py_run!(py, ob2, "print('ob2' + str(ob2))");
}

What might be happening is:

  • ob1 gets put into the release pool
  • the import releases the GIL temporarily
  • test_release_race2 makes progress and ob2 gets put into the release pool
  • test_release_race1 finishes and with dropping of it's GILGuard ob2 instead of ob1 is popped from the relase pool
  • test_release_race2 fails because ob2 has been freed

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions