fix: valgrind-detected after-freeing access of PyMethodDef (macOS Python 3.9.0 segfaults) (#2576)

* Check if valgrind-detected after-freeing access of PyMethodDef causes macOS Python 3.9 segfaults

* fix: only apply leak on 3.9.0

* fix: faster check

* fix: better naming thanks to @bstaletic

Co-authored-by: Henry Schreiner <henryschreineriii@gmail.com>
This commit is contained in:
Yannick Jadoul 2020-10-14 20:11:09 +02:00 committed by GitHub
parent 645d83813b
commit 493649f965
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 15 additions and 7 deletions

View File

@ -70,12 +70,6 @@ jobs:
python: pypy3
arch: x64
# TODO: renable
# Currently segfaults on macOS Python 3.9
- runs-on: macos-latest
python: 3.9
arch: x64
name: "🐍 ${{ matrix.python }} • ${{ matrix.runs-on }} • ${{ matrix.arch }} ${{ matrix.args }}"
runs-on: ${{ matrix.runs-on }}

View File

@ -452,6 +452,12 @@ protected:
/// When a cpp_function is GCed, release any memory allocated by pybind11
static void destruct(detail::function_record *rec) {
// If on Python 3.9, check the interpreter "MICRO" (patch) version.
// If this is running on 3.9.0, we have to work around a bug.
#if !defined(PYPY_VERSION) && PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION == 9
static bool is_zero = Py_GetVersion()[4] == '0';
#endif
while (rec) {
detail::function_record *next = rec->next;
if (rec->free_data)
@ -466,7 +472,15 @@ protected:
}
if (rec->def) {
std::free(const_cast<char *>(rec->def->ml_doc));
delete rec->def;
// Python 3.9.0 decref's these in the wrong order; rec->def
// If loaded on 3.9.0, let these leak (use Python 3.9.1 at runtime to fix)
// See https://github.com/python/cpython/pull/22670
#if !defined(PYPY_VERSION) && PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION == 9
if (!is_zero)
delete rec->def;
#else
delete rec->def;
#endif
}
delete rec;
rec = next;