Skip to content

Commit

Permalink
fix: valgrind-detected after-freeing access of PyMethodDef (macOS Pyt…
Browse files Browse the repository at this point in the history
…hon 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>
  • Loading branch information
YannickJadoul and henryiii authored Oct 14, 2020
1 parent 645d838 commit 493649f
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 7 deletions.
6 changes: 0 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }}

Expand Down
16 changes: 15 additions & 1 deletion include/pybind11/pybind11.h
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,12 @@ class cpp_function : public function {

/// 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)
Expand All @@ -466,7 +472,15 @@ class cpp_function : public function {
}
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;
Expand Down

0 comments on commit 493649f

Please sign in to comment.